📄 ml_iograph.c
字号:
hwgraph_vertex_unref(pci_slot_conn); } hwgraph_vertex_unref(baseio_console_conn);}static voidbaseio_ctlr_num_set(void){ char name[MAXDEVNAME]; devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; DBG("baseio_ctlr_num_set; FIXME\n"); console_vhdl = ioc3_console_vhdl_get(); if (console_vhdl == GRAPH_VERTEX_NONE) return; /* Useful for setting up the system critical graph */ baseio_console_vhdl = console_vhdl; vertex_to_name(console_vhdl,name,MAXDEVNAME); strcat(name,__DEVSTR1); pci_vhdl = hwgraph_path_to_vertex(name); scsi_ctlr_nums_add(pci_vhdl); /* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex */ hwgraph_vertex_unref(pci_vhdl); vertex_to_name(console_vhdl, name, MAXDEVNAME); strcat(name, __DEVSTR4); enet_vhdl = hwgraph_path_to_vertex(name); /* Useful for setting up the system critical graph */ baseio_enet_vhdl = enet_vhdl; device_controller_num_set(enet_vhdl, 0); /* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex */ hwgraph_vertex_unref(enet_vhdl);}/* #endif */voidsn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list){ /* REFERENCED */ int rtn_val; /* ** sn00 population: errb orrb ** 0- ql 3+? ** 1- ql 2 ** 2- ioc3 ethernet 2+? ** 3- ioc3 secondary 1 ** 4- 0 ** 5- PCI slot ** 6- PCI slot ** 7- PCI slot */ /* The following code implements this heuristic for getting * maximum usage out of the rrbs * * constraints: * 8 bit ql1 needs 1+1 * ql0 or ql5,6,7 wants 1+2 * ethernet wants 2 or more * * rules for even rrbs: * if nothing in slot 6 * 4 rrbs to 0 and 2 (0xc8889999) * else * 3 2 3 to slots 0 2 6 (0xc8899bbb) * * rules for odd rrbs * if nothing in slot 5 or 7 (0xc8889999) * 4 rrbs to 1 and 3 * else if 1 thing in 5 or 7 (0xc8899aaa) or (0xc8899bbb) * 3 2 3 to slots 1 3 5|7 * else * 2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this * (0xc89aaabb) may short what it wants therefore the * rule should be to plug pci slots in order) */ if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) { /* something in slot 6 */ rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0); } else { rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0); } if (rtn_val) PRINT_WARNING("sn00_rrb_alloc: pcibr_alloc_all_rrbs failed"); if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) { /* soemthing in slot 5 and 7 */ rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0); } else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) { /* soemthing in slot 5 but not 7 */ rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0); } else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) { /* soemthing in slot 7 but not 5 */ rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0); } else { /* nothing in slot 5 or 7 */ rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0); } if (rtn_val) PRINT_WARNING("sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");}/* * Initialize all I/O devices. Starting closest to nodes, probe and * initialize outward. */voidinit_all_devices(void){ /* Governor on init threads..bump up when safe * (beware many devfs races) */#ifdef LATER int io_init_node_threads = 2; #endif cnodeid_t cnodeid, active;#ifdef LINUX_KERNEL_THREADS sema_init(&io_init_sema, 0);#endif active = 0; for (cnodeid = 0; cnodeid < maxnodes; cnodeid++) {#ifdef LINUX_KERNEL_THREADS char thread_name[16]; extern int io_init_pri; /* * Spawn a service thread for each node to initialize all * I/O on that node. Each thread attempts to bind itself * to the node whose I/O it's initializing. */ sprintf(thread_name, "IO_init[%d]", cnodeid); (void)sthread_create(thread_name, 0, IOINIT_STKSZ, 0, io_init_pri, KT_PS, (st_func_t *)io_init_node, (void *)(long)cnodeid, 0, 0, 0);#else DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid); io_init_node(cnodeid); DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);#endif /* LINUX_KERNEL_THREADS */#ifdef LINUX_KERNEL_THREADS /* Limit how many nodes go at once, to not overload hwgraph */ /* TBD: Should timeout */ DBG("started thread for cnode %d\n", cnodeid); active++; if (io_init_node_threads && active >= io_init_node_threads) { down(&io_init_sema); active--; }#endif /* LINUX_KERNEL_THREADS */ }#ifdef LINUX_KERNEL_THREADS /* Wait until all IO_init threads are done */ while (active > 0) {#ifdef AA_DEBUG DBG("waiting, %d still active\n", active);#endif down(&io_init_sema); active--; }#endif /* LINUX_KERNEL_THREADS */ for (cnodeid = 0; cnodeid < maxnodes; cnodeid++) /* * Update information generated by IO init. */ update_node_information(cnodeid); baseio_ctlr_num_set(); /* Setup the system critical graph (which is a subgraph of the * main hwgraph). This information is useful during io error * handling. */ sys_critical_graph_init();#if HWG_PRINT hwgraph_print();#endif}#define toint(x) ((int)(x) - (int)('0'))voiddevnamefromarcs(char *devnm){ int val; char tmpnm[MAXDEVNAME]; char *tmp1, *tmp2; val = strncmp(devnm, "dks", 3); if (val != 0) return; tmp1 = devnm + 3; if (!isdigit(*tmp1)) return; val = 0; while (isdigit(*tmp1)) { val = 10*val+toint(*tmp1); tmp1++; } if(*tmp1 != 'd') return; else tmp1++; if ((val < 0) || (val >= NUM_BASE_IO_SCSI_CTLR)) { int i; int viable_found = 0; DBG("Only controller numbers 0..%d are supported for\n", NUM_BASE_IO_SCSI_CTLR-1); DBG("prom \"root\" variables of the form dksXdXsX.\n"); DBG("To use another disk you must use the full hardware graph path\n\n"); DBG("Possible controller numbers for use in 'dksXdXsX' on this system: "); for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++) { if (base_io_scsi_ctlr_vhdl[i] != GRAPH_VERTEX_NONE) { DBG("%d ", i); viable_found=1; } } if (viable_found) DBG("\n"); else DBG("none found!\n");#ifdef LATER if (kdebug) debug("ring");#endif DELAY(15000000); //prom_reboot(); panic("FIXME: devnamefromarcs: should call prom_reboot here.\n"); /* NOTREACHED */ } ASSERT(base_io_scsi_ctlr_vhdl[val] != GRAPH_VERTEX_NONE); vertex_to_name(base_io_scsi_ctlr_vhdl[val], tmpnm, MAXDEVNAME); tmp2 = tmpnm + strlen(tmpnm); strcpy(tmp2, __DEVSTR2); tmp2 += strlen(__DEVSTR2); while (*tmp1 != 's') { if((*tmp2++ = *tmp1++) == '\0') return; } tmp1++; strcpy(tmp2, __DEVSTR3); tmp2 += strlen(__DEVSTR3); while ( (*tmp2++ = *tmp1++) ) ; tmp2--; *tmp2++ = '/'; strcpy(tmp2, EDGE_LBL_BLOCK); strcpy(devnm,tmpnm);}staticstruct io_brick_map_s io_brick_tab[] = {/* Ibrick widget number to PCI bus number map */ { 'I', /* Ibrick type */ /* PCI Bus # Widget # */ { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ 0, /* 0x8 */ 0, /* 0x9 */ 0, 0, /* 0xa - 0xb */ 0, /* 0xc */ 0, /* 0xd */ 2, /* 0xe */ 1 /* 0xf */ } },/* Pbrick widget number to PCI bus number map */ { 'P', /* Pbrick type */ /* PCI Bus # Widget # */ { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ 2, /* 0x8 */ 1, /* 0x9 */ 0, 0, /* 0xa - 0xb */ 5, /* 0xc */ 6, /* 0xd */ 4, /* 0xe */ 3 /* 0xf */ } },/* Xbrick widget to XIO slot map */ { 'X', /* Xbrick type */ /* XIO Slot # Widget # */ { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ 1, /* 0x8 */ 2, /* 0x9 */ 0, 0, /* 0xa - 0xb */ 3, /* 0xc */ 4, /* 0xd */ 0, /* 0xe */ 0 /* 0xf */ } }};/* * Use the brick's type to map a widget number to a meaningful int */intio_brick_map_widget(char brick_type, int widget_num){ int num_bricks, i; /* Calculate number of bricks in table */ num_bricks = sizeof(io_brick_tab)/sizeof(io_brick_tab[0]); /* Look for brick prefix in table */ for (i = 0; i < num_bricks; i++) { if (brick_type == io_brick_tab[i].ibm_type) return(io_brick_tab[i].ibm_map_wid[widget_num]); } return 0;}/* * Use the device's vertex to map the device's widget to a meaningful int */intio_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));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -