📄 ml_iograph.c
字号:
int index; for (index = 0; index < 500; index++) printk("Interfering with device probing!!!\n"); }#endif /* Now both nodes can safely inititialize widgets */ io_init_xswitch_widgets(switchv, cnodeid); io_link_xswitch_widgets(switchv, cnodeid); /* io_init_done takes cpu cookie as 2nd argument * to do a restorenoderun for the setnoderun done * at the start of this thread */ io_init_done(cnodeid,c); printk("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);}#define IOINIT_STKSZ (16 * 1024)#ifndef CONFIG_IA64_SGI_IO#include <sys/sn/iograph.h>#endif#define __DEVSTR1 "/../.master/"#define __DEVSTR2 "/target/"#define __DEVSTR3 "/lun/0/disk/partition/"#define __DEVSTR4 "/../ef"#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC/* * Currently, we need to allow for 5 IBrick slots with 1 FC each * plus an internal 1394. * * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR. */#define NUM_BASE_IO_SCSI_CTLR 6#endif/* * This tells ioconfig where it can start numbering scsi controllers. * Below this base number, platform-specific handles the numbering. * XXX Irix legacy..controller numbering should be part of devfsd's job */int num_base_io_scsi_ctlr = 2; /* used by syssgi */devfs_handle_t base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];static devfs_handle_t baseio_enet_vhdl,baseio_console_vhdl;/* * Put the logical controller number information in the * scsi controller vertices for each scsi controller that * is in a "fixed position". */static voidscsi_ctlr_nums_add(devfs_handle_t pci_vhdl){ { int i; num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR; /* Initialize base_io_scsi_ctlr_vhdl array */ for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++) base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE; }#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC { /* * May want to consider changing the SN0 code, above, to work more like * the way this works. */ devfs_handle_t base_ibrick_xbridge_vhdl; devfs_handle_t base_ibrick_xtalk_widget_vhdl; devfs_handle_t scsi_ctlr_vhdl; int i; graph_error_t rv; /* * This is a table of "well-known" SCSI controllers and their well-known * controller numbers. The names in the table start from the base IBrick's * Xbridge vertex, so the first component is the xtalk widget number. */ static struct { char *base_ibrick_scsi_path; int controller_number; } hardwired_scsi_controllers[] = { {"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0}, {"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1}, {"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2}, {"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3}, {"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4}, {NULL, -1} /* must be last */ }; base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl); ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE); base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl); ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE); hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl); /* * Iterate through the list of well-known SCSI controllers. * For each controller found, set it's controller number according * to the table. */ for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) { rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl, hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL); if (rv != GRAPH_SUCCESS) /* No SCSI at this path */ continue; ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR); base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl; device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number); hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */ } hwgraph_vertex_unref(base_ibrick_xbridge_vhdl); }#else#pragma error Bomb!#endif}#ifndef CONFIG_IA64_SGI_IO#include <sys/asm/sn/ioerror_handling.h>#else#include <asm/sn/ioerror_handling.h>#endifextern devfs_handle_t ioc3_console_vhdl_get(void);devfs_handle_t sys_critical_graph_root = GRAPH_VERTEX_NONE;/* Define the system critical vertices and connect them through * a canonical parent-child relationships for easy traversal * during io error handling. */static voidsys_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; printk("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);}static voidbaseio_ctlr_num_set(void){ char name[MAXDEVNAME]; devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; printk("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); }#ifndef CONFIG_IA64_SGI_IO if (rtn_val) cmn_err(CE_WARN, "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");#endif 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); }#ifndef CONFIG_IA64_SGI_IO if (rtn_val) cmn_err(CE_WARN, "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");#endif}/* * 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) */#ifndef CONFIG_IA64_SGI_IO int io_init_node_threads = 2; #endif cnodeid_t cnodeid, active; init_MUTEX(&io_init_sema); active = 0; for (cnodeid = 0; cnodeid < maxnodes; cnodeid++) {#ifndef CONFIG_IA64_SGI_IO 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 printk("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid); io_init_node(cnodeid); printk("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);#endif /* !CONFIG_IA64_SGI_IO */ /* Limit how many nodes go at once, to not overload hwgraph */ /* TBD: Should timeout */#ifdef AA_DEBUG printk("started thread for cnode %d\n", cnodeid);#endif#ifdef LINUX_KERNEL_THREADS 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 printk("waiting, %d still active\n", active);#endif sema(&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; printk("Only controller numbers 0..%d are supported for\n", NUM_BASE_IO_SCSI_CTLR-1); printk("prom \"root\" variables of the form dksXdXsX.\n"); printk("To use another disk you must use the full hardware graph path\n\n"); printk("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) { printk("%d ", i); viable_found=1; } } if (viable_found) printk("\n"); else printk("none found!\n");#ifndef CONFIG_IA64_SGI_IO 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -