static int ofwd_strategy(void *devdata, int flag __unused, daddr_t dblk, size_t size, char *buf, size_t *rsize) { struct ofw_devdesc *dp = (struct ofw_devdesc *)devdata; daddr_t pos; int n; if (dp != kdp) { if (kdp != NULL) { #if !defined(__powerpc__) OF_close(kdp->d_handle); #endif kdp = NULL; } if ((dp->d_handle = OF_open(dp->d_path)) == -1) return (ENOENT); kdp = dp; } pos = dblk * 512; do { if (OF_seek(dp->d_handle, pos) < 0) return (EIO); n = OF_read(dp->d_handle, buf, size); if (n < 0 && n != -2) return (EIO); } while (n == -2); *rsize = size; return (0); }
int ofdisk_close(dev_t dev, int flags, int fmt, struct lwp *l) { struct ofdisk_softc *of = device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); mutex_enter(&of->sc_dk.dk_openlock); switch (fmt) { case S_IFCHR: of->sc_dk.dk_copenmask &= ~(1 << DISKPART(dev)); break; case S_IFBLK: of->sc_dk.dk_bopenmask &= ~(1 << DISKPART(dev)); break; } of->sc_dk.dk_openmask = of->sc_dk.dk_copenmask | of->sc_dk.dk_bopenmask; #ifdef FIRMWORKSBUGS /* * This is a hack to get the firmware to flush its buffers. */ OF_seek(of->sc_ihandle, 0); #endif if (!of->sc_dk.dk_openmask) { OF_close(of->sc_ihandle); of->sc_ihandle = 0; } mutex_exit(&of->sc_dk.dk_openlock); return 0; }
static int ofwd_close(struct open_file *f) { struct ofw_devdesc *dev = f->f_devdata; OF_close(dev->d_handle); return 0; }
static void ofwn_end(struct netif *nif) { #ifdef BROKEN /* dma-free freezes at least some Apple ethernet controllers */ OF_call_method("dma-free", netinstance, 2, 0, dmabuf, MAXPHYS); #endif OF_close(netinstance); }
static int devclose(struct open_file *of) { struct of_dev *op = of->f_devdata; if (op->type == OFDEV_NET) net_close(op); OF_close(op->handle); op->handle = -1; return 0; }
static int devclose(struct open_file *of) { struct of_dev *op = of->f_devdata; #ifdef NETBOOT if (op->type == OFDEV_NET) net_close(op); #endif OF_close(op->handle); op->handle = -1; }
static int devclose(struct open_file *of) { struct of_dev *op = of->f_devdata; if (op->type == OFDEV_NET) net_close(op); OF_call_method("dma-free", op->handle, 2, 0, op->dmabuf, MAXPHYS); OF_close(op->handle); op->handle = -1; return 0; }
static int ofwd_close(struct open_file *f) { struct ofw_devdesc *dev = f->f_devdata; if (dev == kdp) { #if !defined(__powerpc__) OF_close(dev->d_handle); #endif kdp = NULL; } return (0); }
static void fix_cardbus_bridge(int node, pci_chipset_tag_t pc, pcitag_t tag) { uint32_t bus_number = 0xffffffff; pcireg_t bi; int bus, dev, fn, ih, len; char path[256]; #if PB3400_CARDBUS_HACK int root_node; root_node = OF_finddevice("/"); if (of_compatible(root_node, pb3400_compat) != -1) { bus_number = cardbus_number; cardbus_number++; } else { #endif ih = OF_open(path); OF_call_method("load-ata", ih, 0, 0); OF_close(ih); OF_getprop(node, "AAPL,bus-id", &bus_number, sizeof(bus_number)); #if PB3400_CARDBUS_HACK } #endif if (bus_number != 0xffffffff) { len = OF_package_to_path(node, path, sizeof(path)); path[len] = 0; aprint_verbose("\n%s: fixing bus number to %d", path, bus_number); pci_decompose_tag(pc, tag, &bus, &dev, &fn); bi = pci_conf_read(pc, tag, PPB_REG_BUSINFO); bi &= 0xff000000; /* XXX subordinate is always 32 here */ bi |= (bus & 0xff) | (bus_number << 8) | 0x200000; pci_conf_write(pc, tag, PPB_REG_BUSINFO, bi); } }
static int ofwd_open(struct open_file *f, ...) { struct ofw_devdesc *dp; va_list vl; va_start(vl, f); dp = va_arg(vl, struct ofw_devdesc *); va_end(vl); if (dp != kdp) { if (kdp != NULL) { OF_close(kdp->d_handle); kdp = NULL; } if ((dp->d_handle = OF_open(dp->d_path)) == -1) { printf("%s: Could not open %s\n", __func__, dp->d_path); return (ENOENT); } kdp = dp; } return (0); }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; int handle, part; size_t read; char *errmsg = NULL; int error = 0; if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; DNPRINTF(BOOT_D_OFDEV, "devopen: you want %s\n", name); strlcpy(fname, name, sizeof fname); cp = filename(fname, &partition); if (cp) { strlcpy(buf, cp, sizeof buf); *cp = 0; } if (!cp || !*buf) strlcpy(buf, DEFAULT_KERNEL, sizeof buf); if (!*fname) strlcpy(fname, bootdev, sizeof fname); strlcpy(opened_name, fname, sizeof opened_name); if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') strlcat(opened_name, "/", sizeof opened_name); strlcat(opened_name, buf, sizeof opened_name); *file = opened_name + strlen(fname) + 1; DNPRINTF(BOOT_D_OFDEV, "devopen: trying %s\n", fname); if ((handle = OF_finddevice(fname)) == -1) return ENOENT; DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname); if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf); DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname); if ((handle = OF_open(fname)) == -1) { DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname); return ENXIO; } DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname); bzero(&ofdev, sizeof ofdev); ofdev.handle = handle; if (!strcmp(buf, "block")) { ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; /* First try to find a disklabel without MBR partitions */ DNPRINTF(BOOT_D_OFDEV, "devopen: trying to read disklabel\n"); if (strategy(&ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &read) != 0 || read != DEV_BSIZE || (errmsg = getdisklabel(buf, &label))) { #ifdef BOOT_DEBUG if (errmsg) DNPRINTF(BOOT_D_OFDEV, "devopen: getdisklabel says %s\n", errmsg); #endif /* Else try MBR partitions */ errmsg = search_label(&ofdev, LABELSECTOR, buf, &label, 0); if (errmsg) { printf("devopen: search_label says %s\n", errmsg); error = ERDLAB; } if (error && error != ERDLAB) goto bad; } if (error == ERDLAB) { if (partition) /* User specified a parititon, but there is none */ goto bad; /* No, label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; DNPRINTF(BOOT_D_OFDEV, "devopen: setting partition %d " "offset %x\n", part, ofdev.partoff); } of->f_dev = devsw; of->f_devdata = &ofdev; #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); #endif #ifdef SPARC_BOOT_HSFS bcopy(&file_system_cd9660, &file_system[nfsys++], sizeof file_system[0]); #endif DNPRINTF(BOOT_D_OFDEV, "devopen: return 0\n"); return 0; } #ifdef NETBOOT if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = devsw; of->f_devdata = &ofdev; bcopy(&file_system_nfs, file_system, sizeof file_system[0]); nfsys = 1; if (error = net_open(&ofdev)) goto bad; return 0; } #endif error = EFTYPE; bad: DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n", error); OF_close(handle); ofdev.handle = -1; return error; }
static void rtas_setup(void *junk) { ihandle_t rtasi; cell_t rtas_size = 0, rtas_ptr; char path[31]; int result; rtas = OF_finddevice("/rtas"); if (rtas == -1) { rtas = 0; return; } OF_package_to_path(rtas, path, sizeof(path)); rtasi = OF_open(path); if (rtasi == 0) { rtas = 0; printf("Error initializing RTAS: could not open node\n"); return; } mtx_init(&rtas_mtx, "RTAS", MTX_DEF, 0); /* RTAS must be called with everything turned off in MSR */ rtasmsr = mfmsr(); rtasmsr &= ~(PSL_IR | PSL_DR | PSL_EE | PSL_SE); #ifdef __powerpc64__ rtasmsr &= ~PSL_SF; #endif /* * Allocate rtas_size + one page of contiguous, wired physical memory * that can fit into a 32-bit address space and accessed from real mode. * This is used both to bounce arguments and for RTAS private data. * * It must be 4KB-aligned and not cross a 256 MB boundary. */ OF_getprop(rtas, "rtas-size", &rtas_size, sizeof(rtas_size)); rtas_size = round_page(rtas_size); rtas_bounce_virt = contigmalloc(rtas_size + PAGE_SIZE, M_RTAS, 0, 0, ulmin(platform_real_maxaddr(), BUS_SPACE_MAXADDR_32BIT), 4096, 256*1024*1024); rtas_private_data = vtophys(rtas_bounce_virt); rtas_bounce_virt += rtas_size; /* Actual bounce area */ rtas_bounce_phys = vtophys(rtas_bounce_virt); rtas_bounce_size = PAGE_SIZE; /* * Instantiate RTAS. We always use the 32-bit version. */ result = OF_call_method("instantiate-rtas", rtasi, 1, 1, (cell_t)rtas_private_data, &rtas_ptr); OF_close(rtasi); if (result != 0) { rtas = 0; rtas_ptr = 0; printf("Error initializing RTAS (%d)\n", result); return; } rtas_entry = (uintptr_t)(rtas_ptr); }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; struct disklabel label; int handle, part; size_t read; int error = 0; /* allow disk blocks up to 65536 bytes */ char buf[DEV_BSIZE<<7]; if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; strcpy(fname, name); cp = filename(fname, &partition); if (cp) { DPRINTF("filename=%s\n", cp); strcpy(buf, cp); *cp = 0; } if (!cp || !*buf) strcpy(buf, DEFAULT_KERNEL); if (!*fname) strcpy(fname, bootdev); DPRINTF("fname=%s\n", fname); strcpy(opened_name, fname); if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') strcat(opened_name, "/"); strcat(opened_name, buf); *file = opened_name + strlen(fname) + 1; if (partition) { *file += 2; } if ((handle = OF_finddevice(fname)) == -1) { DPRINTF("OF_finddevice(\"%s\") failed\n", fname); return ENOENT; } if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; floppyboot = !strcmp(buf, "floppy"); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; if (!strcmp(buf, "block")) { /* * For block devices, indicate raw partition * (:0 in OpenFirmware) */ strcat(fname, ":0"); } DPRINTF("calling OF_open(fname=%s)\n", fname); if ((handle = OF_open(fname)) == -1) return ENXIO; memset(&ofdev, 0, sizeof ofdev); ofdev.handle = handle; if (!strcmp(buf, "block")) { ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; /* First try to read a disklabel from a NetBSD MBR partition */ error = search_mbr_label(&ofdev, 0, buf, &label, 0); if (error == ERDLAB) { /* Try to construct a disklabel from RDB partitions */ error = search_rdb_label(&ofdev, buf, &label); if (error == ERDLAB) { /* At last read a raw NetBSD disklabel */ error = strategy(&ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &read); if (error == 0 && read != DEV_BSIZE) error = EIO; if (error == 0) if (getdisklabel(buf, &label) != NULL) error = ERDLAB; } } if (error == ERDLAB) { if (partition) { /* * User specified a partition, * but there is none. */ goto bad; } /* No label, just use complete disk */ ofdev.partoff = 0; } else if (error != 0) goto bad; else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; if (label.d_partitions[part].p_fstype == FS_RAID) { #define RF_PROTECTED_SECTORS 64 ofdev.partoff += RF_PROTECTED_SECTORS; DPRINTF("devopen: found RAID partition, " "adjusting offset to %lx\n", ofdev.partoff); } } of->f_dev = devsw; of->f_devdata = &ofdev; file_system[0] = file_system_ufs; file_system[1] = file_system_cd9660; file_system[2] = file_system_dosfs; nfsys = 3; return 0; } if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = devsw; of->f_devdata = &ofdev; file_system[0] = file_system_nfs; nfsys = 1; if ((error = net_open(&ofdev)) != 0) goto bad; return 0; } error = EFTYPE; bad: OF_close(handle); ofdev.handle = -1; return error; }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; int handle, part; size_t nread; int error = 0; if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; strcpy(fname, name); cp = filename(fname, &partition); if (cp) { strcpy(buf, cp); *cp = 0; } if (!cp || !*buf) return ENOENT; if (!*fname) strcpy(fname, bootdev); strcpy(opened_name, fname); if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') strcat(opened_name, "/"); strcat(opened_name, buf); *file = opened_name + strlen(fname) + 1; if ((handle = OF_finddevice(fname)) == -1) return ENOENT; if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; floppyboot = !strcmp(buf, "floppy"); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; #if 0 if (!strcmp(buf, "block")) /* * For block devices, indicate raw partition * (:0 in OpenFirmware) */ strcat(fname, ":0"); #endif if ((handle = OF_open(fname)) == -1) return ENXIO; memset(&ofdev, 0, sizeof ofdev); ofdev.handle = handle; ofdev.dmabuf = NULL; OF_call_method("dma-alloc", handle, 1, 1, MAXPHYS, &ofdev.dmabuf); if (!strcmp(buf, "block")) { ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; /* First try to find a disklabel without MBR partitions */ if (strategy(&ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &nread) != 0 || nread != DEV_BSIZE || getdisklabel(buf, &label)) { /* Else try MBR partitions */ error = search_label(&ofdev, 0, buf, &label, 0); if (error && error != ERDLAB) goto bad; } if (error == ERDLAB) { if (partition) /* * User specified a parititon, * but there is none */ goto bad; /* No, label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; } of->f_dev = of_devsw; of->f_devdata = &ofdev; file_system[0] = file_system_ffsv1; file_system[1] = file_system_ffsv2; file_system[2] = file_system_lfsv1; file_system[3] = file_system_lfsv2; file_system[4] = file_system_ustarfs; file_system[5] = file_system_cd9660; file_system[6] = file_system_hfs; nfsys = 7; return 0; } if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = of_devsw; of->f_devdata = &ofdev; file_system[0] = file_system_nfs; nfsys = 1; if ((error = net_open(&ofdev))) goto bad; return 0; } error = EFTYPE; bad: OF_close(handle); ofdev.handle = -1; return error; }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; int handle, part; int error = 0; #ifdef SOFTRAID char volno; #endif if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; DNPRINTF(BOOT_D_OFDEV, "devopen: you want %s\n", name); if (strlcpy(fname, name, sizeof fname) >= sizeof fname) return ENAMETOOLONG; #ifdef SOFTRAID if (bootdev_dip) { if (fname[0] == 's' && fname[1] == 'r' && '0' <= fname[2] && fname[2] <= '9') { volno = fname[2]; if ('a' <= fname[3] && fname[3] <= 'a' + MAXPARTITIONS) { partition = fname[3]; if (fname[4] == ':') cp = &fname[5]; else cp = &fname[4]; } else { partition = 'a'; cp = &fname[3]; } } else { volno = '0'; partition = 'a'; cp = &fname[0]; } snprintf(buf, sizeof buf, "sr%c:%c", volno, partition); if (strlcpy(opened_name, buf, sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; *file = opened_name + strlen(opened_name); if (!*cp) { if (strlcpy(buf, DEFAULT_KERNEL, sizeof buf) >= sizeof buf) return ENAMETOOLONG; } else { if (snprintf(buf, sizeof buf, "%s%s", *cp == '/' ? "" : "/", cp) >= sizeof buf) return ENAMETOOLONG; } if (strlcat(opened_name, buf, sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; } else { #endif cp = filename(fname, &partition); if (cp) { if (strlcpy(buf, cp, sizeof buf) >= sizeof buf) return ENAMETOOLONG; *cp = 0; } if (!cp || !*buf) { if (strlcpy(buf, DEFAULT_KERNEL, sizeof buf) >= sizeof buf) return ENAMETOOLONG; } if (!*fname) { if (strlcpy(fname, bootdev, sizeof fname) >= sizeof fname) return ENAMETOOLONG; } if (strlcpy(opened_name, fname, partition ? (sizeof opened_name) - 2 : sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') { if (strlcat(opened_name, "/", sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; } if (strlcat(opened_name, buf, sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; *file = opened_name + strlen(fname) + 1; #ifdef SOFTRAID } #endif DNPRINTF(BOOT_D_OFDEV, "devopen: trying %s\n", fname); #ifdef SOFTRAID if (bootdev_dip) { /* Redirect to the softraid boot volume. */ struct partition *pp; bzero(&ofdev, sizeof ofdev); ofdev.type = OFDEV_SOFTRAID; if (partition) { if (partition < 'a' || partition >= 'a' + MAXPARTITIONS) { printf("invalid partition '%c'\n", partition); return EINVAL; } part = partition - 'a'; pp = &bootdev_dip->disklabel.d_partitions[part]; if (pp->p_fstype == FS_UNUSED || pp->p_size == 0) { printf("invalid partition '%c'\n", partition); return EINVAL; } bootdev_dip->sr_vol->sbv_part = partition; } else bootdev_dip->sr_vol->sbv_part = 'a'; of->f_dev = devsw; of->f_devdata = &ofdev; #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); #else #error "-DSOFTRAID requires -DSPARC_BOOT_UFS" #endif return 0; } #endif if ((handle = OF_finddevice(fname)) == -1) return ENOENT; DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname); if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf); DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname); if ((handle = OF_open(fname)) == -1) { DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname); return ENXIO; } DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname); bzero(&ofdev, sizeof ofdev); ofdev.handle = handle; ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; if (!strcmp(buf, "block")) { error = load_disklabel(&ofdev, &label); if (error && error != ERDLAB) goto bad; else if (error == ERDLAB) { if (partition) /* User specified a parititon, but there is none */ goto bad; /* No, label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; DNPRINTF(BOOT_D_OFDEV, "devopen: setting partition %d " "offset %x\n", part, ofdev.partoff); } of->f_dev = devsw; of->f_devdata = &ofdev; #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); #endif #ifdef SPARC_BOOT_HSFS bcopy(&file_system_cd9660, &file_system[nfsys++], sizeof file_system[0]); #endif DNPRINTF(BOOT_D_OFDEV, "devopen: return 0\n"); return 0; } #ifdef NETBOOT if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = devsw; of->f_devdata = &ofdev; bcopy(&file_system_nfs, file_system, sizeof file_system[0]); nfsys = 1; if (error = net_open(&ofdev)) goto bad; return 0; } #endif error = EFTYPE; bad: DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n", error); OF_close(handle); ofdev.handle = -1; return error; }
static void ofwn_end(struct netif *nif) { OF_call_method("dma-free", netinstance, 2, 0, dmabuf, MAXPHYS); OF_close(netinstance); }
int hfs_close(struct open_file *f) { OF_close(OF_fd); return 0; }