/* -*- mode: c; c-basic-offset: 8 -*- */

/* Copyright (C) 1999,2001
 *
 * Author: J.E.J.Bottomley@HansenPartnership.com
 *
 * linux/arch/i386/kernel/voyager_cat.c
 *
 * This file contains all the logic for manipulating the CAT bus
 * in a level 5 machine.
 *
 * The CAT bus is a serial configuration and test bus.  Its primary
 * uses are to probe the initial configuration of the system and to
 * diagnose error conditions when a system interrupt occurs.  The low
 * level interface is fairly primitive, so most of this file consists
 * of bit shift manipulations to send and receive packets on the
 * serial bus */

#include <linux/types.h>
#include <linux/completion.h>
#include <linux/sched.h>
#include <asm/voyager.h>
#include <asm/vic.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/io.h>

#ifdef VOYAGER_CAT_DEBUG
#define CDEBUG(x)	printk x
#else
#define CDEBUG(x)
#endif

/* the CAT command port */
#define CAT_CMD		(sspb + 0xe)
/* the CAT data port */
#define CAT_DATA	(sspb + 0xd)

/* the internal cat functions */
static void cat_pack(__u8 *msg, __u16 start_bit, __u8 *data, 
		     __u16 num_bits);
static void cat_unpack(__u8 *msg, __u16 start_bit, __u8 *data,
		       __u16 num_bits);
static void cat_build_header(__u8 *header, const __u16 len, 
			     const __u16 smallest_reg_bits,
			     const __u16 longest_reg_bits);
static int cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp,
			__u8 reg, __u8 op);
static int cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp,
		       __u8 reg, __u8 *value);
static int cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes,
			__u8 pad_bits);
static int cat_write(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
		     __u8 value);
static int cat_read(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
		    __u8 *value);
static int cat_subread(voyager_module_t *modp, voyager_asic_t *asicp,
		       __u16 offset, __u16 len, void *buf);
static int cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp,
			__u8 reg, __u8 value);
static int cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp);
static int cat_connect(voyager_module_t *modp, voyager_asic_t *asicp);

static inline const char *
cat_module_name(int module_id)
{
	switch(module_id) {
	case 0x10:
		return "Processor Slot 0";
	case 0x11:
		return "Processor Slot 1";
	case 0x12:
		return "Processor Slot 2";
	case 0x13:
		return "Processor Slot 4";
	case 0x14:
		return "Memory Slot 0";
	case 0x15:
		return "Memory Slot 1";
	case 0x18:
		return "Primary Microchannel";
	case 0x19:
		return "Secondary Microchannel";
	case 0x1a:
		return "Power Supply Interface";
	case 0x1c:
		return "Processor Slot 5";
	case 0x1d:
		return "Processor Slot 6";
	case 0x1e:
		return "Processor Slot 7";
	case 0x1f:
		return "Processor Slot 8";
	default:
		return "Unknown Module";
	}
}

static int sspb = 0;		/* stores the super port location */
int voyager_8slot = 0;		/* set to true if a 51xx monster */

voyager_module_t *voyager_cat_list;

/* the I/O port assignments for the VIC and QIC */
static struct resource vic_res = {
	.name	= "Voyager Interrupt Controller",
	.start	= 0xFC00,
	.end	= 0xFC6F
};
static struct resource qic_res = {
	.name	= "Quad Interrupt Controller",
	.start	= 0xFC70,
	.end	= 0xFCFF
};

/* This function is used to pack a data bit stream inside a message.
 * It writes num_bits of the data buffer in msg starting at start_bit.
 * Note: This function assumes that any unused bit in the data stream
 * is set to zero so that the ors will work correctly */
static void
cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
{
	/* compute initial shift needed */
	const __u16 offset = start_bit % BITS_PER_BYTE;
	__u16 len = num_bits / BITS_PER_BYTE;
	__u16 byte = start_bit / BITS_PER_BYTE;
	__u16 residue = (num_bits % BITS_PER_BYTE) + offset;
	int i;

	/* adjust if we have more than a byte of residue */
	if(residue >= BITS_PER_BYTE) {
		residue -= BITS_PER_BYTE;
		len++;
	}

	/* clear out the bits.  We assume here that if len==0 then
	 * residue >= offset.  This is always true for the catbus
	 * operations */
	msg[byte] &= 0xff << (BITS_PER_BYTE - offset); 
	msg[byte++] |= data[0] >> offset;
	if(len == 0)
		return;
	for(i = 1; i < len; i++)
		msg[byte++] = (data[i-1] << (BITS_PER_BYTE - offset))
			| (data[i] >> offset);
	if(residue != 0) {
		__u8 mask = 0xff >> residue;
		__u8 last_byte = data[i-1] << (BITS_PER_BYTE - offset)
			| (data[i] >> offset);
		
		last_byte &= ~mask;
		msg[byte] &= mask;
		msg[byte] |= last_byte;
	}
	return;
}
/* unpack the data again (same arguments as cat_pack()). data buffer
 * must be zero populated.
 *
 * Function: given a message string move to start_bit and copy num_bits into
 * data (starting at bit 0 in data).
 */
static void
cat_unpack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
{
	/* compute initial shift needed */
	const __u16 offset = start_bit % BITS_PER_BYTE;
	__u16 len = num_bits / BITS_PER_BYTE;
	const __u8 last_bits = num_bits % BITS_PER_BYTE;
	__u16 byte = start_bit / BITS_PER_BYTE;
	int i;

	if(last_bits != 0)
		len++;

	/* special case: want < 8 bits from msg and we can get it from
	 * a single byte of the msg */
	if(len == 0 && BITS_PER_BYTE - offset >= num_bits) {
		data[0] = msg[byte] << offset;
		data[0] &= 0xff >> (BITS_PER_BYTE - num_bits);
		return;
	}
	for(i = 0; i < len; i++) {
		/* this annoying if has to be done just in case a read of
		 * msg one beyond the array causes a panic */
		if(offset != 0) {
			data[i] = msg[byte++] << offset;
			data[i] |= msg[byte] >> (BITS_PER_BYTE - offset);
		}
		else {
			data[i] = msg[byte++];
		}
	}
	/* do we need to truncate the final byte */
	if(last_bits != 0) {
		data[i-1] &= 0xff << (BITS_PER_BYTE - last_bits);
	}
	return;
}

static void
cat_build_header(__u8 *header, const __u16 len, const __u16 smallest_reg_bits,
		 const __u16 longest_reg_bits)
{
	int i;
	__u16 start_bit = (smallest_reg_bits - 1) % BITS_PER_BYTE;
	__u8 *last_byte = &header[len - 1];

	if(start_bit == 0)
		start_bit = 1;	/* must have at least one bit in the hdr */
	
	for(i=0; i < len; i++)
		header[i] = 0;

	for(i = start_bit; i > 0; i--)
		*last_byte = ((*last_byte) << 1) + 1;

}

static int
cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, __u8 op)
{
	__u8 parity, inst, inst_buf[4] = { 0 };
	__u8 iseq[VOYAGER_MAX_SCAN_PATH], hseq[VOYAGER_MAX_REG_SIZE];
	__u16 ibytes, hbytes, padbits;
	int i;
	
	/* 
	 * Parity is the parity of the register number + 1 (READ_REGISTER
	 * and WRITE_REGISTER always add '1' to the number of bits == 1)
	 */
	parity = (__u8)(1 + (reg & 0x01) +
	         ((__u8)(reg & 0x02) >> 1) +
	         ((__u8)(reg & 0x04) >> 2) +
	         ((__u8)(reg & 0x08) >> 3)) % 2;

	inst = ((parity << 7) | (reg << 2) | op);

	outb(VOYAGER_CAT_IRCYC, CAT_CMD);
	if(!modp->scan_path_connected) {
		if(asicp->asic_id != VOYAGER_CAT_ID) {
			printk("**WARNING***: cat_sendinst has disconnected scan path not to CAT asic\n");
			return 1;
		}
		outb(VOYAGER_CAT_HEADER, CAT_DATA);
		outb(inst, CAT_DATA);
		if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
			CDEBUG(("VOYAGER CAT: cat_sendinst failed to get CAT_HEADER\n"));
			return 1;
		}
		return 0;
	}
	ibytes = modp->inst_bits / BITS_PER_BYTE;
	if((padbits = modp->inst_bits % BITS_PER_BYTE) != 0) {
		padbits = BITS_PER_BYTE - padbits;
		ibytes++;
	}
	hbytes = modp->largest_reg / BITS_PER_BYTE;
	if(modp->largest_reg % BITS_PER_BYTE)
		hbytes++;
	CDEBUG(("cat_sendinst: ibytes=%d, hbytes=%d\n", ibytes, hbytes));
	/* initialise the instruction sequence to 0xff */
	for(i=0; i < ibytes + hbytes; i++)
		iseq[i] = 0xff;
	cat_build_header(hseq, hbytes, modp->smallest_reg, modp->largest_reg);
	cat_pack(iseq, modp->inst_bits, hseq, hbytes * BITS_PER_BYTE);
	inst_buf[0] = inst;
	inst_buf[1] = 0xFF >> (modp->largest_reg % BITS_PER_BYTE);
	cat_pack(iseq, asicp->bit_location, inst_buf, asicp->ireg_length);
#ifdef VOYAGER_CAT_DEBUG
	printk("ins = 0x%x, iseq: ", inst);
	for(i=0; i< ibytes + hbytes; i++)
		printk("0x%x ", iseq[i]);
	printk("\n");
#endif
	if(cat_shiftout(iseq, ibytes, hbytes, padbits)) {
		CDEBUG(("VOYAGER CAT: cat_sendinst: cat_shiftout failed\n"));
		return 1;
	}
	CDEBUG(("CAT SHIFTOUT DONE\n"));
	return 0;
}

static int
cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, 
	    __u8 *value)
{
	if(!modp->scan_path_connected) {
		if(asicp->asic_id != VOYAGER_CAT_ID) {
			CDEBUG(("VOYAGER CAT: ERROR: cat_getdata to CAT asic with scan path connected\n"));
			return 1;
		}
		if(reg > VOYAGER_SUBADDRHI) 
			outb(VOYAGER_CAT_RUN, CAT_CMD);
		outb(VOYAGER_CAT_DRCYC, CAT_CMD);
		outb(VOYAGER_CAT_HEADER, CAT_DATA);
		*value = inb(CAT_DATA);
		outb(0xAA, CAT_DATA);
		if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
			CDEBUG(("cat_getdata: failed to get VOYAGER_CAT_HEADER\n"));
			return 1;
		}
		return 0;
	}
	else {
		__u16 sbits = modp->num_asics -1 + asicp->ireg_length;
		__u16 sbytes = sbits / BITS_PER_BYTE;
		__u16 tbytes;
		__u8 string[VOYAGER_MAX_SCAN_PATH], trailer[VOYAGER_MAX_REG_SIZE];
		__u8 padbits;
		int i;
		
		outb(VOYAGER_CAT_DRCYC, CAT_CMD);

		if((padbits = sbits % BITS_PER_BYTE) != 0) {
			padbits = BITS_PER_BYTE - padbits;
			sbytes++;
		}
		tbytes = asicp->ireg_length / BITS_PER_BYTE;
		if(asicp->ireg_length % BITS_PER_BYTE)
			tbytes++;
		CDEBUG(("cat_getdata: tbytes = %d, sbytes = %d, padbits = %d\n",
			tbytes,	sbytes, padbits));
		cat_build_header(trailer, tbytes, 1, asicp->ireg_length);

		
		for(i = tbytes - 1; i >= 0; i--) {
			outb(trailer[i], CAT_DATA);
			string[sbytes + i] = inb(CAT_DATA);
		}

		for(i = sbytes - 1; i >= 0; i--) {
			outb(0xaa, CAT_DATA);
			string[i] = inb(CAT_DATA);
		}
		*value = 0;
		cat_unpack(string, padbits + (tbytes * BITS_PER_BYTE) + asicp->asic_location, value, asicp->ireg_length);
#ifdef VOYAGER_CAT_DEBUG
		printk("value=0x%x, string: ", *value);
		for(i=0; i< tbytes+sbytes; i++)
			printk("0x%x ", string[i]);
		printk("\n");
#endif
		
		/* sanity check the rest of the return */
		for(i=0; i < tbytes; i++) {
			__u8 input = 0;

			cat_unpack(string, padbits + (i * BITS_PER_BYTE), &input, BITS_PER_BYTE);
			if(trailer[i] != input) {
				CDEBUG(("cat_getdata: failed to sanity check rest of ret(%d) 0x%x != 0x%x\n", i, input, trailer[i]));
				return 1;
			}
		}
		CDEBUG(("cat_getdata DONE\n"));
		return 0;
	}
}

static int
cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
{
	int i;
	
	for(i = data_bytes + header_bytes - 1; i >= header_bytes; i--)
		outb(data[i], CAT_DATA);

	for(i = header_bytes - 1; i >= 0; i--) {
		__u8 header = 0;
		__u8 input;

		outb(data[i], CAT_DATA);
		input = inb(CAT_DATA);
		CDEBUG(("cat_shiftout: returned 0x%x\n", input));
		cat_unpack(data, ((data_bytes + i) * BITS_PER_BYTE) - pad_bits,
			   &header, BITS_PER_BYTE);
		if(input != header) {
			CDEBUG(("VOYAGER CAT: cat_shiftout failed to return header 0x%x != 0x%x\n", input, header));
			return 1;
		}
	}
	return 0;
}

static int
cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp, 
	     __u8 reg, __u8 value)
{
	outb(VOYAGER_CAT_DRCYC, CAT_CMD);
	if(!modp->scan_path_connected) {
		if(asicp->asic_id != VOYAGER_CAT_ID) {
			CDEBUG(("VOYAGER CAT: ERROR: scan path disconnected when asic != CAT\n"));
			return 1;
		}
		outb(VOYAGER_CAT_HEADER, CAT_DATA);
		outb(value, CAT_DATA);
		if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
			CDEBUG(("cat_senddata: failed to get correct header response to sent data\n"));
			return 1;
		}
		if(reg > VOYAGER_SUBADDRHI) {
			outb(VOYAGER_CAT_RUN, CAT_CMD);
			outb(VOYAGER_CAT_END, CAT_CMD);
			outb(VOYAGER_CAT_RUN, CAT_CMD);
		}
		
		return 0;
	}
	else {
		__u16 hbytes = asicp->ireg_length / BITS_PER_BYTE;
		__u16 dbytes = (modp->num_asics - 1 + asicp->ireg_length)/BITS_PER_BYTE;
		__u8 padbits, dseq[VOYAGER_MAX_SCAN_PATH], 
			hseq[VOYAGER_MAX_REG_SIZE];
		int i;

		if((padbits = (modp->num_asics - 1 
			       + asicp->ireg_length) % BITS_PER_BYTE) != 0) {
			padbits = BITS_PER_BYTE - padbits;
			dbytes++;
		}
		if(asicp->ireg_length % BITS_PER_BYTE)
			hbytes++;
		
		cat_build_header(hseq, hbytes, 1, asicp->ireg_length);
		
		for(i = 0; i < dbytes + hbytes; i++)
			dseq[i] = 0xff;
		CDEBUG(("cat_senddata: dbytes=%d, hbytes=%d, padbits=%d\n",
			dbytes, hbytes, padbits));
		cat_pack(dseq, modp->num_asics - 1 + asicp->ireg_length,
			 hseq, hbytes * BITS_PER_BYTE);
		cat_pack(dseq, asicp->asic_location, &value, 
			 asicp->ireg_length);
#ifdef VOYAGER_CAT_DEBUG
		printk("dseq ");
		for(i=0; i<hbytes+dbytes; i++) {
			printk("0x%x ", dseq[i]);
		}
		printk("\n");
#endif
		return cat_shiftout(dseq, dbytes, hbytes, padbits);
	}
}

static int
cat_write(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
	 __u8 value)
{
	if(cat_sendinst(modp, asicp, reg, VOYAGER_WRITE_CONFIG))
		return 1;
	return cat_senddata(modp, asicp, reg, value);
}

static int
cat_read(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
	 __u8 *value)
{
	if(cat_sendinst(modp, asicp, reg, VOYAGER_READ_CONFIG))
		return 1;
	return cat_getdata(modp, asicp, reg, value);
}

static int
cat_subaddrsetup(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset,
		 __u16 len)
{
	__u8 val;

	if(len > 1) {
		/* set auto increment */
		__u8 newval;
		
		if(cat_read(modp, asicp, VOYAGER_AUTO_INC_REG, &val)) {
			CDEBUG(("cat_subaddrsetup: read of VOYAGER_AUTO_INC_REG failed\n"));
			return 1;
		}
		CDEBUG(("cat_subaddrsetup: VOYAGER_AUTO_INC_REG = 0x%x\n", val));
		newval = val | VOYAGER_AUTO_INC;
		if(newval != val) {
			if(cat_write(modp, asicp, VOYAGER_AUTO_INC_REG, val)) {
				CDEBUG(("cat_subaddrsetup: write to VOYAGER_AUTO_INC_REG failed\n"));
				return 1;
			}
		}
	}
	if(cat_write(modp, asicp, VOYAGER_SUBADDRLO, (__u8)(offset &0xff))) {
		CDEBUG(("cat_subaddrsetup: write to SUBADDRLO failed\n"));
		return 1;
	}
	if(asicp->subaddr > VOYAGER_SUBADDR_LO) {
		if(cat_write(modp, asicp, VOYAGER_SUBADDRHI, (__u8)(offset >> 8))) {
			CDEBUG(("cat_subaddrsetup: write to SUBADDRHI failed\n"));
			return 1;
		}
		cat_read(modp, asicp, VOYAGER_SUBADDRHI, &val);
		CDEBUG(("cat_subaddrsetup: offset = %d, hi = %d\n", offset, val));
	}
	cat_read(modp, asicp, VOYAGER_SUBADDRLO, &val);
	CDEBUG(("cat_subaddrsetup: offset = %d, lo = %d\n", offset, val));
	return 0;
}
		
static int
cat_subwrite(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset,
	    __u16 len, void *buf)
{
	int i, retval;

	/* FIXME: need special actions for VOYAGER_CAT_ID here */
	if(asicp->asic_id == VOYAGER_CAT_ID) {
		CDEBUG(("cat_subwrite: ATTEMPT TO WRITE TO CAT ASIC\n"));
		/* FIXME -- This is supposed to be handled better
		 * There is a problem writing to the cat asic in the
		 * PSI.  The 30us delay seems to work, though */
		udelay(30);
	}
		
	if((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
		printk("cat_subwrite: cat_subaddrsetup FAILED\n");
		return retval;
	}
	
	if(cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_WRITE_CONFIG)) {
		printk("cat_subwrite: cat_sendinst FAILED\n");
		return 1;
	}
	for(i = 0; i < len; i++) {
		if(cat_senddata(modp, asicp, 0xFF, ((__u8 *)buf)[i])) {
			printk("cat_subwrite: cat_sendata element at %d FAILED\n", i);
			return 1;
		}
	}
	return 0;
}
static int
cat_subread(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset,
	    __u16 len, void *buf)
{
	int i, retval;

	if((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
		CDEBUG(("cat_subread: cat_subaddrsetup FAILED\n"));
		return retval;
	}

	if(cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_READ_CONFIG)) {
		CDEBUG(("cat_subread: cat_sendinst failed\n"));
		return 1;
	}
	for(i = 0; i < len; i++) {
		if(cat_getdata(modp, asicp, 0xFF,
			       &((__u8 *)buf)[i])) {
			CDEBUG(("cat_subread: cat_getdata element %d failed\n", i));
			return 1;
		}
	}
	return 0;
}


/* buffer for storing EPROM data read in during initialisation */
static __initdata __u8 eprom_buf[0xFFFF];
static voyager_module_t *voyager_initial_module;

/* Initialise the cat bus components.  We assume this is called by the
 * boot cpu *after* all memory initialisation has been done (so we can
 * use kmalloc) but before smp initialisation, so we can probe the SMP
 * configuration and pick up necessary information.  */
void
voyager_cat_init(void)
{
	voyager_module_t **modpp = &voyager_initial_module;
	voyager_asic_t **asicpp;
	voyager_asic_t *qabc_asic = NULL;
	int i, j;
	unsigned long qic_addr = 0;
	__u8 qabc_data[0x20];
	__u8 num_submodules, val;
	voyager_eprom_hdr_t *eprom_hdr = (voyager_eprom_hdr_t *)&eprom_buf[0];
	
	__u8 cmos[4];
	unsigned long addr;
	
	/* initiallise the SUS mailbox */
	for(i=0; i<sizeof(cmos); i++)
		cmos[i] = voyager_extended_cmos_read(VOYAGER_DUMP_LOCATION + i);
	addr = *(unsigned long *)cmos;
	if((addr & 0xff000000) != 0xff000000) {
		printk(KERN_ERR "Voyager failed to get SUS mailbox (addr = 0x%lx\n", addr);
	} else {
		static struct resource res;
		
		res.name = "voyager SUS";
		res.start = addr;
		res.end = addr+0x3ff;
		
		request_resource(&iomem_resource, &res);
		voyager_SUS = (struct voyager_SUS *)
			ioremap(addr, 0x400);
		printk(KERN_NOTICE "Voyager SUS mailbox version 0x%x\n",
		       voyager_SUS->SUS_version);
		voyager_SUS->kernel_version = VOYAGER_MAILBOX_VERSION;
		voyager_SUS->kernel_flags = VOYAGER_OS_HAS_SYSINT;
	}

	/* clear the processor counts */
	voyager_extended_vic_processors = 0;
	voyager_quad_processors = 0;



	printk("VOYAGER: beginning CAT bus probe\n");
	/* set up the SuperSet Port Block which tells us where the
	 * CAT communication port is */
	sspb = inb(VOYAGER_SSPB_RELOCATION_PORT) * 0x100;
	VDEBUG(("VOYAGER DEBUG: sspb = 0x%x\n", sspb));

	/* now find out if were 8 slot or normal */
	if((inb(VIC_PROC_WHO_AM_I) & EIGHT_SLOT_IDENTIFIER)
	   == EIGHT_SLOT_IDENTIFIER) {
		voyager_8slot = 1;
		printk(KERN_NOTICE "Voyager: Eight slot 51xx configuration detected\n");
	}

	for(i = VOYAGER_MIN_MODULE;
	    i <= VOYAGER_MAX_MODULE; i++) {
		__u8 input;
		int asic;
		__u16 eprom_size;
		__u16 sp_offset;

		outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
		outb(i, VOYAGER_CAT_CONFIG_PORT);

		/* check the presence of the module */
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		outb(VOYAGER_CAT_IRCYC, CAT_CMD);
		outb(VOYAGER_CAT_HEADER, CAT_DATA);
		/* stream series of alternating 1's and 0's to stimulate
		 * response */
		outb(0xAA, CAT_DATA);
		input = inb(CAT_DATA);
		outb(VOYAGER_CAT_END, CAT_CMD);
		if(input != VOYAGER_CAT_HEADER) {
			continue;
		}
		CDEBUG(("VOYAGER DEBUG: found module id 0x%x, %s\n", i,
			cat_module_name(i)));
		*modpp = kmalloc(sizeof(voyager_module_t), GFP_KERNEL); /*&voyager_module_storage[cat_count++];*/
		if(*modpp == NULL) {
			printk("**WARNING** kmalloc failure in cat_init\n");
			continue;
		}
		memset(*modpp, 0, sizeof(voyager_module_t));
		/* need temporary asic for cat_subread.  It will be
		 * filled in correctly later */
		(*modpp)->asic = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count];*/
		if((*modpp)->asic == NULL) {
			printk("**WARNING** kmalloc failure in cat_init\n");
			continue;
		}
		memset((*modpp)->asic, 0, sizeof(voyager_asic_t));
		(*modpp)->asic->asic_id = VOYAGER_CAT_ID;
		(*modpp)->asic->subaddr = VOYAGER_SUBADDR_HI;
		(*modpp)->module_addr = i;
		(*modpp)->scan_path_connected = 0;
		if(i == VOYAGER_PSI) {
			/* Exception leg for modules with no EEPROM */
			printk("Module \"%s\"\n", cat_module_name(i));
			continue;
		}
			       
		CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		cat_disconnect(*modpp, (*modpp)->asic);
		if(cat_subread(*modpp, (*modpp)->asic,
			       VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
			       &eprom_size)) {
			printk("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", i);
			outb(VOYAGER_CAT_END, CAT_CMD);
			continue;
		}
		if(eprom_size > sizeof(eprom_buf)) {
			printk("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x.  Need %d\n", i, eprom_size);
			outb(VOYAGER_CAT_END, CAT_CMD);
			continue;
		}
		outb(VOYAGER_CAT_END, CAT_CMD);
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, eprom_size));
		if(cat_subread(*modpp, (*modpp)->asic, 0, 
			       eprom_size, eprom_buf)) {
			outb(VOYAGER_CAT_END, CAT_CMD);
			continue;
		}
		outb(VOYAGER_CAT_END, CAT_CMD);
		printk("Module \"%s\", version 0x%x, tracer 0x%x, asics %d\n",
		       cat_module_name(i), eprom_hdr->version_id,
		       *((__u32 *)eprom_hdr->tracer),  eprom_hdr->num_asics);
		(*modpp)->ee_size = eprom_hdr->ee_size;
		(*modpp)->num_asics = eprom_hdr->num_asics;
		asicpp = &((*modpp)->asic);
		sp_offset = eprom_hdr->scan_path_offset;
		/* All we really care about are the Quad cards.  We
                 * identify them because they are in a processor slot
                 * and have only four asics */
		if((i < 0x10 || (i>=0x14 && i < 0x1c) || i>0x1f)) {
			modpp = &((*modpp)->next);
			continue;
		}
		/* Now we know it's in a processor slot, does it have
		 * a quad baseboard submodule */
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		cat_read(*modpp, (*modpp)->asic, VOYAGER_SUBMODPRESENT,
			 &num_submodules);
		/* lowest two bits, active low */
		num_submodules = ~(0xfc | num_submodules);
		CDEBUG(("VOYAGER CAT: %d submodules present\n", num_submodules));
		if(num_submodules == 0) {
			/* fill in the dyadic extended processors */
			__u8 cpu = i & 0x07;

			printk("Module \"%s\": Dyadic Processor Card\n",
			       cat_module_name(i));
			voyager_extended_vic_processors |= (1<<cpu);
			cpu += 4;
			voyager_extended_vic_processors |= (1<<cpu);
			outb(VOYAGER_CAT_END, CAT_CMD);
			continue;
		}

		/* now we want to read the asics on the first submodule,
		 * which should be the quad base board */

		cat_read(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, &val);
		CDEBUG(("cat_init: SUBMODSELECT value = 0x%x\n", val));
		val = (val & 0x7c) | VOYAGER_QUAD_BASEBOARD;
		cat_write(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, val);

		outb(VOYAGER_CAT_END, CAT_CMD);
			 

		CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		cat_disconnect(*modpp, (*modpp)->asic);
		if(cat_subread(*modpp, (*modpp)->asic,
			       VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
			       &eprom_size)) {
			printk("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", i);
			outb(VOYAGER_CAT_END, CAT_CMD);
			continue;
		}
		if(eprom_size > sizeof(eprom_buf)) {
			printk("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x.  Need %d\n", i, eprom_size);
			outb(VOYAGER_CAT_END, CAT_CMD);
			continue;
		}
		outb(VOYAGER_CAT_END, CAT_CMD);
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, eprom_size));
		if(cat_subread(*modpp, (*modpp)->asic, 0, 
			       eprom_size, eprom_buf)) {
			outb(VOYAGER_CAT_END, CAT_CMD);
			continue;
		}
		outb(VOYAGER_CAT_END, CAT_CMD);
		/* Now do everything for the QBB submodule 1 */
		(*modpp)->ee_size = eprom_hdr->ee_size;
		(*modpp)->num_asics = eprom_hdr->num_asics;
		asicpp = &((*modpp)->asic);
		sp_offset = eprom_hdr->scan_path_offset;
		/* get rid of the dummy CAT asic and read the real one */
		kfree((*modpp)->asic);
		for(asic=0; asic < (*modpp)->num_asics; asic++) {
			int j;
			voyager_asic_t *asicp = *asicpp 
				= kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++];*/
			voyager_sp_table_t *sp_table;
			voyager_at_t *asic_table;
			voyager_jtt_t *jtag_table;

			if(asicp == NULL) {
				printk("**WARNING** kmalloc failure in cat_init\n");
				continue;
			}
			asicpp = &(asicp->next);
			asicp->asic_location = asic;
			sp_table = (voyager_sp_table_t *)(eprom_buf + sp_offset);
			asicp->asic_id = sp_table->asic_id;
			asic_table = (voyager_at_t *)(eprom_buf + sp_table->asic_data_offset);
			for(j=0; j<4; j++)
				asicp->jtag_id[j] = asic_table->jtag_id[j];
			jtag_table = (voyager_jtt_t *)(eprom_buf + asic_table->jtag_offset);
			asicp->ireg_length = jtag_table->ireg_len;
			asicp->bit_location = (*modpp)->inst_bits;
			(*modpp)->inst_bits += asicp->ireg_length;
			if(asicp->ireg_length > (*modpp)->largest_reg)
				(*modpp)->largest_reg = asicp->ireg_length;
			if (asicp->ireg_length < (*modpp)->smallest_reg ||
			    (*modpp)->smallest_reg == 0)
				(*modpp)->smallest_reg = asicp->ireg_length;
			CDEBUG(("asic 0x%x, ireg_length=%d, bit_location=%d\n",
				asicp->asic_id, asicp->ireg_length,
				asicp->bit_location));
			if(asicp->asic_id == VOYAGER_QUAD_QABC) {
				CDEBUG(("VOYAGER CAT: QABC ASIC found\n"));
				qabc_asic = asicp;
			}
			sp_offset += sizeof(voyager_sp_table_t);
		}
		CDEBUG(("Module inst_bits = %d, largest_reg = %d, smallest_reg=%d\n",
			(*modpp)->inst_bits, (*modpp)->largest_reg,
			(*modpp)->smallest_reg));
		/* OK, now we have the QUAD ASICs set up, use them.
		 * we need to:
		 *
		 * 1. Find the Memory area for the Quad CPIs.
		 * 2. Find the Extended VIC processor
		 * 3. Configure a second extended VIC processor (This
		 *    cannot be done for the 51xx.
		 * */
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		cat_connect(*modpp, (*modpp)->asic);
		CDEBUG(("CAT CONNECTED!!\n"));
		cat_subread(*modpp, qabc_asic, 0, sizeof(qabc_data), qabc_data);
		qic_addr = qabc_data[5] << 8;
		qic_addr = (qic_addr | qabc_data[6]) << 8;
		qic_addr = (qic_addr | qabc_data[7]) << 8;
		printk("Module \"%s\": Quad Processor Card; CPI 0x%lx, SET=0x%x\n",
		       cat_module_name(i), qic_addr, qabc_data[8]);
#if 0				/* plumbing fails---FIXME */
		if((qabc_data[8] & 0xf0) == 0) {
			/* FIXME: 32 way 8 CPU slot monster cannot be
			 * plumbed this way---need to check for it */

			printk("Plumbing second Extended Quad Processor\n");
			/* second VIC line hardwired to Quad CPU 1 */
			qabc_data[8] |= 0x20;
			cat_subwrite(*modpp, qabc_asic, 8, 1, &qabc_data[8]);
#ifdef VOYAGER_CAT_DEBUG
			/* verify plumbing */
			cat_subread(*modpp, qabc_asic, 8, 1, &qabc_data[8]);
			if((qabc_data[8] & 0xf0) == 0) {
				CDEBUG(("PLUMBING FAILED: 0x%x\n", qabc_data[8]));
			}
#endif
		}
#endif

		{
			struct resource *res = kzalloc(sizeof(struct resource),GFP_KERNEL);
			res->name = kmalloc(128, GFP_KERNEL);
			sprintf((char *)res->name, "Voyager %s Quad CPI", cat_module_name(i));
			res->start = qic_addr;
			res->end = qic_addr + 0x3ff;
			request_resource(&iomem_resource, res);
		}

		qic_addr = (unsigned long)ioremap(qic_addr, 0x400);
				
		for(j = 0; j < 4; j++) {
			__u8 cpu;

			if(voyager_8slot) {
				/* 8 slot has a different mapping,
				 * each slot has only one vic line, so
				 * 1 cpu in each slot must be < 8 */
				cpu = (i & 0x07) + j*8;
			} else {
				cpu = (i & 0x03) + j*4;
			}
			if( (qabc_data[8] & (1<<j))) {
				voyager_extended_vic_processors |= (1<<cpu);
			}
			if(qabc_data[8] & (1<<(j+4)) ) {
				/* Second SET register plumbed: Quad
				 * card has two VIC connected CPUs.
				 * Secondary cannot be booted as a VIC
				 * CPU */
				voyager_extended_vic_processors |= (1<<cpu);
				voyager_allowed_boot_processors &= (~(1<<cpu));
			}

			voyager_quad_processors |= (1<<cpu);
			voyager_quad_cpi_addr[cpu] = (struct voyager_qic_cpi *)
				(qic_addr+(j<<8));
			CDEBUG(("CPU%d: CPI address 0x%lx\n", cpu,
				(unsigned long)voyager_quad_cpi_addr[cpu]));
		}
		outb(VOYAGER_CAT_END, CAT_CMD);

		
		
		*asicpp = NULL;
		modpp = &((*modpp)->next);
	}
	*modpp = NULL;
	printk("CAT Bus Initialisation finished: extended procs 0x%x, quad procs 0x%x, allowed vic boot = 0x%x\n", voyager_extended_vic_processors, voyager_quad_processors, voyager_allowed_boot_processors);
	request_resource(&ioport_resource, &vic_res);
	if(voyager_quad_processors)
		request_resource(&ioport_resource, &qic_res);
	/* set up the front power switch */
}

int
voyager_cat_readb(__u8 module, __u8 asic, int reg)
{
	return 0;
}

static int
cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp) 
{
	__u8 val;
	int err = 0;

	if(!modp->scan_path_connected)
		return 0;
	if(asicp->asic_id != VOYAGER_CAT_ID) {
		CDEBUG(("cat_disconnect: ASIC is not CAT\n"));
		return 1;
	}
	err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
	if(err) {
		CDEBUG(("cat_disconnect: failed to read SCANPATH\n"));
		return err;
	}
	val &= VOYAGER_DISCONNECT_ASIC;
	err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
	if(err) {
		CDEBUG(("cat_disconnect: failed to write SCANPATH\n"));
		return err;
	}
	outb(VOYAGER_CAT_END, CAT_CMD);
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	modp->scan_path_connected = 0;

	return 0;
}

static int
cat_connect(voyager_module_t *modp, voyager_asic_t *asicp) 
{
	__u8 val;
	int err = 0;

	if(modp->scan_path_connected)
		return 0;
	if(asicp->asic_id != VOYAGER_CAT_ID) {
		CDEBUG(("cat_connect: ASIC is not CAT\n"));
		return 1;
	}

	err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
	if(err) {
		CDEBUG(("cat_connect: failed to read SCANPATH\n"));
		return err;
	}
	val |= VOYAGER_CONNECT_ASIC;
	err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
	if(err) {
		CDEBUG(("cat_connect: failed to write SCANPATH\n"));
		return err;
	}
	outb(VOYAGER_CAT_END, CAT_CMD);
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	modp->scan_path_connected = 1;

	return 0;
}

void
voyager_cat_power_off(void)
{
	/* Power the machine off by writing to the PSI over the CAT
         * bus */
	__u8 data;
	voyager_module_t psi = { 0 };
	voyager_asic_t psi_asic = { 0 };

	psi.asic = &psi_asic;
	psi.asic->asic_id = VOYAGER_CAT_ID;
	psi.asic->subaddr = VOYAGER_SUBADDR_HI;
	psi.module_addr = VOYAGER_PSI;
	psi.scan_path_connected = 0;

	outb(VOYAGER_CAT_END, CAT_CMD);
	/* Connect the PSI to the CAT Bus */
	outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
	outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	cat_disconnect(&psi, &psi_asic);
	/* Read the status */
	cat_subread(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data);
	outb(VOYAGER_CAT_END, CAT_CMD);
	CDEBUG(("PSI STATUS 0x%x\n", data));
	/* These two writes are power off prep and perform */
	data = PSI_CLEAR;
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data);
	outb(VOYAGER_CAT_END, CAT_CMD);
	data = PSI_POWER_DOWN;
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data);
	outb(VOYAGER_CAT_END, CAT_CMD);
}

struct voyager_status voyager_status = { 0 };

void
voyager_cat_psi(__u8 cmd, __u16 reg, __u8 *data)
{
	voyager_module_t psi = { 0 };
	voyager_asic_t psi_asic = { 0 };

	psi.asic = &psi_asic;
	psi.asic->asic_id = VOYAGER_CAT_ID;
	psi.asic->subaddr = VOYAGER_SUBADDR_HI;
	psi.module_addr = VOYAGER_PSI;
	psi.scan_path_connected = 0;

	outb(VOYAGER_CAT_END, CAT_CMD);
	/* Connect the PSI to the CAT Bus */
	outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
	outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	cat_disconnect(&psi, &psi_asic);
	switch(cmd) {
	case VOYAGER_PSI_READ:
		cat_read(&psi, &psi_asic, reg, data);
		break;
	case VOYAGER_PSI_WRITE:
		cat_write(&psi, &psi_asic, reg, *data);
		break;
	case VOYAGER_PSI_SUBREAD:
		cat_subread(&psi, &psi_asic, reg, 1, data);
		break;
	case VOYAGER_PSI_SUBWRITE:
		cat_subwrite(&psi, &psi_asic, reg, 1, data);
		break;
	default:
		printk(KERN_ERR "Voyager PSI, unrecognised command %d\n", cmd);
		break;
	}
	outb(VOYAGER_CAT_END, CAT_CMD);
}

void
voyager_cat_do_common_interrupt(void)
{
	/* This is caused either by a memory parity error or something
	 * in the PSI */
	__u8 data;
	voyager_module_t psi = { 0 };
	voyager_asic_t psi_asic = { 0 };
	struct voyager_psi psi_reg;
	int i;
 re_read:
	psi.asic = &psi_asic;
	psi.asic->asic_id = VOYAGER_CAT_ID;
	psi.asic->subaddr = VOYAGER_SUBADDR_HI;
	psi.module_addr = VOYAGER_PSI;
	psi.scan_path_connected = 0;

	outb(VOYAGER_CAT_END, CAT_CMD);
	/* Connect the PSI to the CAT Bus */
	outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
	outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	cat_disconnect(&psi, &psi_asic);
	/* Read the status.  NOTE: Need to read *all* the PSI regs here
	 * otherwise the cmn int will be reasserted */
	for(i = 0; i < sizeof(psi_reg.regs); i++) {
		cat_read(&psi, &psi_asic, i, &((__u8 *)&psi_reg.regs)[i]);
	}
	outb(VOYAGER_CAT_END, CAT_CMD);
	if((psi_reg.regs.checkbit & 0x02) == 0) {
		psi_reg.regs.checkbit |= 0x02;
		cat_write(&psi, &psi_asic, 5, psi_reg.regs.checkbit);
		printk("VOYAGER RE-READ PSI\n");
		goto re_read;
	}
	outb(VOYAGER_CAT_RUN, CAT_CMD);
	for(i = 0; i < sizeof(psi_reg.subregs); i++) {
		/* This looks strange, but the PSI doesn't do auto increment
		 * correctly */
		cat_subread(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG + i, 
			    1, &((__u8 *)&psi_reg.subregs)[i]); 
	}
	outb(VOYAGER_CAT_END, CAT_CMD);
#ifdef VOYAGER_CAT_DEBUG
	printk("VOYAGER PSI: ");
	for(i=0; i<sizeof(psi_reg.regs); i++)
		printk("%02x ", ((__u8 *)&psi_reg.regs)[i]);
	printk("\n           ");
	for(i=0; i<sizeof(psi_reg.subregs); i++)
		printk("%02x ", ((__u8 *)&psi_reg.subregs)[i]);
	printk("\n");
#endif
	if(psi_reg.regs.intstatus & PSI_MON) {
		/* switch off or power fail */

		if(psi_reg.subregs.supply & PSI_SWITCH_OFF) {
			if(voyager_status.switch_off) {
				printk(KERN_ERR "Voyager front panel switch turned off again---Immediate power off!\n");
				voyager_cat_power_off();
				/* not reached */
			} else {
				printk(KERN_ERR "Voyager front panel switch turned off\n");
				voyager_status.switch_off = 1;
				voyager_status.request_from_kernel = 1;
				wake_up_process(voyager_thread);
			}
			/* Tell the hardware we're taking care of the
			 * shutdown, otherwise it will power the box off
			 * within 3 seconds of the switch being pressed and,
			 * which is much more important to us, continue to 
			 * assert the common interrupt */
			data = PSI_CLR_SWITCH_OFF;
			outb(VOYAGER_CAT_RUN, CAT_CMD);
			cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG,
				     1, &data);
			outb(VOYAGER_CAT_END, CAT_CMD);
		} else {

			VDEBUG(("Voyager ac fail reg 0x%x\n",
				psi_reg.subregs.ACfail));
			if((psi_reg.subregs.ACfail & AC_FAIL_STAT_CHANGE) == 0) {
				/* No further update */
				return;
			}
#if 0
			/* Don't bother trying to find out who failed.
			 * FIXME: This probably makes the code incorrect on
			 * anything other than a 345x */
			for(i=0; i< 5; i++) {
				if( psi_reg.subregs.ACfail &(1<<i)) {
					break;
				}
			}
			printk(KERN_NOTICE "AC FAIL IN SUPPLY %d\n", i);
#endif
			/* DON'T do this: it shuts down the AC PSI 
			outb(VOYAGER_CAT_RUN, CAT_CMD);
			data = PSI_MASK_MASK | i;
			cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_MASK,
				     1, &data);
			outb(VOYAGER_CAT_END, CAT_CMD);
			*/
			printk(KERN_ERR "Voyager AC power failure\n");
			outb(VOYAGER_CAT_RUN, CAT_CMD);
			data = PSI_COLD_START;
			cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG,
				     1, &data);
			outb(VOYAGER_CAT_END, CAT_CMD);
			voyager_status.power_fail = 1;
			voyager_status.request_from_kernel = 1;
			wake_up_process(voyager_thread);
		}
		
		
	} else if(psi_reg.regs.intstatus & PSI_FAULT) {
		/* Major fault! */
		printk(KERN_ERR "Voyager PSI Detected major fault, immediate power off!\n");
		voyager_cat_power_off();
		/* not reached */
	} else if(psi_reg.regs.intstatus & (PSI_DC_FAIL | PSI_ALARM
					    | PSI_CURRENT | PSI_DVM
					    | PSI_PSCFAULT | PSI_STAT_CHG)) {
		/* other psi fault */

		printk(KERN_WARNING "Voyager PSI status 0x%x\n", data);
		/* clear the PSI fault */
		outb(VOYAGER_CAT_RUN, CAT_CMD);
		cat_write(&psi, &psi_asic, VOYAGER_PSI_STATUS_REG, 0);
		outb(VOYAGER_CAT_END, CAT_CMD);
	}
}
