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

📄 ml_iograph.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $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 */#include <linux/types.h>#include <linux/config.h>#include <linux/slab.h>#include <linux/ctype.h>#include <asm/sn/sgi.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/eeprom.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>extern int maxnodes;/* #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 {	mutex_t xswitch_volunteer_mutex;	int		xswitch_volunteer_count;	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];} *xswitch_vol_t;voidxswitch_vertex_init(devfs_handle_t xswitch){	xswitch_vol_t xvolinfo;	int rc;	xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);	mutex_init(&xvolinfo->xswitch_volunteer_mutex);	xvolinfo->xswitch_volunteer_count = 0;	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(devfs_handle_t xswitch){	xswitch_vol_t xvolinfo;	int rc;	rc = hwgraph_info_remove_LBL(xswitch, 				INFO_LBL_XSWITCH_VOL,				(arbitrary_info_t *)&xvolinfo);#ifdef LATER	ASSERT(rc == GRAPH_SUCCESS); rc = rc;#endif	kfree(xvolinfo);}/* * A Crosstalk master volunteers to manage xwidgets on the specified xswitch. *//* ARGSUSED */static voidvolunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master){	xswitch_vol_t xvolinfo = NULL;	(void)hwgraph_info_get_LBL(xswitch, 				INFO_LBL_XSWITCH_VOL, 				(arbitrary_info_t *)&xvolinfo);	if (xvolinfo == NULL) {#ifdef LATER	    if (!is_headless_node_vertex(master)) {#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("volunteer for widgets: vertex %v has no info label",			xswitch);#else		PRINT_WARNING("volunteer for widgets: vertex 0x%x has no info label",			xswitch);#endif	    }#endif	/* LATER */	    return;	}	mutex_lock(&xvolinfo->xswitch_volunteer_mutex);	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;	xvolinfo->xswitch_volunteer_count++;	mutex_unlock(&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(devfs_handle_t xswitch, devfs_handle_t hubv){	int curr_volunteer, num_volunteer;	xwidgetnum_t widgetnum;	xswitch_info_t xswitch_info;	xswitch_vol_t xvolinfo = NULL;	nasid_t nasid;	hubinfo_t hubinfo;	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) {#ifdef LATER	    if (!is_headless_node_vertex(hubv)) {#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("assign_widgets_to_volunteers:vertex %v has "			" no info label",			xswitch);#else		PRINT_WARNING("assign_widgets_to_volunteers:vertex 0x%x has "			" no info label",			xswitch);#endif	    }#endif	/* LATER */	    return;	}	num_volunteer = xvolinfo->xswitch_volunteer_count;	ASSERT(num_volunteer > 0);	curr_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++) {#ifndef BRINGUP		int i;#endif		/*		 * 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_nasid_widget(nasid, widgetnum)) {			int i;			for (i=0; i<num_volunteer; i++) {				hubv = xvolinfo->xswitch_volunteer[i];				hubinfo_get(hubv, &hubinfo);				nasid = hubinfo->h_nasid;				if (nasid == get_console_nasid())					goto do_assignment;			}#ifdef LATER			PRINT_PANIC("Nasid == %d, console nasid == %d",				nasid, get_console_nasid());#endif		}		/*		 * Do a round-robin assignment among the volunteer nodes.		 */		hubv = xvolinfo->xswitch_volunteer[curr_volunteer];		curr_volunteer = (curr_volunteer + 1) % num_volunteer;		/* fall through */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);}/* * Early iograph initialization.  Called by master CPU in mlreset(). * Useful for including iograph.o in kernel.o. */voidiograph_early_init(void){/* * Need new way to get this information .. */	cnodeid_t cnode;	nasid_t nasid;	lboard_t *board;	/*	 * Init. the board-to-hwgraph link early, so FRU analyzer	 * doesn't trip on leftover values if we panic early on.	 */	for(cnode = 0; cnode < numnodes; cnode++) {		nasid = COMPACT_TO_NASID_NODEID(cnode);		board = (lboard_t *)KL_CONFIG_INFO(nasid);		DBG("iograph_early_init: Found board 0x%p\n", board);		/* Check out all the board info stored on a node */		while(board) {			board->brd_graph_link = GRAPH_VERTEX_NONE;			board = KLCF_NEXT(board);			DBG("iograph_early_init: Found board 0x%p\n", board);		}	}	hubio_init();}#ifdef LATER/* There is an identical definition of this in os/scheduler/runq.c */#define INIT_COOKIE(cookie) cookie.must_run = 0; cookie.cpu = PDA_RUNANYWHERE/* * These functions absolutely doesn't belong here.  It's  here, though,  * until the scheduler provides a platform-independent version * that works the way it should.  The interface will definitely change,  * too.  Currently used only in this file and by io/cdl.c in order to * bind various I/O threads to a CPU on the proper node. */cpu_cookie_tsetnoderun(cnodeid_t cnodeid){	int i;	cpuid_t cpunum;	cpu_cookie_t cookie;	INIT_COOKIE(cookie);	if (cnodeid == CNODEID_NONE)		return(cookie);	/*	 * Do a setmustrun to one of the CPUs on the specified	 * node.	 */	if ((cpunum = CNODE_TO_CPU_BASE(cnodeid)) == CPU_NONE) {		return(cookie);	}	cpunum += CNODE_NUM_CPUS(cnodeid) - 1;	for (i = 0; i < CNODE_NUM_CPUS(cnodeid); i++, cpunum--) {		if (cpu_enabled(cpunum)) {			cookie = setmustrun(cpunum);			break;		}	}	return(cookie);}voidrestorenoderun(cpu_cookie_t cookie){	restoremustrun(cookie);}#endif	/* LATER */#ifdef LINUX_KERNEL_THREADSstatic struct semaphore io_init_sema;#endif/* * Let boot processor know that we're done initializing our node's IO * and then exit. *//* ARGSUSED */static voidio_init_done(cnodeid_t cnodeid,cpu_cookie_t c){	/* Let boot processor know that we're done. */#ifdef LINUX_KERNEL_THREADS	up(&io_init_sema);#endif#ifdef LATER	/* This is for the setnoderun done when the io_init thread	 * started 	 */	restorenoderun(c);	sthread_exit();#endif}/*  * 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(devfs_handle_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(devfs_handle_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,			     board->brd_module,			     SLOTNUM_GETSLOT(board->brd_slot),			     hwid.rev_num);

⌨️ 快捷键说明

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