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

📄 mca.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
EXPORT_SYMBOL(mca_read_stored_pos);/*--------------------------------------------------------------------*//** *	mca_read_pos - read POS register from card *	@slot: slot number to read from *	@reg:  register to read from * *	Fetch a POS value directly from the hardware to obtain the *	current value. This is much slower than mca_read_stored_pos and *	may not be invoked from interrupt context. It handles the *	deep magic required for onboard devices transparently. */unsigned char mca_read_pos(int slot, int reg){	unsigned int byte = 0;	unsigned long flags;	if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0;	if(reg < 0 || reg >= 8) return 0;	save_flags(flags);	cli();	/* Make sure motherboard setup is off */	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);	/* Read in the appropriate register */	if(slot == MCA_INTEGSCSI && mca_info->which_scsi) {		/* Disable adapter setup, enable motherboard setup */		outb_p(0, MCA_ADAPTER_SETUP_REG);		outb_p(mca_info->which_scsi, MCA_MOTHERBOARD_SETUP_REG);		byte = inb_p(MCA_POS_REG(reg));		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);	} else if(slot == MCA_INTEGVIDEO) {		/* Disable adapter setup, enable motherboard setup */		outb_p(0, MCA_ADAPTER_SETUP_REG);		outb_p(0xdf, MCA_MOTHERBOARD_SETUP_REG);		byte = inb_p(MCA_POS_REG(reg));		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);	} else if(slot == MCA_MOTHERBOARD) {		/* Disable adapter setup, enable motherboard setup */		outb_p(0, MCA_ADAPTER_SETUP_REG);		outb_p(0x7f, MCA_MOTHERBOARD_SETUP_REG);		byte = inb_p(MCA_POS_REG(reg));		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);	} else if(slot < MCA_MAX_SLOT_NR) {		/* Make sure motherboard setup is off */		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);		/* Read the appropriate register */		outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG);		byte = inb_p(MCA_POS_REG(reg));		outb_p(0, MCA_ADAPTER_SETUP_REG);	}	/* Make sure the stored values are consistent, while we're here */	mca_info->slot[slot].pos[reg] = byte;	restore_flags(flags);	return byte;} /* mca_read_pos() */EXPORT_SYMBOL(mca_read_pos);/*--------------------------------------------------------------------*//** *	mca_write_pos - read POS register from card *	@slot: slot number to read from *	@reg:  register to read from *	@byte: byte to write to the POS registers * *	Store a POS value directly from the hardware. You should not *	normally need to use this function and should have a very good *	knowledge of MCA bus before you do so. Doing this wrongly can *	damage the hardware. * *	This function may not be used from interrupt context. * *	Note that this a technically a Bad Thing, as IBM tech stuff says *	you should only set POS values through their utilities. *	However, some devices such as the 3c523 recommend that you write *	back some data to make sure the configuration is consistent. *	I'd say that IBM is right, but I like my drivers to work. * *	This function can't do checks to see if multiple devices end up *	with the same resources, so you might see magic smoke if someone *	screws up. */void mca_write_pos(int slot, int reg, unsigned char byte){	unsigned long flags;	if(slot < 0 || slot >= MCA_MAX_SLOT_NR)		return;	if(reg < 0 || reg >= 8)		return;	if(mca_info == NULL)		return;	save_flags(flags);	cli();	/* Make sure motherboard setup is off */	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);	/* Read in the appropriate register */	outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG);	outb_p(byte, MCA_POS_REG(reg));	outb_p(0, MCA_ADAPTER_SETUP_REG);	restore_flags(flags);	/* Update the global register list, while we have the byte */	mca_info->slot[slot].pos[reg] = byte;} /* mca_write_pos() */EXPORT_SYMBOL(mca_write_pos);/*--------------------------------------------------------------------*//** *	mca_set_adapter_name - Set the description of the card *	@slot: slot to name *	@name: text string for the namen * *	This function sets the name reported via /proc for this *	adapter slot. This is for user information only. Setting a *	name deletes any previous name. */void mca_set_adapter_name(int slot, char* name){	if(mca_info == NULL) return;	if(slot >= 0 && slot < MCA_NUMADAPTERS) {		if(name != NULL) {			strncpy(mca_info->slot[slot].name, name,				sizeof(mca_info->slot[slot].name)-1);			mca_info->slot[slot].name[				sizeof(mca_info->slot[slot].name)-1] = 0;		} else {			mca_info->slot[slot].name[0] = 0;		}	}}EXPORT_SYMBOL(mca_set_adapter_name);/** *	mca_set_adapter_procfn - Set the /proc callback *	@slot: slot to configure *	@procfn: callback function to call for /proc *	@dev: device information passed to the callback * *	This sets up an information callback for /proc/mca/slot?.  The *	function is called with the buffer, slot, and device pointer (or *	some equally informative context information, or nothing, if you *	prefer), and is expected to put useful information into the *	buffer.  The adapter name, ID, and POS registers get printed *	before this is called though, so don't do it again. * *	This should be called with a %NULL @procfn when a module *	unregisters, thus preventing kernel crashes and other such *	nastiness. */void mca_set_adapter_procfn(int slot, MCA_ProcFn procfn, void* dev){	if(mca_info == NULL) return;	if(slot >= 0 && slot < MCA_NUMADAPTERS) {		mca_info->slot[slot].procfn = procfn;		mca_info->slot[slot].dev = dev;	}}EXPORT_SYMBOL(mca_set_adapter_procfn);/** *	mca_is_adapter_used - check if claimed by driver *	@slot:	slot to check * *	Returns 1 if the slot has been claimed by a driver */int mca_is_adapter_used(int slot){	return mca_info->slot[slot].driver_loaded;}EXPORT_SYMBOL(mca_is_adapter_used);/** *	mca_mark_as_used - claim an MCA device *	@slot:	slot to claim *	FIXME:  should we make this threadsafe * *	Claim an MCA slot for a device driver. If the *	slot is already taken the function returns 1, *	if it is not taken it is claimed and 0 is *	returned. */int mca_mark_as_used(int slot){	if(mca_info->slot[slot].driver_loaded) return 1;	mca_info->slot[slot].driver_loaded = 1;	return 0;}EXPORT_SYMBOL(mca_mark_as_used);/** *	mca_mark_as_unused - release an MCA device *	@slot:	slot to claim * *	Release the slot for other drives to use. */void mca_mark_as_unused(int slot){	mca_info->slot[slot].driver_loaded = 0;}EXPORT_SYMBOL(mca_mark_as_unused);/** *	mca_get_adapter_name - get the adapter description *	@slot:	slot to query * *	Return the adapter description if set. If it has not been *	set or the slot is out range then return NULL. */char *mca_get_adapter_name(int slot){	if(mca_info == NULL) return 0;	if(slot >= 0 && slot < MCA_NUMADAPTERS) {		return mca_info->slot[slot].name;	}	return 0;}EXPORT_SYMBOL(mca_get_adapter_name);/** *	mca_isadapter - check if the slot holds an adapter *	@slot:	slot to query * *	Returns zero if the slot does not hold an adapter, non zero if *	it does. */int mca_isadapter(int slot){	if(mca_info == NULL) return 0;	if(slot >= 0 && slot < MCA_NUMADAPTERS) {		return ((mca_info->slot[slot].status == MCA_ADAPTER_NORMAL)			|| (mca_info->slot[slot].status == MCA_ADAPTER_DISABLED));	}	return 0;}EXPORT_SYMBOL(mca_isadapter);/** *	mca_isadapter - check if the slot holds an adapter *	@slot:	slot to query * *	Returns a non zero value if the slot holds an enabled adapter *	and zero for any other case. */int mca_isenabled(int slot){	if(mca_info == NULL) return 0;	if(slot >= 0 && slot < MCA_NUMADAPTERS) {		return (mca_info->slot[slot].status == MCA_ADAPTER_NORMAL);	}	return 0;}EXPORT_SYMBOL(mca_isenabled);/*--------------------------------------------------------------------*/#ifdef CONFIG_PROC_FSint get_mca_info(char *page, char **start, off_t off,				 int count, int *eof, void *data){	int i, j, len = 0;	if(MCA_bus && mca_info != NULL) {		/* Format POS registers of eight MCA slots */		for(i=0; i<MCA_MAX_SLOT_NR; i++) {			len += sprintf(page+len, "Slot %d: ", i+1);			for(j=0; j<8; j++)				len += sprintf(page+len, "%02x ", mca_info->slot[i].pos[j]);			len += sprintf(page+len, " %s\n", mca_info->slot[i].name);		}		/* Format POS registers of integrated video subsystem */		len += sprintf(page+len, "Video : ");		for(j=0; j<8; j++)			len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]);		len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name);		/* Format POS registers of integrated SCSI subsystem */		len += sprintf(page+len, "SCSI  : ");		for(j=0; j<8; j++)			len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]);		len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name);		/* Format POS registers of motherboard */		len += sprintf(page+len, "Planar: ");		for(j=0; j<8; j++)			len += sprintf(page+len, "%02x ", mca_info->slot[MCA_MOTHERBOARD].pos[j]);		len += sprintf(page+len, " %s\n", mca_info->slot[MCA_MOTHERBOARD].name);	} else {		/* Leave it empty if MCA not detected - this should *never*		 * happen!		 */	}	if (len <= off+count) *eof = 1;	*start = page + off;	len -= off;	if (len>count) len = count;	if (len<0) len = 0;	return len;}/*--------------------------------------------------------------------*/static int mca_default_procfn(char* buf, struct MCA_adapter *p){	int len = 0, i;	int slot = p - mca_info->slot;	/* Print out the basic information */	if(slot < MCA_MAX_SLOT_NR) {		len += sprintf(buf+len, "Slot: %d\n", slot+1);	} else if(slot == MCA_INTEGSCSI) {		len += sprintf(buf+len, "Integrated SCSI Adapter\n");	} else if(slot == MCA_INTEGVIDEO) {		len += sprintf(buf+len, "Integrated Video Adapter\n");	} else if(slot == MCA_MOTHERBOARD) {		len += sprintf(buf+len, "Motherboard\n");	}	if(p->name[0]) {		/* Drivers might register a name without /proc handler... */		len += sprintf(buf+len, "Adapter Name: %s\n",			p->name);	} else {		len += sprintf(buf+len, "Adapter Name: Unknown\n");	}	len += sprintf(buf+len, "Id: %02x%02x\n",		p->pos[1], p->pos[0]);	len += sprintf(buf+len, "Enabled: %s\nPOS: ",		mca_isenabled(slot) ? "Yes" : "No");	for(i=0; i<8; i++) {		len += sprintf(buf+len, "%02x ", p->pos[i]);	}	len += sprintf(buf+len, "\nDriver Installed: %s",		mca_is_adapter_used(slot) ? "Yes" : "No");	buf[len++] = '\n';	buf[len] = 0;	return len;} /* mca_default_procfn() */static int get_mca_machine_info(char* page, char **start, off_t off,				 int count, int *eof, void *data){	int len = 0;	len += sprintf(page+len, "Model Id: 0x%x\n", machine_id);	len += sprintf(page+len, "Submodel Id: 0x%x\n", machine_submodel_id);	len += sprintf(page+len, "BIOS Revision: 0x%x\n", BIOS_revision);	if (len <= off+count) *eof = 1;	*start = page + off;	len -= off;	if (len>count) len = count;	if (len<0) len = 0;	return len;}static int mca_read_proc(char *page, char **start, off_t off,				 int count, int *eof, void *data){	struct MCA_adapter *p = (struct MCA_adapter *)data;	int len = 0;	/* Get the standard info */	len = mca_default_procfn(page, p);	/* Do any device-specific processing, if there is any */	if(p->procfn) {		len += p->procfn(page+len, p-mca_info->slot, p->dev);	}	if (len <= off+count) *eof = 1;	*start = page + off;	len -= off;	if (len>count) len = count;	if (len<0) len = 0;	return len;} /* mca_read_proc() *//*--------------------------------------------------------------------*/void __init mca_do_proc_init(void){	int i;	struct proc_dir_entry *proc_mca;	struct proc_dir_entry* node = NULL;	struct MCA_adapter *p;	if(mca_info == NULL) return;	/* Should never happen */	proc_mca = proc_mkdir("mca", &proc_root);	create_proc_read_entry("pos",0,proc_mca,get_mca_info,NULL);	create_proc_read_entry("machine",0,proc_mca,get_mca_machine_info,NULL);	/* Initialize /proc/mca entries for existing adapters */	for(i = 0; i < MCA_NUMADAPTERS; i++) {		p = &mca_info->slot[i];		p->procfn = 0;		if(i < MCA_MAX_SLOT_NR) sprintf(p->procname,"slot%d", i+1);		else if(i == MCA_INTEGVIDEO) sprintf(p->procname,"video");		else if(i == MCA_INTEGSCSI) sprintf(p->procname,"scsi");		else if(i == MCA_MOTHERBOARD) sprintf(p->procname,"planar");		if(!mca_isadapter(i)) continue;		node = create_proc_read_entry(p->procname, 0, proc_mca,						mca_read_proc, (void *)p);		if(node == NULL) {			printk("Failed to allocate memory for MCA proc-entries!");			return;		}	}} /* mca_do_proc_init() */#endif

⌨️ 快捷键说明

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