/* * devfn_to_vertex() - returns the vertex of the device given the bus, slot, * and function numbers. */ devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn) { int slot = 0; int func = 0; char name[16]; devfs_handle_t pci_bus = NULL; devfs_handle_t device_vertex = (devfs_handle_t)NULL; /* * Go get the pci bus vertex. */ pci_bus = pci_bus_to_vertex(busnum); if (!pci_bus) { /* * During probing, the Linux pci code invents non-existent * bus numbers and pci_dev structures and tries to access * them to determine existence. Don't crib during probing. */ if (done_probing) printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum); return(NULL); } /* * Go get the slot&function vertex. * Should call pciio_slot_func_to_name() when ready. */ slot = PCI_SLOT(devfn); func = PCI_FUNC(devfn); /* * For a NON Multi-function card the name of the device looks like: * ../pci/1, ../pci/2 .. */ if (func == 0) { sprintf(name, "%d", slot); if (hwgraph_traverse(pci_bus, name, &device_vertex) == GRAPH_SUCCESS) { if (device_vertex) { return(device_vertex); } } } /* * This maybe a multifunction card. It's names look like: * ../pci/1a, ../pci/1b, etc. */ sprintf(name, "%d%c", slot, 'a'+func); if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) { if (!device_vertex) { return(NULL); } } return(device_vertex); }
/* * For each PCI bridge connected to the xswitch, add a link from the * board's klconfig info to the bridge's hwgraph vertex. This lets * the FRU analyzer find the bridge without traversing the hardware * graph and risking hangs. */ static void io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) { xwidgetnum_t widgetnum; char pathname[128]; devfs_handle_t vhdl; nasid_t nasid, peer_nasid; lboard_t *board; /* And its connected hub's nasids */ nasid = COMPACT_TO_NASID_NODEID(cnodeid); peer_nasid = NODEPDA(cnodeid)->xbow_peer; /* * Look for paths matching "<widgetnum>/pci" under xswitchv. * For every widget, init. its lboard's hwgraph link. If the * board has a PCI bridge, point the link to it. */ for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { sprintf(pathname, "%d", widgetnum); if (hwgraph_traverse(xswitchv, pathname, &vhdl) != GRAPH_SUCCESS) continue; board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), NODEPDA(cnodeid)->module_id); if (board == NULL && peer_nasid != INVALID_NASID) { /* * Try to find the board on our peer */ board = find_lboard_module( (lboard_t *)KL_CONFIG_INFO(peer_nasid), NODEPDA(cnodeid)->module_id); } if (board == NULL) { #if defined(SUPPORT_PRINTING_V_FORMAT) printk(KERN_WARNING "Could not find PROM info for vertex %v, " "FRU analyzer may fail", vhdl); #else printk(KERN_WARNING "Could not find PROM info for vertex 0x%p, " "FRU analyzer may fail", (void *)vhdl); #endif return; } sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) board->brd_graph_link = vhdl; else board->brd_graph_link = GRAPH_VERTEX_NONE; } }
/* * hub_device_inquiry * Find out the xtalk widget related information stored in this * hub's II. */ void hub_device_inquiry(devfs_handle_t xbus_vhdl, xwidgetnum_t widget) { devfs_handle_t xconn, hub_vhdl; char widget_name[8]; hubreg_t ii_iidem,ii_iiwa, ii_iowa; hubinfo_t hubinfo; nasid_t nasid; int d; sprintf(widget_name, "%d", widget); if (hwgraph_traverse(xbus_vhdl, widget_name, &xconn) != GRAPH_SUCCESS) return; hub_vhdl = device_master_get(xconn); if (hub_vhdl == GRAPH_VERTEX_NONE) return; hubinfo_get(hub_vhdl, &hubinfo); if (!hubinfo) return; nasid = hubinfo->h_nasid; ii_iidem = REMOTE_HUB_L(nasid, IIO_IIDEM); ii_iiwa = REMOTE_HUB_L(nasid, IIO_IIWA); ii_iowa = REMOTE_HUB_L(nasid, IIO_IOWA); #if defined(SUPPORT_PRINTING_V_FORMAT) cmn_err(CE_CONT, "Inquiry Info for %v\n", xconn); #else cmn_err(CE_CONT, "Inquiry Info for 0x%p\n", &xconn); #endif cmn_err(CE_CONT,"\tDevices shutdown [ "); for (d = 0 ; d <= 7 ; d++) if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d)))) cmn_err(CE_CONT, " %d", d); cmn_err(CE_CONT,"]\n"); cmn_err(CE_CONT, "\tInbound access ? %s\n", ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no"); cmn_err(CE_CONT, "\tOutbound access ? %s\n", ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no"); }
/* * pciio_cardinfo_get * * Get the pciio info structure corresponding to the * specified PCI "slot" (we like it when the same index * number is used for the PCI IDSEL, the REQ/GNT pair, * and the interrupt line being used for INTA. We like * it so much we call it the slot number). */ static pciio_info_t pciio_cardinfo_get( devfs_handle_t pciio_vhdl, pciio_slot_t pci_slot) { char namebuf[16]; pciio_info_t info = 0; devfs_handle_t conn; pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE); if (GRAPH_SUCCESS == hwgraph_traverse(pciio_vhdl, namebuf, &conn)) { info = pciio_info_chk(conn); hwgraph_vertex_unref(conn); } return info; }
/*ARGSUSED */ int pciio_error_handler( devfs_handle_t pciio_vhdl, int error_code, ioerror_mode_t mode, ioerror_t *ioerror) { pciio_info_t pciio_info; devfs_handle_t pconn_vhdl; #if USRPCI devfs_handle_t usrpci_v; #endif pciio_slot_t slot; int retval; #if defined(CONFIG_SGI_IO_ERROR_HANDLING) error_state_t e_state; #endif #if DEBUG && ERROR_DEBUG #if defined(SUPPORT_PRINTING_V_FORMAT) printk("%v: pciio_error_handler\n", pciio_vhdl); #else printk("0x%x: pciio_error_handler\n", pciio_vhdl); #endif #endif #if defined(SUPPORT_PRINTING_V_FORMAT) IOERR_PRINTF(printk("%v: PCI Bus Error: Error code: %d Error mode: %d\n", pciio_vhdl, error_code, mode)); #else IOERR_PRINTF(printk("0x%x: PCI Bus Error: Error code: %d Error mode: %d\n", pciio_vhdl, error_code, mode)); #endif /* If there is an error handler sitting on * the "no-slot" connection point, give it * first crack at the error. NOTE: it is * quite possible that this function may * do further refining of the ioerror. */ pciio_info = pciio_cardinfo_get(pciio_vhdl, PCIIO_SLOT_NONE); if (pciio_info && pciio_info->c_efunc) { pconn_vhdl = pciio_info_dev_get(pciio_info); #if defined(CONFIG_SGI_IO_ERROR_HANDLING) e_state = error_state_get(pciio_vhdl); if (e_state == ERROR_STATE_ACTION) (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE) return(IOERROR_UNHANDLED); #endif retval = pciio_info->c_efunc (pciio_info->c_einfo, error_code, mode, ioerror); if (retval != IOERROR_UNHANDLED) return retval; } /* Is the error associated with a particular slot? */ if (IOERROR_FIELDVALID(ioerror, widgetdev)) { /* * NOTE : * widgetdev is a 4byte value encoded as slot in the higher order * 2 bytes and function in the lower order 2 bytes. */ #ifdef LATER slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioerror, widgetdev)); #else slot = 0; #endif /* If this slot has an error handler, * deliver the error to it. */ pciio_info = pciio_cardinfo_get(pciio_vhdl, slot); if (pciio_info != NULL) { if (pciio_info->c_efunc != NULL) { pconn_vhdl = pciio_info_dev_get(pciio_info); #if defined(CONFIG_SGI_IO_ERROR_HANDLING) e_state = error_state_get(pciio_vhdl); if (e_state == ERROR_STATE_ACTION) (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE) return(IOERROR_UNHANDLED); #endif retval = pciio_info->c_efunc (pciio_info->c_einfo, error_code, mode, ioerror); if (retval != IOERROR_UNHANDLED) return retval; } #if USRPCI /* If the USRPCI driver is available and * knows about this connection point, * deliver the error to it. * * OK to use pconn_vhdl here, even though we * have already UNREF'd it, since we know that * it is not going away. */ pconn_vhdl = pciio_info_dev_get(pciio_info); if (GRAPH_SUCCESS == hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) { retval = usrpci_error_handler (usrpci_v, error_code, IOERROR_GETVALUE(ioerror, busaddr)); hwgraph_vertex_unref(usrpci_v); if (retval != IOERROR_UNHANDLED) { /* * This unref is not needed. If this code is called often enough, * the system will crash, due to vertex reference count reaching 0, * causing vertex to be unallocated. -jeremy * hwgraph_vertex_unref(pconn_vhdl); */ return retval; } } #endif } } return (mode == MODE_DEVPROBE) ? IOERROR_HANDLED /* probes are OK */ : IOERROR_UNHANDLED; /* otherwise, foo! */ }
static void __init klhwg_connect_hubs(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; klhub_t *hub; lboard_t *dest_brd; vertex_hdl_t hub_hndl; vertex_hdl_t dest_hndl; char path_buffer[50]; char dest_path[50]; graph_error_t rc; int port; for (cnode = 0; cnode < numionodes; cnode++) { nasid = cnodeid_to_nasid(cnode); brd = find_lboard_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); ASSERT(hub); for (port = 1; port <= MAX_NI_PORTS; port++) { if (hub->hub_port[port].port_nasid == INVALID_NASID) { continue; /* Port not active */ } if (nasid_to_cnodeid(hub->hub_port[port].port_nasid) == INVALID_CNODEID) continue; /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer); rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl); if (rc != GRAPH_SUCCESS) printk(KERN_WARNING "Can't find hub: %s", path_buffer); dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( hub->hub_port[port].port_nasid, hub->hub_port[port].port_offset); /* Generate a hardware graph path for this board. */ board_to_path(dest_brd, dest_path); rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); if (rc != GRAPH_SUCCESS) { if (KL_CONFIG_DUPLICATE_BOARD(dest_brd)) continue; printk("Can't find board: %s", dest_path); return; } else { char buf[1024]; rc = hwgraph_path_add(hub_hndl, EDGE_LBL_INTERCONNECT, &hub_hndl); HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, NULL, "Created link path.\n"); sprintf(buf,"%s/%s",path_buffer,EDGE_LBL_INTERCONNECT); rc = hwgraph_traverse(hwgraph_root, buf, &hub_hndl); sprintf(buf,"%d",port); rc = hwgraph_edge_add(hub_hndl, dest_hndl, buf); HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", buf); if (rc != GRAPH_SUCCESS) { printk("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n", path_buffer, dest_path, (void *)dest_hndl, rc); return; } } } } }
/* ARGSUSED */ static void __init klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd, cnodeid_t cnode, nasid_t nasid) { klrou_t *router; char path_buffer[50]; char dest_path[50]; vertex_hdl_t router_hndl; vertex_hdl_t dest_hndl; int rc; int port; lboard_t *dest_brd; /* Don't add duplicate boards. */ if (brd->brd_flags & DUPLICATE_BOARD) { return; } /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer); rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl); if (rc != GRAPH_SUCCESS) return; if (rc != GRAPH_SUCCESS) printk(KERN_WARNING "Can't find router: %s", path_buffer); /* We don't know what to do with multiple router components */ if (brd->brd_numcompts != 1) { printk("klhwg_connect_one_router: %d cmpts on router\n", brd->brd_numcompts); return; } /* Convert component 0 to klrou_t ptr */ router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); for (port = 1; port <= MAX_ROUTER_PORTS; port++) { /* See if the port's active */ if (router->rou_port[port].port_nasid == INVALID_NASID) { GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n", port)); continue; } if (nasid_to_cnodeid(router->rou_port[port].port_nasid) == INVALID_CNODEID) { continue; } dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( router->rou_port[port].port_nasid, router->rou_port[port].port_offset); /* Generate a hardware graph path for this board. */ board_to_path(dest_brd, dest_path); rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); if (rc != GRAPH_SUCCESS) { if (KL_CONFIG_DUPLICATE_BOARD(dest_brd)) continue; printk("Can't find router: %s", dest_path); return; } sprintf(dest_path, "%d", port); rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path); if (rc == GRAPH_DUP) { GRPRINTF(("Skipping port %d. nasid %d %s/%s\n", port, router->rou_port[port].port_nasid, path_buffer, dest_path)); continue; } if (rc != GRAPH_SUCCESS) { printk("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n", path_buffer, dest_path, (void *)dest_hndl, rc); return; } HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, router_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", dest_path); } }
/* Define the system critical vertices and connect them through * a canonical parent-child relationships for easy traversal * during io error handling. */ static void sys_critical_graph_init(void) { devfs_handle_t bridge_vhdl,master_node_vhdl; devfs_handle_t xbow_vhdl = GRAPH_VERTEX_NONE; extern devfs_handle_t hwgraph_root; devfs_handle_t pci_slot_conn; int slot; devfs_handle_t baseio_console_conn; DBG("sys_critical_graph_init: FIXME.\n"); baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl); if (baseio_console_conn == NULL) { return; } /* Get the vertex handle for the baseio bridge */ bridge_vhdl = device_master_get(baseio_console_conn); /* Get the master node of the baseio card */ master_node_vhdl = cnodeid_to_vertex( master_node_get(baseio_console_vhdl)); /* Add the "root->node" part of the system critical graph */ sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl); /* Check if we have a crossbow */ if (hwgraph_traverse(master_node_vhdl, EDGE_LBL_XTALK"/0", &xbow_vhdl) == GRAPH_SUCCESS) { /* We have a crossbow.Add "node->xbow" part of the system * critical graph. */ sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl); /* Add "xbow->baseio bridge" of the system critical graph */ sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl); hwgraph_vertex_unref(xbow_vhdl); } else /* We donot have a crossbow. Add "node->baseio_bridge" * part of the system critical graph. */ sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl); /* Add all the populated PCI slot vertices to the system critical * graph with the bridge vertex as the parent. */ for (slot = 0 ; slot < 8; slot++) { char slot_edge[10]; sprintf(slot_edge,"%d",slot); if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn) != GRAPH_SUCCESS) continue; sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn); hwgraph_vertex_unref(pci_slot_conn); } hwgraph_vertex_unref(bridge_vhdl); /* Add the "ioc3 pci connection point -> console ioc3" part * of the system critical graph */ if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) == GRAPH_SUCCESS) { sys_critical_graph_vertex_add(pci_slot_conn, baseio_console_vhdl); hwgraph_vertex_unref(pci_slot_conn); } /* Add the "ethernet pci connection point -> base ethernet" part of * the system critical graph */ if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) == GRAPH_SUCCESS) { sys_critical_graph_vertex_add(pci_slot_conn, baseio_enet_vhdl); hwgraph_vertex_unref(pci_slot_conn); } /* Add the "scsi controller pci connection point -> base scsi * controller" part of the system critical graph */ if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0], "../..",&pci_slot_conn) == GRAPH_SUCCESS) { sys_critical_graph_vertex_add(pci_slot_conn, base_io_scsi_ctlr_vhdl[0]); hwgraph_vertex_unref(pci_slot_conn); } if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1], "../..",&pci_slot_conn) == GRAPH_SUCCESS) { sys_critical_graph_vertex_add(pci_slot_conn, base_io_scsi_ctlr_vhdl[1]); hwgraph_vertex_unref(pci_slot_conn); } hwgraph_vertex_unref(baseio_console_conn); }
/* * If this PIC is attached to two Cbricks ("dual-ported") then * attach each bus to opposite Cbricks. * * If successful, return a new vertex suitable for attaching the PIC bus. * If not successful, return zero and both buses will attach to the * vertex passed into pic_attach(). */ static vertex_hdl_t pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v) { cnodeid_t cnode = nasid_to_cnodeid(nasid); cnodeid_t xbow_peer = -1; char pathname[256], peer_path[256], tmpbuf[256]; char *p; int rc; vertex_hdl_t peer_conn_v, hubv; int pos; slabid_t slab; if (NODEPDA(cnode)->xbow_peer >= 0) { /* if dual-ported */ /* create a path for this widget on the peer Cbrick */ /* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */ /* sprintf(pathname, "%v", conn_v); */ xbow_peer = nasid_to_cnodeid(NODEPDA(cnode)->xbow_peer); pos = hwgfs_generate_path(conn_v, tmpbuf, 256); strcpy(pathname, &tmpbuf[pos]); p = pathname + strlen("hw/module/001c01/slab/0/"); memset(tmpbuf, 0, 16); format_module_id(tmpbuf, geo_module((NODEPDA(xbow_peer))->geoid), MODULE_FORMAT_BRIEF); slab = geo_slab((NODEPDA(xbow_peer))->geoid); sprintf(peer_path, "module/%s/slab/%d/%s", tmpbuf, (int)slab, p); /* Look for vertex for this widget on the peer Cbrick. * Expect GRAPH_NOT_FOUND. */ rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v); if (GRAPH_SUCCESS == rc) printk("pic_attach: found unexpected vertex: 0x%lx\n", (uint64_t)peer_conn_v); else if (GRAPH_NOT_FOUND != rc) { printk("pic_attach: hwgraph_traverse unexpectedly" " returned 0x%x\n", rc); } else { /* try to add the widget vertex to the peer Cbrick */ rc = hwgraph_path_add(hwgraph_root, peer_path, &peer_conn_v); if (GRAPH_SUCCESS != rc) printk("pic_attach: hwgraph_path_add" " failed with 0x%x\n", rc); else { PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_bus1_redist: added vertex %v\n", peer_conn_v)); /* Now hang appropiate stuff off of the new * vertex. We bail out if we cannot add something. * In that case, we don't remove the newly added * vertex but that should be safe and we don't * really expect the additions to fail anyway. */ if (!pic_bus1_widget_info_dup(conn_v, peer_conn_v, xbow_peer, peer_path)) return 0; hubv = cnodeid_to_vertex(xbow_peer); ASSERT(hubv != GRAPH_VERTEX_NONE); device_master_set(peer_conn_v, hubv); xtalk_provider_register(hubv, &hub_provider); xtalk_provider_startup(hubv); return peer_conn_v; } } } return 0; }
/* * 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); }