📄 ml_iograph.c
字号:
/* 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; } { /* * 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}, {"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5}, {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); }}#include <asm/sn/ioerror_handling.h>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; 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);}static voidbaseio_ctlr_num_set(void){ char name[MAXDEVNAME]; devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; devfs_handle_t ioc3_console_vhdl_get(void); 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 *//* * 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) */ cnodeid_t cnodeid, active; active = 0; for (cnodeid = 0; cnodeid < numnodes; cnodeid++) { 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); } for (cnodeid = 0; cnodeid < numnodes; 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"); 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 */ { MODULE_IBRICK, /* 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 */ { MODULE_PBRICK, /* 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 */ } },/* PXbrick widget number to PCI bus number map */ { MODULE_PXBRICK, /* PXbrick type */ /* PCI Bus # Widget # */ { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ 0, /* 0x8 */ 0, /* 0x9 */ 0, 0, /* 0xa - 0xb */ 1, /* 0xc */ 5, /* 0xd */ 0, /* 0xe */ 3 /* 0xf */ } },/* Xbrick widget to XIO slot map */ { MODULE_XBRICK, /* Xbrick type */ /* XIO Slot # Widget # */ { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ 1, /* 0x8 */ 3, /* 0x9 */ 0, 0, /* 0xa - 0xb */ 2, /* 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(int 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((int)*sp, widget_num));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -