/*
 *  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	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++) {
		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 */
