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

📄 ml_iograph.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -