diff options
Diffstat (limited to 'arch/x86/kernel/mca_32.c')
| -rw-r--r-- | arch/x86/kernel/mca_32.c | 476 | 
1 files changed, 0 insertions, 476 deletions
| diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c deleted file mode 100644 index 7eb1e2b97827..000000000000 --- a/arch/x86/kernel/mca_32.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - *  Written by Martin Kolinek, February 1996 - * - * Changes: - * - *	Chris Beauregard July 28th, 1996 - *	- Fixed up integrated SCSI detection - * - *	Chris Beauregard August 3rd, 1996 - *	- Made mca_info local - *	- Made integrated registers accessible through standard function calls - *	- Added name field - *	- More sanity checking - * - *	Chris Beauregard August 9th, 1996 - *	- Rewrote /proc/mca - * - *	Chris Beauregard January 7th, 1997 - *	- Added basic NMI-processing - *	- Added more information to mca_info structure - * - *	David Weinehall October 12th, 1998 - *	- Made a lot of cleaning up in the source - *	- Added use of save_flags / restore_flags - *	- Added the 'driver_loaded' flag in MCA_adapter - *	- Added an alternative implemention of ZP Gu's mca_find_unused_adapter - * - *	David Weinehall March 24th, 1999 - *	- Fixed the output of 'Driver Installed' in /proc/mca/pos - *	- Made the Integrated Video & SCSI show up even if they have id 0000 - * - *	Alexander Viro November 9th, 1999 - *	- Switched to regular procfs methods - * - *	Alfred Arnold & David Weinehall August 23rd, 2000 - *	- Added support for Planar POS-registers - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/mca.h> -#include <linux/kprobes.h> -#include <linux/slab.h> -#include <asm/io.h> -#include <linux/proc_fs.h> -#include <linux/mman.h> -#include <linux/mm.h> -#include <linux/pagemap.h> -#include <linux/ioport.h> -#include <asm/uaccess.h> -#include <linux/init.h> - -static unsigned char which_scsi; - -int MCA_bus; -EXPORT_SYMBOL(MCA_bus); - -/* - * Motherboard register spinlock. Untested on SMP at the moment, but - * are there any MCA SMP boxes? - * - * Yes - Alan - */ -static DEFINE_SPINLOCK(mca_lock); - -/* Build the status info for the adapter */ - -static void mca_configure_adapter_status(struct mca_device *mca_dev) -{ -	mca_dev->status = MCA_ADAPTER_NONE; - -	mca_dev->pos_id = mca_dev->pos[0] -		+ (mca_dev->pos[1] << 8); - -	if (!mca_dev->pos_id && mca_dev->slot < MCA_MAX_SLOT_NR) { - -		/* -		 * id = 0x0000 usually indicates hardware failure, -		 * however, ZP Gu ([email protected]> reports that his 9556 -		 * has 0x0000 as id and everything still works. There -		 * also seem to be an adapter with id = 0x0000; the -		 * NCR Parallel Bus Memory Card. Until this is confirmed, -		 * however, this code will stay. -		 */ - -		mca_dev->status = MCA_ADAPTER_ERROR; - -		return; -	} else if (mca_dev->pos_id != 0xffff) { - -		/* -		 * 0xffff usually indicates that there's no adapter, -		 * however, some integrated adapters may have 0xffff as -		 * their id and still be valid. Examples are on-board -		 * VGA of the 55sx, the integrated SCSI of the 56 & 57, -		 * and possibly also the 95 ULTIMEDIA. -		 */ - -		mca_dev->status = MCA_ADAPTER_NORMAL; -	} - -	if ((mca_dev->pos_id == 0xffff || -	    mca_dev->pos_id == 0x0000) && mca_dev->slot >= MCA_MAX_SLOT_NR) { -		int j; - -		for (j = 2; j < 8; j++) { -			if (mca_dev->pos[j] != 0xff) { -				mca_dev->status = MCA_ADAPTER_NORMAL; -				break; -			} -		} -	} - -	if (!(mca_dev->pos[2] & MCA_ENABLED)) { - -		/* enabled bit is in POS 2 */ - -		mca_dev->status = MCA_ADAPTER_DISABLED; -	} -} /* mca_configure_adapter_status */ - -/*--------------------------------------------------------------------*/ - -static struct resource mca_standard_resources[] = { -	{ .start = 0x60, .end = 0x60, .name = "system control port B (MCA)" }, -	{ .start = 0x90, .end = 0x90, .name = "arbitration (MCA)" }, -	{ .start = 0x91, .end = 0x91, .name = "card Select Feedback (MCA)" }, -	{ .start = 0x92, .end = 0x92, .name = "system Control port A (MCA)" }, -	{ .start = 0x94, .end = 0x94, .name = "system board setup (MCA)" }, -	{ .start = 0x96, .end = 0x97, .name = "POS (MCA)" }, -	{ .start = 0x100, .end = 0x107, .name = "POS (MCA)" } -}; - -#define MCA_STANDARD_RESOURCES	ARRAY_SIZE(mca_standard_resources) - -/* - *	mca_read_and_store_pos - read the POS registers into a memory buffer - *      @pos: a char pointer to 8 bytes, contains the POS register value on - *            successful return - * - *	Returns 1 if a card actually exists (i.e. the pos isn't - *	all 0xff) or 0 otherwise - */ -static int mca_read_and_store_pos(unsigned char *pos) -{ -	int j; -	int found = 0; - -	for (j = 0; j < 8; j++) { -		pos[j] = inb_p(MCA_POS_REG(j)); -		if (pos[j] != 0xff) { -			/* 0xff all across means no device. 0x00 means -			 * something's broken, but a device is -			 * probably there.  However, if you get 0x00 -			 * from a motherboard register it won't matter -			 * what we find.  For the record, on the -			 * 57SLC, the integrated SCSI adapter has -			 * 0xffff for the adapter ID, but nonzero for -			 * other registers.  */ - -			found = 1; -		} -	} -	return found; -} - -static unsigned char mca_pc_read_pos(struct mca_device *mca_dev, int reg) -{ -	unsigned char byte; -	unsigned long flags; - -	if (reg < 0 || reg >= 8) -		return 0; - -	spin_lock_irqsave(&mca_lock, flags); -	if (mca_dev->pos_register) { -		/* Disable adapter setup, enable motherboard setup */ - -		outb_p(0, MCA_ADAPTER_SETUP_REG); -		outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); - -		byte = inb_p(MCA_POS_REG(reg)); -		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); -	} else { - -		/* Make sure motherboard setup is off */ - -		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - -		/* Read the appropriate register */ - -		outb_p(0x8|(mca_dev->slot & 0xf), MCA_ADAPTER_SETUP_REG); -		byte = inb_p(MCA_POS_REG(reg)); -		outb_p(0, MCA_ADAPTER_SETUP_REG); -	} -	spin_unlock_irqrestore(&mca_lock, flags); - -	mca_dev->pos[reg] = byte; - -	return byte; -} - -static void mca_pc_write_pos(struct mca_device *mca_dev, int reg, -			     unsigned char byte) -{ -	unsigned long flags; - -	if (reg < 0 || reg >= 8) -		return; - -	spin_lock_irqsave(&mca_lock, flags); - -	/* Make sure motherboard setup is off */ - -	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - -	/* Read in the appropriate register */ - -	outb_p(0x8|(mca_dev->slot&0xf), MCA_ADAPTER_SETUP_REG); -	outb_p(byte, MCA_POS_REG(reg)); -	outb_p(0, MCA_ADAPTER_SETUP_REG); - -	spin_unlock_irqrestore(&mca_lock, flags); - -	/* Update the global register list, while we have the byte */ - -	mca_dev->pos[reg] = byte; - -} - -/* for the primary MCA bus, we have identity transforms */ -static int mca_dummy_transform_irq(struct mca_device *mca_dev, int irq) -{ -	return irq; -} - -static int mca_dummy_transform_ioport(struct mca_device *mca_dev, int port) -{ -	return port; -} - -static void *mca_dummy_transform_memory(struct mca_device *mca_dev, void *mem) -{ -	return mem; -} - - -static int __init mca_init(void) -{ -	unsigned int i, j; -	struct mca_device *mca_dev; -	unsigned char pos[8]; -	short mca_builtin_scsi_ports[] = {0xf7, 0xfd, 0x00}; -	struct mca_bus *bus; - -	/* -	 * WARNING: Be careful when making changes here. Putting an adapter -	 * and the motherboard simultaneously into setup mode may result in -	 * damage to chips (according to The Indispensable PC Hardware Book -	 * by Hans-Peter Messmer). Also, we disable system interrupts (so -	 * that we are not disturbed in the middle of this). -	 */ - -	/* Make sure the MCA bus is present */ - -	if (mca_system_init()) { -		printk(KERN_ERR "MCA bus system initialisation failed\n"); -		return -ENODEV; -	} - -	if (!MCA_bus) -		return -ENODEV; - -	printk(KERN_INFO "Micro Channel bus detected.\n"); - -	/* All MCA systems have at least a primary bus */ -	bus = mca_attach_bus(MCA_PRIMARY_BUS); -	if (!bus) -		goto out_nomem; -	bus->default_dma_mask = 0xffffffffLL; -	bus->f.mca_write_pos = mca_pc_write_pos; -	bus->f.mca_read_pos = mca_pc_read_pos; -	bus->f.mca_transform_irq = mca_dummy_transform_irq; -	bus->f.mca_transform_ioport = mca_dummy_transform_ioport; -	bus->f.mca_transform_memory = mca_dummy_transform_memory; - -	/* get the motherboard device */ -	mca_dev = kzalloc(sizeof(struct mca_device), GFP_KERNEL); -	if (unlikely(!mca_dev)) -		goto out_nomem; - -	/* -	 * We do not expect many MCA interrupts during initialization, -	 * but let us be safe: -	 */ -	spin_lock_irq(&mca_lock); - -	/* Make sure adapter setup is off */ - -	outb_p(0, MCA_ADAPTER_SETUP_REG); - -	/* Read motherboard POS registers */ - -	mca_dev->pos_register = 0x7f; -	outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); -	mca_dev->name[0] = 0; -	mca_read_and_store_pos(mca_dev->pos); -	mca_configure_adapter_status(mca_dev); -	/* fake POS and slot for a motherboard */ -	mca_dev->pos_id = MCA_MOTHERBOARD_POS; -	mca_dev->slot = MCA_MOTHERBOARD; -	mca_register_device(MCA_PRIMARY_BUS, mca_dev); - -	mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); -	if (unlikely(!mca_dev)) -		goto out_unlock_nomem; - -	/* Put motherboard into video setup mode, read integrated video -	 * POS registers, and turn motherboard setup off. -	 */ - -	mca_dev->pos_register = 0xdf; -	outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); -	mca_dev->name[0] = 0; -	mca_read_and_store_pos(mca_dev->pos); -	mca_configure_adapter_status(mca_dev); -	/* fake POS and slot for the integrated video */ -	mca_dev->pos_id = MCA_INTEGVIDEO_POS; -	mca_dev->slot = MCA_INTEGVIDEO; -	mca_register_device(MCA_PRIMARY_BUS, mca_dev); - -	/* -	 * Put motherboard into scsi setup mode, read integrated scsi -	 * POS registers, and turn motherboard setup off. -	 * -	 * It seems there are two possible SCSI registers. Martin says that -	 * for the 56,57, 0xf7 is the one, but fails on the 76. -	 * Alfredo ([email protected]) says -	 * 0xfd works on his machine. We'll try both of them. I figure it's -	 * a good bet that only one could be valid at a time. This could -	 * screw up though if one is used for something else on the other -	 * machine. -	 */ - -	for (i = 0; (which_scsi = mca_builtin_scsi_ports[i]) != 0; i++) { -		outb_p(which_scsi, MCA_MOTHERBOARD_SETUP_REG); -		if (mca_read_and_store_pos(pos)) -			break; -	} -	if (which_scsi) { -		/* found a scsi card */ -		mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); -		if (unlikely(!mca_dev)) -			goto out_unlock_nomem; - -		for (j = 0; j < 8; j++) -			mca_dev->pos[j] = pos[j]; - -		mca_configure_adapter_status(mca_dev); -		/* fake POS and slot for integrated SCSI controller */ -		mca_dev->pos_id = MCA_INTEGSCSI_POS; -		mca_dev->slot = MCA_INTEGSCSI; -		mca_dev->pos_register = which_scsi; -		mca_register_device(MCA_PRIMARY_BUS, mca_dev); -	} - -	/* Turn off motherboard setup */ - -	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - -	/* -	 * Now loop over MCA slots: put each adapter into setup mode, and -	 * read its POS registers. Then put adapter setup off. -	 */ - -	for (i = 0; i < MCA_MAX_SLOT_NR; i++) { -		outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG); -		if (!mca_read_and_store_pos(pos)) -			continue; - -		mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); -		if (unlikely(!mca_dev)) -			goto out_unlock_nomem; - -		for (j = 0; j < 8; j++) -			mca_dev->pos[j] = pos[j]; - -		mca_dev->driver_loaded = 0; -		mca_dev->slot = i; -		mca_dev->pos_register = 0; -		mca_configure_adapter_status(mca_dev); -		mca_register_device(MCA_PRIMARY_BUS, mca_dev); -	} -	outb_p(0, MCA_ADAPTER_SETUP_REG); - -	/* Enable interrupts and return memory start */ -	spin_unlock_irq(&mca_lock); - -	for (i = 0; i < MCA_STANDARD_RESOURCES; i++) -		request_resource(&ioport_resource, mca_standard_resources + i); - -	mca_do_proc_init(); - -	return 0; - - out_unlock_nomem: -	spin_unlock_irq(&mca_lock); - out_nomem: -	printk(KERN_EMERG "Failed memory allocation in MCA setup!\n"); -	return -ENOMEM; -} - -subsys_initcall(mca_init); - -/*--------------------------------------------------------------------*/ - -static __kprobes void -mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) -{ -	int slot = mca_dev->slot; - -	if (slot == MCA_INTEGSCSI) { -		printk(KERN_CRIT "NMI: caused by MCA integrated SCSI adapter (%s)\n", -			mca_dev->name); -	} else if (slot == MCA_INTEGVIDEO) { -		printk(KERN_CRIT "NMI: caused by MCA integrated video adapter (%s)\n", -			mca_dev->name); -	} else if (slot == MCA_MOTHERBOARD) { -		printk(KERN_CRIT "NMI: caused by motherboard (%s)\n", -			mca_dev->name); -	} - -	/* More info available in POS 6 and 7? */ - -	if (check_flag) { -		unsigned char pos6, pos7; - -		pos6 = mca_device_read_pos(mca_dev, 6); -		pos7 = mca_device_read_pos(mca_dev, 7); - -		printk(KERN_CRIT "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7); -	} - -} /* mca_handle_nmi_slot */ - -/*--------------------------------------------------------------------*/ - -static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data) -{ -	struct mca_device *mca_dev = to_mca_device(dev); -	unsigned char pos5; - -	pos5 = mca_device_read_pos(mca_dev, 5); - -	if (!(pos5 & 0x80)) { -		/* -		 *  Bit 7 of POS 5 is reset when this adapter has a hardware -		 * error. Bit 7 it reset if there's error information -		 * available in POS 6 and 7. -		 */ -		mca_handle_nmi_device(mca_dev, !(pos5 & 0x40)); -		return 1; -	} -	return 0; -} - -void __kprobes mca_handle_nmi(void) -{ -	/* -	 *  First try - scan the various adapters and see if a specific -	 * adapter was responsible for the error. -	 */ -	bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback); -} |