/* ARGSUSED */ int hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name) { char *path; char *s1; char *index; int name_start; vertex_hdl_t handle = NULL; int rv; int i, count; path = kmalloc(1024, GFP_KERNEL); memset(path, 0x0, 1024); name_start = devfs_generate_path (from, path, 1024); s1 = &path[name_start]; count = 0; while (1) { index = strstr (s1, "/"); if (index) { count++; s1 = ++index; } else { count++; break; } } memset(path, 0x0, 1024); name_start = devfs_generate_path (to, path, 1024); for (i = 0; i < count; i++) { strcat(path,"../"); } strcat(path, &path[name_start]); /* * Otherwise, just create a symlink to the vertex. * In this case the vertex was previous created with a REAL pathname. */ rv = devfs_mk_symlink (from, (const char *)name, DEVFS_FL_DEFAULT, path, &handle, NULL); name_start = devfs_generate_path (handle, path, 1024); return(rv); }
pciio_info_t pciio_info_get(vertex_hdl_t pciio) { pciio_info_t pciio_info; pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio); #ifdef DEBUG_PCIIO { int pos; char dname[256]; pos = devfs_generate_path(pciio, dname, 256); printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); } #endif /* DEBUG_PCIIO */ if ((pciio_info != NULL) && (pciio_info->c_fingerprint != pciio_info_fingerprint) && (pciio_info->c_fingerprint != NULL)) { return((pciio_info_t)-1); /* Should panic .. */ } return pciio_info; }
vertex_hdl_t pciio_device_info_register( vertex_hdl_t connectpt, /* vertex at center of bus */ pciio_info_t pciio_info) /* details about the connectpt */ { char name[32]; vertex_hdl_t pconn; int device_master_set(vertex_hdl_t, vertex_hdl_t); pciio_slot_func_to_name(name, pciio_info->c_slot, pciio_info->c_func); if (GRAPH_SUCCESS != hwgraph_path_add(connectpt, name, &pconn)) return pconn; pciio_info->c_vertex = pconn; pciio_info_set(pconn, pciio_info); #ifdef DEBUG_PCIIO { int pos; char dname[256]; pos = devfs_generate_path(pconn, dname, 256); printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]); } #endif /* DEBUG_PCIIO */ /* * create link to our pci provider */ device_master_set(pconn, pciio_info->c_master); return pconn; }
int hwgraph_generate_path( vertex_hdl_t de, char *path, int buflen) { return (devfs_generate_path(de, path, buflen)); }
devfs_handle_t pciio_device_info_register( devfs_handle_t connectpt, /* vertex at center of bus */ pciio_info_t pciio_info) /* details about the connectpt */ { char name[32]; devfs_handle_t pconn; pciio_slot_func_to_name(name, pciio_info->c_slot, pciio_info->c_func); if (GRAPH_SUCCESS != hwgraph_path_add(connectpt, name, &pconn)) return pconn; pciio_info->c_vertex = pconn; pciio_info_set(pconn, pciio_info); #ifdef BRINGUP { int pos; char dname[256]; pos = devfs_generate_path(pconn, dname, 256); #ifdef DEBUG_PCIIO printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]); #endif } #endif /* BRINGUP */ /* * create link to our pci provider */ device_master_set(pconn, pciio_info->c_master); #if USRPCI /* * Call into usrpci provider to let it initialize for * the given slot. */ if (pciio_info->c_slot != PCIIO_SLOT_NONE) usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot); #endif return pconn; }
static int __init create_dev(char *name, kdev_t dev, char *devfs_name) { void *handle; char path[64]; int n; sys_unlink(name); if (!do_devfs) return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev)); handle = devfs_find_handle(NULL, dev ? NULL : devfs_name, MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1); if (!handle) return -1; n = devfs_generate_path(handle, path + 5, sizeof (path) - 5); if (n < 0) return -1; return sys_symlink(path + n + 5, name); }
pciio_info_t pciio_info_get(devfs_handle_t pciio) { pciio_info_t pciio_info; pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio); #ifdef DEBUG_PCIIO { int pos; char dname[256]; pos = devfs_generate_path(pciio, dname, 256); printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); } #endif /* DEBUG_PCIIO */ #ifdef BRINGUP if ((pciio_info != NULL) && (pciio_info->c_fingerprint != pciio_info_fingerprint) && (pciio_info->c_fingerprint != NULL)) { #else if ((pciio_info != NULL) && (pciio_info->c_fingerprint != pciio_info_fingerprint)) { #endif /* BRINGUP */ return((pciio_info_t)-1); /* Should panic .. */ } return pciio_info; } void pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info) { if (pciio_info != NULL) pciio_info->c_fingerprint = pciio_info_fingerprint; hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info); /* Also, mark this vertex as a PCI slot * and use the pciio_info, so pciio_info_chk * can work (and be fairly efficient). */ hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO, (arbitrary_info_t) pciio_info); } devfs_handle_t pciio_info_dev_get(pciio_info_t pciio_info) { return (pciio_info->c_vertex); } /*ARGSUSED*/ pciio_bus_t pciio_info_bus_get(pciio_info_t pciio_info) { /* XXX for now O2 always gets back bus 0 */ return (pciio_bus_t)0; } pciio_slot_t pciio_info_slot_get(pciio_info_t pciio_info) { return (pciio_info->c_slot); } pciio_function_t pciio_info_function_get(pciio_info_t pciio_info) { return (pciio_info->c_func); } pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t pciio_info) { return (pciio_info->c_vendor); } pciio_device_id_t pciio_info_device_id_get(pciio_info_t pciio_info) { return (pciio_info->c_device); } devfs_handle_t pciio_info_master_get(pciio_info_t pciio_info) { return (pciio_info->c_master); } arbitrary_info_t pciio_info_mfast_get(pciio_info_t pciio_info) { return (pciio_info->c_mfast); } pciio_provider_t * pciio_info_pops_get(pciio_info_t pciio_info) { return (pciio_info->c_pops); } error_handler_f * pciio_info_efunc_get(pciio_info_t pciio_info) { return (pciio_info->c_efunc); } error_handler_arg_t * pciio_info_einfo_get(pciio_info_t pciio_info) { return (pciio_info->c_einfo); } pciio_space_t pciio_info_bar_space_get(pciio_info_t info, int win) { return info->c_window[win].w_space; } iopaddr_t pciio_info_bar_base_get(pciio_info_t info, int win) { return info->c_window[win].w_base; } size_t pciio_info_bar_size_get(pciio_info_t info, int win) { return info->c_window[win].w_size; } iopaddr_t pciio_info_rom_base_get(pciio_info_t info) { return info->c_rbase; } size_t pciio_info_rom_size_get(pciio_info_t info) { return info->c_rsize; } /* ===================================================================== * GENERIC PCI INITIALIZATION FUNCTIONS */ /* * pciioinit: called once during device driver * initializtion if this driver is configured into * the system. */ void pciio_init(void) { cdl_p cp; #if DEBUG && ATTACH_DEBUG printf("pciio_init\n"); #endif /* Allocate the registry. * We might already have one. * If we don't, go get one. * MPness: someone might have * set one up for us while we * were not looking; use an atomic * compare-and-swap to commit to * using the new registry if and * only if nobody else did first. * If someone did get there first, * toss the one we allocated back * into the pool. */ if (pciio_registry == NULL) { cp = cdl_new(EDGE_LBL_PCI, "vendor", "device"); if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) { cdl_del(cp); } } ASSERT(pciio_registry != NULL); }
char *disk_name (struct gendisk *hd, int minor, char *buf) { const char *maj = hd->major_name; unsigned int unit = minor >> hd->minor_shift; unsigned int part = minor & (( 1 << hd->minor_shift) - 1); char *p; if (unit < hd->nr_real && hd->part[minor].de) { int pos; pos = devfs_generate_path (hd->part[minor].de, buf, 64); if (pos >= 0) return buf + pos; } #ifdef CONFIG_ARCH_S390 if (genhd_dasd_name && genhd_dasd_name (buf, unit, part, hd) == 0) return buf; #endif /* * IDE devices use multiple major numbers, but the drives * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}.. * This requires special handling here. */ switch (hd->major) { case IDE9_MAJOR: unit += 2; case IDE8_MAJOR: unit += 2; case IDE7_MAJOR: unit += 2; case IDE6_MAJOR: unit += 2; case IDE5_MAJOR: unit += 2; case IDE4_MAJOR: unit += 2; case IDE3_MAJOR: unit += 2; case IDE2_MAJOR: unit += 2; case IDE1_MAJOR: unit += 2; case IDE0_MAJOR: maj = "hd"; break; case MD_MAJOR: sprintf(buf, "%s%d", maj, unit); return buf; } if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) { unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16; } if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) { return raid_name(hd, unit, part, COMPAQ_SMART2_MAJOR, buf); } if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) { return raid_name(hd, unit, part, COMPAQ_CISS_MAJOR, buf); } if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) { return raid_name(hd, unit, part, DAC960_MAJOR, buf); } if (hd->major == ATARAID_MAJOR) { int disk = minor >> hd->minor_shift; int part = minor & (( 1 << hd->minor_shift) - 1); if (part == 0) sprintf(buf, "%s/d%d", maj, disk); else sprintf(buf, "%s/d%dp%d", maj, disk, part); return buf; }
/* * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. * * Linux PCI Bus numbers are assigned from lowest module_id numbers * (rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to * HUB_WIDGET_ID_MIN: * widgetnum 15 gets lower Bus Number than widgetnum 14 etc. * * Given 2 modules 001c01 and 001c02 we get the following mappings: * 001c01, widgetnum 15 = Bus number 0 * 001c01, widgetnum 14 = Bus number 1 * 001c02, widgetnum 15 = Bus number 3 * 001c02, widgetnum 14 = Bus number 4 * etc. * * The rational for starting Bus Number 0 with Widget number 15 is because * the system boot disks are always connected via Widget 15 Slot 0 of the * I-brick. Linux creates /dev/sd* devices(naming) strating from Bus Number 0 * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest * module id(Master Cnode) of the system. * */ static int pci_bus_map_create(devfs_handle_t xtalk) { devfs_handle_t master_node_vertex = NULL; devfs_handle_t xwidget = NULL; devfs_handle_t pci_bus = NULL; hubinfo_t hubinfo = NULL; xwidgetnum_t widgetnum; char pathname[128]; graph_error_t rv; /* * Loop throught this vertex and get the Xwidgets .. */ for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) { #if 0 { int pos; char dname[256]; pos = devfs_generate_path(xtalk, dname, 256); printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); } #endif sprintf(pathname, "%d", widgetnum); xwidget = NULL; /* * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget * /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device */ rv = hwgraph_traverse(xtalk, pathname, &xwidget); if ( (rv != GRAPH_SUCCESS) ) { if (!xwidget) continue; } sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); pci_bus = NULL; if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) if (!pci_bus) continue; /* * Assign the correct bus number and also the nasid of this * pci Xwidget. * * Should not be any race here ... */ num_bridges++; busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus; /* * Get the master node and from there get the NASID. */ master_node_vertex = device_master_get(xwidget); if (!master_node_vertex) { printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget); } hubinfo_get(master_node_vertex, &hubinfo); if (!hubinfo) { printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex); return(1); } else { busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; } /* * Pre assign DMA maps needed for 32 Bits Page Map DMA. */ busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc( sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); if (!busnum_to_atedmamaps[num_bridges - 1]) printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); } return(0); }