/* * Use the device's vertex to map the device's widget to a meaningful int */ int io_path_map_widget(devfs_handle_t vertex) { char hw_path_name[MAXDEVNAME]; char *wp, *bp, *sp = NULL; int widget_num; long atoi(char *); int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen); /* Get the full path name of the vertex */ if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name, MAXDEVNAME)) return 0; /* Find the widget number in the path name */ wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/"); if (wp == NULL) return 0; widget_num = atoi(wp+7); if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F) return 0; /* Find "brick" in the path name */ bp = strstr(hw_path_name, "brick"); if (bp == NULL) return 0; /* Find preceding slash */ sp = bp; while (sp > hw_path_name) { sp--; if (*sp == '/') break; } /* Invalid if no preceding slash */ if (!sp) return 0; /* Bump slash pointer to "brick" prefix */ sp++; /* * Verify "brick" prefix length; valid exaples: * 'I' from "/Ibrick" * 'P' from "/Pbrick" * 'X' from "/Xbrick" */ if ((bp - sp) != 1) return 0; return (io_brick_map_widget(*sp, widget_num)); }
/* ARGSUSED */ static void assign_widgets_to_volunteers(vertex_hdl_t xswitch, vertex_hdl_t hubv) { xswitch_info_t xswitch_info; xswitch_vol_t xvolinfo = NULL; xwidgetnum_t widgetnum; int num_volunteer; nasid_t nasid; hubinfo_t hubinfo; extern int iobrick_type_get_nasid(nasid_t); hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; xswitch_info = xswitch_info_get(xswitch); ASSERT(xswitch_info != NULL); (void)hwgraph_info_get_LBL(xswitch, INFO_LBL_XSWITCH_VOL, (arbitrary_info_t *)&xvolinfo); if (xvolinfo == NULL) { if (!is_headless_node_vertex(hubv)) printk(KERN_WARNING "assign_widgets_to_volunteers:vertex 0x%p has " " no info label", (void *)xswitch); return; } num_volunteer = xvolinfo->xswitch_volunteer_count; ASSERT(num_volunteer > 0); /* Assign master hub for xswitch itself. */ if (HUB_WIDGET_ID_MIN > 0) { hubv = xvolinfo->xswitch_volunteer[0]; xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv); } /* * TBD: Use administrative information to alter assignment of * widgets to hubs. */ for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { int i; /* * Ignore disabled/empty ports. */ if (!xbow_port_io_enabled(nasid, widgetnum)) continue; /* * If this is the master IO board, assign it to the same * hub that owned it in the prom. */ if (is_master_baseio_nasid_widget(nasid, widgetnum)) { extern nasid_t snia_get_master_baseio_nasid(void); for (i=0; i<num_volunteer; i++) { hubv = xvolinfo->xswitch_volunteer[i]; hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; if (nasid == snia_get_master_baseio_nasid()) goto do_assignment; } panic("Nasid == %d, console nasid == %d", nasid, snia_get_master_baseio_nasid()); } /* * Assuming that we're dual-hosted and that PCI cards * are naturally placed left-to-right, alternate PCI * buses across both Cbricks. For Pbricks, and Ibricks, * io_brick_map_widget() returns the PCI bus number * associated with the given brick type and widget number. * For Xbricks, it returns the XIO slot number. */ i = 0; if (num_volunteer > 1) { int bt; bt = iobrick_type_get_nasid(nasid); if (bt >= 0) { i = io_brick_map_widget(bt, widgetnum) & 1; } } hubv = xvolinfo->xswitch_volunteer[i]; do_assignment: /* * At this point, we want to make hubv the master of widgetnum. */ xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv); } xswitch_volunteer_delete(xswitch); }
/* ARGSUSED */ static void assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv) { xswitch_info_t xswitch_info; xswitch_vol_t xvolinfo = NULL; xwidgetnum_t widgetnum; int num_volunteer; nasid_t nasid; hubinfo_t hubinfo; extern int iobrick_type_get_nasid(nasid_t); hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; xswitch_info = xswitch_info_get(xswitch); ASSERT(xswitch_info != NULL); (void)hwgraph_info_get_LBL(xswitch, INFO_LBL_XSWITCH_VOL, (arbitrary_info_t *)&xvolinfo); if (xvolinfo == NULL) { return; } num_volunteer = xvolinfo->xswitch_volunteer_count; ASSERT(num_volunteer > 0); /* Assign master hub for xswitch itself. */ if (HUB_WIDGET_ID_MIN > 0) { hubv = xvolinfo->xswitch_volunteer[0]; xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv); } /* * TBD: Use administrative information to alter assignment of * widgets to hubs. */ for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { int i; /* * Ignore disabled/empty ports. */ if (!xbow_port_io_enabled(nasid, widgetnum)) continue; /* * If this is the master IO board, assign it to the same * hub that owned it in the prom. */ if (is_master_nasid_widget(nasid, widgetnum)) { for (i=0; i<num_volunteer; i++) { hubv = xvolinfo->xswitch_volunteer[i]; hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; if (nasid == get_console_nasid()) goto do_assignment; } } /* * Assuming that we're dual-hosted and that PCI cards * are naturally placed left-to-right, alternate PCI * buses across both Cbricks. For Pbricks, and Ibricks, * io_brick_map_widget() returns the PCI bus number * associated with the given brick type and widget number. * For Xbricks, it returns the XIO slot number. */ i = 0; if (num_volunteer > 1) { int bt; bt = iobrick_type_get_nasid(nasid); if (bt >= 0) { /* * PXBRICK has two busses per widget so this * algorithm wouldn't work (all busses would * be assigned to one volunteer). Change the * bricktype to PBRICK whose mapping is setup * suchthat 2 of the PICs will be assigned to * one volunteer and the other one will be * assigned to the other volunteer. */ if (bt == MODULE_PXBRICK) bt = MODULE_PBRICK; i = io_brick_map_widget(bt, widgetnum) & 1; } } hubv = xvolinfo->xswitch_volunteer[i]; do_assignment: /* * At this point, we want to make hubv the master of widgetnum. */ xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv); } xswitch_volunteer_delete(xswitch); }