⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ml_iograph.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $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-2003 Silicon Graphics, Inc. All rights reserved. */#include <linux/types.h>#include <linux/slab.h>#include <linux/ctype.h>#include <asm/sn/sgi.h>#include <asm/sn/sn_sal.h>#include <asm/sn/io.h>#include <asm/sn/sn_cpuid.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/hcl_util.h>#include <asm/sn/labelcl.h>#include <asm/sn/xtalk/xbow.h>#include <asm/sn/pci/bridge.h>#include <asm/sn/klconfig.h>#include <asm/sn/sn_private.h>#include <asm/sn/pci/pcibr.h>#include <asm/sn/xtalk/xtalk.h>#include <asm/sn/xtalk/xswitch.h>#include <asm/sn/xtalk/xwidget.h>#include <asm/sn/xtalk/xtalk_private.h>#include <asm/sn/xtalk/xtalkaddrs.h>/* #define IOGRAPH_DEBUG */#ifdef IOGRAPH_DEBUG#define DBG(x...) printk(x)#else#define DBG(x...)#endif /* IOGRAPH_DEBUG *//* #define PROBE_TEST *//* At most 2 hubs can be connected to an xswitch */#define NUM_XSWITCH_VOLUNTEER 2/* * Track which hubs have volunteered to manage devices hanging off of * a Crosstalk Switch (e.g. xbow).  This structure is allocated, * initialized, and hung off the xswitch vertex early on when the * xswitch vertex is created. */typedef struct xswitch_vol_s {	struct semaphore xswitch_volunteer_mutex;	int		xswitch_volunteer_count;	vertex_hdl_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];} *xswitch_vol_t;voidxswitch_vertex_init(vertex_hdl_t xswitch){	xswitch_vol_t xvolinfo;	int rc;	xvolinfo = snia_kmem_zalloc(sizeof(struct xswitch_vol_s));	init_MUTEX(&xvolinfo->xswitch_volunteer_mutex);	rc = hwgraph_info_add_LBL(xswitch, 			INFO_LBL_XSWITCH_VOL,			(arbitrary_info_t)xvolinfo);	ASSERT(rc == GRAPH_SUCCESS); rc = rc;}/* * When assignment of hubs to widgets is complete, we no longer need the * xswitch volunteer structure hanging around.  Destroy it. */static voidxswitch_volunteer_delete(vertex_hdl_t xswitch){	xswitch_vol_t xvolinfo;	int rc;	extern void snia_kmem_free(void *ptr, size_t size);	rc = hwgraph_info_remove_LBL(xswitch, 				INFO_LBL_XSWITCH_VOL,				(arbitrary_info_t *)&xvolinfo);	snia_kmem_free(xvolinfo, sizeof(struct xswitch_vol_s));}/* * A Crosstalk master volunteers to manage xwidgets on the specified xswitch. *//* ARGSUSED */static voidvolunteer_for_widgets(vertex_hdl_t xswitch, vertex_hdl_t master){	xswitch_vol_t xvolinfo = NULL;	vertex_hdl_t hubv;	hubinfo_t hubinfo;	(void)hwgraph_info_get_LBL(xswitch, 				INFO_LBL_XSWITCH_VOL, 				(arbitrary_info_t *)&xvolinfo);	if (xvolinfo == NULL) {	    if (!is_headless_node_vertex(master))		    printk(KERN_WARNING			"volunteer for widgets: vertex 0x%p has no info label",			(void *)xswitch);	    return;	}	down(&xvolinfo->xswitch_volunteer_mutex);	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;	xvolinfo->xswitch_volunteer_count++;	/*	 * if dual ported, make the lowest widgetid always be 	 * xswitch_volunteer[0].	 */	if (xvolinfo->xswitch_volunteer_count == NUM_XSWITCH_VOLUNTEER) {		hubv = xvolinfo->xswitch_volunteer[0];		hubinfo_get(hubv, &hubinfo);		if (hubinfo->h_widgetid != XBOW_HUBLINK_LOW) {			xvolinfo->xswitch_volunteer[0] = 						xvolinfo->xswitch_volunteer[1];			xvolinfo->xswitch_volunteer[1] = hubv;		}	}	up(&xvolinfo->xswitch_volunteer_mutex);}extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);/* * Assign all the xwidgets hanging off the specified xswitch to the * Crosstalk masters that have volunteered for xswitch duty. *//* ARGSUSED */static voidassign_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);}/* * Let boot processor know that we're done initializing our node's IO * and then exit. *//* ARGSUSED */static voidio_init_done(cnodeid_t cnodeid,cpuid_t c){	/* Let boot processor know that we're done. */}/*  * Probe to see if this hub's xtalk link is active.  If so, * return the Crosstalk Identification of the widget that we talk to.   * This is called before any of the Crosstalk infrastructure for  * this hub is set up.  It's usually called on the node that we're * probing, but not always. * * TBD: Prom code should actually do this work, and pass through  * hwid for our use. */static voidearly_probe_for_widget(vertex_hdl_t hubv, xwidget_hwid_t hwid){	hubreg_t llp_csr_reg;	nasid_t nasid;	hubinfo_t hubinfo;	hubinfo_get(hubv, &hubinfo);	nasid = hubinfo->h_nasid;	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);	/* 	 * If link is up, read the widget's part number.	 * A direct connect widget must respond to widgetnum=0.	 */	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) {		/* TBD: Put hub into "indirect" mode */		/*		 * We're able to read from a widget because our hub's 		 * WIDGET_ID was set up earlier.		 */		widgetreg_t widget_id = *(volatile widgetreg_t *)			(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);		DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id,		(volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) );		hwid->part_num = XWIDGET_PART_NUM(widget_id);		hwid->rev_num = XWIDGET_REV_NUM(widget_id);		hwid->mfg_num = XWIDGET_MFG_NUM(widget_id);		/* TBD: link reset */	} else {		hwid->part_num = XWIDGET_PART_NUM_NONE;		hwid->rev_num = XWIDGET_REV_NUM_NONE;		hwid->mfg_num = XWIDGET_MFG_NUM_NONE;	}}/* Add inventory information to the widget vertex  * Right now (module,slot,revision) is being * added as inventory information. */static voidxwidget_inventory_add(vertex_hdl_t 		widgetv,		      lboard_t 			*board,		      struct xwidget_hwid_s 	hwid){	if (!board)		return;	/* Donot add inventory information for the baseio	 * on a speedo with an xbox. It has already been	 * taken care of in SN00_vmc.	 * Speedo with xbox's baseio comes in at slot io1 (widget 9)	 */	device_inventory_add(widgetv,INV_IOBD,board->brd_type,			     geo_module(board->brd_geoid),			     SLOTNUM_GETSLOT(board->brd_slot),			     hwid.rev_num);}/* * io_xswitch_widget_init *	 */voidio_xswitch_widget_init(vertex_hdl_t  	xswitchv,		       vertex_hdl_t	hubv,		       xwidgetnum_t	widgetnum){	xswitch_info_t		xswitch_info;	xwidgetnum_t		hub_widgetid;	vertex_hdl_t		widgetv;	cnodeid_t		cnode;	widgetreg_t		widget_id;	nasid_t			nasid, peer_nasid;	struct xwidget_hwid_s 	hwid;	hubinfo_t		hubinfo;	/*REFERENCED*/	int			rc;	char 			pathname[128];	lboard_t		*board = NULL;	char			buffer[16];	char			bt;	moduleid_t		io_module;	slotid_t get_widget_slotnum(int xbow, int widget);		DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);	/*	 * Verify that xswitchv is indeed an attached xswitch.	 */	xswitch_info = xswitch_info_get(xswitchv);	ASSERT(xswitch_info != NULL);	hubinfo_get(hubv, &hubinfo);	nasid = hubinfo->h_nasid;	cnode = NASID_TO_COMPACT_NODEID(nasid);	hub_widgetid = hubinfo->h_widgetid;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -