/*
 *    Disk Array driver for HP Smart Array controllers, SCSI Tape module.
 *    (C) Copyright 2001, 2007 Hewlett-Packard Development Company, L.P.
 *
 *    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; version 2 of the License.
 *
 *    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. 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., 59 Temple Place, Suite 300, Boston, MA
 *    02111-1307, USA.
 *
 *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
 *    
 *    Author: Stephen M. Cameron
 */
#ifdef CONFIG_CISS_SCSI_TAPE

/* Here we have code to present the driver as a scsi driver 
   as it is simultaneously presented as a block driver.  The 
   reason for doing this is to allow access to SCSI tape drives
   through the array controller.  Note in particular, neither 
   physical nor logical disks are presented through the scsi layer. */

#include <linux/timer.h>
#include <linux/completion.h>
#include <linux/slab.h>
#include <linux/string.h>

#include <asm/atomic.h>

#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h> 

#include "cciss_scsi.h"

#define CCISS_ABORT_MSG 0x00
#define CCISS_RESET_MSG 0x01

static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
	size_t size,
	__u8 page_code, unsigned char *scsi3addr,
	int cmd_type);

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

static int cciss_scsi_proc_info(
		struct Scsi_Host *sh,
		char *buffer, /* data buffer */
		char **start, 	   /* where data in buffer starts */
		off_t offset,	   /* offset from start of imaginary file */
		int length, 	   /* length of data in buffer */
		int func);	   /* 0 == read, 1 == write */

static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
		void (* done)(struct scsi_cmnd *));
static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
static int cciss_eh_abort_handler(struct scsi_cmnd *);

static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
	{ .name = "cciss0", .ndevices = 0 },
	{ .name = "cciss1", .ndevices = 0 },
	{ .name = "cciss2", .ndevices = 0 },
	{ .name = "cciss3", .ndevices = 0 },
	{ .name = "cciss4", .ndevices = 0 },
	{ .name = "cciss5", .ndevices = 0 },
	{ .name = "cciss6", .ndevices = 0 },
	{ .name = "cciss7", .ndevices = 0 },
};

static struct scsi_host_template cciss_driver_template = {
	.module			= THIS_MODULE,
	.name			= "cciss",
	.proc_name		= "cciss",
	.proc_info		= cciss_scsi_proc_info,
	.queuecommand		= cciss_scsi_queue_command,
	.can_queue		= SCSI_CCISS_CAN_QUEUE,
	.this_id		= 7,
	.cmd_per_lun		= 1,
	.use_clustering		= DISABLE_CLUSTERING,
	/* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
	.eh_device_reset_handler= cciss_eh_device_reset_handler,
	.eh_abort_handler	= cciss_eh_abort_handler,
};

#pragma pack(1)

#define SCSI_PAD_32 8
#define SCSI_PAD_64 8

struct cciss_scsi_cmd_stack_elem_t {
	CommandList_struct cmd;
	ErrorInfo_struct Err;
	__u32 busaddr;
	int cmdindex;
	u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64];
};

#pragma pack()

#define CMD_STACK_SIZE (SCSI_CCISS_CAN_QUEUE * \
		CCISS_MAX_SCSI_DEVS_PER_HBA + 2)
			// plus two for init time usage

#pragma pack(1)
struct cciss_scsi_cmd_stack_t {
	struct cciss_scsi_cmd_stack_elem_t *pool;
	struct cciss_scsi_cmd_stack_elem_t *elem[CMD_STACK_SIZE];
	dma_addr_t cmd_pool_handle;
	int top;
};
#pragma pack()

struct cciss_scsi_adapter_data_t {
	struct Scsi_Host *scsi_host;
	struct cciss_scsi_cmd_stack_t cmd_stack;
	SGDescriptor_struct **cmd_sg_list;
	int registered;
	spinlock_t lock; // to protect ccissscsi[ctlr]; 
};

#define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \
	&hba[ctlr]->scsi_ctlr->lock, flags);
#define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \
	&hba[ctlr]->scsi_ctlr->lock, flags);

static CommandList_struct *
scsi_cmd_alloc(ctlr_info_t *h)
{
	/* assume only one process in here at a time, locking done by caller. */
	/* use CCISS_LOCK(ctlr) */
	/* might be better to rewrite how we allocate scsi commands in a way that */
	/* needs no locking at all. */

	/* take the top memory chunk off the stack and return it, if any. */
	struct cciss_scsi_cmd_stack_elem_t *c;
	struct cciss_scsi_adapter_data_t *sa;
	struct cciss_scsi_cmd_stack_t *stk;
	u64bit temp64;

	sa = h->scsi_ctlr;
	stk = &sa->cmd_stack; 

	if (stk->top < 0) 
		return NULL;
	c = stk->elem[stk->top]; 	
	/* memset(c, 0, sizeof(*c)); */
	memset(&c->cmd, 0, sizeof(c->cmd));
	memset(&c->Err, 0, sizeof(c->Err));
	/* set physical addr of cmd and addr of scsi parameters */
	c->cmd.busaddr = c->busaddr; 
	c->cmd.cmdindex = c->cmdindex;
	/* (__u32) (stk->cmd_pool_handle + 
		(sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */

	temp64.val = (__u64) (c->busaddr + sizeof(CommandList_struct));
	/* (__u64) (stk->cmd_pool_handle + 
		(sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top) +
		 sizeof(CommandList_struct)); */
	stk->top--;
	c->cmd.ErrDesc.Addr.lower = temp64.val32.lower;
	c->cmd.ErrDesc.Addr.upper = temp64.val32.upper;
	c->cmd.ErrDesc.Len = sizeof(ErrorInfo_struct);
	
	c->cmd.ctlr = h->ctlr;
	c->cmd.err_info = &c->Err;

	return (CommandList_struct *) c;
}

static void 
scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
{
	/* assume only one process in here at a time, locking done by caller. */
	/* use CCISS_LOCK(ctlr) */
	/* drop the free memory chunk on top of the stack. */

	struct cciss_scsi_adapter_data_t *sa;
	struct cciss_scsi_cmd_stack_t *stk;

	sa = h->scsi_ctlr;
	stk = &sa->cmd_stack; 
	stk->top++;
	if (stk->top >= CMD_STACK_SIZE) {
		printk("cciss: scsi_cmd_free called too many times.\n");
		BUG();
	}
	stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd;
}

static int
scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
{
	int i;
	struct cciss_scsi_cmd_stack_t *stk;
	size_t size;

	sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr],
		hba[ctlr]->chainsize, CMD_STACK_SIZE);
	if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0)
		return -ENOMEM;

	stk = &sa->cmd_stack; 
	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;

	/* Check alignment, see cciss_cmd.h near CommandList_struct def. */
	BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0);
	/* printk(KERN_WARNING "cciss_scsi.c: 0x%08x 0x%08x 0x%08x\n",
			0xdeadbeef, sizeof(*stk->pool), 0xbeefdead); */
	/* pci_alloc_consistent guarantees 32-bit DMA address will be used */
	stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
		pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);

	if (stk->pool == NULL) {
		cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
		sa->cmd_sg_list = NULL;
		return -ENOMEM;
	}

	for (i=0; i<CMD_STACK_SIZE; i++) {
		stk->elem[i] = &stk->pool[i];
		stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle + 
			(sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
		stk->elem[i]->cmdindex = i;
	}
	stk->top = CMD_STACK_SIZE-1;
	return 0;
}

static void
scsi_cmd_stack_free(int ctlr)
{
	struct cciss_scsi_adapter_data_t *sa;
	struct cciss_scsi_cmd_stack_t *stk;
	size_t size;

	sa = hba[ctlr]->scsi_ctlr;
	stk = &sa->cmd_stack; 
	if (stk->top != CMD_STACK_SIZE-1) {
		printk( "cciss: %d scsi commands are still outstanding.\n",
			CMD_STACK_SIZE - stk->top);
		// BUG();
		printk("WE HAVE A BUG HERE!!! stk=0x%p\n", stk);
	}
	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;

	pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
	stk->pool = NULL;
	cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
}

#if 0
static int xmargin=8;
static int amargin=60;

static void
print_bytes (unsigned char *c, int len, int hex, int ascii)
{

	int i;
	unsigned char *x;

	if (hex)
	{
		x = c;
		for (i=0;i<len;i++)
		{
			if ((i % xmargin) == 0 && i>0) printk("\n");
			if ((i % xmargin) == 0) printk("0x%04x:", i);
			printk(" %02x", *x);
			x++;
		}
		printk("\n");
	}
	if (ascii)
	{
		x = c;
		for (i=0;i<len;i++)
		{
			if ((i % amargin) == 0 && i>0) printk("\n");
			if ((i % amargin) == 0) printk("0x%04x:", i);
			if (*x > 26 && *x < 128) printk("%c", *x);
			else printk(".");
			x++;
		}
		printk("\n");
	}
}

static void
print_cmd(CommandList_struct *cp)
{
	printk("queue:%d\n", cp->Header.ReplyQueue);
	printk("sglist:%d\n", cp->Header.SGList);
	printk("sgtot:%d\n", cp->Header.SGTotal);
	printk("Tag:0x%08x/0x%08x\n", cp->Header.Tag.upper, 
			cp->Header.Tag.lower);
	printk("LUN:0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
		cp->Header.LUN.LunAddrBytes[0],
		cp->Header.LUN.LunAddrBytes[1],
		cp->Header.LUN.LunAddrBytes[2],
		cp->Header.LUN.LunAddrBytes[3],
		cp->Header.LUN.LunAddrBytes[4],
		cp->Header.LUN.LunAddrBytes[5],
		cp->Header.LUN.LunAddrBytes[6],
		cp->Header.LUN.LunAddrBytes[7]);
	printk("CDBLen:%d\n", cp->Request.CDBLen);
	printk("Type:%d\n",cp->Request.Type.Type);
	printk("Attr:%d\n",cp->Request.Type.Attribute);
	printk(" Dir:%d\n",cp->Request.Type.Direction);
	printk("Timeout:%d\n",cp->Request.Timeout);
	printk( "CDB: %02x %02x %02x %02x %02x %02x %02x %02x"
		" %02x %02x %02x %02x %02x %02x %02x %02x\n",
		cp->Request.CDB[0], cp->Request.CDB[1],
		cp->Request.CDB[2], cp->Request.CDB[3],
		cp->Request.CDB[4], cp->Request.CDB[5],
		cp->Request.CDB[6], cp->Request.CDB[7],
		cp->Request.CDB[8], cp->Request.CDB[9],
		cp->Request.CDB[10], cp->Request.CDB[11],
		cp->Request.CDB[12], cp->Request.CDB[13],
		cp->Request.CDB[14], cp->Request.CDB[15]),
	printk("edesc.Addr: 0x%08x/0%08x, Len  = %d\n", 
		cp->ErrDesc.Addr.upper, cp->ErrDesc.Addr.lower, 
			cp->ErrDesc.Len);
	printk("sgs..........Errorinfo:\n");
	printk("scsistatus:%d\n", cp->err_info->ScsiStatus);
	printk("senselen:%d\n", cp->err_info->SenseLen);
	printk("cmd status:%d\n", cp->err_info->CommandStatus);
	printk("resid cnt:%d\n", cp->err_info->ResidualCnt);
	printk("offense size:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_size);
	printk("offense byte:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_num);
	printk("offense value:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
			
}

#endif

static int 
find_bus_target_lun(int ctlr, int *bus, int *target, int *lun)
{
	/* finds an unused bus, target, lun for a new device */
	/* assumes hba[ctlr]->scsi_ctlr->lock is held */ 
	int i, found=0;
	unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA];

	memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA);

	target_taken[SELF_SCSI_ID] = 1;	
	for (i=0;i<ccissscsi[ctlr].ndevices;i++)
		target_taken[ccissscsi[ctlr].dev[i].target] = 1;
	
	for (i=0;i<CCISS_MAX_SCSI_DEVS_PER_HBA;i++) {
		if (!target_taken[i]) {
			*bus = 0; *target=i; *lun = 0; found=1;
			break;
		}
	}
	return (!found);	
}
struct scsi2map {
	char scsi3addr[8];
	int bus, target, lun;
};

static int 
cciss_scsi_add_entry(int ctlr, int hostno, 
		struct cciss_scsi_dev_t *device,
		struct scsi2map *added, int *nadded)
{
	/* assumes hba[ctlr]->scsi_ctlr->lock is held */ 
	int n = ccissscsi[ctlr].ndevices;
	struct cciss_scsi_dev_t *sd;
	int i, bus, target, lun;
	unsigned char addr1[8], addr2[8];

	if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
		printk("cciss%d: Too many devices, "
			"some will be inaccessible.\n", ctlr);
		return -1;
	}

	bus = target = -1;
	lun = 0;
	/* Is this device a non-zero lun of a multi-lun device */
	/* byte 4 of the 8-byte LUN addr will contain the logical unit no. */
	if (device->scsi3addr[4] != 0) {
		/* Search through our list and find the device which */
		/* has the same 8 byte LUN address, excepting byte 4. */
		/* Assign the same bus and target for this new LUN. */
		/* Use the logical unit number from the firmware. */
		memcpy(addr1, device->scsi3addr, 8);
		addr1[4] = 0;
		for (i = 0; i < n; i++) {
			sd = &ccissscsi[ctlr].dev[i];
			memcpy(addr2, sd->scsi3addr, 8);
			addr2[4] = 0;
			/* differ only in byte 4? */
			if (memcmp(addr1, addr2, 8) == 0) {
				bus = sd->bus;
				target = sd->target;
				lun = device->scsi3addr[4];
				break;
			}
		}
	}

	sd = &ccissscsi[ctlr].dev[n];
	if (lun == 0) {
		if (find_bus_target_lun(ctlr,
			&sd->bus, &sd->target, &sd->lun) != 0)
			return -1;
	} else {
		sd->bus = bus;
		sd->target = target;
		sd->lun = lun;
	}
	added[*nadded].bus = sd->bus;
	added[*nadded].target = sd->target;
	added[*nadded].lun = sd->lun;
	(*nadded)++;

	memcpy(sd->scsi3addr, device->scsi3addr, 8);
	memcpy(sd->vendor, device->vendor, sizeof(sd->vendor));
	memcpy(sd->revision, device->revision, sizeof(sd->revision));
	memcpy(sd->device_id, device->device_id, sizeof(sd->device_id));
	sd->devtype = device->devtype;

	ccissscsi[ctlr].ndevices++;

	/* initially, (before registering with scsi layer) we don't 
	   know our hostno and we don't want to print anything first 
	   time anyway (the scsi layer's inquiries will show that info) */
	if (hostno != -1)
		printk("cciss%d: %s device c%db%dt%dl%d added.\n", 
			ctlr, scsi_device_type(sd->devtype), hostno,
			sd->bus, sd->target, sd->lun);
	return 0;
}

static void
cciss_scsi_remove_entry(int ctlr, int hostno, int entry,
	struct scsi2map *removed, int *nremoved)
{
	/* assumes hba[ctlr]->scsi_ctlr->lock is held */ 
	int i;
	struct cciss_scsi_dev_t sd;

	if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return;
	sd = ccissscsi[ctlr].dev[entry];
	removed[*nremoved].bus    = sd.bus;
	removed[*nremoved].target = sd.target;
	removed[*nremoved].lun    = sd.lun;
	(*nremoved)++;
	for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++)
		ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1];
	ccissscsi[ctlr].ndevices--;
	printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
		ctlr, scsi_device_type(sd.devtype), hostno,
			sd.bus, sd.target, sd.lun);
}


#define SCSI3ADDR_EQ(a,b) ( \
	(a)[7] == (b)[7] && \
	(a)[6] == (b)[6] && \
	(a)[5] == (b)[5] && \
	(a)[4] == (b)[4] && \
	(a)[3] == (b)[3] && \
	(a)[2] == (b)[2] && \
	(a)[1] == (b)[1] && \
	(a)[0] == (b)[0])

static void fixup_botched_add(int ctlr, char *scsi3addr)
{
	/* called when scsi_add_device fails in order to re-adjust */
	/* ccissscsi[] to match the mid layer's view. */
	unsigned long flags;
	int i, j;
	CPQ_TAPE_LOCK(ctlr, flags);
	for (i = 0; i < ccissscsi[ctlr].ndevices; i++) {
		if (memcmp(scsi3addr,
				ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) {
			for (j = i; j < ccissscsi[ctlr].ndevices-1; j++)
				ccissscsi[ctlr].dev[j] =
					ccissscsi[ctlr].dev[j+1];
			ccissscsi[ctlr].ndevices--;
			break;
		}
	}
	CPQ_TAPE_UNLOCK(ctlr, flags);
}

static int device_is_the_same(struct cciss_scsi_dev_t *dev1,
	struct cciss_scsi_dev_t *dev2)
{
	return dev1->devtype == dev2->devtype &&
		memcmp(dev1->scsi3addr, dev2->scsi3addr,
			sizeof(dev1->scsi3addr)) == 0 &&
		memcmp(dev1->device_id, dev2->device_id,
			sizeof(dev1->device_id)) == 0 &&
		memcmp(dev1->vendor, dev2->vendor,
			sizeof(dev1->vendor)) == 0 &&
		memcmp(dev1->model, dev2->model,
			sizeof(dev1->model)) == 0 &&
		memcmp(dev1->revision, dev2->revision,
			sizeof(dev1->revision)) == 0;
}

static int
adjust_cciss_scsi_table(int ctlr, int hostno,
	struct cciss_scsi_dev_t sd[], int nsds)
{
	/* sd contains scsi3 addresses and devtypes, but
	   bus target and lun are not filled in.  This funciton
	   takes what's in sd to be the current and adjusts
	   ccissscsi[] to be in line with what's in sd. */ 

	int i,j, found, changes=0;
	struct cciss_scsi_dev_t *csd;
	unsigned long flags;
	struct scsi2map *added, *removed;
	int nadded, nremoved;
	struct Scsi_Host *sh = NULL;

	added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA,
			GFP_KERNEL);
	removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA,
			GFP_KERNEL);

	if (!added || !removed) {
		printk(KERN_WARNING "cciss%d: Out of memory in "
			"adjust_cciss_scsi_table\n", ctlr);
		goto free_and_out;
	}

	CPQ_TAPE_LOCK(ctlr, flags);

	if (hostno != -1)  /* if it's not the first time... */
		sh = hba[ctlr]->scsi_ctlr->scsi_host;

	/* find any devices in ccissscsi[] that are not in 
	   sd[] and remove them from ccissscsi[] */

	i = 0;
	nremoved = 0;
	nadded = 0;
	while(i<ccissscsi[ctlr].ndevices) {
		csd = &ccissscsi[ctlr].dev[i];
		found=0;
		for (j=0;j<nsds;j++) {
			if (SCSI3ADDR_EQ(sd[j].scsi3addr,
				csd->scsi3addr)) {
				if (device_is_the_same(&sd[j], csd))
					found=2;
				else
					found=1;
				break;
			}
		}

		if (found == 0) { /* device no longer present. */ 
			changes++;
			/* printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
				ctlr, scsi_device_type(csd->devtype), hostno,
					csd->bus, csd->target, csd->lun); */
			cciss_scsi_remove_entry(ctlr, hostno, i,
				removed, &nremoved);
			/* remove ^^^, hence i not incremented */
		} else if (found == 1) { /* device is different in some way */
			changes++;
			printk("cciss%d: device c%db%dt%dl%d has changed.\n",
				ctlr, hostno, csd->bus, csd->target, csd->lun);
			cciss_scsi_remove_entry(ctlr, hostno, i,
				removed, &nremoved);
			/* remove ^^^, hence i not incremented */
			if (cciss_scsi_add_entry(ctlr, hostno, &sd[j],
				added, &nadded) != 0)
				/* we just removed one, so add can't fail. */
					BUG();
			csd->devtype = sd[j].devtype;
			memcpy(csd->device_id, sd[j].device_id,
				sizeof(csd->device_id));
			memcpy(csd->vendor, sd[j].vendor,
				sizeof(csd->vendor));
			memcpy(csd->model, sd[j].model,
				sizeof(csd->model));
			memcpy(csd->revision, sd[j].revision,
				sizeof(csd->revision));
		} else 		/* device is same as it ever was, */
			i++;	/* so just move along. */
	}

	/* Now, make sure every device listed in sd[] is also
 	   listed in ccissscsi[], adding them if they aren't found */

	for (i=0;i<nsds;i++) {
		found=0;
		for (j=0;j<ccissscsi[ctlr].ndevices;j++) {
			csd = &ccissscsi[ctlr].dev[j];
			if (SCSI3ADDR_EQ(sd[i].scsi3addr,
				csd->scsi3addr)) {
				if (device_is_the_same(&sd[i], csd))
					found=2;	/* found device */
				else
					found=1; 	/* found a bug. */
				break;
			}
		}
		if (!found) {
			changes++;
			if (cciss_scsi_add_entry(ctlr, hostno, &sd[i],
				added, &nadded) != 0)
				break;
		} else if (found == 1) {
			/* should never happen... */
			changes++;
			printk(KERN_WARNING "cciss%d: device "
				"unexpectedly changed\n", ctlr);
			/* but if it does happen, we just ignore that device */
		}
	}
	CPQ_TAPE_UNLOCK(ctlr, flags);

	/* Don't notify scsi mid layer of any changes the first time through */
	/* (or if there are no changes) scsi_scan_host will do it later the */
	/* first time through. */
	if (hostno == -1 || !changes)
		goto free_and_out;

	/* Notify scsi mid layer of any removed devices */
	for (i = 0; i < nremoved; i++) {
		struct scsi_device *sdev =
			scsi_device_lookup(sh, removed[i].bus,
				removed[i].target, removed[i].lun);
		if (sdev != NULL) {
			scsi_remove_device(sdev);
			scsi_device_put(sdev);
		} else {
			/* We don't expect to get here. */
			/* future cmds to this device will get selection */
			/* timeout as if the device was gone. */
			printk(KERN_WARNING "cciss%d: didn't find "
				"c%db%dt%dl%d\n for removal.",
				ctlr, hostno, removed[i].bus,
				removed[i].target, removed[i].lun);
		}
	}

	/* Notify scsi mid layer of any added devices */
	for (i = 0; i < nadded; i++) {
		int rc;
		rc = scsi_add_device(sh, added[i].bus,
			added[i].target, added[i].lun);
		if (rc == 0)
			continue;
		printk(KERN_WARNING "cciss%d: scsi_add_device "
			"c%db%dt%dl%d failed, device not added.\n",
			ctlr, hostno,
			added[i].bus, added[i].target, added[i].lun);
		/* now we have to remove it from ccissscsi, */
		/* since it didn't get added to scsi mid layer */
		fixup_botched_add(ctlr, added[i].scsi3addr);
	}

free_and_out:
	kfree(added);
	kfree(removed);
	return 0;
}

static int
lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr)
{
	int i;
	struct cciss_scsi_dev_t *sd;
	unsigned long flags;

	CPQ_TAPE_LOCK(ctlr, flags);
	for (i=0;i<ccissscsi[ctlr].ndevices;i++) {
		sd = &ccissscsi[ctlr].dev[i];
		if (sd->bus == bus &&
		    sd->target == target &&
		    sd->lun == lun) {
			memcpy(scsi3addr, &sd->scsi3addr[0], 8);
			CPQ_TAPE_UNLOCK(ctlr, flags);
			return 0;
		}
	}
	CPQ_TAPE_UNLOCK(ctlr, flags);
	return -1;
}

static void 
cciss_scsi_setup(int cntl_num)
{
	struct cciss_scsi_adapter_data_t * shba;

	ccissscsi[cntl_num].ndevices = 0;
	shba = (struct cciss_scsi_adapter_data_t *)
		kmalloc(sizeof(*shba), GFP_KERNEL);	
	if (shba == NULL)
		return;
	shba->scsi_host = NULL;
	spin_lock_init(&shba->lock);
	shba->registered = 0;
	if (scsi_cmd_stack_setup(cntl_num, shba) != 0) {
		kfree(shba);
		shba = NULL;
	}
	hba[cntl_num]->scsi_ctlr = shba;
	return;
}

static void
complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
{
	struct scsi_cmnd *cmd;
	ctlr_info_t *ctlr;
	ErrorInfo_struct *ei;

	ei = cp->err_info;

	/* First, see if it was a message rather than a command */
	if (cp->Request.Type.Type == TYPE_MSG)  {
		cp->cmd_type = CMD_MSG_DONE;
		return;
	}

	cmd = (struct scsi_cmnd *) cp->scsi_cmd;	
	ctlr = hba[cp->ctlr];

	scsi_dma_unmap(cmd);
	if (cp->Header.SGTotal > ctlr->max_cmd_sgentries)
		cciss_unmap_sg_chain_block(ctlr, cp);

	cmd->result = (DID_OK << 16); 		/* host byte */
	cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
	/* cmd->result |= (GOOD < 1); */		/* status byte */

	cmd->result |= (ei->ScsiStatus);
	/* printk("Scsistatus is 0x%02x\n", ei->ScsiStatus);  */

	/* copy the sense data whether we need to or not. */

	memcpy(cmd->sense_buffer, ei->SenseInfo, 
		ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
			SCSI_SENSE_BUFFERSIZE : 
			ei->SenseLen);
	scsi_set_resid(cmd, ei->ResidualCnt);

	if(ei->CommandStatus != 0) 
	{ /* an error has occurred */ 
		switch(ei->CommandStatus)
		{
			case CMD_TARGET_STATUS:
				/* Pass it up to the upper layers... */
				if( ei->ScsiStatus)
                		{
#if 0
                    			printk(KERN_WARNING "cciss: cmd %p "
					"has SCSI Status = %x\n",
                        			cp,  
						ei->ScsiStatus); 
#endif
					cmd->result |= (ei->ScsiStatus << 1);
                		}
				else {  /* scsi status is zero??? How??? */
					
	/* Ordinarily, this case should never happen, but there is a bug
	   in some released firmware revisions that allows it to happen
	   if, for example, a 4100 backplane loses power and the tape
	   drive is in it.  We assume that it's a fatal error of some
	   kind because we can't show that it wasn't. We will make it
	   look like selection timeout since that is the most common
	   reason for this to occur, and it's severe enough. */

					cmd->result = DID_NO_CONNECT << 16;
				}
			break;
			case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
			break;
			case CMD_DATA_OVERRUN:
				printk(KERN_WARNING "cciss: cp %p has"
					" completed with data overrun "
					"reported\n", cp);
			break;
			case CMD_INVALID: {
				/* print_bytes(cp, sizeof(*cp), 1, 0);
				print_cmd(cp); */
     /* We get CMD_INVALID if you address a non-existent tape drive instead
	of a selection timeout (no response).  You will see this if you yank 
	out a tape drive, then try to access it. This is kind of a shame
	because it means that any other CMD_INVALID (e.g. driver bug) will
	get interpreted as a missing target. */
				cmd->result = DID_NO_CONNECT << 16;
				}
			break;
			case CMD_PROTOCOL_ERR:
                                printk(KERN_WARNING "cciss: cp %p has "
					"protocol error \n", cp);
                        break;
			case CMD_HARDWARE_ERR:
				cmd->result = DID_ERROR << 16;
                                printk(KERN_WARNING "cciss: cp %p had " 
                                        " hardware error\n", cp);
                        break;
			case CMD_CONNECTION_LOST:
				cmd->result = DID_ERROR << 16;
				printk(KERN_WARNING "cciss: cp %p had "
					"connection lost\n", cp);
			break;
			case CMD_ABORTED:
				cmd->result = DID_ABORT << 16;
				printk(KERN_WARNING "cciss: cp %p was "
					"aborted\n", cp);
			break;
			case CMD_ABORT_FAILED:
				cmd->result = DID_ERROR << 16;
				printk(KERN_WARNING "cciss: cp %p reports "
					"abort failed\n", cp);
			break;
			case CMD_UNSOLICITED_ABORT:
				cmd->result = DID_ABORT << 16;
				printk(KERN_WARNING "cciss: cp %p aborted "
					"do to an unsolicited abort\n", cp);
			break;
			case CMD_TIMEOUT:
				cmd->result = DID_TIME_OUT << 16;
				printk(KERN_WARNING "cciss: cp %p timedout\n",
					cp);
			break;
			default:
				cmd->result = DID_ERROR << 16;
				printk(KERN_WARNING "cciss: cp %p returned "
					"unknown status %x\n", cp, 
						ei->CommandStatus); 
		}
	}
	// printk("c:%p:c%db%dt%dl%d ", cmd, ctlr->ctlr, cmd->channel, 
	//	cmd->target, cmd->lun);
	cmd->scsi_done(cmd);
	scsi_cmd_free(ctlr, cp);
}

static int
cciss_scsi_detect(int ctlr)
{
	struct Scsi_Host *sh;
	int error;

	sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
	if (sh == NULL)
		goto fail;
	sh->io_port = 0;	// good enough?  FIXME, 
	sh->n_io_port = 0;	// I don't think we use these two...
	sh->this_id = SELF_SCSI_ID;  
	sh->sg_tablesize = hba[ctlr]->maxsgentries;
	sh->max_cmd_len = MAX_COMMAND_SIZE;

	((struct cciss_scsi_adapter_data_t *) 
		hba[ctlr]->scsi_ctlr)->scsi_host = sh;
	sh->hostdata[0] = (unsigned long) hba[ctlr];
	sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
	sh->unique_id = sh->irq;
	error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
	if (error)
		goto fail_host_put;
	scsi_scan_host(sh);
	return 1;

 fail_host_put:
	scsi_host_put(sh);
 fail:
	return 0;
}

static void
cciss_unmap_one(struct pci_dev *pdev,
		CommandList_struct *cp,
		size_t buflen,
		int data_direction)
{
	u64bit addr64;

	addr64.val32.lower = cp->SG[0].Addr.lower;
	addr64.val32.upper = cp->SG[0].Addr.upper;
	pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction);
}

static void
cciss_map_one(struct pci_dev *pdev,
		CommandList_struct *cp,
		unsigned char *buf,
		size_t buflen,
		int data_direction)
{
	__u64 addr64;

	addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction);
	cp->SG[0].Addr.lower = 
	  (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
	cp->SG[0].Addr.upper =
	  (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
	cp->SG[0].Len = buflen;
	cp->Header.SGList = (__u8) 1;   /* no. SGs contig in this cmd */
	cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */
}

static int
cciss_scsi_do_simple_cmd(ctlr_info_t *c,
			CommandList_struct *cp,
			unsigned char *scsi3addr, 
			unsigned char *cdb,
			unsigned char cdblen,
			unsigned char *buf, int bufsize,
			int direction)
{
	unsigned long flags;
	DECLARE_COMPLETION_ONSTACK(wait);

	cp->cmd_type = CMD_IOCTL_PEND;		// treat this like an ioctl 
	cp->scsi_cmd = NULL;
	cp->Header.ReplyQueue = 0;  // unused in simple mode
	memcpy(&cp->Header.LUN, scsi3addr, sizeof(cp->Header.LUN));
	cp->Header.Tag.lower = cp->busaddr;  // Use k. address of cmd as tag
	// Fill in the request block...

	/* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n", 
		scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3],
		scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */

	memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
	memcpy(cp->Request.CDB, cdb, cdblen);
	cp->Request.Timeout = 0;
	cp->Request.CDBLen = cdblen;
	cp->Request.Type.Type = TYPE_CMD;
	cp->Request.Type.Attribute = ATTR_SIMPLE;
	cp->Request.Type.Direction = direction;

	/* Fill in the SG list and do dma mapping */
	cciss_map_one(c->pdev, cp, (unsigned char *) buf,
			bufsize, DMA_FROM_DEVICE); 

	cp->waiting = &wait;

	/* Put the request on the tail of the request queue */
	spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
	addQ(&c->reqQ, cp);
	c->Qdepth++;
	start_io(c);
	spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);

	wait_for_completion(&wait);

	/* undo the dma mapping */
	cciss_unmap_one(c->pdev, cp, bufsize, DMA_FROM_DEVICE);
	return(0);
}

static void 
cciss_scsi_interpret_error(CommandList_struct *cp)
{
	ErrorInfo_struct *ei;

	ei = cp->err_info; 
	switch(ei->CommandStatus)
	{
		case CMD_TARGET_STATUS:
			printk(KERN_WARNING "cciss: cmd %p has "
				"completed with errors\n", cp);
			printk(KERN_WARNING "cciss: cmd %p "
				"has SCSI Status = %x\n",
					cp,  
					ei->ScsiStatus);
			if (ei->ScsiStatus == 0)
				printk(KERN_WARNING 
				"cciss:SCSI status is abnormally zero.  "
				"(probably indicates selection timeout "
				"reported incorrectly due to a known "
				"firmware bug, circa July, 2001.)\n");
		break;
		case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
			printk("UNDERRUN\n");
		break;
		case CMD_DATA_OVERRUN:
			printk(KERN_WARNING "cciss: cp %p has"
				" completed with data overrun "
				"reported\n", cp);
		break;
		case CMD_INVALID: {
			/* controller unfortunately reports SCSI passthru's */
			/* to non-existent targets as invalid commands. */
			printk(KERN_WARNING "cciss: cp %p is "
				"reported invalid (probably means "
				"target device no longer present)\n", 
				cp); 
			/* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0);
			print_cmd(cp);  */
			}
		break;
		case CMD_PROTOCOL_ERR:
			printk(KERN_WARNING "cciss: cp %p has "
				"protocol error \n", cp);
		break;
		case CMD_HARDWARE_ERR:
			/* cmd->result = DID_ERROR << 16; */
			printk(KERN_WARNING "cciss: cp %p had " 
				" hardware error\n", cp);
		break;
		case CMD_CONNECTION_LOST:
			printk(KERN_WARNING "cciss: cp %p had "
				"connection lost\n", cp);
		break;
		case CMD_ABORTED:
			printk(KERN_WARNING "cciss: cp %p was "
				"aborted\n", cp);
		break;
		case CMD_ABORT_FAILED:
			printk(KERN_WARNING "cciss: cp %p reports "
				"abort failed\n", cp);
		break;
		case CMD_UNSOLICITED_ABORT:
			printk(KERN_WARNING "cciss: cp %p aborted "
				"do to an unsolicited abort\n", cp);
		break;
		case CMD_TIMEOUT:
			printk(KERN_WARNING "cciss: cp %p timedout\n",
				cp);
		break;
		default:
			printk(KERN_WARNING "cciss: cp %p returned "
				"unknown status %x\n", cp, 
					ei->CommandStatus); 
	}
}

static int
cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, 
	unsigned char page, unsigned char *buf,
	unsigned char bufsize)
{
	int rc;
	CommandList_struct *cp;
	char cdb[6];
	ErrorInfo_struct *ei;
	unsigned long flags;

	spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
	cp = scsi_cmd_alloc(c);
	spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);

	if (cp == NULL) {			/* trouble... */
		printk("cmd_alloc returned NULL!\n");
		return -1;
	}

	ei = cp->err_info; 

	cdb[0] = CISS_INQUIRY;
	cdb[1] = (page != 0);
	cdb[2] = page;
	cdb[3] = 0;
	cdb[4] = bufsize;
	cdb[5] = 0;
	rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb, 
				6, buf, bufsize, XFER_READ);

	if (rc != 0) return rc; /* something went wrong */

	if (ei->CommandStatus != 0 && 
	    ei->CommandStatus != CMD_DATA_UNDERRUN) {
		cciss_scsi_interpret_error(cp);
		rc = -1;
	}
	spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
	scsi_cmd_free(c, cp);
	spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
	return rc;	
}

/* Get the device id from inquiry page 0x83 */
static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr,
	unsigned char *device_id, int buflen)
{
	int rc;
	unsigned char *buf;

	if (buflen > 16)
		buflen = 16;
	buf = kzalloc(64, GFP_KERNEL);
	if (!buf)
		return -1;
	rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64);
	if (rc == 0)
		memcpy(device_id, &buf[8], buflen);
	kfree(buf);
	return rc != 0;
}

static int
cciss_scsi_do_report_phys_luns(ctlr_info_t *c, 
		ReportLunData_struct *buf, int bufsize)
{
	int rc;
	CommandList_struct *cp;
	unsigned char cdb[12];
	unsigned char scsi3addr[8]; 
	ErrorInfo_struct *ei;
	unsigned long flags;

	spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
	cp = scsi_cmd_alloc(c);
	spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
	if (cp == NULL) {			/* trouble... */
		printk("cmd_alloc returned NULL!\n");
		return -1;
	}

	memset(&scsi3addr[0], 0, 8); /* address the controller */
	cdb[0] = CISS_REPORT_PHYS;
	cdb[1] = 0;
	cdb[2] = 0;
	cdb[3] = 0;
	cdb[4] = 0;
	cdb[5] = 0;
	cdb[6] = (bufsize >> 24) & 0xFF;  //MSB
	cdb[7] = (bufsize >> 16) & 0xFF;
	cdb[8] = (bufsize >> 8) & 0xFF;
	cdb[9] = bufsize & 0xFF;
	cdb[10] = 0;
	cdb[11] = 0;

	rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, 
				cdb, 12, 
				(unsigned char *) buf, 
				bufsize, XFER_READ);

	if (rc != 0) return rc; /* something went wrong */

	ei = cp->err_info; 
	if (ei->CommandStatus != 0 && 
	    ei->CommandStatus != CMD_DATA_UNDERRUN) {
		cciss_scsi_interpret_error(cp);
		rc = -1;
	}
	spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
	scsi_cmd_free(c, cp);
	spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
	return rc;	
}

static void
cciss_update_non_disk_devices(int cntl_num, int hostno)
{
	/* the idea here is we could get notified from /proc
	   that some devices have changed, so we do a report 
	   physical luns cmd, and adjust our list of devices 
	   accordingly.  (We can't rely on the scsi-mid layer just
	   doing inquiries, because the "busses" that the scsi 
	   mid-layer probes are totally fabricated by this driver,
	   so new devices wouldn't show up.

	   the scsi3addr's of devices won't change so long as the 
	   adapter is not reset.  That means we can rescan and 
	   tell which devices we already know about, vs. new 
	   devices, vs.  disappearing devices.

	   Also, if you yank out a tape drive, then put in a disk
	   in it's place, (say, a configured volume from another 
	   array controller for instance)  _don't_ poke this driver 
           (so it thinks it's still a tape, but _do_ poke the scsi 
           mid layer, so it does an inquiry... the scsi mid layer 
           will see the physical disk.  This would be bad.  Need to
	   think about how to prevent that.  One idea would be to 
	   snoop all scsi responses and if an inquiry repsonse comes
	   back that reports a disk, chuck it an return selection
	   timeout instead and adjust our table...  Not sure i like
	   that though.  

	 */
#define OBDR_TAPE_INQ_SIZE 49
#define OBDR_TAPE_SIG "$DR-10"
	ReportLunData_struct *ld_buff;
	unsigned char *inq_buff;
	unsigned char scsi3addr[8];
	ctlr_info_t *c;
	__u32 num_luns=0;
	unsigned char *ch;
	struct cciss_scsi_dev_t *currentsd, *this_device;
	int ncurrent=0;
	int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
	int i;

	c = (ctlr_info_t *) hba[cntl_num];	
	ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
	inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
	currentsd = kzalloc(sizeof(*currentsd) *
			(CCISS_MAX_SCSI_DEVS_PER_HBA+1), GFP_KERNEL);
	if (ld_buff == NULL || inq_buff == NULL || currentsd == NULL) {
		printk(KERN_ERR "cciss: out of memory\n");
		goto out;
	}
	this_device = &currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
	if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) {
		ch = &ld_buff->LUNListLength[0];
		num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8;
		if (num_luns > CISS_MAX_PHYS_LUN) {
			printk(KERN_WARNING 
				"cciss: Maximum physical LUNs (%d) exceeded.  "
				"%d LUNs ignored.\n", CISS_MAX_PHYS_LUN, 
				num_luns - CISS_MAX_PHYS_LUN);
			num_luns = CISS_MAX_PHYS_LUN;
		}
	}
	else {
		printk(KERN_ERR  "cciss: Report physical LUNs failed.\n");
		goto out;
	}


	/* adjust our table of devices */	
	for (i = 0; i < num_luns; i++) {
		/* for each physical lun, do an inquiry */
		if (ld_buff->LUN[i][3] & 0xC0) continue;
		memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
		memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);

		if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff,
			(unsigned char) OBDR_TAPE_INQ_SIZE) != 0)
			/* Inquiry failed (msg printed already) */
			continue; /* so we will skip this device. */

		this_device->devtype = (inq_buff[0] & 0x1f);
		this_device->bus = -1;
		this_device->target = -1;
		this_device->lun = -1;
		memcpy(this_device->scsi3addr, scsi3addr, 8);
		memcpy(this_device->vendor, &inq_buff[8],
			sizeof(this_device->vendor));
		memcpy(this_device->model, &inq_buff[16],
			sizeof(this_device->model));
		memcpy(this_device->revision, &inq_buff[32],
			sizeof(this_device->revision));
		memset(this_device->device_id, 0,
			sizeof(this_device->device_id));
		cciss_scsi_get_device_id(hba[cntl_num], scsi3addr,
			this_device->device_id, sizeof(this_device->device_id));

		switch (this_device->devtype)
		{
		  case 0x05: /* CD-ROM */ {

			/* We don't *really* support actual CD-ROM devices,
			 * just this "One Button Disaster Recovery" tape drive
			 * which temporarily pretends to be a CD-ROM drive.
			 * So we check that the device is really an OBDR tape
			 * device by checking for "$DR-10" in bytes 43-48 of
			 * the inquiry data.
			 */
				char obdr_sig[7];

				strncpy(obdr_sig, &inq_buff[43], 6);
				obdr_sig[6] = '\0';
				if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
					/* Not OBDR device, ignore it. */
					break;
			}
			/* fall through . . . */
		  case 0x01: /* sequential access, (tape) */
		  case 0x08: /* medium changer */
			if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
				printk(KERN_INFO "cciss%d: %s ignored, "
					"too many devices.\n", cntl_num,
					scsi_device_type(this_device->devtype));
				break;
			}
			currentsd[ncurrent] = *this_device;
			ncurrent++;
			break;
		  default: 
			break;
		}
	}

	adjust_cciss_scsi_table(cntl_num, hostno, currentsd, ncurrent);
out:
	kfree(inq_buff);
	kfree(ld_buff);
	kfree(currentsd);
	return;
}

static int
is_keyword(char *ptr, int len, char *verb)  // Thanks to ncr53c8xx.c
{
	int verb_len = strlen(verb);
	if (len >= verb_len && !memcmp(verb,ptr,verb_len))
		return verb_len;
	else
		return 0;
}

static int
cciss_scsi_user_command(int ctlr, int hostno, char *buffer, int length)
{
	int arg_len;

	if ((arg_len = is_keyword(buffer, length, "rescan")) != 0)
		cciss_update_non_disk_devices(ctlr, hostno);
	else
		return -EINVAL;
	return length;
}


static int
cciss_scsi_proc_info(struct Scsi_Host *sh,
		char *buffer, /* data buffer */
		char **start, 	   /* where data in buffer starts */
		off_t offset,	   /* offset from start of imaginary file */
		int length, 	   /* length of data in buffer */
		int func)	   /* 0 == read, 1 == write */
{

	int buflen, datalen;
	ctlr_info_t *ci;
	int i;
	int cntl_num;


	ci = (ctlr_info_t *) sh->hostdata[0];
	if (ci == NULL)  /* This really shouldn't ever happen. */
		return -EINVAL;

	cntl_num = ci->ctlr;	/* Get our index into the hba[] array */

	if (func == 0) {	/* User is reading from /proc/scsi/ciss*?/?*  */
		buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n",
				cntl_num, sh->host_no);

		/* this information is needed by apps to know which cciss
		   device corresponds to which scsi host number without
		   having to open a scsi target device node.  The device
		   information is not a duplicate of /proc/scsi/scsi because
		   the two may be out of sync due to scsi hotplug, rather
		   this info is for an app to be able to use to know how to
		   get them back in sync. */

		for (i=0;i<ccissscsi[cntl_num].ndevices;i++) {
			struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i];
			buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d "
				"0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
				sh->host_no, sd->bus, sd->target, sd->lun,
				sd->devtype,
				sd->scsi3addr[0], sd->scsi3addr[1],
				sd->scsi3addr[2], sd->scsi3addr[3],
				sd->scsi3addr[4], sd->scsi3addr[5],
				sd->scsi3addr[6], sd->scsi3addr[7]);
		}
		datalen = buflen - offset;
		if (datalen < 0) { 	/* they're reading past EOF. */
			datalen = 0;
			*start = buffer+buflen;	
		} else
			*start = buffer + offset;
		return(datalen);
	} else 	/* User is writing to /proc/scsi/cciss*?/?*  ... */
		return cciss_scsi_user_command(cntl_num, sh->host_no,
			buffer, length);	
} 

/* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci 
   dma mapping  and fills in the scatter gather entries of the 
   cciss command, cp. */

static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp,
	struct scsi_cmnd *cmd)
{
	unsigned int len;
	struct scatterlist *sg;
	__u64 addr64;
	int request_nsgs, i, chained, sg_index;
	struct cciss_scsi_adapter_data_t *sa = h->scsi_ctlr;
	SGDescriptor_struct *curr_sg;

	BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);

	chained = 0;
	sg_index = 0;
	curr_sg = cp->SG;
	request_nsgs = scsi_dma_map(cmd);
	if (request_nsgs) {
		scsi_for_each_sg(cmd, sg, request_nsgs, i) {
			if (sg_index + 1 == h->max_cmd_sgentries &&
				!chained && request_nsgs - i > 1) {
				chained = 1;
				sg_index = 0;
				curr_sg = sa->cmd_sg_list[cp->cmdindex];
			}
			addr64 = (__u64) sg_dma_address(sg);
			len  = sg_dma_len(sg);
			curr_sg[sg_index].Addr.lower =
				(__u32) (addr64 & 0x0FFFFFFFFULL);
			curr_sg[sg_index].Addr.upper =
				(__u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
			curr_sg[sg_index].Len = len;
			curr_sg[sg_index].Ext = 0;
			++sg_index;
		}
		if (chained)
			cciss_map_sg_chain_block(h, cp,
				sa->cmd_sg_list[cp->cmdindex],
				(request_nsgs - (h->max_cmd_sgentries - 1)) *
					sizeof(SGDescriptor_struct));
	}
	/* track how many SG entries we are using */
	if (request_nsgs > h->maxSG)
		h->maxSG = request_nsgs;
	cp->Header.SGTotal = (__u8) request_nsgs + chained;
	if (request_nsgs > h->max_cmd_sgentries)
		cp->Header.SGList = h->max_cmd_sgentries;
	else
		cp->Header.SGList = cp->Header.SGTotal;
	return;
}


static int
cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
{
	ctlr_info_t *c;
	int ctlr, rc;
	unsigned char scsi3addr[8];
	CommandList_struct *cp;
	unsigned long flags;

	// Get the ptr to our adapter structure (hba[i]) out of cmd->host.
	// We violate cmd->host privacy here.  (Is there another way?)
	c = (ctlr_info_t *) cmd->device->host->hostdata[0];
	ctlr = c->ctlr;

	rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id, 
			cmd->device->lun, scsi3addr);
	if (rc != 0) {
		/* the scsi nexus does not match any that we presented... */
		/* pretend to mid layer that we got selection timeout */
		cmd->result = DID_NO_CONNECT << 16;
		done(cmd);
		/* we might want to think about registering controller itself
		   as a processor device on the bus so sg binds to it. */
		return 0;
	}

	/* printk("cciss_queue_command, p=%p, cmd=0x%02x, c%db%dt%dl%d\n", 
		cmd, cmd->cmnd[0], ctlr, cmd->channel, cmd->target, cmd->lun);*/
	// printk("q:%p:c%db%dt%dl%d ", cmd, ctlr, cmd->channel, 
	//	cmd->target, cmd->lun);

	/* Ok, we have a reasonable scsi nexus, so send the cmd down, and
           see what the device thinks of it. */

	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
	cp = scsi_cmd_alloc(c);
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
	if (cp == NULL) {			/* trouble... */
		printk("scsi_cmd_alloc returned NULL!\n");
		/* FIXME: next 3 lines are -> BAD! <- */
		cmd->result = DID_NO_CONNECT << 16;
		done(cmd);
		return 0;
	}

	// Fill in the command list header

	cmd->scsi_done = done;    // save this for use by completion code 

	// save cp in case we have to abort it 
	cmd->host_scribble = (unsigned char *) cp; 

	cp->cmd_type = CMD_SCSI;
	cp->scsi_cmd = cmd;
	cp->Header.ReplyQueue = 0;  // unused in simple mode
	memcpy(&cp->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
	cp->Header.Tag.lower = cp->busaddr;  // Use k. address of cmd as tag
	
	// Fill in the request block...

	cp->Request.Timeout = 0;
	memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
	BUG_ON(cmd->cmd_len > sizeof(cp->Request.CDB));
	cp->Request.CDBLen = cmd->cmd_len;
	memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len);
	cp->Request.Type.Type = TYPE_CMD;
	cp->Request.Type.Attribute = ATTR_SIMPLE;
	switch(cmd->sc_data_direction)
	{
	  case DMA_TO_DEVICE: cp->Request.Type.Direction = XFER_WRITE; break;
	  case DMA_FROM_DEVICE: cp->Request.Type.Direction = XFER_READ; break;
	  case DMA_NONE: cp->Request.Type.Direction = XFER_NONE; break;
	  case DMA_BIDIRECTIONAL:
		// This can happen if a buggy application does a scsi passthru
		// and sets both inlen and outlen to non-zero. ( see
		// ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() )

	  	cp->Request.Type.Direction = XFER_RSVD;
		// This is technically wrong, and cciss controllers should
		// reject it with CMD_INVALID, which is the most correct 
		// response, but non-fibre backends appear to let it 
		// slide by, and give the same results as if this field
		// were set correctly.  Either way is acceptable for
		// our purposes here.

		break;

	  default: 
		printk("cciss: unknown data direction: %d\n", 
			cmd->sc_data_direction);
		BUG();
		break;
	}
	cciss_scatter_gather(c, cp, cmd);

	/* Put the request on the tail of the request queue */

	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
	addQ(&c->reqQ, cp);
	c->Qdepth++;
	start_io(c);
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);

	/* the cmd'll come back via intr handler in complete_scsi_command()  */
	return 0;
}

static void 
cciss_unregister_scsi(int ctlr)
{
	struct cciss_scsi_adapter_data_t *sa;
	struct cciss_scsi_cmd_stack_t *stk;
	unsigned long flags;

	/* we are being forcibly unloaded, and may not refuse. */

	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
	sa = hba[ctlr]->scsi_ctlr;
	stk = &sa->cmd_stack; 

	/* if we weren't ever actually registered, don't unregister */ 
	if (sa->registered) {
		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
		scsi_remove_host(sa->scsi_host);
		scsi_host_put(sa->scsi_host);
		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
	}

	/* set scsi_host to NULL so our detect routine will 
	   find us on register */
	sa->scsi_host = NULL;
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
	scsi_cmd_stack_free(ctlr);
	kfree(sa);
}

static int 
cciss_engage_scsi(int ctlr)
{
	struct cciss_scsi_adapter_data_t *sa;
	struct cciss_scsi_cmd_stack_t *stk;
	unsigned long flags;

	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
	sa = hba[ctlr]->scsi_ctlr;
	stk = &sa->cmd_stack; 

	if (sa->registered) {
		printk("cciss%d: SCSI subsystem already engaged.\n", ctlr);
		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
		return -ENXIO;
	}
	sa->registered = 1;
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
	cciss_update_non_disk_devices(ctlr, -1);
	cciss_scsi_detect(ctlr);
	return 0;
}

static void
cciss_seq_tape_report(struct seq_file *seq, int ctlr)
{
	unsigned long flags;

	CPQ_TAPE_LOCK(ctlr, flags);
	seq_printf(seq,
		"Sequential access devices: %d\n\n",
			ccissscsi[ctlr].ndevices);
	CPQ_TAPE_UNLOCK(ctlr, flags);
}

static int wait_for_device_to_become_ready(ctlr_info_t *h,
	unsigned char lunaddr[])
{
	int rc;
	int count = 0;
	int waittime = HZ;
	CommandList_struct *c;

	c = cmd_alloc(h, 1);
	if (!c) {
		printk(KERN_WARNING "cciss%d: out of memory in "
			"wait_for_device_to_become_ready.\n", h->ctlr);
		return IO_ERROR;
	}

	/* Send test unit ready until device ready, or give up. */
	while (count < 20) {

		/* Wait for a bit.  do this first, because if we send
		 * the TUR right away, the reset will just abort it.
		 */
		schedule_timeout_uninterruptible(waittime);
		count++;

		/* Increase wait time with each try, up to a point. */
		if (waittime < (HZ * 30))
			waittime = waittime * 2;

		/* Send the Test Unit Ready */
		rc = fill_cmd(c, TEST_UNIT_READY, h->ctlr, NULL, 0, 0,
			lunaddr, TYPE_CMD);
		if (rc == 0)
			rc = sendcmd_withirq_core(h, c, 0);

		(void) process_sendcmd_error(h, c);

		if (rc != 0)
			goto retry_tur;

		if (c->err_info->CommandStatus == CMD_SUCCESS)
			break;

		if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
			c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION) {
			if (c->err_info->SenseInfo[2] == NO_SENSE)
				break;
			if (c->err_info->SenseInfo[2] == UNIT_ATTENTION) {
				unsigned char asc;
				asc = c->err_info->SenseInfo[12];
				check_for_unit_attention(h, c);
				if (asc == POWER_OR_RESET)
					break;
			}
		}
retry_tur:
		printk(KERN_WARNING "cciss%d: Waiting %d secs "
			"for device to become ready.\n",
			h->ctlr, waittime / HZ);
		rc = 1; /* device not ready. */
	}

	if (rc)
		printk("cciss%d: giving up on device.\n", h->ctlr);
	else
		printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr);

	cmd_free(h, c, 1);
	return rc;
}

/* Need at least one of these error handlers to keep ../scsi/hosts.c from 
 * complaining.  Doing a host- or bus-reset can't do anything good here. 
 * Despite what it might say in scsi_error.c, there may well be commands
 * on the controller, as the cciss driver registers twice, once as a block
 * device for the logical drives, and once as a scsi device, for any tape
 * drives.  So we know there are no commands out on the tape drives, but we
 * don't know there are no commands on the controller, and it is likely 
 * that there probably are, as the cciss block device is most commonly used
 * as a boot device (embedded controller on HP/Compaq systems.)
*/

static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
{
	int rc;
	CommandList_struct *cmd_in_trouble;
	unsigned char lunaddr[8];
	ctlr_info_t *c;
	int ctlr;

	/* find the controller to which the command to be aborted was sent */
	c = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
	if (c == NULL) /* paranoia */
		return FAILED;
	ctlr = c->ctlr;
	printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr);
	/* find the command that's giving us trouble */
	cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
	if (cmd_in_trouble == NULL) /* paranoia */
		return FAILED;
	memcpy(lunaddr, &cmd_in_trouble->Header.LUN.LunAddrBytes[0], 8);
	/* send a reset to the SCSI LUN which the command was sent to */
	rc = sendcmd_withirq(CCISS_RESET_MSG, ctlr, NULL, 0, 0, lunaddr,
		TYPE_MSG);
	if (rc == 0 && wait_for_device_to_become_ready(c, lunaddr) == 0)
		return SUCCESS;
	printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr);
	return FAILED;
}

static int  cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
{
	int rc;
	CommandList_struct *cmd_to_abort;
	unsigned char lunaddr[8];
	ctlr_info_t *c;
	int ctlr;

	/* find the controller to which the command to be aborted was sent */
	c = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
	if (c == NULL) /* paranoia */
		return FAILED;
	ctlr = c->ctlr;
	printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr);

	/* find the command to be aborted */
	cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble;
	if (cmd_to_abort == NULL) /* paranoia */
		return FAILED;
	memcpy(lunaddr, &cmd_to_abort->Header.LUN.LunAddrBytes[0], 8);
	rc = sendcmd_withirq(CCISS_ABORT_MSG, ctlr, &cmd_to_abort->Header.Tag,
		0, 0, lunaddr, TYPE_MSG);
	if (rc == 0)
		return SUCCESS;
	return FAILED;

}

#else /* no CONFIG_CISS_SCSI_TAPE */

/* If no tape support, then these become defined out of existence */

#define cciss_scsi_setup(cntl_num)

#endif /* CONFIG_CISS_SCSI_TAPE */
