void OF_init(int (*openfirm)(void *)) { phandle_t options; char mode[sizeof("true")]; openfirmware = openfirm; if ((chosen = OF_finddevice("/chosen")) == -1) OF_exit(); if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1) { memory = OF_open("/memory"); if (memory == -1) memory = OF_open("/memory@0"); if (memory == -1) OF_exit(); } if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1) OF_exit(); /* * Check if we run in real mode. If so, we do not need to map * memory later on. */ options = OF_finddevice("/options"); if (OF_getprop(options, "real-mode?", mode, sizeof(mode)) > 0 && strcmp(mode, "true") == 0) real_mode = 1; }
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); }
vt_efb_initialize(struct fb_info *info) #endif { #ifdef FDT char name[64]; cell_t retval; ihandle_t ih; int i; /* Open display device, thereby initializing it */ memset(name, 0, sizeof(name)); OF_package_to_path(node, name, sizeof(name)); ih = OF_open(name); #endif /* * Set up the color map */ switch (info->fb_depth) { case 8: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x7, 5, 0x7, 2, 0x3, 0); break; case 15: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x1f, 10, 0x1f, 5, 0x1f, 0); break; case 16: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x1f, 11, 0x3f, 5, 0x1f, 0); break; case 24: case 32: #if BYTE_ORDER == BIG_ENDIAN vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); #else vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); #endif #ifdef FDT for (i = 0; i < 16; i++) { OF_call_method("color!", ih, 4, 1, (cell_t)((info->fb_cmap[i] >> 16) & 0xff), (cell_t)((info->fb_cmap[i] >> 8) & 0xff), (cell_t)((info->fb_cmap[i] >> 0) & 0xff), (cell_t)i, &retval); } #endif break; default: panic("Unknown color space fb_depth %d", info->fb_depth); break; } }
static void ofwn_init(struct iodesc *desc, void *machdep_hint) { phandle_t netdev; char path[64]; char *ch; int pathlen; pathlen = OF_getprop(chosen, "bootpath", path, 64); if ((ch = index(path, ':')) != NULL) *ch = '\0'; netdev = OF_finddevice(path); #ifdef __sparc64__ if (OF_getprop(netdev, "mac-address", desc->myea, 6) == -1) #else if (OF_getprop(netdev, "local-mac-address", desc->myea, 6) == -1) #endif goto punt; printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea)); if ((netinstance = OF_open(path)) == -1) { printf("Could not open network device.\n"); goto punt; } #if defined(NETIF_DEBUG) printf("ofwn_init: Open Firmware instance handle: %08x\n", netinstance); #endif #ifndef __sparc64__ dmabuf = NULL; if (OF_call_method("dma-alloc", netinstance, 1, 1, (64 * 1024), &dmabuf) < 0) { printf("Failed to allocate DMA buffer (got %08x).\n", dmabuf); goto punt; } #if defined(NETIF_DEBUG) printf("ofwn_init: allocated DMA buffer: %08x\n", dmabuf); #endif #endif return; punt: printf("\n"); printf("Could not boot from %s.\n", path); OF_enter(); }
static int ofwd_open(struct open_file *f, ...) { struct ofw_devdesc *dp; phandle_t handle; va_list vl; va_start(vl, f); dp = va_arg(vl, struct ofw_devdesc *); va_end(vl); if ((handle = OF_open(dp->d_path)) == -1) { printf("ofwd_open: Could not open %s\n", dp->d_path); return 1; } dp->d_handle = handle; return 0; }
static void ofnet_attach(struct device *parent, struct device *self, void *aux) { struct ofnet_softc *of = device_private(self); struct ifnet *ifp = &of->sc_ethercom.ec_if; struct ofbus_attach_args *oba = aux; char path[256]; int l; u_int8_t myaddr[ETHER_ADDR_LEN]; of->sc_phandle = oba->oba_phandle; #if NIPKDB_OFN > 0 if (kifp && kifp->unit - 1 == device_unit(&of->sc_dev) && OF_instance_to_package(kifp->port) == oba->oba_phandle) { ipkdb_of = of; of->sc_ihandle = kifp->port; } else #endif if ((l = OF_package_to_path(oba->oba_phandle, path, sizeof path - 1)) < 0 || l >= sizeof path || (path[l] = 0, !(of->sc_ihandle = OF_open(path)))) panic("ofnet_attach: unable to open"); if (OF_getprop(oba->oba_phandle, "mac-address", myaddr, sizeof myaddr) < 0) panic("ofnet_attach: no mac-address"); printf(": address %s\n", ether_sprintf(myaddr)); callout_init(&of->sc_callout, 0); strlcpy(ifp->if_xname, device_xname(&of->sc_dev), IFNAMSIZ); ifp->if_softc = of; ifp->if_start = ofnet_start; ifp->if_ioctl = ofnet_ioctl; ifp->if_watchdog = ofnet_watchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); ether_ifattach(ifp, myaddr); }
int hfs_open(char *path, struct open_file *f) { int chosen; char bootpath[128], *cp; if ((chosen = OF_finddevice("/chosen")) == -1) return ENXIO; bzero(bootpath, sizeof bootpath); OF_getprop(chosen, "bootpath", bootpath, sizeof bootpath); cp = strrchr(bootpath, ','); if (cp == NULL) return ENXIO; strlcpy(cp + 1, path, bootpath + sizeof bootpath - (cp + 1)); OF_fd = OF_open(bootpath); if (OF_fd == -1) return ENOENT; 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 ofwfb_set_mode(video_adapter_t *adp, int mode) { struct ofwfb_softc *sc; char name[64]; ihandle_t ih; int i, retval; sc = (struct ofwfb_softc *)adp; if (ofwfb_reset_on_switch) { /* * Open the display device, which will initialize it. */ memset(name, 0, sizeof(name)); OF_package_to_path(sc->sc_node, name, sizeof(name)); ih = OF_open(name); if (sc->sc_depth == 8) { /* * Install the ISO6429 colormap - older OFW systems * don't do this by default */ for (i = 0; i < 16; i++) { OF_call_method("color!", ih, 4, 1, ofwfb_cmap[i].red, ofwfb_cmap[i].green, ofwfb_cmap[i].blue, i, &retval); } } } ofwfb_blank_display(&sc->sc_va, V_DISPLAY_ON); return (0); }
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; 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; }
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); }
/* * Called back during autoconfiguration for each device found */ void device_register(device_t dev, void *aux) { device_t busdev = device_parent(dev); int ofnode = 0; /* * We don't know the type of 'aux' - it depends on the * bus this device attaches to. We are only interested in * certain bus types, this only is used to find the boot * device. */ if (busdev == NULL) { /* * Ignore mainbus0 itself, it certainly is not a boot * device. */ } else if (device_is_a(busdev, "mainbus")) { struct mainbus_attach_args *ma = aux; ofnode = ma->ma_node; } else if (device_is_a(busdev, "pci")) { struct pci_attach_args *pa = aux; ofnode = PCITAG_NODE(pa->pa_tag); } else if (device_is_a(busdev, "sbus") || device_is_a(busdev, "dma") || device_is_a(busdev, "ledma")) { struct sbus_attach_args *sa = aux; ofnode = sa->sa_node; } else if (device_is_a(busdev, "ebus")) { struct ebus_attach_args *ea = aux; ofnode = ea->ea_node; } else if (device_is_a(busdev, "iic")) { struct i2c_attach_args *ia = aux; if (ia->ia_name == NULL) /* indirect config */ return; ofnode = (int)ia->ia_cookie; } else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; int off = 0; /* * There are two "cd" attachments: * atapibus -> atabus -> controller * scsibus -> controller * We want the node of the controller. */ if (device_is_a(busdev, "atapibus")) { busdev = device_parent(busdev); /* * if the atapibus is connected to the secondary * channel of the atabus, we need an offset of 2 * to match OF's idea of the target number. * (i.e. on U5/U10 "cdrom" and "disk2" have the * same target encoding, though different names) */ if (periph->periph_channel->chan_channel == 1) off = 2; } ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, periph->periph_target + off, 0, periph->periph_lun); return; } else if (device_is_a(dev, "wd")) { struct ata_device *adev = aux; ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, adev->adev_channel*2+ adev->adev_drv_data->drive, 0, 0); return; } if (busdev == NULL) return; if (ofnode != 0) { uint8_t eaddr[ETHER_ADDR_LEN]; char tmpstr[32]; char tmpstr2[32]; int node; uint32_t id = 0; uint64_t nwwn = 0, pwwn = 0; prop_dictionary_t dict; prop_data_t blob; prop_number_t pwwnd = NULL, nwwnd = NULL; prop_number_t idd = NULL; device_setofnode(dev, ofnode); dev_path_exact_match(dev, ofnode); if (OF_getprop(ofnode, "name", tmpstr, sizeof(tmpstr)) <= 0) tmpstr[0] = 0; if (OF_getprop(ofnode, "device_type", tmpstr2, sizeof(tmpstr2)) <= 0) tmpstr2[0] = 0; /* * If this is a network interface, note the * mac address. */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr, "ethernet") == 0 || strcmp(tmpstr2, "network") == 0 || strcmp(tmpstr2, "ethernet") == 0 || OF_getprop(ofnode, "mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN || OF_getprop(ofnode, "local-mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN) { dict = device_properties(dev); /* * Is it a network interface with FCode? */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr2, "network") == 0) { prop_dictionary_set_bool(dict, "without-seeprom", true); prom_getether(ofnode, eaddr); } else { if (!prom_get_node_ether(ofnode, eaddr)) goto noether; } blob = prop_data_create_data(eaddr, ETHER_ADDR_LEN); prop_dictionary_set(dict, "mac-address", blob); prop_object_release(blob); of_to_dataprop(dict, ofnode, "shared-pins", "shared-pins"); } noether: /* is this a FC node? */ if (strcmp(tmpstr, "scsi-fcp") == 0) { dict = device_properties(dev); if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn)) == sizeof(pwwn)) { pwwnd = prop_number_create_unsigned_integer(pwwn); prop_dictionary_set(dict, "port-wwn", pwwnd); prop_object_release(pwwnd); } if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn)) == sizeof(nwwn)) { nwwnd = prop_number_create_unsigned_integer(nwwn); prop_dictionary_set(dict, "node-wwn", nwwnd); prop_object_release(nwwnd); } } /* is this an spi device? look for scsi-initiator-id */ if (strcmp(tmpstr2, "scsi") == 0 || strcmp(tmpstr2, "scsi-2") == 0) { dict = device_properties(dev); for (node = ofnode; node != 0; node = OF_parent(node)) { if (OF_getprop(node, "scsi-initiator-id", &id, sizeof(id)) <= 0) continue; idd = prop_number_create_unsigned_integer(id); prop_dictionary_set(dict, "scsi-initiator-id", idd); prop_object_release(idd); break; } } } /* * Check for I2C busses and add data for their direct configuration. */ if (device_is_a(dev, "iic")) { int busnode = device_ofnode(busdev); if (busnode) { prop_dictionary_t props = device_properties(busdev); prop_object_t cfg = prop_dictionary_get(props, "i2c-child-devices"); if (!cfg) { int node; const char *name; /* * pmu's i2c devices are under the "i2c" node, * so find it out. */ name = prom_getpropstring(busnode, "name"); if (strcmp(name, "pmu") == 0) { for (node = OF_child(busnode); node != 0; node = OF_peer(node)) { name = prom_getpropstring(node, "name"); if (strcmp(name, "i2c") == 0) { busnode = node; break; } } } of_enter_i2c_devs(props, busnode, sizeof(cell_t)); } } /* * Add SPARCle spdmem devices (0x50 and 0x51) that the * firmware does not know about. */ if (!strcmp(machine_model, "TAD,SPARCLE")) { prop_dictionary_t props = device_properties(busdev); prop_array_t cfg = prop_array_create(); int i; DPRINTF(ACDB_PROBE, ("\nAdding spdmem for SPARCle ")); for (i = 0x50; i <= 0x51; i++) { prop_dictionary_t spd = prop_dictionary_create(); prop_dictionary_set_cstring(spd, "name", "dimm-spd"); prop_dictionary_set_uint32(spd, "addr", i); prop_dictionary_set_uint64(spd, "cookie", 0); prop_array_add(cfg, spd); prop_object_release(spd); } prop_dictionary_set(props, "i2c-child-devices", cfg); prop_object_release(cfg); } } /* set properties for PCI framebuffers */ if (device_is_a(busdev, "pci")) { /* see if this is going to be console */ struct pci_attach_args *pa = aux; prop_dictionary_t dict; int sub; int console = 0; dict = device_properties(dev); /* we only care about display devices from here on */ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) return; console = (ofnode == console_node); if (!console) { /* * see if any child matches since OF attaches * nodes for each head and /chosen/stdout * points to the head rather than the device * itself in this case */ sub = OF_child(ofnode); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } copyprops(busdev, ofnode, dict, console); if (console) { uint64_t cmap_cb; prop_dictionary_set_uint32(dict, "instance_handle", console_instance); gfb_cb.gcc_cookie = (void *)(intptr_t)console_instance; gfb_cb.gcc_set_mapreg = of_set_palette; cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); } #ifdef notyet else { int width; /* * the idea is to 'open' display devices with no useful * properties, in the hope that the firmware will * properly initialize them and we can run things like * genfb on them */ if (OF_getprop(node, "width", &width, sizeof(width)) != 4) { instance = OF_open(name); #endif } } /* * Called back after autoconfiguration of a device is done */ void device_register_post_config(device_t dev, void *aux) { if (booted_device == NULL && device_is_a(dev, "sd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; uint64_t wwn = 0; int ofnode; /* * If this is a FC-AL drive it will have * aquired its WWN device property by now, * so we can properly match it. */ if (prop_dictionary_get_uint64(device_properties(dev), "port-wwn", &wwn)) { /* * Different to what we do in device_register, * we do not pass the "controller" ofnode, * because FC-AL devices attach below a "fp" node, * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk * and we need the parent of "disk" here. */ ofnode = device_ofnode( device_parent(device_parent(dev))); for (ofnode = OF_child(ofnode); ofnode != 0 && booted_device == NULL; ofnode = OF_peer(ofnode)) { dev_path_drive_match(dev, ofnode, periph->periph_target, wwn, periph->periph_lun); } } } } static void copyprops(device_t busdev, int node, prop_dictionary_t dict, int is_console) { device_t cntrlr; prop_dictionary_t psycho; paddr_t fbpa, mem_base = 0; uint32_t temp, fboffset; uint32_t fbaddr = 0; int options; char output_device[256]; char *pos; cntrlr = device_parent(busdev); if (cntrlr != NULL) { psycho = device_properties(cntrlr); prop_dictionary_get_uint64(psycho, "mem_base", &mem_base); } if (is_console) prop_dictionary_set_bool(dict, "is_console", 1); of_to_uint32_prop(dict, node, "width", "width"); of_to_uint32_prop(dict, node, "height", "height"); of_to_uint32_prop(dict, node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, node, "depth", "depth") && /* Some cards have an extra space in the property name */ !of_to_uint32_prop(dict, node, "depth ", "depth")) { /* * XXX we should check linebytes vs. width but those * FBs that don't have a depth property ( /chaos/control... ) * won't have linebytes either */ prop_dictionary_set_uint32(dict, "depth", 8); } OF_getprop(node, "address", &fbaddr, sizeof(fbaddr)); if (fbaddr != 0) { pmap_extract(pmap_kernel(), fbaddr, &fbpa); #ifdef DEBUG printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base, (unsigned long)fbpa); #endif if (mem_base == 0) { /* XXX this is guesswork */ fboffset = (uint32_t)(fbpa & 0xffffffff); } fboffset = (uint32_t)(fbpa - mem_base); prop_dictionary_set_uint32(dict, "address", fboffset); } if (!of_to_dataprop(dict, node, "EDID", "EDID")) of_to_dataprop(dict, node, "edid", "EDID"); temp = 0; if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { OF_getprop(OF_parent(node), "ATY,RefCLK", &temp, sizeof(temp)); } if (temp != 0) prop_dictionary_set_uint32(dict, "refclk", temp / 10); /* * finally, let's see if there's a video mode specified in * output-device and pass it on so drivers like radeonfb * can do their thing */ if (!is_console) return; options = OF_finddevice("/options"); if ((options == 0) || (options == -1)) return; if (OF_getprop(options, "output-device", output_device, 256) == 0) return; /* find the mode string if there is one */ pos = strstr(output_device, ":r"); if (pos == NULL) return; prop_dictionary_set_cstring(dict, "videomode", pos + 2); } static void of_set_palette(void *cookie, int index, int r, int g, int b) { int ih = (int)((intptr_t)cookie); OF_call_method_1("color!", ih, 4, r, g, b, index); }
void bmac_attach(struct device *parent, struct device *self, void *aux) { struct confargs *ca = aux; struct bmac_softc *sc = (void *)self; struct ifnet *ifp = &sc->sc_if; struct mii_data *mii = &sc->sc_mii; u_char laddr[6]; callout_init(&sc->sc_tick_ch, 0); sc->sc_flags =0; if (strcmp(ca->ca_name, "ethernet") == 0) { char name[64]; memset(name, 0, 64); OF_package_to_path(ca->ca_node, name, sizeof(name)); OF_open(name); sc->sc_flags |= BMAC_BMACPLUS; } ca->ca_reg[0] += ca->ca_baseaddr; ca->ca_reg[2] += ca->ca_baseaddr; ca->ca_reg[4] += ca->ca_baseaddr; sc->sc_iot = ca->ca_tag; if (bus_space_map(sc->sc_iot, ca->ca_reg[0], ca->ca_reg[1], 0, &sc->sc_ioh) != 0) { aprint_error(": couldn't map %#x", ca->ca_reg[0]); return; } bmac_write_reg(sc, INTDISABLE, NoEventsMask); if (OF_getprop(ca->ca_node, "local-mac-address", laddr, 6) == -1 && OF_getprop(ca->ca_node, "mac-address", laddr, 6) == -1) { printf(": cannot get mac-address\n"); return; } memcpy(sc->sc_enaddr, laddr, 6); sc->sc_txdma = mapiodev(ca->ca_reg[2], PAGE_SIZE); sc->sc_rxdma = mapiodev(ca->ca_reg[4], PAGE_SIZE); sc->sc_txcmd = dbdma_alloc(BMAC_TXBUFS * sizeof(dbdma_command_t)); sc->sc_rxcmd = dbdma_alloc((BMAC_RXBUFS + 1) * sizeof(dbdma_command_t)); sc->sc_txbuf = malloc(BMAC_BUFLEN * BMAC_TXBUFS, M_DEVBUF, M_NOWAIT); sc->sc_rxbuf = malloc(BMAC_BUFLEN * BMAC_RXBUFS, M_DEVBUF, M_NOWAIT); if (sc->sc_txbuf == NULL || sc->sc_rxbuf == NULL || sc->sc_txcmd == NULL || sc->sc_rxcmd == NULL) { printf("cannot allocate memory\n"); return; } printf(" irq %d,%d: address %s\n", ca->ca_intr[0], ca->ca_intr[2], ether_sprintf(laddr)); intr_establish(ca->ca_intr[0], IST_EDGE, IPL_NET, bmac_intr, sc); intr_establish(ca->ca_intr[2], IST_EDGE, IPL_NET, bmac_rint, sc); memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_ioctl = bmac_ioctl; ifp->if_start = bmac_start; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; ifp->if_watchdog = bmac_watchdog; IFQ_SET_READY(&ifp->if_snd); mii->mii_ifp = ifp; mii->mii_readreg = bmac_mii_readreg; mii->mii_writereg = bmac_mii_writereg; mii->mii_statchg = bmac_mii_statchg; sc->sc_ethercom.ec_mii = mii; ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); /* Choose a default media. */ if (LIST_FIRST(&mii->mii_phys) == NULL) { ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_10_T, 0, NULL); ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_10_T); } else ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); bmac_reset_chip(sc); if_attach(ifp); ether_ifattach(ifp, sc->sc_enaddr); }
static void ofwpci_attach(device_t parent, device_t self, void *aux) { struct ofwpci_softc *sc = device_private(self); pci_chipset_tag_t pc = &sc->sc_pc; struct confargs *ca = aux; struct pcibus_attach_args pba; struct genppc_pci_chipset_businfo *pbi; int node = ca->ca_node; int i, isprim = 0; uint32_t busrange[2]; char buf[64]; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #endif aprint_normal("\n"); sc->sc_dev = self; /* PCI bus number */ if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8) return; /* bus space map the io ranges */ sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE; sc->sc_iot.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot, "ofwpci io-space") != 0) panic("Can't init ofwpci io tag"); sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE; sc->sc_memt.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt, "ofwpci mem-space") != 0) panic("Can't init ofwpci mem tag"); aprint_debug("io base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n", sc->sc_iot.pbs_base, sc->sc_iot.pbs_offset, sc->sc_iot.pbs_limit); aprint_debug("mem base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n", sc->sc_memt.pbs_base, sc->sc_memt.pbs_offset, sc->sc_memt.pbs_limit); /* are we the primary pci bus? */ if (of_find_firstchild_byname(OF_finddevice("/"), "pci") == node) { int isa_node; isprim++; /* yes we are, now do we have an ISA child? */ isa_node = of_find_firstchild_byname(node, "isa"); if (isa_node != -1) { /* isa == pci */ genppc_isa_io_space_tag = sc->sc_iot; genppc_isa_mem_space_tag = sc->sc_memt; map_isa_ioregs(); init_ofppc_interrupt(); ofppc_init_comcons(isa_node); } } ofwpci_get_chipset_tag(pc); pc->pc_node = node; i = OF_package_to_path(node, buf, sizeof(buf)-5); if (i <= 0) panic("Can't determine path for pci node %d", node); buf[i] = '\0'; pc->pc_ihandle = OF_open(buf); if (pc->pc_ihandle < 0) panic("Can't open device %s", buf); pc->pc_bus = busrange[0]; pc->pc_iot = &sc->sc_iot; pc->pc_memt = &sc->sc_memt; pbi = malloc(sizeof(struct genppc_pci_chipset_businfo), M_DEVBUF, M_NOWAIT); KASSERT(pbi != NULL); pbi->pbi_properties = prop_dictionary_create(); KASSERT(pbi->pbi_properties != NULL); SIMPLEQ_INIT(&pc->pc_pbi); SIMPLEQ_INSERT_TAIL(&pc->pc_pbi, pbi, next); genofw_setup_pciintr_map((void *)pc, pbi, pc->pc_node); #ifdef PCI_NETBSD_CONFIGURE ioext = extent_create("pciio", modeldata.pciiodata[device_unit(self)].start, modeldata.pciiodata[device_unit(self)].limit, NULL, 0, EX_NOWAIT); memext = extent_create("pcimem", sc->sc_memt.pbs_base, sc->sc_memt.pbs_limit-1, NULL, 0, EX_NOWAIT); if (pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINESIZE)) aprint_error("pci_configure_bus() failed\n"); extent_destroy(ioext); extent_destroy(memext); #endif /* PCI_NETBSD_CONFIGURE */ memset(&pba, 0, sizeof(pba)); pba.pba_memt = pc->pc_memt; pba.pba_iot = pc->pc_iot; pba.pba_dmat = &pci_bus_dma_tag; pba.pba_dmat64 = NULL; pba.pba_bus = pc->pc_bus; pba.pba_bridgetag = NULL; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; config_found_ia(self, "pcibus", &pba, pcibusprint); }
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 ofdisk_open(dev_t dev, int flags, int fmt, struct lwp *lwp) { struct ofdisk_softc *of; char path[256]; int error, l, part; of = device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); if (of == NULL) return ENXIO; part = DISKPART(dev); mutex_enter(&of->sc_dk.dk_openlock); /* * If there are wedges, and this is not RAW_PART, then we * need to fail. */ if (of->sc_dk.dk_nwedges != 0 && part != RAW_PART) { error = EBUSY; goto bad1; } if (!of->sc_ihandle) { if ((l = OF_package_to_path(of->sc_phandle, path, sizeof path - 3)) < 0 || l >= sizeof path - 3) { error = ENXIO; goto bad1; } path[l] = 0; /* * XXX This is for the benefit of SCSI/IDE disks that don't * XXX have all their childs in the device tree. * XXX YES, I DO THINK THIS IS A BUG IN OPENFIRMWARE!!! * XXX And yes, this is a very gross hack! * XXX See also ofscsi.c */ if (!strcmp(path + l - 4, "disk")) { path[l++] = '@'; path[l++] = '0' + of->sc_unit; path[l] = 0; } strlcat(path, ":0", sizeof(path)); if ((of->sc_ihandle = OF_open(path)) == -1) { error = ENXIO; goto bad1; } /* * Try to get characteristics of the disk. */ of->max_transfer = OF_call_method_1("max-transfer", of->sc_ihandle, 0); if (of->max_transfer > MAXPHYS) of->max_transfer = MAXPHYS; ofdisk_getdisklabel(dev); } switch (fmt) { case S_IFCHR: of->sc_dk.dk_copenmask |= 1 << part; break; case S_IFBLK: of->sc_dk.dk_bopenmask |= 1 << part; break; } of->sc_dk.dk_openmask = of->sc_dk.dk_copenmask | of->sc_dk.dk_bopenmask; error = 0; bad1: mutex_exit(&of->sc_dk.dk_openlock); return (error); }
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; }