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

📄 ioconfig_bus.c

📁 linux-2.4.29操作系统的源码
💻 C
字号:
/* * 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. * *  ioconfig_bus - SGI's Persistent PCI Bus Numbering. * * 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 <linux/module.h>#include <linux/init.h>#include <linux/pci.h>#include <asm/sn/sgi.h>#include <asm/uaccess.h>#include <linux/devfs_fs.h>#include <linux/devfs_fs_kernel.h>#include <asm/io.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/labelcl.h>#include <asm//sn/sn_sal.h>#include <asm/sn/addrs.h>#include <asm/sn/ioconfig_bus.h>#define SGI_IOCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"#define SGI_IOCONFIG_BUS_VERSION "1.0"/* * Some Global definitions. */static vertex_hdl_t ioconfig_bus_handle;static unsigned long ioconfig_bus_debug;static struct ioconfig_parm parm;#ifdef IOCONFIG_BUS_DEBUG#define DBG(x...)	printk(x)#else#define DBG(x...)#endifstatic u64 ioconfig_file;static u64 ioconfig_file_size;static u64 ioconfig_activated;static char ioconfig_kernopts[128];/* * For debugging purpose .. hardcode a table .. */struct  ascii_moduleid *ioconfig_bus_table;u64 ioconfig_bus_table_size;static int free_entry;static int new_entry;int next_basebus_number;voidioconfig_get_busnum(char *io_moduleid, int *bus_num){	struct	ascii_moduleid  *temp;	int index;	DBG("ioconfig_get_busnum io_moduleid %s\n", io_moduleid);	*bus_num = -1;	temp = ioconfig_bus_table;	for (index = 0; index < free_entry; temp++, index++) {		if ( (io_moduleid[0] == temp->io_moduleid[0]) &&		     (io_moduleid[1] == temp->io_moduleid[1]) &&		     (io_moduleid[2] == temp->io_moduleid[2]) &&		     (io_moduleid[4] == temp->io_moduleid[4]) &&		     (io_moduleid[5] == temp->io_moduleid[5]) ) {			*bus_num = index * 0x10;			return;		}	}	/*	 * New IO Brick encountered.	 */	if (((int)io_moduleid[0]) == 0) {		DBG("ioconfig_get_busnum: Invalid Module Id given %s\n", io_moduleid);		return;	}	io_moduleid[3] = '#';	strcpy((char *)&(ioconfig_bus_table[free_entry].io_moduleid), io_moduleid);	*bus_num = free_entry * 0x10;	free_entry++;}static voiddump_ioconfig_table(void){	int index = 0;	struct ascii_moduleid *temp;	temp = ioconfig_bus_table;	while (index < free_entry) {		DBG("ASSCI Module ID %s\n", temp->io_moduleid);		temp++;		index++;	}}/* * nextline *	This routine returns the nextline in the buffer. */int nextline(char *buffer, char **next, char *line){	char *temp;	if (buffer[0] == 0x0) {		return(0);	}	temp = buffer;	while (*temp != 0) {		*line = *temp;		if (*temp != '\n'){			*line = *temp;			temp++; line++;		} else			break;	}	if (*temp == 0)		*next = temp;	else		*next = ++temp;	return(1);}/* * build_pcibus_name *	This routine parses the ioconfig contents read into *	memory by ioconfig command in EFI and builds the *	persistent pci bus naming table. */voidbuild_moduleid_table(char *file_contents, struct ascii_moduleid *table){	/*	 * Read the whole file into memory.	 */	int rc;	char *name;	char *temp;	char *next;	char *current;	char *line;	struct ascii_moduleid *moduleid;	line = kmalloc(256, GFP_KERNEL);	if (line <= 0)		BUG(); /* Do not want to continue system boot .. */	memset(line, 0,256);	name = kmalloc(125, GFP_KERNEL);	if (name <= 0){		BUG(); /* Do not want to continue system boot .. */	}	memset(name, 0, 125);	moduleid = table;	current = file_contents;	while (nextline(current, &next, line)){		DBG("current 0x%lx next 0x%lx\n", current, next);		temp = line;		/*		 * Skip all leading Blank lines ..		 */		while (isspace(*temp))			if (*temp != '\n')				temp++;			else				break;		if (*temp == '\n') {			current = next;			memset(line, 0, 256);			continue;		} 		/*		 * Skip comment lines		 */		if (*temp == '#') {			current = next;			memset(line, 0, 256);			continue;		}		/*		 * Get the next free entry in the table.		 */		rc = sscanf(temp, "%s", name);		strcpy(&moduleid->io_moduleid[0], name);		DBG("Found %s\n", name);		moduleid++;		free_entry++;		current = next;		memset(line, 0, 256);	}	new_entry = free_entry;	kfree(line);	kfree(name);	return;}voidioconfig_bus_init(void){	struct ia64_sal_retval ret_stuff;	u64	*temp;	int	cnode;	DBG("ioconfig_bus_init called.\n");        for (cnode = 0; cnode < numnodes; cnode++) {		nasid_t nasid;		/*	 	 * Make SAL call to get the address of the bus configuration table.	 	 */		ret_stuff.status = (uint64_t)0;		ret_stuff.v0 = (uint64_t)0;		ret_stuff.v1 = (uint64_t)0;		ret_stuff.v2 = (uint64_t)0;		nasid = COMPACT_TO_NASID_NODEID(cnode);		SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, nasid, 0, 0, 0, 0, 0);		temp = (u64 *)TO_NODE_CAC(nasid, ret_stuff.v0);		ioconfig_file = *temp;		DBG("ioconfig_bus_init: Nasid %d ret_stuff.v0 0x%lx\n", nasid,			ret_stuff.v0);		if (ioconfig_file) {			ioconfig_file_size = ret_stuff.v1;			ioconfig_file = (ioconfig_file | CACHEABLE_MEM_SPACE);			ioconfig_activated = 1;			break;		}	}	DBG("ioconfig_bus_init: ret_stuff.v0 %p ioconfig_file %p %d\n",		ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size);	ioconfig_bus_table = kmalloc( 512, GFP_KERNEL );	if (ioconfig_bus_table <= 0)		BUG(); /* Seriously, we should not be out of memory at init */	memset(ioconfig_bus_table, 0, 512);	/*	 * If ioconfig options are given on the bootline .. take it.	 */	if (*ioconfig_kernopts != '\0') {		/*		 * ioconfig="..." kernel options given.		 */		DBG("ioconfig_bus_init: Kernel Options given.\n");		(void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table);		(void) dump_ioconfig_table();	}	if (ioconfig_activated) {		DBG("ioconfig_bus_init: ioconfig file given.\n");		(void) build_moduleid_table((char *)ioconfig_file, ioconfig_bus_table);		(void) dump_ioconfig_table();	} else {		DBG("ioconfig_bus_init: ioconfig command not executed in prom\n");	}}voidioconfig_bus_new_entries(void){		int index = 0;	struct ascii_moduleid *temp;	if ((ioconfig_activated) && (free_entry > new_entry)) {		printk("### Please add the following new IO Bricks Module ID \n");		printk("### to your Persistent Bus Numbering Config File\n");	} else		return;	index = new_entry;	temp = &ioconfig_bus_table[index];        while (index < free_entry) {                printk("%s\n", (char *)temp);		temp++;                index++;        }	printk("### End\n");}static int ioconfig_bus_ioctl(struct inode * inode, struct file * file,        unsigned int cmd, unsigned long arg){	int length;	/*	 * Copy in the parameters.	 */	length = copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));	if (length <= 0)		return -EFAULT;	parm.number = free_entry - new_entry;	parm.ioconfig_activated = ioconfig_activated;	if (copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm)))		return -EFAULT;	if (copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct  ascii_moduleid) * (free_entry - new_entry)))		return -EFAULT;	return 0;}/* * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus". */static int ioconfig_bus_open(struct inode * inode, struct file * filp){	if (ioconfig_bus_debug) {        	DBG("ioconfig_bus_open called.\n");	}        return(0);}/* * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus". */static int ioconfig_bus_close(struct inode * inode, struct file * filp){	if (ioconfig_bus_debug) {        	DBG("ioconfig_bus_close called.\n");	}        return(0);}struct file_operations ioconfig_bus_fops = {	ioctl:ioconfig_bus_ioctl,	open:ioconfig_bus_open,		/* open */	release:ioconfig_bus_close	/* release */};/* * init_ifconfig_bus() - Boot time initialization.  Ensure that it is called  *	after devfs has been initialized. * */int init_ioconfig_bus(void){	ioconfig_bus_handle = NULL;	ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",			0, DEVFS_FL_AUTO_DEVNUM,			0, 0,			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,			&ioconfig_bus_fops, NULL);	if (ioconfig_bus_handle == NULL) {		panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");	}	return(0);}static int __init ioconfig_bus_setup (char *str){	char *temp;	DBG("ioconfig_bus_setup: Kernel Options %s\n", str);	temp = (char *)ioconfig_kernopts;	memset(temp, 0, 128);	while ( (*str != '\0') && !isspace (*str) ) {		if (*str == ',') {			*temp = '\n';			temp++;			str++;			continue;		}		*temp = *str;		temp++;		str++;	}	return(0);		}__setup("ioconfig=", ioconfig_bus_setup);

⌨️ 快捷键说明

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