/*
 *  linux/arch/i386/kernel/mca.c
 *  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 <asm/system.h>
#include <asm/io.h>
#include <linux/proc_fs.h>
#include <linux/mman.h>
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <asm/arch_hooks.h>

static unsigned char which_scsi = 0;

int MCA_bus = 0;
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 (zpg@castle.net> 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	(sizeof(mca_standard_resources)/sizeof(struct resource))

/**
 *	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++) {
		if((pos[j] = inb_p(MCA_POS_REG(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 Indispensible 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 = kmalloc(sizeof(struct mca_device), GFP_KERNEL);
	if(unlikely(!mca_dev))
		goto out_nomem;
	memset(mca_dev, 0, sizeof(struct mca_device));

	/*
	 * 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 = kmalloc(sizeof(struct mca_device), GFP_ATOMIC);
	if(unlikely(!mca_dev))
		goto out_unlock_nomem;
	memset(mca_dev, 0, sizeof(struct mca_device));


	/* 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 (apena@vnet.ibm.com) 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 = kmalloc(sizeof(struct mca_device), GFP_ATOMIC);
		if(unlikely(!mca_dev))
			goto out_unlock_nomem;
		memset(mca_dev, 0, sizeof(struct mca_device));

		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 = kmalloc(sizeof(struct mca_device), GFP_ATOMIC);
		if(unlikely(!mca_dev))
			goto out_unlock_nomem;
		memset(mca_dev, 0, sizeof(struct mca_device));

		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 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 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 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);

	mca_nmi_hook();
} /* mca_handle_nmi */
