📄 klgraph.c
字号:
/* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc. * Copyright (C) 2000 by Colin Ngam *//* * klgraph.c- * This file specifies the interface between the kernel and the PROM's * configuration data structures. */#include <linux/types.h>#include <linux/config.h>#include <linux/slab.h>#include <asm/sn/sgi.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/labelcl.h>#include <asm/sn/cmn_err.h>#include <asm/sn/agent.h>#ifdef CONFIG_IA64_SGI_IO#include <asm/sn/kldir.h>#endif#include <asm/sn/gda.h> #include <asm/sn/klconfig.h>#include <asm/sn/router.h>#include <asm/sn/xtalk/xbow.h>#include <asm/sn/hcl_util.h>#define KLGRAPH_DEBUG 1#ifdef KLGRAPH_DEBUG#define GRPRINTF(x) printk x#define CE_GRPANIC CE_PANIC#else#define GRPRINTF(x)#define CE_GRPANIC CE_PANIC#endif#include <asm/sn/sn_private.h>extern char arg_maxnodes[];extern int maxnodes;#ifndef BRINGUP/* * Gets reason for diagval using table lookup. */static char*get_diag_string(uint diagcode){ int num_entries; int i; num_entries = sizeof(diagval_map) / sizeof(diagval_t); for (i = 0; i < num_entries; i++){ if ((unchar)diagval_map[i].dv_code == (unchar)diagcode) return diagval_map[i].dv_msg; } return "Unknown";}#endif /* ndef BRINGUP *//* * Support for verbose inventory via hardware graph. * klhwg_invent_alloc allocates the necessary size of inventory information * and fills in the generic information. */invent_generic_t *klhwg_invent_alloc(cnodeid_t cnode, int class, int size){ invent_generic_t *invent; invent = kern_malloc(size); if (!invent) return NULL; invent->ig_module = NODE_MODULEID(cnode); invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode)); invent->ig_invclass = class; return invent;}/* * Add information about the baseio prom version number * as a part of detailed inventory info in the hwgraph. */voidklhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode){ invent_miscinfo_t *baseio_inventory; unsigned char version = 0,revision = 0; /* Allocate memory for the "detailed inventory" info * for the baseio */ baseio_inventory = (invent_miscinfo_t *) klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t)); baseio_inventory->im_type = INV_IO6PROM; /* Read the io6prom revision from the nvram */#ifndef CONFIG_IA64_SGI_IO nvram_prom_version_get(&version,&revision);#endif /* Store the revision info in the inventory */ baseio_inventory->im_version = version; baseio_inventory->im_rev = revision; /* Put the inventory info in the hardware graph */ hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, (arbitrary_info_t) baseio_inventory); /* Make the information available to the user programs * thru hwgfs. */ hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, sizeof(invent_miscinfo_t));}char *hub_rev[] = { "0.0", "1.0", "2.0", "2.1", "2.2", "2.3"};/* * Add detailed cpu inventory info to the hardware graph. */voidklhwg_hub_invent_info(devfs_handle_t hubv, cnodeid_t cnode, klhub_t *hub){ invent_miscinfo_t *hub_invent; hub_invent = (invent_miscinfo_t *) klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t)); if (!hub_invent) return; if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub)) hub_invent->im_gen.ig_flag = INVENT_ENABLED; hub_invent->im_type = INV_HUB; hub_invent->im_rev = hub->hub_info.revision; hub_invent->im_speed = hub->hub_speed; hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, (arbitrary_info_t) hub_invent); hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT, sizeof(invent_miscinfo_t));}/* ARGSUSED */voidklhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode){ devfs_handle_t myhubv; int rc; GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB)); (void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv); rc = device_master_set(myhubv, node_vertex);#ifndef CONFIG_IA64_SGI_IO /* * Activate when we support hub stats. */ rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO, (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));#endif if (rc != GRAPH_SUCCESS) { cmn_err(CE_WARN, "klhwg_add_hub: Can't add hub info label 0x%p, code %d", myhubv, rc); } klhwg_hub_invent_info(myhubv, cnode, hub);#ifndef BRINGUP init_hub_stats(cnode, NODEPDA(cnode));#endif /* ndef BRINGUP */#ifndef CONFIG_IA64_SGI_IO sndrv_attach(myhubv);#else /* * Need to call our driver to do the attach? */ printk("klhwg_add_hub: Need to add code to do the attach.\n");#endif}#ifndef BRINGUPvoidklhwg_add_rps(devfs_handle_t node_vertex, cnodeid_t cnode, int flag){ devfs_handle_t myrpsv; invent_rpsinfo_t *rps_invent; int rc; if(cnode == CNODEID_NONE) return; GRPRINTF(("klhwg_add_rps: adding %s to vertex 0x%x\n", EDGE_LBL_RPS, node_vertex)); rc = hwgraph_path_add(node_vertex, EDGE_LBL_RPS, &myrpsv); if (rc != GRAPH_SUCCESS) return; device_master_set(myrpsv, node_vertex); rps_invent = (invent_rpsinfo_t *) klhwg_invent_alloc(cnode, INV_RPS, sizeof(invent_rpsinfo_t)); if (!rps_invent) return; rps_invent->ir_xbox = 0; /* not an xbox RPS */ if (flag) rps_invent->ir_gen.ig_flag = INVENT_ENABLED; else rps_invent->ir_gen.ig_flag = 0x0; hwgraph_info_add_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, (arbitrary_info_t) rps_invent); hwgraph_info_export_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, sizeof(invent_rpsinfo_t)); }/* * klhwg_update_rps gets invoked when the system controller sends an * interrupt indicating the power supply has lost/regained the redundancy. * It's responsible for updating the Hardware graph information. * rps_state = 0 -> if the rps lost the redundancy * = 1 -> If it is redundant. */void klhwg_update_rps(cnodeid_t cnode, int rps_state){ devfs_handle_t node_vertex; devfs_handle_t rpsv; invent_rpsinfo_t *rps_invent; int rc; if(cnode == CNODEID_NONE) return; node_vertex = cnodeid_to_vertex(cnode); rc = hwgraph_edge_get(node_vertex, EDGE_LBL_RPS, &rpsv); if (rc != GRAPH_SUCCESS) { return; } rc = hwgraph_info_get_LBL(rpsv, INFO_LBL_DETAIL_INVENT, (arbitrary_info_t *)&rps_invent); if (rc != GRAPH_SUCCESS) { return; } if (rps_state == 0 ) rps_invent->ir_gen.ig_flag = 0; else rps_invent->ir_gen.ig_flag = INVENT_ENABLED;}voidklhwg_add_xbox_rps(devfs_handle_t node_vertex, cnodeid_t cnode, int flag){ devfs_handle_t myrpsv; invent_rpsinfo_t *rps_invent; int rc; if(cnode == CNODEID_NONE) return; GRPRINTF(("klhwg_add_rps: adding %s to vertex 0x%x\n", EDGE_LBL_XBOX_RPS, node_vertex)); rc = hwgraph_path_add(node_vertex, EDGE_LBL_XBOX_RPS, &myrpsv); if (rc != GRAPH_SUCCESS) return; device_master_set(myrpsv, node_vertex); rps_invent = (invent_rpsinfo_t *) klhwg_invent_alloc(cnode, INV_RPS, sizeof(invent_rpsinfo_t)); if (!rps_invent) return; rps_invent->ir_xbox = 1; /* xbox RPS */ if (flag) rps_invent->ir_gen.ig_flag = INVENT_ENABLED; else rps_invent->ir_gen.ig_flag = 0x0; hwgraph_info_add_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, (arbitrary_info_t) rps_invent); hwgraph_info_export_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, sizeof(invent_rpsinfo_t)); }/* * klhwg_update_xbox_rps gets invoked when the xbox system controller * polls the status register and discovers that the power supply has * lost/regained the redundancy. * It's responsible for updating the Hardware graph information. * rps_state = 0 -> if the rps lost the redundancy * = 1 -> If it is redundant. */void klhwg_update_xbox_rps(cnodeid_t cnode, int rps_state){ devfs_handle_t node_vertex; devfs_handle_t rpsv; invent_rpsinfo_t *rps_invent; int rc; if(cnode == CNODEID_NONE) return; node_vertex = cnodeid_to_vertex(cnode); rc = hwgraph_edge_get(node_vertex, EDGE_LBL_XBOX_RPS, &rpsv); if (rc != GRAPH_SUCCESS) { return; } rc = hwgraph_info_get_LBL(rpsv, INFO_LBL_DETAIL_INVENT, (arbitrary_info_t *)&rps_invent); if (rc != GRAPH_SUCCESS) { return; } if (rps_state == 0 ) rps_invent->ir_gen.ig_flag = 0; else rps_invent->ir_gen.ig_flag = INVENT_ENABLED;}#endif /* ndef BRINGUP */voidklhwg_add_xbow(cnodeid_t cnode, nasid_t nasid){ lboard_t *brd; klxbow_t *xbow_p; nasid_t hub_nasid; cnodeid_t hub_cnode; int widgetnum; devfs_handle_t xbow_v, hubv; /*REFERENCED*/ graph_error_t err;#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || defined(CONFIG_IA64_GENERIC) if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_PBRICK_XBOW)) == NULL) return;#endif if (KL_CONFIG_DUPLICATE_BOARD(brd)) return; GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n", cnode, nasid)); if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL) return;#ifndef CONFIG_IA64_SGI_IO /* * We cannot support this function in devfs .. see below where * we use hwgraph_path_add() to create this vertex with a known * name. */ err = hwgraph_vertex_create(&xbow_v); ASSERT(err == GRAPH_SUCCESS); xswitch_vertex_init(xbow_v);#endif /* !CONFIG_IA64_SGI_IO */ for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) continue; hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum); printk("klhwg_add_xbow: Found xbow port type hub hub_nasid %d widgetnum %d\n", hub_nasid, widgetnum); if (hub_nasid == INVALID_NASID) { cmn_err(CE_WARN, "hub widget %d, skipping xbow graph\n", widgetnum); continue; } hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid); printk("klhwg_add_xbow: cnode %d cnode %d\n", nasid_to_compact_node[0], nasid_to_compact_node[1]); if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) { continue; } hubv = cnodeid_to_vertex(hub_cnode);#ifdef CONFIG_IA64_SGI_IO printk("klhwg_add_xbow: Hub Vertex found = %p hub_cnode %d\n", hubv, hub_cnode); err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v); if (err != GRAPH_SUCCESS) { if (err == GRAPH_DUP) cmn_err(CE_WARN, "klhwg_add_xbow: Check for " "working routers and router links!"); cmn_err(CE_GRPANIC, "klhwg_add_xbow: Failed to add " "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p)," "error %d\n", hubv, hubv, xbow_v, xbow_v, err); } xswitch_vertex_init(xbow_v); #endif NODEPDA(hub_cnode)->xbow_vhdl = xbow_v; /* * XXX - This won't work is we ever hook up two hubs * by crosstown through a crossbow. */ if (hub_nasid != nasid) { NODEPDA(hub_cnode)->xbow_peer = nasid; NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer = hub_nasid; } GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n", hub_nasid, EDGE_LBL_XTALK, hubv));#ifndef CONFIG_IA64_SGI_IO err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK); if (err != GRAPH_SUCCESS) { if (err == GRAPH_DUP) cmn_err(CE_WARN, "klhwg_add_xbow: Check for " "working routers and router links!"); cmn_err(CE_GRPANIC, "klhwg_add_xbow: Failed to add " "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), " "error %d\n", hubv, hubv, xbow_v, xbow_v, err); }#endif }}/* ARGSUSED */voidklhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap){ nasid_t nasid; lboard_t *brd; klhub_t *hub; devfs_handle_t node_vertex = NULL; char path_buffer[100]; int rv; char *s; int board_disabled = 0; nasid = COMPACT_TO_NASID_NODEID(cnode); brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n", cnode, nasid, brd)); ASSERT(brd); do { /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -