/*
 *    Disk Array driver for Compaq SMART2 Controllers
 *    Copyright 1998 Compaq Computer Corporation
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *    NON INFRINGEMENT.  See the GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
 *
 */
#include <linux/module.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/bio.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
#include <linux/timer.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/hdreg.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/genhd.h>
#include <linux/scatterlist.h>
#include <asm/uaccess.h>
#include <asm/io.h>


#define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))

#define DRIVER_NAME "Compaq SMART2 Driver (v 2.6.0)"
#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,6,0)

/* Embedded module documentation macros - see modules.h */
/* Original author Chris Frantz - Compaq Computer Corporation */
MODULE_AUTHOR("Compaq Computer Corporation");
MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.6.0");
MODULE_LICENSE("GPL");

#include "cpqarray.h"
#include "ida_cmd.h"
#include "smart1,2.h"
#include "ida_ioctl.h"

#define READ_AHEAD	128
#define NR_CMDS		128 /* This could probably go as high as ~400 */

#define MAX_CTLR	8
#define CTLR_SHIFT	8

#define CPQARRAY_DMA_MASK	0xFFFFFFFF	/* 32 bit DMA */

static int nr_ctlr;
static ctlr_info_t *hba[MAX_CTLR];

static int eisa[8];

#define NR_PRODUCTS ARRAY_SIZE(products)

/*  board_id = Subsystem Device ID & Vendor ID
 *  product = Marketing Name for the board
 *  access = Address of the struct of function pointers
 */
static struct board_type products[] = {
	{ 0x0040110E, "IDA",			&smart1_access },
	{ 0x0140110E, "IDA-2",			&smart1_access },
	{ 0x1040110E, "IAES",			&smart1_access },
	{ 0x2040110E, "SMART",			&smart1_access },
	{ 0x3040110E, "SMART-2/E",		&smart2e_access },
	{ 0x40300E11, "SMART-2/P",		&smart2_access },
	{ 0x40310E11, "SMART-2SL",		&smart2_access },
	{ 0x40320E11, "Smart Array 3200",	&smart2_access },
	{ 0x40330E11, "Smart Array 3100ES",	&smart2_access },
	{ 0x40340E11, "Smart Array 221",	&smart2_access },
	{ 0x40400E11, "Integrated Array",	&smart4_access },
	{ 0x40480E11, "Compaq Raid LC2",        &smart4_access },
	{ 0x40500E11, "Smart Array 4200",	&smart4_access },
	{ 0x40510E11, "Smart Array 4250ES",	&smart4_access },
	{ 0x40580E11, "Smart Array 431",	&smart4_access },
};

/* define the PCI info for the PCI cards this driver can control */
static const struct pci_device_id cpqarray_pci_device_id[] =
{
	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX,
		0x0E11, 0x4058, 0, 0, 0},       /* SA431 */
	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX,
		0x0E11, 0x4051, 0, 0, 0},      /* SA4250ES */
	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX,
		0x0E11, 0x4050, 0, 0, 0},      /* SA4200 */
	{ PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510,
		0x0E11, 0x4048, 0, 0, 0},       /* LC2 */
	{ PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510,
		0x0E11, 0x4040, 0, 0, 0},      /* Integrated Array */
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P,
		0x0E11, 0x4034, 0, 0, 0},       /* SA 221 */
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P,
		0x0E11, 0x4033, 0, 0, 0},       /* SA 3100ES*/
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P,
		0x0E11, 0x4032, 0, 0, 0},       /* SA 3200*/
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P,
		0x0E11, 0x4031, 0, 0, 0},       /* SA 2SL*/
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P,
		0x0E11, 0x4030, 0, 0, 0},       /* SA 2P */
	{ 0 }
};

MODULE_DEVICE_TABLE(pci, cpqarray_pci_device_id);

static struct gendisk *ida_gendisk[MAX_CTLR][NWD];

/* Debug... */
#define DBG(s)	do { s } while(0)
/* Debug (general info)... */
#define DBGINFO(s) do { } while(0)
/* Debug Paranoid... */
#define DBGP(s)  do { } while(0)
/* Debug Extra Paranoid... */
#define DBGPX(s) do { } while(0)

static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev);
static void __iomem *remap_pci_mem(ulong base, ulong size);
static int cpqarray_eisa_detect(void);
static int pollcomplete(int ctlr);
static void getgeometry(int ctlr);
static void start_fwbk(int ctlr);

static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool);
static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool);

static void free_hba(int i);
static int alloc_cpqarray_hba(void);

static int sendcmd(
	__u8	cmd,
	int	ctlr,
	void	*buff,
	size_t	size,
	unsigned int blk,
	unsigned int blkcnt,
	unsigned int log_unit );

static int ida_open(struct block_device *bdev, fmode_t mode);
static int ida_release(struct gendisk *disk, fmode_t mode);
static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg);
static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);
static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);

static void do_ida_request(struct request_queue *q);
static void start_io(ctlr_info_t *h);

static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c);
static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c);
static inline void complete_command(cmdlist_t *cmd, int timeout);

static irqreturn_t do_ida_intr(int irq, void *dev_id);
static void ida_timer(unsigned long tdata);
static int ida_revalidate(struct gendisk *disk);
static int revalidate_allvol(ctlr_info_t *host);
static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev);

#ifdef CONFIG_PROC_FS
static void ida_procinit(int i);
static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
#else
static void ida_procinit(int i) {}
#endif

static inline drv_info_t *get_drv(struct gendisk *disk)
{
	return disk->private_data;
}

static inline ctlr_info_t *get_host(struct gendisk *disk)
{
	return disk->queue->queuedata;
}


static struct block_device_operations ida_fops  = {
	.owner		= THIS_MODULE,
	.open		= ida_open,
	.release	= ida_release,
	.locked_ioctl	= ida_ioctl,
	.getgeo		= ida_getgeo,
	.revalidate_disk= ida_revalidate,
};


#ifdef CONFIG_PROC_FS

static struct proc_dir_entry *proc_array;

/*
 * Get us a file in /proc/array that says something about each controller.
 * Create /proc/array if it doesn't exist yet.
 */
static void __init ida_procinit(int i)
{
	if (proc_array == NULL) {
		proc_array = proc_mkdir("driver/cpqarray", NULL);
		if (!proc_array) return;
	}

	create_proc_read_entry(hba[i]->devname, 0, proc_array,
			       ida_proc_get_info, hba[i]);
}

/*
 * Report information about this controller.
 */
static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
{
	off_t pos = 0;
	off_t len = 0;
	int size, i, ctlr;
	ctlr_info_t *h = (ctlr_info_t*)data;
	drv_info_t *drv;
#ifdef CPQ_PROC_PRINT_QUEUES
	cmdlist_t *c;
	unsigned long flags;
#endif

	ctlr = h->ctlr;
	size = sprintf(buffer, "%s:  Compaq %s Controller\n"
		"       Board ID: 0x%08lx\n"
		"       Firmware Revision: %c%c%c%c\n"
		"       Controller Sig: 0x%08lx\n"
		"       Memory Address: 0x%08lx\n"
		"       I/O Port: 0x%04x\n"
		"       IRQ: %d\n"
		"       Logical drives: %d\n"
		"       Physical drives: %d\n\n"
		"       Current Q depth: %d\n"
		"       Max Q depth since init: %d\n\n",
		h->devname, 
		h->product_name,
		(unsigned long)h->board_id,
		h->firm_rev[0], h->firm_rev[1], h->firm_rev[2], h->firm_rev[3],
		(unsigned long)h->ctlr_sig, (unsigned long)h->vaddr,
		(unsigned int) h->io_mem_addr, (unsigned int)h->intr,
		h->log_drives, h->phys_drives,
		h->Qdepth, h->maxQsinceinit);

	pos += size; len += size;
	
	size = sprintf(buffer+len, "Logical Drive Info:\n");
	pos += size; len += size;

	for(i=0; i<h->log_drives; i++) {
		drv = &h->drv[i];
		size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
				ctlr, i, drv->blk_size, drv->nr_blks);
		pos += size; len += size;
	}

#ifdef CPQ_PROC_PRINT_QUEUES
	spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); 
	size = sprintf(buffer+len, "\nCurrent Queues:\n");
	pos += size; len += size;

	c = h->reqQ;
	size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size;
	if (c) c=c->next;
	while(c && c != h->reqQ) {
		size = sprintf(buffer+len, "->%p", c);
		pos += size; len += size;
		c=c->next;
	}

	c = h->cmpQ;
	size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size;
	if (c) c=c->next;
	while(c && c != h->cmpQ) {
		size = sprintf(buffer+len, "->%p", c);
		pos += size; len += size;
		c=c->next;
	}

	size = sprintf(buffer+len, "\n"); pos += size; len += size;
	spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); 
#endif
	size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n",
			h->nr_allocs, h->nr_frees);
	pos += size; len += size;

	*eof = 1;
	*start = buffer+offset;
	len -= offset;
	if (len>length)
		len = length;
	return len;
}
#endif /* CONFIG_PROC_FS */

module_param_array(eisa, int, NULL, 0);

static void release_io_mem(ctlr_info_t *c)
{
	/* if IO mem was not protected do nothing */
	if( c->io_mem_addr == 0)
		return;
	release_region(c->io_mem_addr, c->io_mem_length);
	c->io_mem_addr = 0;
	c->io_mem_length = 0;
}

static void __devexit cpqarray_remove_one(int i)
{
	int j;
	char buff[4];

	/* sendcmd will turn off interrupt, and send the flush...
	 * To write all data in the battery backed cache to disks
	 * no data returned, but don't want to send NULL to sendcmd */
	if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0))
	{
		printk(KERN_WARNING "Unable to flush cache on controller %d\n",
				i);
	}
	free_irq(hba[i]->intr, hba[i]);
	iounmap(hba[i]->vaddr);
	unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname);
	del_timer(&hba[i]->timer);
	remove_proc_entry(hba[i]->devname, proc_array);
	pci_free_consistent(hba[i]->pci_dev,
			NR_CMDS * sizeof(cmdlist_t), (hba[i]->cmd_pool),
			hba[i]->cmd_pool_dhandle);
	kfree(hba[i]->cmd_pool_bits);
	for(j = 0; j < NWD; j++) {
		if (ida_gendisk[i][j]->flags & GENHD_FL_UP)
			del_gendisk(ida_gendisk[i][j]);
		put_disk(ida_gendisk[i][j]);
	}
	blk_cleanup_queue(hba[i]->queue);
	release_io_mem(hba[i]);
	free_hba(i);
}

static void __devexit cpqarray_remove_one_pci (struct pci_dev *pdev)
{
	int i;
	ctlr_info_t *tmp_ptr;

	if (pci_get_drvdata(pdev) == NULL) {
		printk( KERN_ERR "cpqarray: Unable to remove device \n");
		return;
	}

	tmp_ptr = pci_get_drvdata(pdev);
	i = tmp_ptr->ctlr;
	if (hba[i] == NULL) {
		printk(KERN_ERR "cpqarray: controller %d appears to have"
			"already been removed \n", i);
		return;
        }
	pci_set_drvdata(pdev, NULL);

	cpqarray_remove_one(i);
}

/* removing an instance that was not removed automatically..
 * must be an eisa card.
 */
static void __devexit cpqarray_remove_one_eisa (int i)
{
	if (hba[i] == NULL) {
		printk(KERN_ERR "cpqarray: controller %d appears to have"
			"already been removed \n", i);
		return;
        }
	cpqarray_remove_one(i);
}

/* pdev is NULL for eisa */
static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev)
{
	struct request_queue *q;
	int j;

	/* 
	 * register block devices
	 * Find disks and fill in structs
	 * Get an interrupt, set the Q depth and get into /proc
	 */

	/* If this successful it should insure that we are the only */
	/* instance of the driver */
	if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname)) {
		goto Enomem4;
	}
	hba[i]->access.set_intr_mask(hba[i], 0);
	if (request_irq(hba[i]->intr, do_ida_intr,
		IRQF_DISABLED|IRQF_SHARED, hba[i]->devname, hba[i]))
	{
		printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n",
				hba[i]->intr, hba[i]->devname);
		goto Enomem3;
	}
		
	for (j=0; j<NWD; j++) {
		ida_gendisk[i][j] = alloc_disk(1 << NWD_SHIFT);
		if (!ida_gendisk[i][j])
			goto Enomem2;
	}

	hba[i]->cmd_pool = pci_alloc_consistent(
		hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t),
		&(hba[i]->cmd_pool_dhandle));
	hba[i]->cmd_pool_bits = kcalloc(
		DIV_ROUND_UP(NR_CMDS, BITS_PER_LONG), sizeof(unsigned long),
		GFP_KERNEL);

	if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool)
			goto Enomem1;

	memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
	printk(KERN_INFO "cpqarray: Finding drives on %s",
		hba[i]->devname);

	spin_lock_init(&hba[i]->lock);
	q = blk_init_queue(do_ida_request, &hba[i]->lock);
	if (!q)
		goto Enomem1;

	hba[i]->queue = q;
	q->queuedata = hba[i];

	getgeometry(i);
	start_fwbk(i);

	ida_procinit(i);

	if (pdev)
		blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask);

	/* This is a hardware imposed limit. */
	blk_queue_max_hw_segments(q, SG_MAX);

	/* This is a driver limit and could be eliminated. */
	blk_queue_max_phys_segments(q, SG_MAX);
	
	init_timer(&hba[i]->timer);
	hba[i]->timer.expires = jiffies + IDA_TIMER;
	hba[i]->timer.data = (unsigned long)hba[i];
	hba[i]->timer.function = ida_timer;
	add_timer(&hba[i]->timer);

	/* Enable IRQ now that spinlock and rate limit timer are set up */
	hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);

	for(j=0; j<NWD; j++) {
		struct gendisk *disk = ida_gendisk[i][j];
		drv_info_t *drv = &hba[i]->drv[j];
		sprintf(disk->disk_name, "ida/c%dd%d", i, j);
		disk->major = COMPAQ_SMART2_MAJOR + i;
		disk->first_minor = j<<NWD_SHIFT;
		disk->fops = &ida_fops;
		if (j && !drv->nr_blks)
			continue;
		blk_queue_hardsect_size(hba[i]->queue, drv->blk_size);
		set_capacity(disk, drv->nr_blks);
		disk->queue = hba[i]->queue;
		disk->private_data = drv;
		add_disk(disk);
	}

	/* done ! */
	return(i);

Enomem1:
	nr_ctlr = i; 
	kfree(hba[i]->cmd_pool_bits);
	if (hba[i]->cmd_pool)
		pci_free_consistent(hba[i]->pci_dev, NR_CMDS*sizeof(cmdlist_t), 
				    hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
Enomem2:
	while (j--) {
		put_disk(ida_gendisk[i][j]);
		ida_gendisk[i][j] = NULL;
	}
	free_irq(hba[i]->intr, hba[i]);
Enomem3:
	unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname);
Enomem4:
	if (pdev)
		pci_set_drvdata(pdev, NULL);
	release_io_mem(hba[i]);
	free_hba(i);

	printk( KERN_ERR "cpqarray: out of memory");

	return -1;
}

static int __init cpqarray_init_one( struct pci_dev *pdev,
	const struct pci_device_id *ent)
{
	int i;

	printk(KERN_DEBUG "cpqarray: Device 0x%x has been found at"
			" bus %d dev %d func %d\n",
			pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),
			PCI_FUNC(pdev->devfn));
	i = alloc_cpqarray_hba();
	if( i < 0 )
		return (-1);
	memset(hba[i], 0, sizeof(ctlr_info_t));
	sprintf(hba[i]->devname, "ida%d", i);
	hba[i]->ctlr = i;
	/* Initialize the pdev driver private data */
	pci_set_drvdata(pdev, hba[i]);

	if (cpqarray_pci_init(hba[i], pdev) != 0) {
		pci_set_drvdata(pdev, NULL);
		release_io_mem(hba[i]);
		free_hba(i);
		return -1;
	}

	return (cpqarray_register_ctlr(i, pdev));
}

static struct pci_driver cpqarray_pci_driver = {
	.name = "cpqarray",
	.probe = cpqarray_init_one,
	.remove = __devexit_p(cpqarray_remove_one_pci),
	.id_table = cpqarray_pci_device_id,
};

/*
 *  This is it.  Find all the controllers and register them.
 *  returns the number of block devices registered.
 */
static int __init cpqarray_init(void)
{
	int num_cntlrs_reg = 0;
	int i;
	int rc = 0;

	/* detect controllers */
	printk(DRIVER_NAME "\n");

	rc = pci_register_driver(&cpqarray_pci_driver);
	if (rc)
		return rc;
	cpqarray_eisa_detect();
	
	for (i=0; i < MAX_CTLR; i++) {
		if (hba[i] != NULL)
			num_cntlrs_reg++;
	}

	if (num_cntlrs_reg)
		return 0;
	else {
		pci_unregister_driver(&cpqarray_pci_driver);
		return -ENODEV;
	}
}

/* Function to find the first free pointer into our hba[] array */
/* Returns -1 if no free entries are left.  */
static int alloc_cpqarray_hba(void)
{
	int i;

	for(i=0; i< MAX_CTLR; i++) {
		if (hba[i] == NULL) {
			hba[i] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
			if(hba[i]==NULL) {
				printk(KERN_ERR "cpqarray: out of memory.\n");
				return (-1);
			}
			return (i);
		}
	}
	printk(KERN_WARNING "cpqarray: This driver supports a maximum"
		" of 8 controllers.\n");
	return(-1);
}

static void free_hba(int i)
{
	kfree(hba[i]);
	hba[i]=NULL;
}

/*
 * Find the IO address of the controller, its IRQ and so forth.  Fill
 * in some basic stuff into the ctlr_info_t structure.
 */
static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
{
	ushort vendor_id, device_id, command;
	unchar cache_line_size, latency_timer;
	unchar irq, revision;
	unsigned long addr[6];
	__u32 board_id;

	int i;

	c->pci_dev = pdev;
	pci_set_master(pdev);
	if (pci_enable_device(pdev)) {
		printk(KERN_ERR "cpqarray: Unable to Enable PCI device\n");
		return -1;
	}
	vendor_id = pdev->vendor;
	device_id = pdev->device;
	irq = pdev->irq;

	for(i=0; i<6; i++)
		addr[i] = pci_resource_start(pdev, i);

	if (pci_set_dma_mask(pdev, CPQARRAY_DMA_MASK) != 0)
	{
		printk(KERN_ERR "cpqarray: Unable to set DMA mask\n");
		return -1;
	}

	pci_read_config_word(pdev, PCI_COMMAND, &command);
	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size);
	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);

	pci_read_config_dword(pdev, 0x2c, &board_id);

	/* check to see if controller has been disabled */
	if(!(command & 0x02)) {
		printk(KERN_WARNING
			"cpqarray: controller appears to be disabled\n");
		return(-1);
	}

DBGINFO(
	printk("vendor_id = %x\n", vendor_id);
	printk("device_id = %x\n", device_id);
	printk("command = %x\n", command);
	for(i=0; i<6; i++)
		printk("addr[%d] = %lx\n", i, addr[i]);
	printk("revision = %x\n", revision);
	printk("irq = %x\n", irq);
	printk("cache_line_size = %x\n", cache_line_size);
	printk("latency_timer = %x\n", latency_timer);
	printk("board_id = %x\n", board_id);
);

	c->intr = irq;

	for(i=0; i<6; i++) {
		if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO)
		{ /* IO space */
			c->io_mem_addr = addr[i];
			c->io_mem_length = pci_resource_end(pdev, i)
				- pci_resource_start(pdev, i) + 1;
			if(!request_region( c->io_mem_addr, c->io_mem_length,
				"cpqarray"))
			{
				printk( KERN_WARNING "cpqarray I/O memory range already in use addr %lx length = %ld\n", c->io_mem_addr, c->io_mem_length);
				c->io_mem_addr = 0;
				c->io_mem_length = 0;
			}
			break;
		}
	}

	c->paddr = 0;
	for(i=0; i<6; i++)
		if (!(pci_resource_flags(pdev, i) &
				PCI_BASE_ADDRESS_SPACE_IO)) {
			c->paddr = pci_resource_start (pdev, i);
			break;
		}
	if (!c->paddr)
		return -1;
	c->vaddr = remap_pci_mem(c->paddr, 128);
	if (!c->vaddr)
		return -1;
	c->board_id = board_id;

	for(i=0; i<NR_PRODUCTS; i++) {
		if (board_id == products[i].board_id) {
			c->product_name = products[i].product_name;
			c->access = *(products[i].access);
			break;
		}
	}
	if (i == NR_PRODUCTS) {
		printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
			" to access the SMART Array controller %08lx\n", 
				(unsigned long)board_id);
		return -1;
	}

	return 0;
}

/*
 * Map (physical) PCI mem into (virtual) kernel space
 */
static void __iomem *remap_pci_mem(ulong base, ulong size)
{
        ulong page_base        = ((ulong) base) & PAGE_MASK;
        ulong page_offs        = ((ulong) base) - page_base;
        void __iomem *page_remapped    = ioremap(page_base, page_offs+size);

        return (page_remapped ? (page_remapped + page_offs) : NULL);
}

#ifndef MODULE
/*
 * Config string is a comma separated set of i/o addresses of EISA cards.
 */
static int cpqarray_setup(char *str)
{
	int i, ints[9];

	(void)get_options(str, ARRAY_SIZE(ints), ints);

	for(i=0; i<ints[0] && i<8; i++)
		eisa[i] = ints[i+1];
	return 1;
}

__setup("smart2=", cpqarray_setup);

#endif

/*
 * Find an EISA controller's signature.  Set up an hba if we find it.
 */
static int __init cpqarray_eisa_detect(void)
{
	int i=0, j;
	__u32 board_id;
	int intr;
	int ctlr;
	int num_ctlr = 0;

	while(i<8 && eisa[i]) {
		ctlr = alloc_cpqarray_hba();
		if(ctlr == -1)
			break;
		board_id = inl(eisa[i]+0xC80);
		for(j=0; j < NR_PRODUCTS; j++)
			if (board_id == products[j].board_id) 
				break;

		if (j == NR_PRODUCTS) {
			printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
				" to access the SMART Array controller %08lx\n",				 (unsigned long)board_id);
			continue;
		}

		memset(hba[ctlr], 0, sizeof(ctlr_info_t));
		hba[ctlr]->io_mem_addr = eisa[i];
		hba[ctlr]->io_mem_length = 0x7FF;
		if(!request_region(hba[ctlr]->io_mem_addr,
				hba[ctlr]->io_mem_length,
				"cpqarray"))
		{
			printk(KERN_WARNING "cpqarray: I/O range already in "
					"use addr = %lx length = %ld\n",
					hba[ctlr]->io_mem_addr,
					hba[ctlr]->io_mem_length);
			free_hba(ctlr);
			continue;
		}

		/*
		 * Read the config register to find our interrupt
		 */
		intr = inb(eisa[i]+0xCC0) >> 4;
		if (intr & 1) intr = 11;
		else if (intr & 2) intr = 10;
		else if (intr & 4) intr = 14;
		else if (intr & 8) intr = 15;
		
		hba[ctlr]->intr = intr;
		sprintf(hba[ctlr]->devname, "ida%d", nr_ctlr);
		hba[ctlr]->product_name = products[j].product_name;
		hba[ctlr]->access = *(products[j].access);
		hba[ctlr]->ctlr = ctlr;
		hba[ctlr]->board_id = board_id;
		hba[ctlr]->pci_dev = NULL; /* not PCI */

DBGINFO(
	printk("i = %d, j = %d\n", i, j);
	printk("irq = %x\n", intr);
	printk("product name = %s\n", products[j].product_name);
	printk("board_id = %x\n", board_id);
);

		num_ctlr++;
		i++;

		if (cpqarray_register_ctlr(ctlr, NULL) == -1)
			printk(KERN_WARNING
				"cpqarray: Can't register EISA controller %d\n",
				ctlr);

	}

	return num_ctlr;
}

/*
 * Open.  Make sure the device is really there.
 */
static int ida_open(struct block_device *bdev, fmode_t mode)
{
	drv_info_t *drv = get_drv(bdev->bd_disk);
	ctlr_info_t *host = get_host(bdev->bd_disk);

	DBGINFO(printk("ida_open %s\n", bdev->bd_disk->disk_name));
	/*
	 * Root is allowed to open raw volume zero even if it's not configured
	 * so array config can still work.  I don't think I really like this,
	 * but I'm already using way to many device nodes to claim another one
	 * for "raw controller".
	 */
	if (!drv->nr_blks) {
		if (!capable(CAP_SYS_RAWIO))
			return -ENXIO;
		if (!capable(CAP_SYS_ADMIN) && drv != host->drv)
			return -ENXIO;
	}
	host->usage_count++;
	return 0;
}

/*
 * Close.  Sync first.
 */
static int ida_release(struct gendisk *disk, fmode_t mode)
{
	ctlr_info_t *host = get_host(disk);
	host->usage_count--;
	return 0;
}

/*
 * Enqueuing and dequeuing functions for cmdlists.
 */
static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c)
{
	if (*Qptr == NULL) {
		*Qptr = c;
		c->next = c->prev = c;
	} else {
		c->prev = (*Qptr)->prev;
		c->next = (*Qptr);
		(*Qptr)->prev->next = c;
		(*Qptr)->prev = c;
	}
}

static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c)
{
	if (c && c->next != c) {
		if (*Qptr == c) *Qptr = c->next;
		c->prev->next = c->next;
		c->next->prev = c->prev;
	} else {
		*Qptr = NULL;
	}
	return c;
}

/*
 * Get a request and submit it to the controller.
 * This routine needs to grab all the requests it possibly can from the
 * req Q and submit them.  Interrupts are off (and need to be off) when you
 * are in here (either via the dummy do_ida_request functions or by being
 * called from the interrupt handler
 */
static void do_ida_request(struct request_queue *q)
{
	ctlr_info_t *h = q->queuedata;
	cmdlist_t *c;
	struct request *creq;
	struct scatterlist tmp_sg[SG_MAX];
	int i, dir, seg;

	if (blk_queue_plugged(q))
		goto startio;

queue_next:
	creq = elv_next_request(q);
	if (!creq)
		goto startio;

	BUG_ON(creq->nr_phys_segments > SG_MAX);

	if ((c = cmd_alloc(h,1)) == NULL)
		goto startio;

	blkdev_dequeue_request(creq);

	c->ctlr = h->ctlr;
	c->hdr.unit = (drv_info_t *)(creq->rq_disk->private_data) - h->drv;
	c->hdr.size = sizeof(rblk_t) >> 2;
	c->size += sizeof(rblk_t);

	c->req.hdr.blk = creq->sector;
	c->rq = creq;
DBGPX(
	printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
);
	sg_init_table(tmp_sg, SG_MAX);
	seg = blk_rq_map_sg(q, creq, tmp_sg);

	/* Now do all the DMA Mappings */
	if (rq_data_dir(creq) == READ)
		dir = PCI_DMA_FROMDEVICE;
	else
		dir = PCI_DMA_TODEVICE;
	for( i=0; i < seg; i++)
	{
		c->req.sg[i].size = tmp_sg[i].length;
		c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
						 sg_page(&tmp_sg[i]),
						 tmp_sg[i].offset,
						 tmp_sg[i].length, dir);
	}
DBGPX(	printk("Submitting %d sectors in %d segments\n", creq->nr_sectors, seg); );
	c->req.hdr.sg_cnt = seg;
	c->req.hdr.blk_cnt = creq->nr_sectors;
	c->req.hdr.cmd = (rq_data_dir(creq) == READ) ? IDA_READ : IDA_WRITE;
	c->type = CMD_RWREQ;

	/* Put the request on the tail of the request queue */
	addQ(&h->reqQ, c);
	h->Qdepth++;
	if (h->Qdepth > h->maxQsinceinit) 
		h->maxQsinceinit = h->Qdepth;

	goto queue_next;

startio:
	start_io(h);
}

/* 
 * start_io submits everything on a controller's request queue
 * and moves it to the completion queue.
 *
 * Interrupts had better be off if you're in here
 */
static void start_io(ctlr_info_t *h)
{
	cmdlist_t *c;

	while((c = h->reqQ) != NULL) {
		/* Can't do anything if we're busy */
		if (h->access.fifo_full(h) == 0)
			return;

		/* Get the first entry from the request Q */
		removeQ(&h->reqQ, c);
		h->Qdepth--;
	
		/* Tell the controller to do our bidding */
		h->access.submit_command(h, c);

		/* Get onto the completion Q */
		addQ(&h->cmpQ, c);
	}
}

/*
 * Mark all buffers that cmd was responsible for
 */
static inline void complete_command(cmdlist_t *cmd, int timeout)
{
	struct request *rq = cmd->rq;
	int error = 0;
	int i, ddir;

	if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
	   (hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) {
		printk(KERN_NOTICE "Non Fatal error on ida/c%dd%d\n",
				cmd->ctlr, cmd->hdr.unit);
		hba[cmd->ctlr]->misc_tflags |= MISC_NONFATAL_WARN;
	}
	if (cmd->req.hdr.rcode & RCODE_FATAL) {
		printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
				cmd->ctlr, cmd->hdr.unit);
		error = -EIO;
	}
	if (cmd->req.hdr.rcode & RCODE_INVREQ) {
				printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
				cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd,
				cmd->req.hdr.blk, cmd->req.hdr.blk_cnt,
				cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode);
		error = -EIO;
	}
	if (timeout)
		error = -EIO;
	/* unmap the DMA mapping for all the scatter gather elements */
	if (cmd->req.hdr.cmd == IDA_READ)
		ddir = PCI_DMA_FROMDEVICE;
	else
		ddir = PCI_DMA_TODEVICE;
        for(i=0; i<cmd->req.hdr.sg_cnt; i++)
                pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
				cmd->req.sg[i].size, ddir);

	DBGPX(printk("Done with %p\n", rq););
	if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
		BUG();
}

/*
 *  The controller will interrupt us upon completion of commands.
 *  Find the command on the completion queue, remove it, tell the OS and
 *  try to queue up more IO
 */
static irqreturn_t do_ida_intr(int irq, void *dev_id)
{
	ctlr_info_t *h = dev_id;
	cmdlist_t *c;
	unsigned long istat;
	unsigned long flags;
	__u32 a,a1;

	istat = h->access.intr_pending(h);
	/* Is this interrupt for us? */
	if (istat == 0)
		return IRQ_NONE;

	/*
	 * If there are completed commands in the completion queue,
	 * we had better do something about it.
	 */
	spin_lock_irqsave(IDA_LOCK(h->ctlr), flags);
	if (istat & FIFO_NOT_EMPTY) {
		while((a = h->access.command_completed(h))) {
			a1 = a; a &= ~3;
			if ((c = h->cmpQ) == NULL)
			{  
				printk(KERN_WARNING "cpqarray: Completion of %08lx ignored\n", (unsigned long)a1);
				continue;	
			} 
			while(c->busaddr != a) {
				c = c->next;
				if (c == h->cmpQ) 
					break;
			}
			/*
			 * If we've found the command, take it off the
			 * completion Q and free it
			 */
			if (c->busaddr == a) {
				removeQ(&h->cmpQ, c);
				/*  Check for invalid command.
                                 *  Controller returns command error,
                                 *  But rcode = 0.
                                 */

				if((a1 & 0x03) && (c->req.hdr.rcode == 0))
                                {
                                	c->req.hdr.rcode = RCODE_INVREQ;
                                }
				if (c->type == CMD_RWREQ) {
					complete_command(c, 0);
					cmd_free(h, c, 1);
				} else if (c->type == CMD_IOCTL_PEND) {
					c->type = CMD_IOCTL_DONE;
				}
				continue;
			}
		}
	}

	/*
	 * See if we can queue up some more IO
	 */
	do_ida_request(h->queue);
	spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); 
	return IRQ_HANDLED;
}

/*
 * This timer was for timing out requests that haven't happened after
 * IDA_TIMEOUT.  That wasn't such a good idea.  This timer is used to
 * reset a flags structure so we don't flood the user with
 * "Non-Fatal error" messages.
 */
static void ida_timer(unsigned long tdata)
{
	ctlr_info_t *h = (ctlr_info_t*)tdata;

	h->timer.expires = jiffies + IDA_TIMER;
	add_timer(&h->timer);
	h->misc_tflags = 0;
}

static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
	drv_info_t *drv = get_drv(bdev->bd_disk);

	if (drv->cylinders) {
		geo->heads = drv->heads;
		geo->sectors = drv->sectors;
		geo->cylinders = drv->cylinders;
	} else {
		geo->heads = 0xff;
		geo->sectors = 0x3f;
		geo->cylinders = drv->nr_blks / (0xff*0x3f);
	}

	return 0;
}

/*
 *  ida_ioctl does some miscellaneous stuff like reporting drive geometry,
 *  setting readahead and submitting commands from userspace to the controller.
 */
static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
{
	drv_info_t *drv = get_drv(bdev->bd_disk);
	ctlr_info_t *host = get_host(bdev->bd_disk);
	int error;
	ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
	ida_ioctl_t *my_io;

	switch(cmd) {
	case IDAGETDRVINFO:
		if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
			return -EFAULT;
		return 0;
	case IDAPASSTHRU:
		if (!capable(CAP_SYS_RAWIO))
			return -EPERM;
		my_io = kmalloc(sizeof(ida_ioctl_t), GFP_KERNEL);
		if (!my_io)
			return -ENOMEM;
		error = -EFAULT;
		if (copy_from_user(my_io, io, sizeof(*my_io)))
			goto out_passthru;
		error = ida_ctlr_ioctl(host, drv - host->drv, my_io);
		if (error)
			goto out_passthru;
		error = -EFAULT;
		if (copy_to_user(io, my_io, sizeof(*my_io)))
			goto out_passthru;
		error = 0;
out_passthru:
		kfree(my_io);
		return error;
	case IDAGETCTLRSIG:
		if (!arg) return -EINVAL;
		put_user(host->ctlr_sig, (int __user *)arg);
		return 0;
	case IDAREVALIDATEVOLS:
		if (MINOR(bdev->bd_dev) != 0)
			return -ENXIO;
		return revalidate_allvol(host);
	case IDADRIVERVERSION:
		if (!arg) return -EINVAL;
		put_user(DRIVER_VERSION, (unsigned long __user *)arg);
		return 0;
	case IDAGETPCIINFO:
	{
		
		ida_pci_info_struct pciinfo;

		if (!arg) return -EINVAL;
		pciinfo.bus = host->pci_dev->bus->number;
		pciinfo.dev_fn = host->pci_dev->devfn;
		pciinfo.board_id = host->board_id;
		if(copy_to_user((void __user *) arg, &pciinfo,  
			sizeof( ida_pci_info_struct)))
				return -EFAULT;
		return(0);
	}	

	default:
		return -EINVAL;
	}
		
}
/*
 * ida_ctlr_ioctl is for passing commands to the controller from userspace.
 * The command block (io) has already been copied to kernel space for us,
 * however, any elements in the sglist need to be copied to kernel space
 * or copied back to userspace.
 *
 * Only root may perform a controller passthru command, however I'm not doing
 * any serious sanity checking on the arguments.  Doing an IDA_WRITE_MEDIA and
 * putting a 64M buffer in the sglist is probably a *bad* idea.
 */
static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io)
{
	int ctlr = h->ctlr;
	cmdlist_t *c;
	void *p = NULL;
	unsigned long flags;
	int error;

	if ((c = cmd_alloc(h, 0)) == NULL)
		return -ENOMEM;
	c->ctlr = ctlr;
	c->hdr.unit = (io->unit & UNITVALID) ? (io->unit & ~UNITVALID) : dsk;
	c->hdr.size = sizeof(rblk_t) >> 2;
	c->size += sizeof(rblk_t);

	c->req.hdr.cmd = io->cmd;
	c->req.hdr.blk = io->blk;
	c->req.hdr.blk_cnt = io->blk_cnt;
	c->type = CMD_IOCTL_PEND;

	/* Pre submit processing */
	switch(io->cmd) {
	case PASSTHRU_A:
		p = kmalloc(io->sg[0].size, GFP_KERNEL);
		if (!p) 
		{ 
			error = -ENOMEM; 
			cmd_free(h, c, 0); 
			return(error);
		}
		if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
			kfree(p);
			cmd_free(h, c, 0); 
			return -EFAULT;
		}
		c->req.hdr.blk = pci_map_single(h->pci_dev, &(io->c), 
				sizeof(ida_ioctl_t), 
				PCI_DMA_BIDIRECTIONAL);
		c->req.sg[0].size = io->sg[0].size;
		c->req.sg[0].addr = pci_map_single(h->pci_dev, p, 
			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
		c->req.hdr.sg_cnt = 1;
		break;
	case IDA_READ:
	case READ_FLASH_ROM:
	case SENSE_CONTROLLER_PERFORMANCE:
		p = kmalloc(io->sg[0].size, GFP_KERNEL);
		if (!p) 
		{ 
                        error = -ENOMEM; 
                        cmd_free(h, c, 0);
                        return(error);
                }

		c->req.sg[0].size = io->sg[0].size;
		c->req.sg[0].addr = pci_map_single(h->pci_dev, p, 
			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); 
		c->req.hdr.sg_cnt = 1;
		break;
	case IDA_WRITE:
	case IDA_WRITE_MEDIA:
	case DIAG_PASS_THRU:
	case COLLECT_BUFFER:
	case WRITE_FLASH_ROM:
		p = kmalloc(io->sg[0].size, GFP_KERNEL);
		if (!p) 
 		{ 
                        error = -ENOMEM; 
                        cmd_free(h, c, 0);
                        return(error);
                }
		if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
			kfree(p);
                        cmd_free(h, c, 0);
			return -EFAULT;
		}
		c->req.sg[0].size = io->sg[0].size;
		c->req.sg[0].addr = pci_map_single(h->pci_dev, p, 
			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); 
		c->req.hdr.sg_cnt = 1;
		break;
	default:
		c->req.sg[0].size = sizeof(io->c);
		c->req.sg[0].addr = pci_map_single(h->pci_dev,&io->c, 
			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
		c->req.hdr.sg_cnt = 1;
	}
	
	/* Put the request on the tail of the request queue */
	spin_lock_irqsave(IDA_LOCK(ctlr), flags);
	addQ(&h->reqQ, c);
	h->Qdepth++;
	start_io(h);
	spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);

	/* Wait for completion */
	while(c->type != CMD_IOCTL_DONE)
		schedule();

	/* Unmap the DMA  */
	pci_unmap_single(h->pci_dev, c->req.sg[0].addr, c->req.sg[0].size, 
		PCI_DMA_BIDIRECTIONAL);
	/* Post submit processing */
	switch(io->cmd) {
	case PASSTHRU_A:
		pci_unmap_single(h->pci_dev, c->req.hdr.blk,
                                sizeof(ida_ioctl_t),
                                PCI_DMA_BIDIRECTIONAL);
	case IDA_READ:
	case DIAG_PASS_THRU:
	case SENSE_CONTROLLER_PERFORMANCE:
	case READ_FLASH_ROM:
		if (copy_to_user(io->sg[0].addr, p, io->sg[0].size)) {
			kfree(p);
			return -EFAULT;
		}
		/* fall through and free p */
	case IDA_WRITE:
	case IDA_WRITE_MEDIA:
	case COLLECT_BUFFER:
	case WRITE_FLASH_ROM:
		kfree(p);
		break;
	default:;
		/* Nothing to do */
	}

	io->rcode = c->req.hdr.rcode;
	cmd_free(h, c, 0);
	return(0);
}

/*
 * Commands are pre-allocated in a large block.  Here we use a simple bitmap
 * scheme to suballocte them to the driver.  Operations that are not time
 * critical (and can wait for kmalloc and possibly sleep) can pass in NULL
 * as the first argument to get a new command.
 */
static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool)
{
	cmdlist_t * c;
	int i;
	dma_addr_t cmd_dhandle;

	if (!get_from_pool) {
		c = (cmdlist_t*)pci_alloc_consistent(h->pci_dev, 
			sizeof(cmdlist_t), &cmd_dhandle);
		if(c==NULL)
			return NULL;
	} else {
		do {
			i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS);
			if (i == NR_CMDS)
				return NULL;
		} while(test_and_set_bit(i&(BITS_PER_LONG-1), h->cmd_pool_bits+(i/BITS_PER_LONG)) != 0);
		c = h->cmd_pool + i;
		cmd_dhandle = h->cmd_pool_dhandle + i*sizeof(cmdlist_t);
		h->nr_allocs++;
	}

	memset(c, 0, sizeof(cmdlist_t));
	c->busaddr = cmd_dhandle; 
	return c;
}

static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool)
{
	int i;

	if (!got_from_pool) {
		pci_free_consistent(h->pci_dev, sizeof(cmdlist_t), c,
			c->busaddr);
	} else {
		i = c - h->cmd_pool;
		clear_bit(i&(BITS_PER_LONG-1), h->cmd_pool_bits+(i/BITS_PER_LONG));
		h->nr_frees++;
	}
}

/***********************************************************************
    name:        sendcmd
    Send a command to an IDA using the memory mapped FIFO interface
    and wait for it to complete.  
    This routine should only be called at init time.
***********************************************************************/
static int sendcmd(
	__u8	cmd,
	int	ctlr,
	void	*buff,
	size_t	size,
	unsigned int blk,
	unsigned int blkcnt,
	unsigned int log_unit )
{
	cmdlist_t *c;
	int complete;
	unsigned long temp;
	unsigned long i;
	ctlr_info_t *info_p = hba[ctlr];

	c = cmd_alloc(info_p, 1);
	if(!c)
		return IO_ERROR;
	c->ctlr = ctlr;
	c->hdr.unit = log_unit;
	c->hdr.prio = 0;
	c->hdr.size = sizeof(rblk_t) >> 2;
	c->size += sizeof(rblk_t);

	/* The request information. */
	c->req.hdr.next = 0;
	c->req.hdr.rcode = 0;
	c->req.bp = 0;
	c->req.hdr.sg_cnt = 1;
	c->req.hdr.reserved = 0;
	
	if (size == 0)
		c->req.sg[0].size = 512;
	else
		c->req.sg[0].size = size;

	c->req.hdr.blk = blk;
	c->req.hdr.blk_cnt = blkcnt;
	c->req.hdr.cmd = (unsigned char) cmd;
	c->req.sg[0].addr = (__u32) pci_map_single(info_p->pci_dev, 
		buff, c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
	/*
	 * Disable interrupt
	 */
	info_p->access.set_intr_mask(info_p, 0);
	/* Make sure there is room in the command FIFO */
	/* Actually it should be completely empty at this time. */
	for (i = 200000; i > 0; i--) {
		temp = info_p->access.fifo_full(info_p);
		if (temp != 0) {
			break;
		}
		udelay(10);
DBG(
		printk(KERN_WARNING "cpqarray ida%d: idaSendPciCmd FIFO full,"
			" waiting!\n", ctlr);
);
	} 
	/*
	 * Send the cmd
	 */
	info_p->access.submit_command(info_p, c);
	complete = pollcomplete(ctlr);
	
	pci_unmap_single(info_p->pci_dev, (dma_addr_t) c->req.sg[0].addr, 
		c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
	if (complete != 1) {
		if (complete != c->busaddr) {
			printk( KERN_WARNING
			"cpqarray ida%d: idaSendPciCmd "
		      "Invalid command list address returned! (%08lx)\n",
				ctlr, (unsigned long)complete);
			cmd_free(info_p, c, 1);
			return (IO_ERROR);
		}
	} else {
		printk( KERN_WARNING
			"cpqarray ida%d: idaSendPciCmd Timeout out, "
			"No command list address returned!\n",
			ctlr);
		cmd_free(info_p, c, 1);
		return (IO_ERROR);
	}

	if (c->req.hdr.rcode & 0x00FE) {
		if (!(c->req.hdr.rcode & BIG_PROBLEM)) {
			printk( KERN_WARNING
			"cpqarray ida%d: idaSendPciCmd, error: "
				"Controller failed at init time "
				"cmd: 0x%x, return code = 0x%x\n",
				ctlr, c->req.hdr.cmd, c->req.hdr.rcode);

			cmd_free(info_p, c, 1);
			return (IO_ERROR);
		}
	}
	cmd_free(info_p, c, 1);
	return (IO_OK);
}

/*
 * revalidate_allvol is for online array config utilities.  After a
 * utility reconfigures the drives in the array, it can use this function
 * (through an ioctl) to make the driver zap any previous disk structs for
 * that controller and get new ones.
 *
 * Right now I'm using the getgeometry() function to do this, but this
 * function should probably be finer grained and allow you to revalidate one
 * particualar logical volume (instead of all of them on a particular
 * controller).
 */
static int revalidate_allvol(ctlr_info_t *host)
{
	int ctlr = host->ctlr;
	int i;
	unsigned long flags;

	spin_lock_irqsave(IDA_LOCK(ctlr), flags);
	if (host->usage_count > 1) {
		spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
		printk(KERN_WARNING "cpqarray: Device busy for volume"
			" revalidation (usage=%d)\n", host->usage_count);
		return -EBUSY;
	}
	host->usage_count++;
	spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);

	/*
	 * Set the partition and block size structures for all volumes
	 * on this controller to zero.  We will reread all of this data
	 */
	set_capacity(ida_gendisk[ctlr][0], 0);
	for (i = 1; i < NWD; i++) {
		struct gendisk *disk = ida_gendisk[ctlr][i];
		if (disk->flags & GENHD_FL_UP)
			del_gendisk(disk);
	}
	memset(host->drv, 0, sizeof(drv_info_t)*NWD);

	/*
	 * Tell the array controller not to give us any interrupts while
	 * we check the new geometry.  Then turn interrupts back on when
	 * we're done.
	 */
	host->access.set_intr_mask(host, 0);
	getgeometry(ctlr);
	host->access.set_intr_mask(host, FIFO_NOT_EMPTY);

	for(i=0; i<NWD; i++) {
		struct gendisk *disk = ida_gendisk[ctlr][i];
		drv_info_t *drv = &host->drv[i];
		if (i && !drv->nr_blks)
			continue;
		blk_queue_hardsect_size(host->queue, drv->blk_size);
		set_capacity(disk, drv->nr_blks);
		disk->queue = host->queue;
		disk->private_data = drv;
		if (i)
			add_disk(disk);
	}

	host->usage_count--;
	return 0;
}

static int ida_revalidate(struct gendisk *disk)
{
	drv_info_t *drv = disk->private_data;
	set_capacity(disk, drv->nr_blks);
	return 0;
}

/********************************************************************
    name: pollcomplete
    Wait polling for a command to complete.
    The memory mapped FIFO is polled for the completion.
    Used only at init time, interrupts disabled.
 ********************************************************************/
static int pollcomplete(int ctlr)
{
	int done;
	int i;

	/* Wait (up to 2 seconds) for a command to complete */

	for (i = 200000; i > 0; i--) {
		done = hba[ctlr]->access.command_completed(hba[ctlr]);
		if (done == 0) {
			udelay(10);	/* a short fixed delay */
		} else
			return (done);
	}
	/* Invalid address to tell caller we ran out of time */
	return 1;
}
/*****************************************************************
    start_fwbk
    Starts controller firmwares background processing. 
    Currently only the Integrated Raid controller needs this done.
    If the PCI mem address registers are written to after this, 
	 data corruption may occur
*****************************************************************/
static void start_fwbk(int ctlr)
{
		id_ctlr_t *id_ctlr_buf; 
	int ret_code;

	if(	(hba[ctlr]->board_id != 0x40400E11)
		&& (hba[ctlr]->board_id != 0x40480E11) )

	/* Not a Integrated Raid, so there is nothing for us to do */
		return;
	printk(KERN_DEBUG "cpqarray: Starting firmware's background"
		" processing\n");
	/* Command does not return anything, but idasend command needs a 
		buffer */
	id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
	if(id_ctlr_buf==NULL)
	{
		printk(KERN_WARNING "cpqarray: Out of memory. "
			"Unable to start background processing.\n");
		return;
	}		
	ret_code = sendcmd(RESUME_BACKGROUND_ACTIVITY, ctlr, 
		id_ctlr_buf, 0, 0, 0, 0);
	if(ret_code != IO_OK)
		printk(KERN_WARNING "cpqarray: Unable to start"
			" background processing\n");

	kfree(id_ctlr_buf);
}
/*****************************************************************
    getgeometry
    Get ida logical volume geometry from the controller 
    This is a large bit of code which once existed in two flavors,
    It is used only at init time.
*****************************************************************/
static void getgeometry(int ctlr)
{				
	id_log_drv_t *id_ldrive;
	id_ctlr_t *id_ctlr_buf;
	sense_log_drv_stat_t *id_lstatus_buf;
	config_t *sense_config_buf;
	unsigned int log_unit, log_index;
	int ret_code, size;
	drv_info_t *drv;
	ctlr_info_t *info_p = hba[ctlr];
	int i;

	info_p->log_drv_map = 0;	
	
	id_ldrive = kzalloc(sizeof(id_log_drv_t), GFP_KERNEL);
	if (!id_ldrive)	{
		printk( KERN_ERR "cpqarray:  out of memory.\n");
		goto err_0;
	}

	id_ctlr_buf = kzalloc(sizeof(id_ctlr_t), GFP_KERNEL);
	if (!id_ctlr_buf) {
		printk( KERN_ERR "cpqarray:  out of memory.\n");
		goto err_1;
	}

	id_lstatus_buf = kzalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
	if (!id_lstatus_buf) {
		printk( KERN_ERR "cpqarray:  out of memory.\n");
		goto err_2;
	}

	sense_config_buf = kzalloc(sizeof(config_t), GFP_KERNEL);
	if (!sense_config_buf) {
		printk( KERN_ERR "cpqarray:  out of memory.\n");
		goto err_3;
	}

	info_p->phys_drives = 0;
	info_p->log_drv_map = 0;
	info_p->drv_assign_map = 0;
	info_p->drv_spare_map = 0;
	info_p->mp_failed_drv_map = 0;	/* only initialized here */
	/* Get controllers info for this logical drive */
	ret_code = sendcmd(ID_CTLR, ctlr, id_ctlr_buf, 0, 0, 0, 0);
	if (ret_code == IO_ERROR) {
		/*
		 * If can't get controller info, set the logical drive map to 0,
		 * so the idastubopen will fail on all logical drives
		 * on the controller.
		 */
		printk(KERN_ERR "cpqarray: error sending ID controller\n");
                goto err_4;
        }

	info_p->log_drives = id_ctlr_buf->nr_drvs;
	for(i=0;i<4;i++)
		info_p->firm_rev[i] = id_ctlr_buf->firm_rev[i];
	info_p->ctlr_sig = id_ctlr_buf->cfg_sig;

	printk(" (%s)\n", info_p->product_name);
	/*
	 * Initialize logical drive map to zero
	 */
	log_index = 0;
	/*
	 * Get drive geometry for all logical drives
	 */
	if (id_ctlr_buf->nr_drvs > 16)
		printk(KERN_WARNING "cpqarray ida%d:  This driver supports "
			"16 logical drives per controller.\n.  "
			" Additional drives will not be "
			"detected\n", ctlr);

	for (log_unit = 0;
	     (log_index < id_ctlr_buf->nr_drvs)
	     && (log_unit < NWD);
	     log_unit++) {
		size = sizeof(sense_log_drv_stat_t);

		/*
		   Send "Identify logical drive status" cmd
		 */
		ret_code = sendcmd(SENSE_LOG_DRV_STAT,
			     ctlr, id_lstatus_buf, size, 0, 0, log_unit);
		if (ret_code == IO_ERROR) {
			/*
			   If can't get logical drive status, set
			   the logical drive map to 0, so the
			   idastubopen will fail for all logical drives
			   on the controller. 
			 */
			info_p->log_drv_map = 0;	
			printk( KERN_WARNING
			     "cpqarray ida%d: idaGetGeometry - Controller"
				" failed to report status of logical drive %d\n"
			 "Access to this controller has been disabled\n",
				ctlr, log_unit);
                	goto err_4;
		}
		/*
		   Make sure the logical drive is configured
		 */
		if (id_lstatus_buf->status != LOG_NOT_CONF) {
			ret_code = sendcmd(ID_LOG_DRV, ctlr, id_ldrive,
			       sizeof(id_log_drv_t), 0, 0, log_unit);
			/*
			   If error, the bit for this
			   logical drive won't be set and
			   idastubopen will return error. 
			 */
			if (ret_code != IO_ERROR) {
				drv = &info_p->drv[log_unit];
				drv->blk_size = id_ldrive->blk_size;
				drv->nr_blks = id_ldrive->nr_blks;
				drv->cylinders = id_ldrive->drv.cyl;
				drv->heads = id_ldrive->drv.heads;
				drv->sectors = id_ldrive->drv.sect_per_track;
				info_p->log_drv_map |=	(1 << log_unit);

	printk(KERN_INFO "cpqarray ida/c%dd%d: blksz=%d nr_blks=%d\n",
		ctlr, log_unit, drv->blk_size, drv->nr_blks);
				ret_code = sendcmd(SENSE_CONFIG,
						  ctlr, sense_config_buf,
				 sizeof(config_t), 0, 0, log_unit);
				if (ret_code == IO_ERROR) {
					info_p->log_drv_map = 0;
                			printk(KERN_ERR "cpqarray: error sending sense config\n");
                			goto err_4;
				}

				info_p->phys_drives =
				    sense_config_buf->ctlr_phys_drv;
				info_p->drv_assign_map
				    |= sense_config_buf->drv_asgn_map;
				info_p->drv_assign_map
				    |= sense_config_buf->spare_asgn_map;
				info_p->drv_spare_map
				    |= sense_config_buf->spare_asgn_map;
			}	/* end of if no error on id_ldrive */
			log_index = log_index + 1;
		}		/* end of if logical drive configured */
	}			/* end of for log_unit */

	/* Free all the buffers and return */
err_4:
	kfree(sense_config_buf);
err_3:
  	kfree(id_lstatus_buf);
err_2:
	kfree(id_ctlr_buf);
err_1:
  	kfree(id_ldrive);
err_0:
	return;
}

static void __exit cpqarray_exit(void)
{
	int i;

	pci_unregister_driver(&cpqarray_pci_driver);

	/* Double check that all controller entries have been removed */
	for(i=0; i<MAX_CTLR; i++) {
		if (hba[i] != NULL) {
			printk(KERN_WARNING "cpqarray: Removing EISA "
					"controller %d\n", i);
			cpqarray_remove_one_eisa(i);
		}
	}

	remove_proc_entry("driver/cpqarray", NULL);
}

module_init(cpqarray_init)
module_exit(cpqarray_exit)
