public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH] aacraid changes for 2.4.24 kernel to add support of AMD64 (part 2)
@ 2004-02-13 22:37 Salyzyn, Mark
  2004-02-13 23:04 ` Christoph Hellwig
  0 siblings, 1 reply; 4+ messages in thread
From: Salyzyn, Mark @ 2004-02-13 22:37 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-scsi

Comments embedded

-----Original Message-----
From: Christoph Hellwig [mailto:hch@infradead.org] 
Sent: Friday, February 13, 2004 4:59 PM
To: Salyzyn, Mark
Cc: linux-scsi
Subject: Re: [PATCH] aacraid changes for 2.4.24 kernel to add support of
AMD64 (part 2)

 struct fib_ioctl
 {
-	char	*fibctx;
-	int	wait;
-	char	*fib;
+	u32	fibctx;
+	s32	wait;
+#if (defined(__x86_64__))
+	u64	fib;
+#else
+	u32	fib;
+#endif

	This is broken.   If you really mean what you wrote just use
	unsigned long, but if you want this API to actually work as
	expected use the same value on all architectures.

[MGS] The ioctl that utilizes this structure detects if the caller is a
32 bit or a 64 bit application under the AMD64 environment, and tunes
itself to the size of the fib element as necessary. I opted to use the
redefinition of this structure as a means to simplify the split
personality code that utilizes this structure.

In a 32 bit environment, there is no need to detect if the caller is a
32 bit or a 64 bit application, so the smaller fib element is all that
is needed.

+	if (!dev || !dev->scsi_host_ptr) {
+		return;
+	}
+	for (device = dev->scsi_host_ptr->host_queue;
+	  device != (Scsi_Device *)NULL;
+	  device = device->next)
+	{
+		dprintk((KERN_INFO "aifd: device (%d,%d,%d,%d)?\n",
+		  dev->scsi_host_ptr->host_no,
+		  device->channel,
+		  device->id,
+		  device->lun));
+		if ((device->channel == CONTAINER_TO_CHANNEL(container))
+		 && (device->id == CONTAINER_TO_ID(container))
+		 && (device->lun == CONTAINER_TO_LUN(container))) {
+			busy |= device->access_count ||
dev->scsi_host_ptr->in_recovery;
+			if (busy == 0) {
+				device->removable = TRUE;
+			}
+		}
+	}

	This gives you nice races again.

[MGS] Without any test of busy status at all, we run the *high* risk of
a panic resulting from a stack overflow. This code is here because of a
broken error recovery in the scsi layer resulting in infinite recursion
under some sensitive activities.

Fix the scsi layer, and this code can go away.

+		dprintk((KERN_INFO "proc_scsi=%p ", proc_scsi));
+		for (entry = proc_scsi->subdir;
+		  entry != (struct proc_dir_entry *)NULL;
+		  entry = entry->next) {
+			dprintk(("\"%.*s\"[%d]=%x ", entry->namelen,
+			  entry->name, entry->namelen, entry->low_ino));
+			if ((entry->low_ino != 0)
+			 && (entry->namelen == 4)
+			 && (memcmp ("scsi", entry->name, 4) == 0)) {
+				dprintk(("%p->write_proc=%p ", entry,
entry->write_proc));
+				if (entry->write_proc != (int (*)(struct
file *, const char *, unsigned long, void *))NULL) {
+					char buffer[80];
+					int length;
+					mm_segment_t fs;
+
+					sprintf (buffer,
+					  "scsi %s-single-device %d %d
%d %d\n",
+					  ((DeviceConfigNeeded ==
DELETE)
+					   ? "remove"
+					   : "add"),
+					  dev->scsi_host_ptr->host_no,
+
CONTAINER_TO_CHANNEL(container),
+					  CONTAINER_TO_ID(container),
+					  CONTAINER_TO_LUN(container));
+					length = strlen (buffer);
+					dprintk((KERN_INFO
+					  "echo %.*s >
/proc/scsi/scsi\n",
+					  length-1,
+					  buffer));
+//printk("echo %.*s > /proc/scsi/scsi\n", length-1, buffer);
+					fs = get_fs();
+					set_fs(get_ds());
+					length = entry->write_proc(
+					  NULL, buffer, length, NULL);
+					set_fs(fs);
+					dprintk((KERN_INFO
+					  "returns %d\n", length));

	Stop it.  The code is bogus that I wonder how you even dare to
post it.

[MGS] Ok, tell me how to rescan for a device? The RAID drivers cause
asynchronous device changes that need to be reported to the scsi layer.
The scan_scsis call is hidden, so we *must* use the proc write to get to
it.

The code may be bogus, but it works. If you have a means to rescan
devices in the current 2.4 scsi layer, I will take that as a valid
alternative. Otherwise Adaptec customers will need to reboot their
machine every time something significant happens with the array.

+#if (defined(__x86_64__))
+# include <asm-x86_64/ioctl32.h>
+  /* Cast the function, since sys_ioctl does not match */
+# define aac_ioctl32(x,y) register_ioctl32_conversion((x), \
+    (int(*)(unsigned int,unsigned int,unsigned long,struct file*))(y))
+# include <asm/uaccess.h>
+#endif

	So why do the other drivers not need this?

[MGS] Not sure what you mean about other drivers? I have a series of
warning messages without the cast.

Or do you mean the arrangements for register_ioctl32_conversion? Because
other drivers do not have 32 bit applications calling a 64 bit ioctl for
RAID management functions. The current structure of the x86_64 port in
the 2.4 tree is to block 32 bit applications from calling the ioctl
without these arrangements.

 

^ permalink raw reply	[flat|nested] 4+ messages in thread
* [PATCH] aacraid changes for 2.4.24 kernel to add support of AMD64 (part 2)
@ 2004-02-13 21:16 Salyzyn, Mark
  2004-02-13 21:58 ` Christoph Hellwig
  0 siblings, 1 reply; 4+ messages in thread
From: Salyzyn, Mark @ 2004-02-13 21:16 UTC (permalink / raw)
  To: linux-scsi

[-- Attachment #1: Type: text/plain, Size: 554 bytes --]

This is part 2 to the following referenced patch.

Sincerely -- Mark Salyzyn

-----Original Message-----
From: Salyzyn, Mark 
Sent: Friday, February 13, 2004 4:16 PM
To: 'linux-scsi'
Subject: [PATCH] aacraid changes for 2.4.24 kernel to add support of
AMD64 (part 1)

This first part of two forms a `big' patch to the aacraid driver adds
support for the AMD64 systems.

There is some side effect of this patch associated with bug fixes and
clean up that became apparent as a result of the 64 bit adjustments.

Sincerely -- Mark Salyzyn

[-- Attachment #2: aac_x86_64.patch.pt2 --]
[-- Type: application/octet-stream, Size: 48903 bytes --]

@@ -649,6 +657,7 @@
 struct aac_fib_context {
 	s16	 		type;		// used for verification of structure	
 	s16	 		size;
+	u32			unique;		// unique value representing this context
 	ulong			jiffies;	// used for cleanup - dmb changed to ulong
 	struct list_head	next;		// used to link context's into a linked list
 	struct semaphore 	wait_sem;	// this is used to wait for the next fib to arrive.
@@ -664,7 +673,7 @@
 	u8		ro[MAXIMUM_NUM_CONTAINERS];
 	u8		locked[MAXIMUM_NUM_CONTAINERS];
 	u8		deleted[MAXIMUM_NUM_CONTAINERS];
-	s32		devno[MAXIMUM_NUM_CONTAINERS];
+	char		devname[MAXIMUM_NUM_CONTAINERS][8];
 };
 
 struct fib {
@@ -836,11 +845,14 @@
 	u32			aif_thread;
 	struct completion	aif_completion;
 	struct aac_adapter_info adapter_info;
+	u32			DeviceContainerID;
+	u32			DeviceConfigWaitingOn;
+	int			DeviceConfigNeeded;
 	/* These are in adapter info but they are in the io flow so
 	 * lets break them out so we don't have to do an AND to check them
 	 */
 	u8			nondasd_support; 
-	u8			pae_support;
+	u8			dac_support;
 	u8			raid_scsi_mode;
 };
 
@@ -1054,7 +1066,7 @@
 {
 	u32		function;
 	u32		channel;
-	u32		target;
+	u32		id;
 	u32		lun;
 	u32		timeout;
 	u32		flags;
@@ -1255,6 +1267,19 @@
 	u8		data[16];
 };
 
+/**
+ * 	Convert capacity to cylinders
+ *  	accounting for the fact capacity could be a 64 bit value
+ *
+ */
+typedef unsigned long sector_t;
+
+static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
+{
+	capacity /= divisor;
+	return (u32)capacity;
+}
+
 /*
  * The following command is sent to shut down each container.
  */
@@ -1268,7 +1293,7 @@
 {
 	s32	cnum;
 	s32	bus;
-	s32	target;
+	s32	id;
 	s32	lun;
 	u32	valid;
 	u32	locked;
@@ -1285,9 +1310,13 @@
 
 struct fib_ioctl
 {
-	char	*fibctx;
-	int	wait;
-	char	*fib;
+	u32	fibctx;
+	s32	wait;
+#if (defined(__x86_64__))
+	u64	fib;
+#else
+	u32	fib;
+#endif
 };
 
 struct revision
@@ -1327,6 +1356,7 @@
 #define FSACTL_MINIPORT_REV_CHECK               CTL_CODE(2107, METHOD_BUFFERED)
 #define FSACTL_GET_PCI_INFO               	CTL_CODE(2119, METHOD_BUFFERED)
 #define FSACTL_FORCE_DELETE_DISK		CTL_CODE(2120, METHOD_NEITHER)
+#define FSACTL_REGISTER_FIB_SEND		CTL_CODE(2136, METHOD_BUFFERED)
 
 
 struct aac_common
@@ -1424,8 +1454,14 @@
  */
  
 #define 	AifCmdEventNotify	1	/* Notify of event */
+#define		AifEnConfigChange	3	/* Adapter configuration change */
 #define		AifEnContainerChange	4	/* Container configuration change */
+#define		AifEnDeviceFailure	5	/* SCSI device failed */
+#define		AifEnAddContainer	15	/* A new array was created. */
+#define		AifEnDeleteContainer	16	/* A container was deleted. */
 #define		AifCmdJobProgress	2	/* Progress report */
+#define		AifJobCtrZero		101	/* Array Zero progress */
+#define		AifJobStsSuccess	1	/* Job completes successfully */
 #define		AifCmdAPIReport		3	/* Report from other user of API */
 #define		AifCmdDriverNotify	4	/* Notify host driver of event */
 #define		AifDenMorphComplete	200	/* A morph operation completed */
@@ -1462,7 +1498,8 @@
 void fib_init(struct fib * context);
 void fib_dealloc(struct fib * context);
 void aac_printf(struct aac_dev *dev, u32 val);
-int fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
+#define aac_fib_send fib_send
+int aac_fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
 int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry);
 int aac_consumer_avail(struct aac_dev * dev, struct aac_queue * q);
 void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
diff -u -P --recursive linux-2.4.24/drivers/scsi/aacraid/commctrl.c linux-2.4.24-2322/drivers/scsi/aacraid/commctrl.c
--- linux-2.4.24/drivers/scsi/aacraid/commctrl.c	Mon Oct 20 10:43:26 2003
+++ linux-2.4.24-2322/drivers/scsi/aacraid/commctrl.c	Fri Feb 13 11:48:51 2004
@@ -37,7 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 #include "scsi.h"
@@ -60,8 +60,9 @@
 	struct fib *fibptr;
 
 	fibptr = fib_alloc(dev);
-	if(fibptr == NULL)
+	if(fibptr == NULL) {
 		return -ENOMEM;
+	}
 		
 	kfib = fibptr->hw_fib;
 	/*
@@ -94,11 +95,12 @@
 		 */
 		kfib->header.XferState = 0;
 	} else {
-		if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal,
-			1, 1, NULL, NULL) != 0) 
-		{
+		int retval = fib_send(kfib->header.Command, fibptr,
+				le32_to_cpu(kfib->header.Size) , FsaNormal,
+				1, 1, NULL, NULL);
+		if (retval != 0) {
 			fib_free(fibptr);
-			return -EINVAL;
+			return retval;
 		}
 		if (fib_complete(fibptr) != 0) {
 			fib_free(fibptr);
@@ -132,15 +134,25 @@
 {
 	struct aac_fib_context * fibctx;
 	int status;
-	unsigned long flags;
 
 	fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
 	if (fibctx == NULL) {
 		status = -ENOMEM;
 	} else {
+		unsigned long flags;
+		struct list_head * entry;
+		struct aac_fib_context * context;
+
 		fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
 		fibctx->size = sizeof(struct aac_fib_context);
 		/*
+		 *	Yes yes, I know this could be an index, but we have a
+		 * better guarantee of uniqueness for the locked loop below.
+		 * Without the aid of a persistent history, this also helps
+		 * reduce the chance that the opaque context would be reused.
+		 */
+		fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF);
+		/*
 		 *	Initialize the mutex used to wait for the next AIF.
 		 */
 		init_MUTEX_LOCKED(&fibctx->wait_sem);
@@ -157,9 +169,21 @@
 		 *	AdapterFibContext list.
 		 */
 		spin_lock_irqsave(&dev->fib_lock, flags);
+		/* Ensure that we have a unique identifier */
+		entry = dev->fib_list.next;
+		while(entry != &dev->fib_list) {
+			context = list_entry(entry, struct aac_fib_context, next);
+			if (context->unique == fibctx->unique) {
+				/* Not unique (32 bits) */
+				fibctx->unique++;
+				entry = dev->fib_list.next;
+			} else {
+				entry = entry->next;
+			}
+		}
 		list_add_tail(&fibctx->next, &dev->fib_list);
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		if (copy_to_user(arg,  &fibctx, sizeof(struct aac_fib_context *))) {
+		if (copy_to_user(arg,  &fibctx->unique, sizeof(fibctx->unique))) {
 			status = -EFAULT;
 		} else {
 			status = 0;
@@ -180,19 +204,14 @@
 static int next_getadapter_fib(struct aac_dev * dev, void *arg)
 {
 	struct fib_ioctl f;
-	struct aac_fib_context *fibctx, *aifcp;
+	struct aac_fib_context *fibctx;
 	struct fib * fib;
 	int status;
 	struct list_head * entry;
-	int found;
 	unsigned long flags;
 	
 	if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
 		return -EFAULT;
-	/*
-	 *	Extract the AdapterFibContext from the Input parameters.
-	 */
-	fibctx = (struct aac_fib_context *) f.fibctx;
 
 	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
@@ -200,18 +219,21 @@
 	 *	Search the list of AdapterFibContext addresses on the adapter
 	 *	to be sure this is a valid address
 	 */
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
 	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the AdapterFibContext from the Input parameters.
+		 */
+		if(fibctx->unique == f.fibctx) {   /* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
-	if (found == 0) {
+	if (!fibctx) {
 		dprintk ((KERN_INFO "Fib not found\n"));
 		return -EINVAL;
 	}
@@ -239,7 +261,7 @@
 		fib = list_entry(entry, struct fib, fiblink);
 		fibctx->count--;
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) {
+		if (copy_to_user((char *)(unsigned long)f.fib, fib->hw_fib, sizeof(struct hw_fib))) {
 			kfree(fib->hw_fib);
 			kfree(fib);
 			return -EFAULT;
@@ -315,16 +337,10 @@
  
 static int close_getadapter_fib(struct aac_dev * dev, void *arg)
 {
-	struct aac_fib_context *fibctx, *aifcp;
+	struct aac_fib_context *fibctx;
 	int status;
 	unsigned long flags;
 	struct list_head * entry;
-	int found;
-
-	/*
-	 *	Extract the fibctx from the input parameters
-	 */
-	fibctx = arg;
 
 	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
@@ -333,19 +349,22 @@
 	 *	to be sure this is a valid address
 	 */
 
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
 	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the fibctx from the input parameters
+		 */
+		if(fibctx->unique == (u32)(unsigned long)arg) {   /* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
 
-	if(found == 0)
+	if(!fibctx)
 		return 0; /* Already gone */
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
@@ -363,16 +382,22 @@
  *	@arg: ioctl arguments
  *
  *	This routine returns the driver version.
- *      Under Linux, there have been no version incompatibilities, so this is simple!
+ *      Under Linux, there have been no version incompatibilities, so
+ *	this is simple!
  */
 
 static int check_revision(struct aac_dev *dev, void *arg)
 {
 	struct revision response;
+	extern unsigned long aac_driver_version;
 
 	response.compat = 1;
-	response.version = AAC_DRIVER_VERSION;
-	response.build = 9999;
+	response.version = aac_driver_version;
+#	if (defined(AAC_DRIVER_BUILD))
+		response.build = AAC_DRIVER_BUILD;
+#	else
+		response.build = 9999;
+#	endif
 
 	if (copy_to_user(arg, &response, sizeof(response)))
 		return -EFAULT;
@@ -437,7 +462,7 @@
 	// Fix up srb for endian and force some values
 	srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);	// Force this
 	srbcmd->channel  = cpu_to_le32(srbcmd->channel);
-	srbcmd->target   = cpu_to_le32(srbcmd->target);
+	srbcmd->id       = cpu_to_le32(srbcmd->id);
 	srbcmd->lun      = cpu_to_le32(srbcmd->lun);
 	srbcmd->flags    = cpu_to_le32(srbcmd->flags);
 	srbcmd->timeout  = cpu_to_le32(srbcmd->timeout);
@@ -458,12 +483,14 @@
 		data_dir = SCSI_DATA_NONE;
 	}
 	
-	if( dev->pae_support ==1 ) {
+	if( dev->dac_support ==1 ) {
 		struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
 		byte_count = 0;
 
 		// This should also catch if user used the 32 bit sgmap
-		actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64));
+		actual_fibsize = sizeof (struct aac_srb) -
+			sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) *
+				sizeof (struct sgentry64));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
 			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
 			rcode = -EINVAL;
@@ -602,10 +629,10 @@
 	pci_info.bus = dev->pdev->bus->number;
 	pci_info.slot = PCI_SLOT(dev->pdev->devfn);
 
-       if(copy_to_user( arg, (void*)&pci_info, sizeof(struct aac_pci_info)))
+        if(copy_to_user( arg, (void*)&pci_info, sizeof(struct aac_pci_info)))
                return -EFAULT;
         return 0;
- }
+}
  
 
 int aac_do_ioctl(struct aac_dev * dev, int cmd, void *arg)
@@ -617,8 +644,9 @@
 	 */
 	 
 	status = aac_dev_ioctl(dev, cmd, arg);
-	if(status != -ENOTTY)
+	if(status != -ENOTTY) {
 		return status;
+	}
 
 	switch (cmd) {
 	case FSACTL_MINIPORT_REV_CHECK:
diff -u -P --recursive linux-2.4.24/drivers/scsi/aacraid/commsup.c linux-2.4.24-2322/drivers/scsi/aacraid/commsup.c
--- linux-2.4.24/drivers/scsi/aacraid/commsup.c	Fri Feb 13 11:31:25 2004
+++ linux-2.4.24-2322/drivers/scsi/aacraid/commsup.c	Fri Feb 13 12:14:24 2004
@@ -311,10 +311,7 @@
 {
 	struct aac_entry * entry = NULL;
 	int map = 0;
-	struct aac_queue * q = &dev->queues->queue[qid];
-		
-	spin_lock_irqsave(q->lock, q->SavedIrql);
-	    
+
 	if (qid == AdapHighCmdQueue || qid == AdapNormCmdQueue) 
 	{
 		/*  if no entries wait for some if caller wants to */
@@ -352,42 +349,6 @@
 	return 0;
 }
 
-
-/**
- *	aac_insert_entry	-	insert a queue entry
- *	@dev: Adapter
- *	@index: Index of entry to insert
- *	@qid: Queue number
- *	@nonotify: Suppress adapter notification
- *
- *	Gets the next free QE off the requested priorty adapter command
- *	queue and associates the Fib with the QE. The QE represented by
- *	index is ready to insert on the queue when this routine returns
- *	success.
- */
- 
-static int aac_insert_entry(struct aac_dev * dev, u32 index, u32 qid, unsigned long nonotify) 
-{
-	struct aac_queue * q = &dev->queues->queue[qid];
-
-	if(q == NULL)
-		BUG();
-	*(q->headers.producer) = cpu_to_le32(index + 1);
-	spin_unlock_irqrestore(q->lock, q->SavedIrql);
-
-	if (qid == AdapHighCmdQueue ||
-	    qid == AdapNormCmdQueue ||
-	    qid == AdapHighRespQueue ||
-	    qid == AdapNormRespQueue)
-	{
-		if (!nonotify)
-			aac_adapter_notify(dev, qid);
-	}
-	else
-		printk("Suprise insert!\n");
-	return 0;
-}
-
 /*
  *	Define the highest level of host to adapter communication routines. 
  *	These routines will support host to adapter FS commuication. These 
@@ -413,7 +374,9 @@
  *	response FIB is received from the adapter.
  */
  
-int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority, int wait, int reply, fib_callback callback, void * callback_data)
+int aac_fib_send(u16 command, struct fib * fibptr, unsigned long size,
+		int priority, int wait, int reply, fib_callback callback,
+		void * callback_data)
 {
 	u32 index;
 	u32 qid;
@@ -422,14 +385,15 @@
 	struct hw_fib * hw_fib = fibptr->hw_fib;
 	struct aac_queue * q;
 	unsigned long flags = 0;
+	unsigned long qflags;
 
-	if (!(le32_to_cpu(hw_fib->header.XferState) & HostOwned))
+	if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
 		return -EBUSY;
 	/*
 	 *	There are 5 cases with the wait and reponse requested flags. 
 	 *	The only invalid cases are if the caller requests to wait and
 	 *	does not request a response and if the caller does not want a
-	 *	response and the Fibis not allocated from pool. If a response
+	 *	response and the Fib is not allocated from pool. If a response
 	 *	is not requesed the Fib will just be deallocaed by the DPC
 	 *	routine when the response comes back from the adapter. No
 	 *	further processing will be done besides deleting the Fib. We 
@@ -486,12 +450,13 @@
 
 	if(wait)
 		spin_lock_irqsave(&fibptr->event_lock, flags);
-	if(aac_queue_get( dev, &index, qid, hw_fib, 1, fibptr, &nointr)<0)
-		return -EWOULDBLOCK;
+	spin_lock_irqsave(q->lock, qflags);
+	aac_queue_get( dev, &index, qid, hw_fib, 1, fibptr, &nointr);
+
 	dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
 	dprintk((KERN_DEBUG "Fib contents:.\n"));
-	dprintk((KERN_DEBUG "  Command =               %d.\n", hw_fib->header.Command));
-	dprintk((KERN_DEBUG "  XferState  =            %x.\n", hw_fib->header.XferState));
+	dprintk((KERN_DEBUG "  Command =               %d.\n", le32_to_cpu(hw_fib->header.Command)));
+	dprintk((KERN_DEBUG "  XferState  =            %x.\n", le32_to_cpu(hw_fib->header.XferState)));
 	dprintk((KERN_DEBUG "  hw_fib va being sent=%p\n",fibptr->hw_fib));
 	dprintk((KERN_DEBUG "  hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
 	dprintk((KERN_DEBUG "  fib being sent=%p\n",fibptr));
@@ -510,8 +475,10 @@
 	fibptr->done = 0;
 	fibptr->flags = 0;
 
-	if(aac_insert_entry(dev, index, qid, (nointr & aac_config.irq_mod)) < 0)
-		return -EWOULDBLOCK;
+	*(q->headers.producer) = cpu_to_le32(index + 1);
+	spin_unlock_irqrestore(q->lock, qflags);
+	if (!(nointr & aac_config.irq_mod))
+		aac_adapter_notify(dev, qid);
 	/*
 	 *	If the caller wanted us to wait for response wait now. 
 	 */
@@ -635,15 +602,19 @@
 {
 	struct hw_fib * hw_fib = fibptr->hw_fib;
 	struct aac_dev * dev = fibptr->dev;
+	struct aac_queue * q;
 	unsigned long nointr = 0;
-	if (le32_to_cpu(hw_fib->header.XferState) == 0)
+	unsigned long qflags;
+	u32 qid;
+
+	if (hw_fib->header.XferState == 0)
         	return 0;
 	/*
 	 *	If we plan to do anything check the structure type first.
 	 */ 
-	if ( hw_fib->header.StructType != FIB_MAGIC ) {
+	if ( hw_fib->header.StructType != FIB_MAGIC )
         	return -EINVAL;
-	}
+
 	/*
 	 *	This block handles the case where the adapter had sent us a
 	 *	command and we have finished processing the command. We
@@ -652,39 +623,27 @@
 	 *	send the completed cdb to the adapter.
 	 */
 	if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
+       		u32 index;
 	        hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
-	        if (hw_fib->header.XferState & cpu_to_le32(HighPriority)) {
-        		u32 index;
-       			if (size) 
-			{
-				size += sizeof(struct aac_fibhdr);
-				if (size > le16_to_cpu(hw_fib->header.SenderSize))
-					return -EMSGSIZE;
-				hw_fib->header.Size = cpu_to_le16(size);
-			}
-			if(aac_queue_get(dev, &index, AdapHighRespQueue, hw_fib, 1, NULL, &nointr) < 0) {
-				return -EWOULDBLOCK;
-			}
-			if (aac_insert_entry(dev, index, AdapHighRespQueue,  (nointr & (int)aac_config.irq_mod)) != 0) {
-			}
-		}
-		else if (hw_fib->header.XferState & NormalPriority) 
-		{
-			u32 index;
-
-			if (size) {
-				size += sizeof(struct aac_fibhdr);
-				if (size > le16_to_cpu(hw_fib->header.SenderSize)) 
-					return -EMSGSIZE;
-				hw_fib->header.Size = cpu_to_le16(size);
-			}
-			if (aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr) < 0) 
-				return -EWOULDBLOCK;
-			if (aac_insert_entry(dev, index, AdapNormRespQueue, 
-				(nointr & (int)aac_config.irq_mod)) != 0) 
-			{
-			}
+	        if (hw_fib->header.XferState & cpu_to_le32(HighPriority))
+			qid = AdapHighRespQueue;
+		else if (hw_fib->header.XferState & cpu_to_le32(NormalPriority))
+			qid = AdapNormRespQueue;
+		else
+			return 0;
+		if (size) {
+			size += sizeof(struct aac_fibhdr);
+			if (size > le16_to_cpu(hw_fib->header.SenderSize)) 
+				return -EMSGSIZE;
+			hw_fib->header.Size = cpu_to_le16(size);
 		}
+		q = &dev->queues->queue[qid];
+		spin_lock_irqsave(q->lock, qflags);
+		aac_queue_get(dev, &index, qid, hw_fib, 1, NULL, &nointr);
+		*(q->headers.producer) = cpu_to_le32(index + 1);
+		spin_unlock_irqrestore(q->lock, qflags);
+		if (!(nointr & (int)aac_config.irq_mod))
+			aac_adapter_notify(dev, qid);
 	}
 	else 
 	{
@@ -754,9 +713,10 @@
 
 void aac_printf(struct aac_dev *dev, u32 val)
 {
+	char *cp = dev->printfbuf;
+#if (defined(AAC_PRINTF_ENABLED))
 	int length = val & 0xffff;
 	int level = (val >> 16) & 0xffff;
-	char *cp = dev->printfbuf;
 	
 	/*
 	 *	The size of the printfbuf is set in port.c
@@ -770,6 +730,7 @@
 		printk(KERN_WARNING "aacraid:%s", cp);
 	else
 		printk(KERN_INFO "aacraid:%s", cp);
+#endif
 	memset(cp, 0,  256);
 }
 
@@ -783,122 +744,274 @@
  *	dispatches it to the appropriate routine for handling.
  */
 
-#define CONTAINER_TO_BUS(cont)		(0)
-#define CONTAINER_TO_TARGET(cont)	((cont))
-#define CONTAINER_TO_LUN(cont)		(0)
-
 static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
 {
 	struct hw_fib * hw_fib = fibptr->hw_fib;
 	struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data;
 	int busy;
 	u32 container;
+	Scsi_Device * device;
+	enum {
+		NOTHING,
+		DELETE,
+		ADD,
+		CHANGE
+	} DeviceConfigNeeded;
+	extern struct proc_dir_entry * proc_scsi;
 
 	/* Sniff for container changes */
-	dprintk ((KERN_INFO "AifCmdDriverNotify=%x\n", le32_to_cpu(*(u32 *)aifcmd->data)));
-	switch (le32_to_cpu(*(u32 *)aifcmd->data)) {
-	case AifDenMorphComplete:
-	case AifDenVolumeExtendComplete:
-	case AifEnContainerChange: /* Not really a driver notify Event */
-
-		busy = 0;
-		container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
-		dprintk ((KERN_INFO "container=%d(%d,%d,%d,%d) ",
-		  container,
-		  (dev && dev->scsi_host_ptr)
-		    ? dev->scsi_host_ptr->host_no
-		    : -1,
-		  CONTAINER_TO_BUS(container),
-		  CONTAINER_TO_TARGET(container),
-		  CONTAINER_TO_LUN(container)));
+	dprintk ((KERN_INFO "aac_handle_aif: Aif command=%x type=%x\n",
+	  le32_to_cpu(aifcmd->command), le32_to_cpu(*(u32 *)aifcmd->data)));
+
+	DeviceConfigNeeded = NOTHING;
 
+	/*
+	 *	We have set this up to try and minimize the number of
+	 * re-configures that take place. As a result of this when
+	 * certain AIF's come in we will set a flag waiting for another
+	 * type of AIF before setting the re-config flag.
+	 */
+	switch (le32_to_cpu(aifcmd->command)) {
+	case AifCmdDriverNotify:
+		switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) {
 		/*
-		 *	Find the Scsi_Device associated with the SCSI address,
-		 * and mark it as changed, invalidating the cache. This deals
-		 * with changes to existing device IDs.
+		 *	Morph or Expand complete
 		 */
+		case AifDenMorphComplete:
+		case AifDenVolumeExtendComplete:
+			container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+			if (container >= MAXIMUM_NUM_CONTAINERS)
+				break;
+			dprintk ((KERN_INFO "container=%d(%d,%d,%d,%d)\n",
+			  container,
+			  (dev && dev->scsi_host_ptr)
+			    ? dev->scsi_host_ptr->host_no
+			    : -1,
+			  CONTAINER_TO_CHANNEL(container),
+			  CONTAINER_TO_ID(container),
+			  CONTAINER_TO_LUN(container)));
 
-		if ((dev != (struct aac_dev *)NULL)
-		 && (dev->scsi_host_ptr != (struct Scsi_Host *)NULL)) {
-			Scsi_Device * device;
-
-			for (device = dev->scsi_host_ptr->host_queue;
-			  device != (Scsi_Device *)NULL;
-			  device = device->next) {
-				dprintk((KERN_INFO
-				  "aifd: device (%d,%d,%d,%d)?\n",
-				  dev->scsi_host_ptr->host_no,
-				  device->channel,
-				  device->id,
-				  device->lun));
-				if ((device->channel == CONTAINER_TO_BUS(container))
-				 && (device->id == CONTAINER_TO_TARGET(container))
-				 && (device->lun == CONTAINER_TO_LUN(container))) {
-					busy |= (device->access_count != 0);
-					if (busy == 0) {
-						device->removable = TRUE;
-					}
-				}
+			/*
+			 *	Find the Scsi_Device associated with the SCSI
+			 * address. Make sure we have the right array, and if
+			 * so set the flag to initiate a new re-config once we
+			 * see an AifEnConfigChange AIF come through.
+			 */
+
+			if ((dev != (struct aac_dev *)NULL)
+			 && (dev->scsi_host_ptr != (struct Scsi_Host *)NULL)) {
+				for (device = dev->scsi_host_ptr->host_queue;
+				  device != (Scsi_Device *)NULL;
+				  device = device->next)
+				{
+					if ((device->channel == CONTAINER_TO_CHANNEL(container))
+					 && (device->id == CONTAINER_TO_ID(container))
+					 && (device->lun == CONTAINER_TO_LUN(container))) {
+						dev->DeviceContainerID = container;
+						dev->DeviceConfigNeeded = CHANGE;
+						dev->DeviceConfigWaitingOn = AifEnConfigChange;
+						break;
+					} /* if */
+				} /* for */
+			} /* if */
+		} /* switch */
+
+		/*
+		 *	If we are waiting on something and this happens to be
+		 * that thing then set the re-configure flag.
+		 */
+		if (dev->DeviceConfigWaitingOn == le32_to_cpu(*(u32 *)aifcmd->data)) {
+			DeviceConfigNeeded = dev->DeviceConfigNeeded;
+		}
+		break;
+
+	case AifCmdEventNotify:
+		switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) {
+		/*
+		 *	Add an Array.
+		 */
+		case AifEnAddContainer:
+			container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+			if (container >= MAXIMUM_NUM_CONTAINERS)
+				break;
+			dev->DeviceContainerID = container;
+			dev->DeviceConfigNeeded = ADD;
+			dev->DeviceConfigWaitingOn = AifEnConfigChange;
+			break;
+
+		/*
+		 *	Delete an Array.
+		 */
+		case AifEnDeleteContainer:
+			container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+			if (container >= MAXIMUM_NUM_CONTAINERS)
+				break;
+			dev->DeviceContainerID = container;
+			dev->DeviceConfigNeeded = DELETE;
+			dev->DeviceConfigWaitingOn = AifEnConfigChange;
+			break;
+
+		/*
+		 *	Container change detected. If we currently are not
+		 * waiting on something else, setup to wait on a Config Change.
+		 */
+		case AifEnContainerChange:
+			container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+			if (container >= MAXIMUM_NUM_CONTAINERS)
+				break;
+			dev->DeviceContainerID = container;
+			if (dev->DeviceConfigWaitingOn) {
+				break;
 			}
+			dev->DeviceConfigNeeded = CHANGE;
+			dev->DeviceConfigWaitingOn = AifEnConfigChange;
+			break;
+		} /* switch */
+
+		/*
+		 *	If we are waiting on something and this happens to be
+		 * that thing then set the re-configure flag.
+		 */
+		if (dev->DeviceConfigWaitingOn == le32_to_cpu(*(u32 *)aifcmd->data)) {
+			DeviceConfigNeeded = dev->DeviceConfigNeeded;
 		}
-		dprintk (("busy=%d\n", busy));
+		break;
 
+	case AifCmdJobProgress:
 		/*
-		 * if (busy == 0) {
-		 *	scan_scsis(dev->scsi_host_ptr, 1,
-		 *	  CONTAINER_TO_BUS(container),
-		 *	  CONTAINER_TO_TARGET(container),
-		 *	  CONTAINER_TO_LUN(container));
-		 * }
-		 * is not exported as accessible, so we need to go around it
-		 * another way. So, we look for the "proc/scsi/scsi" entry in
-		 * the proc filesystem (using proc_scsi as a shortcut) and send
-		 * it a message. This deals with new devices that have
-		 * appeared. If the device has gone offline, scan_scsis will
-		 * also discover this, but we do not want the device to
-		 * go away. We need to check the access_count for the
-		 * device since we are not wanting the devices to go away.
+		 *	These are job progress AIF's. When a Clear is being
+		 * done on a container it is initially created then hidden from
+		 * the OS. When the clear completes we don't get a config
+		 * change so we monitor the job status complete on a clear then
+		 * wait for a containe change.
 		 */
-		if ((busy == 0)
-		 && (proc_scsi != (struct proc_dir_entry *)NULL)) {
-			struct proc_dir_entry * entry;
-
-			dprintk((KERN_INFO "proc_scsi=%p ", proc_scsi));
-			for (entry = proc_scsi->subdir;
-			  entry != (struct proc_dir_entry *)NULL;
-			  entry = entry->next) {
-				dprintk(("\"%.*s\"[%d]=%x ", entry->namelen,
-				  entry->name, entry->namelen, entry->low_ino));
-				if ((entry->low_ino != 0)
-				 && (entry->namelen == 4)
-				 && (memcmp ("scsi", entry->name, 4) == 0)) {
-					dprintk(("%p->write_proc=%p ", entry, entry->write_proc));
-					if (entry->write_proc != (int (*)(struct file *, const char *, unsigned long, void *))NULL) {
-						char buffer[80];
-						int length;
-						mm_segment_t fs;
-
-						sprintf (buffer,
-						  "scsi add-single-device %d %d %d %d\n",
-						  dev->scsi_host_ptr->host_no,
-						  CONTAINER_TO_BUS(container),
-						  CONTAINER_TO_TARGET(container),
-						  CONTAINER_TO_LUN(container));
-						length = strlen (buffer);
-						dprintk((KERN_INFO
-						  "echo %.*s > /proc/scsi/scsi\n",
-						  length-1,
-						  buffer));
-						fs = get_fs();
-						set_fs(get_ds());
-						length = entry->write_proc(
-						  NULL, buffer, length, NULL);
-						set_fs(fs);
-						dprintk((KERN_INFO
-						  "returns %d\n", length));
-					}
-					break;
+
+		if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))
+		 && ((((u32 *)aifcmd->data)[6] == ((u32 *)aifcmd->data)[5])
+		  || (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsSuccess)))) {
+			dev->DeviceContainerID = -1;
+			dev->DeviceConfigWaitingOn = AifEnContainerChange;
+			dev->DeviceConfigNeeded = ADD;
+		}
+		break;
+	} /* switch */
+
+	if (DeviceConfigNeeded == NOTHING) {
+		return;
+	}
+
+	/*
+	 *	If we decided that a re-configuration needs to be done,
+	 * schedule it here on the way out the door, please close the door
+	 * behind you.
+	 */
+	dev->DeviceConfigWaitingOn = 0;
+	dev->DeviceConfigNeeded = NOTHING;
+	container = dev->DeviceContainerID;
+	dev->DeviceContainerID = -1;
+
+	busy = 0;
+
+	dprintk ((KERN_INFO "container=%d(%d,%d,%d,%d)\n",
+	  container,
+	  (dev && dev->scsi_host_ptr)
+	    ? dev->scsi_host_ptr->host_no
+	    : -1,
+	  CONTAINER_TO_CHANNEL(container),
+	  CONTAINER_TO_ID(container),
+	  CONTAINER_TO_LUN(container)));
+
+	/*
+	 *	Find the Scsi_Device associated with the SCSI address,
+	 * and mark it as changed, invalidating the cache. This deals
+	 * with changes to existing device IDs.
+	 */
+
+	if (!dev || !dev->scsi_host_ptr) {
+		return;
+	}
+	for (device = dev->scsi_host_ptr->host_queue;
+	  device != (Scsi_Device *)NULL;
+	  device = device->next)
+	{
+		dprintk((KERN_INFO "aifd: device (%d,%d,%d,%d)?\n",
+		  dev->scsi_host_ptr->host_no,
+		  device->channel,
+		  device->id,
+		  device->lun));
+		if ((device->channel == CONTAINER_TO_CHANNEL(container))
+		 && (device->id == CONTAINER_TO_ID(container))
+		 && (device->lun == CONTAINER_TO_LUN(container))) {
+			busy |= device->access_count || dev->scsi_host_ptr->in_recovery;
+			if (busy == 0) {
+				device->removable = TRUE;
+			}
+		}
+	}
+	dprintk (("busy=%d\n", busy));
+
+	/*
+	 * if (busy == 0) {
+	 *	scan_scsis(dev->scsi_host_ptr, 1,
+	 *	  CONTAINER_TO_CHANNEL(container),
+	 *	  CONTAINER_TO_ID(container),
+	 *	  CONTAINER_TO_LUN(container));
+	 * }
+	 * is not exported as accessible, so we need to go around it
+	 * another way. So, we look for the "proc/scsi/scsi" entry in
+	 * the proc filesystem (using proc_scsi as a shortcut) and send
+	 * it a message. This deals with new devices that have
+	 * appeared. If the device has gone offline, scan_scsis will
+	 * also discover this, but we do not want the device to
+	 * go away. We need to check the access_count for the
+	 * device since we are not wanting the devices to go away.
+	 */
+	if ((busy == 0) && (DeviceConfigNeeded == CHANGE) && (dev->fsa_dev.valid[container] == 1)) {
+		dev->fsa_dev.valid[container] = 2;
+	}
+	if ((busy == 0)
+	 && (proc_scsi != (struct proc_dir_entry *)NULL)) {
+		struct proc_dir_entry * entry;
+
+		dprintk((KERN_INFO "proc_scsi=%p ", proc_scsi));
+		for (entry = proc_scsi->subdir;
+		  entry != (struct proc_dir_entry *)NULL;
+		  entry = entry->next) {
+			dprintk(("\"%.*s\"[%d]=%x ", entry->namelen,
+			  entry->name, entry->namelen, entry->low_ino));
+			if ((entry->low_ino != 0)
+			 && (entry->namelen == 4)
+			 && (memcmp ("scsi", entry->name, 4) == 0)) {
+				dprintk(("%p->write_proc=%p ", entry, entry->write_proc));
+				if (entry->write_proc != (int (*)(struct file *, const char *, unsigned long, void *))NULL) {
+					char buffer[80];
+					int length;
+					mm_segment_t fs;
+
+					sprintf (buffer,
+					  "scsi %s-single-device %d %d %d %d\n",
+					  ((DeviceConfigNeeded == DELETE)
+					   ? "remove"
+					   : "add"),
+					  dev->scsi_host_ptr->host_no,
+					  CONTAINER_TO_CHANNEL(container),
+					  CONTAINER_TO_ID(container),
+					  CONTAINER_TO_LUN(container));
+					length = strlen (buffer);
+					dprintk((KERN_INFO
+					  "echo %.*s > /proc/scsi/scsi\n",
+					  length-1,
+					  buffer));
+//printk("echo %.*s > /proc/scsi/scsi\n", length-1, buffer);
+					fs = get_fs();
+					set_fs(get_ds());
+					length = entry->write_proc(
+					  NULL, buffer, length, NULL);
+					set_fs(fs);
+					dprintk((KERN_INFO
+					  "returns %d\n", length));
 				}
+				break;
 			}
 		}
 	}
@@ -918,7 +1031,7 @@
 {
 	struct hw_fib *hw_fib, *hw_newfib;
 	struct fib *fib, *newfib;
-	struct aac_queue_block *queues = dev->queues;
+	struct aac_queue *q = &dev->queues->queue[HostNormCmdQueue];
 	struct aac_fib_context *fibctx;
 	unsigned long flags;
 	DECLARE_WAITQUEUE(wait, current);
@@ -938,22 +1051,22 @@
 	 *	Let the DPC know it has a place to send the AIF's to.
 	 */
 	dev->aif_thread = 1;
-	add_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
+	add_wait_queue(&q->cmdready, &wait);
 	set_current_state(TASK_INTERRUPTIBLE);
 	dprintk ((KERN_INFO "aac_command_thread start\n"));
 	while(1) 
 	{
-		spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
-		while(!list_empty(&(queues->queue[HostNormCmdQueue].cmdq))) {
+		spin_lock_irqsave(q->lock, flags);
+		while(!list_empty(&(q->cmdq))) {
 			struct list_head *entry;
 			struct aac_aifcmd * aifcmd;
 
 			set_current_state(TASK_RUNNING);
 
-			entry = queues->queue[HostNormCmdQueue].cmdq.next;
+			entry = q->cmdq.next;
 			list_del(entry);
 	
-			spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
+			spin_unlock_irqrestore(q->lock, flags);
 			fib = list_entry(entry, struct fib, fiblink);
 			/*
 			 *	We will process the FIB here or pass it to a 
@@ -987,8 +1101,10 @@
 				unsigned long flagv;
 				
 				/* Sniff events */
-				if (aifcmd->command == cpu_to_le32(AifCmdEventNotify))
+				if ((aifcmd->command == cpu_to_le32(AifCmdEventNotify))
+				 || (aifcmd->command == cpu_to_le32(AifCmdJobProgress))) {
 					aac_handle_aif(dev, fib);
+				}
 
 				time_now = jiffies/HZ;
 
@@ -1069,20 +1185,21 @@
 				fib_adapter_complete(fib, sizeof(u32));
 				spin_unlock_irqrestore(&dev->fib_lock, flagv);
 			}
-			spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
+			spin_lock_irqsave(q->lock, flags);
 			kfree(fib);
 		}
 		/*
 		 *	There are no more AIF's
 		 */
-		spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
+		spin_unlock_irqrestore(q->lock, flags);
 		schedule();
 
 		if(signal_pending(current))
 			break;
 		set_current_state(TASK_INTERRUPTIBLE);
 	}
-	remove_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
+	remove_wait_queue(&q->cmdready, &wait);
 	dev->aif_thread = 0;
 	complete_and_exit(&dev->aif_completion, 0);
+	return 0;
 }
diff -u -P --recursive linux-2.4.24/drivers/scsi/aacraid/dpcsup.c linux-2.4.24-2322/drivers/scsi/aacraid/dpcsup.c
--- linux-2.4.24/drivers/scsi/aacraid/dpcsup.c	Fri Feb 13 11:31:25 2004
+++ linux-2.4.24-2322/drivers/scsi/aacraid/dpcsup.c	Tue Oct  7 12:59:37 2003
@@ -182,18 +182,24 @@
 		u32 index;
 		struct fib *fib = &fibctx;
 
-		index = le32_to_cpu(entry->addr / sizeof(struct hw_fib));
-		hw_fib = &dev->aif_base_va[index];
-
 		/*
-		 *	Allocate a FIB at all costs. For non queued stuff
-		 *	we can just use the stack so we are happy. We need
-		 *	a fib object in order to manage the linked lists
+		 *	Allocate a FIB. For non queued stuff we can just use
+		 * the stack so we are happy. We need a fib object in order to
+		 * manage the linked lists.
 		 */
-		if (dev->aif_thread)
-			if((fib = kmalloc(sizeof(struct fib), GFP_ATOMIC))==NULL)
+		if (dev->aif_thread) {
+			/* Limit the number we retreive from fib pool */
+			struct list_head * each;
+			int i = (dev->init->AdapterFibsSize / sizeof(struct hw_fib)) - 1;
+			list_for_each(each, &(q->cmdq))
+				if (--i <= 0)
+					break;
+			if ((i <= 0) || (!(fib = kmalloc(sizeof(struct fib),GFP_ATOMIC))))
 				fib = &fibctx;
-			
+		}
+
+		index = le32_to_cpu(entry->addr / sizeof(struct hw_fib));
+		hw_fib = &dev->aif_base_va[index];
 		memset(fib, 0, sizeof(struct fib));
 		INIT_LIST_HEAD(&fib->fiblink);
 		fib->type = FSAFS_NTC_FIB_CONTEXT;
diff -u -P --recursive linux-2.4.24/drivers/scsi/aacraid/linit.c linux-2.4.24-2322/drivers/scsi/aacraid/linit.c
--- linux-2.4.24/drivers/scsi/aacraid/linit.c	Fri Feb 13 11:31:25 2004
+++ linux-2.4.24-2322/drivers/scsi/aacraid/linit.c	Fri Feb 13 12:13:20 2004
@@ -35,6 +35,9 @@
  *	
  */
 
+#define AAC_DRIVER_VERSION		0x01010004
+#define AAC_DRIVER_BUILD_DATE		__DATE__ " " __TIME__
+
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -45,13 +48,22 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
+#include <linux/interrupt.h>
 #include <asm/semaphore.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include "scsi.h"
 #include "hosts.h"
+#include "sd.h"
+#include <linux/blk.h>	/* for io_request_lock definition */
+#if (defined(__x86_64__))
+# include <asm-x86_64/ioctl32.h>
+  /* Cast the function, since sys_ioctl does not match */
+# define aac_ioctl32(x,y) register_ioctl32_conversion((x), \
+    (int(*)(unsigned int,unsigned int,unsigned long,struct file*))(y))
+# include <asm/uaccess.h>
+#endif
 
 #include "aacraid.h"
-#include "sd.h"
 
 #define AAC_DRIVER_NAME	"aacraid"
 
@@ -63,6 +75,7 @@
 
 static unsigned aac_count = 0;
 static int aac_cfg_major = -1;
+unsigned long aac_driver_version = AAC_DRIVER_VERSION | 0x00000400;
 
 /*
  * Because of the way Linux names scsi devices, the order in this table has
@@ -138,13 +179,31 @@
 static int aac_queuecommand(Scsi_Cmnd *, void (*CompletionRoutine)(Scsi_Cmnd *));
 static int aac_biosparm(Scsi_Disk *, kdev_t, int *);
 static int aac_procinfo(char *, char **, off_t, int, int, int);
+static void aac_queuedepth(struct Scsi_Host *, Scsi_Device *);
 static int aac_ioctl(Scsi_Device *, int, void *);
 static int aac_eh_abort(Scsi_Cmnd * cmd);
 static int aac_eh_device_reset(Scsi_Cmnd* cmd);
 static int aac_eh_bus_reset(Scsi_Cmnd* cmd);
 static int aac_eh_reset(Scsi_Cmnd* cmd);
 
-static void aac_queuedepth(struct Scsi_Host *, Scsi_Device *);
+#if (defined(__x86_64__))
+/* Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version */
+int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct fib_ioctl f;
+	mm_segment_t fs;
+	int retval;
+
+	memset (&f, 0, sizeof(f));
+	if(copy_from_user((void *)&f, (void *)arg, sizeof(struct fib_ioctl) - sizeof(u32)))
+		return -EFAULT;
+	fs = get_fs();
+	set_fs(get_ds());
+	retval = sys_ioctl(fd, cmd, (unsigned long)&f);
+	set_fs(fs);
+	return retval;
+}
+#endif /* __x86_64__ */
 
 /**
  *	aac_detect	-	Probe for aacraid cards
@@ -175,43 +234,56 @@
 	struct aac_dev *aac;
 	struct fsa_scsi_hba *fsa_dev_ptr;
 	char *name = NULL;
-	
-	printk(KERN_INFO "Red Hat/Adaptec %s driver (%d.%d-%d %s)\n",
-		AAC_DRIVER_NAME,
-		AAC_DRIVER_VERSION >> 24,
-		(AAC_DRIVER_VERSION >> 16) & 0xFF,
-		(AAC_DRIVER_VERSION >> 8) & 0xFF,
-		AAC_DRIVER_BUILD_DATE);
-		
+	int ret;
+
+#	if (defined(AAC_DRIVER_BUILD))
+		printk(KERN_INFO "Red Hat/Adaptec %s driver (%d.%d-%d[%d])\n",
+		  AAC_DRIVER_NAME,
+		  AAC_DRIVER_VERSION >> 24,
+		  (AAC_DRIVER_VERSION >> 16) & 0xFF,
+		  AAC_DRIVER_VERSION & 0xFF,
+		  AAC_DRIVER_BUILD);
+#	else
+		printk(KERN_INFO "Red Hat/Adaptec %s driver (%d.%d-%d %s)\n",
+		  AAC_DRIVER_NAME,
+		  AAC_DRIVER_VERSION >> 24,
+		  (AAC_DRIVER_VERSION >> 16) & 0xFF,
+		  AAC_DRIVER_VERSION & 0xFF,
+		  AAC_DRIVER_BUILD_DATE);
+#	endif
+
 	/* setting up the proc directory structure */
-	
-	template->proc_name = "aacraid";
 	spin_unlock_irq(&io_request_lock);
 
-	for( index = 0; index != num_aacdrivers; index++ )
+	dev = NULL;
+	while((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
 	{
-		device_id = aac_drivers[index].device;
-		vendor_id = aac_drivers[index].vendor;
-		name = aac_drivers[index].name;
-		dprintk((KERN_DEBUG "Checking %s %x/%x/%x/%x.\n", 
-			name, vendor_id, device_id,
-			aac_drivers[index].subsystem_vendor,
-			aac_drivers[index].subsystem_device));
-
-		dev = NULL;
-		while((dev = pci_find_device(vendor_id, device_id, dev))) {
-			if (pci_enable_device(dev))
+		if (pci_enable_device(dev))
+			continue;
+		for( index = 0; index != num_aacdrivers; index++ )
+		{
+			device_id = aac_drivers[index].device;
+			vendor_id = aac_drivers[index].vendor;
+			name = aac_drivers[index].name;
+
+			if((dev->vendor != vendor_id) ||
+			   (dev->device != device_id) ||
+			   ((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) &&
+			    (aac_drivers[index].subsystem_vendor != (unsigned short)PCI_ANY_ID)) ||
+			   ((dev->subsystem_device != aac_drivers[index].subsystem_device) &&
+			    (aac_drivers[index].subsystem_device != (unsigned short)PCI_ANY_ID)))
 				continue;
+
 			pci_set_master(dev);
-			
-			if(aac_drivers[index].quirks & AAC_QUIRK_31BIT)
-				pci_set_dma_mask(dev, 0x7FFFFFFFULL);
+
+			if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
+				ret = pci_set_dma_mask(dev, 0x7FFFFFFFULL);
 			else
-				pci_set_dma_mask(dev, 0xFFFFFFFFULL);
+				ret = pci_set_dma_mask(dev, 0xFFFFFFFFULL);
 
-			if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) || 
-			   (dev->subsystem_device != aac_drivers[index].subsystem_device))
-					continue;
+			if (ret) {
+				printk(KERN_WARNING "%s: Can't set DMA mask.\n", name);
+			}
 
 			dprintk((KERN_DEBUG "%s device detected.\n", name));
 			dprintk((KERN_DEBUG "%x/%x/%x/%x.\n", vendor_id, device_id, 
@@ -254,9 +331,9 @@
 			 */
 			host_ptr->unique_id = aac_count - 1;
 			/*
-			 *	This function is called after the device list has
-			 *	been built to find the tagged queueing depth 
-			 *	supported for each device.
+			 *	This function is called after the device list
+			 *	has been built to find the tagged queueing
+			 *	depth supported for each device.
 			 */
 			host_ptr->select_queue_depths = aac_queuedepth;
 			aac = (struct aac_dev *)host_ptr->hostdata;
@@ -273,16 +350,16 @@
 			/* Initialize the ordinal number of the device to -1 */
 			fsa_dev_ptr = &(aac->fsa_dev);
 			for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ )
-				fsa_dev_ptr->devno[container] = -1;
+				fsa_dev_ptr->devname[container][0] = '\0';
 
 			dprintk((KERN_DEBUG "Initializing Hardware...\n"));
 			if((*aac_drivers[index].init)(aac , host_ptr->unique_id) != 0)
 			{
 				/* device initialization failed */
-				printk(KERN_WARNING "aacraid: device initialization failed.\n");
+				printk(KERN_WARNING "%s: device initialization failed.\n", AAC_DRIVER_NAME);
 				scsi_unregister(host_ptr);
 				aac_count--;
-				continue;
+				break;
 			} 
 			dprintk((KERN_DEBUG "%s:%d device initialization successful.\n", name, host_ptr->unique_id));
 			aac_get_adapter_info(aac);
@@ -305,18 +382,32 @@
 			 * dmb - we may need to move the setting of these parms somewhere else once
 			 * we get a fib that can report the actual numbers
 			 */
-			host_ptr->max_id = AAC_MAX_TARGET;
+			host_ptr->max_id = MAXIMUM_NUM_CONTAINERS;
 			host_ptr->max_lun = AAC_MAX_LUN;
+			break;
 		}
 	}
 
 	if( aac_count ){
 		if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0)
-			printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n");
+			printk(KERN_WARNING "%s: unable to register \"aac\" device.\n", AAC_DRIVER_NAME);
+#		if (defined(__x86_64__))
+			aac_ioctl32(FSACTL_MINIPORT_REV_CHECK, sys_ioctl);
+			aac_ioctl32(FSACTL_SENDFIB, sys_ioctl);
+			aac_ioctl32(FSACTL_OPEN_GET_ADAPTER_FIB, sys_ioctl);
+			aac_ioctl32(FSACTL_GET_NEXT_ADAPTER_FIB,
+			  aac_get_next_adapter_fib_ioctl);
+			aac_ioctl32(FSACTL_CLOSE_GET_ADAPTER_FIB, sys_ioctl);
+			aac_ioctl32(FSACTL_SEND_RAW_SRB, sys_ioctl);
+			aac_ioctl32(FSACTL_GET_PCI_INFO, sys_ioctl);
+			aac_ioctl32(FSACTL_QUERY_DISK, sys_ioctl);
+			aac_ioctl32(FSACTL_DELETE_DISK, sys_ioctl);
+			aac_ioctl32(FSACTL_FORCE_DELETE_DISK, sys_ioctl);
+			aac_ioctl32(2131, sys_ioctl);
+#		endif
 	}
 	spin_lock_irq(&io_request_lock);
 
-	template->present = aac_count; /* # of cards of this type found */
 	return aac_count;
 }
 
@@ -355,6 +446,19 @@
 	 */
 	if( aac_cfg_major >= 0 )
 	{
+#		if (defined(__x86_64__))
+			unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK);
+			unregister_ioctl32_conversion(FSACTL_SENDFIB);
+			unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB);
+			unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB);
+			unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB);
+			unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB);
+			unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO);
+			unregister_ioctl32_conversion(FSACTL_QUERY_DISK);
+			unregister_ioctl32_conversion(FSACTL_DELETE_DISK);
+			unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK);
+			unregister_ioctl32_conversion(2131);
+#		endif
 		unregister_chrdev(aac_cfg_major, "aac");
 		aac_cfg_major = -1;
 	}
@@ -411,6 +515,9 @@
  *	aac_biosparm	-	return BIOS parameters for disk
  *	@disk: SCSI disk object to process
  *	@device: kdev_t of the disk in question
+ *	@sdev: The scsi device corresponding to the disk
+ *	@bdev: The block device corresponding to the disk
+ *	@capacity: The sector capacity of the disk
  *	@geom: geometry block to fill in
  *
  *	Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.  
@@ -428,19 +535,22 @@
  *	be displayed.
  */
  
-static int aac_biosparm(Scsi_Disk *disk, kdev_t dev, int *geom)
+static int aac_biosparm(
+	Scsi_Disk *disk, kdev_t dev,
+	int *geom)
 {
 	struct diskparm *param = (struct diskparm *)geom;
 	struct buffer_head * buf;
+	sector_t capacity = disk->capacity;
 
 	dprintk((KERN_DEBUG "aac_biosparm.\n"));
 
 	/*
 	 *	Assuming extended translation is enabled - #REVISIT#
 	 */
-	if( disk->capacity >= 2 * 1024 * 1024 ) /* 1 GB in 512 byte sectors */
+	if( capacity >= 2 * 1024 * 1024 ) /* 1 GB in 512 byte sectors */
 	{
-		if( disk->capacity >= 4 * 1024 * 1024 ) /* 2 GB in 512 byte sectors */
+		if( capacity >= 4 * 1024 * 1024 ) /* 2 GB in 512 byte sectors */
 		{
 			param->heads = 255;
 			param->sectors = 63;
@@ -457,7 +567,7 @@
 		param->sectors = 32;
 	}
 
-	param->cylinders = disk->capacity/(param->heads * param->sectors);
+	param->cylinders = cap_to_cyls(capacity, param->heads * param->sectors);
 
 	/*
 	 *	Read the first 1024 bytes from the disk device
@@ -512,7 +622,7 @@
 			end_sec = first->end_sector & 0x3f;
 		}
 
-		param->cylinders = disk->capacity / (param->heads * param->sectors);
+		param->cylinders = cap_to_cyls(capacity, param->heads * param->sectors);
 
 		if(num < 4 && end_sec == param->sectors)
 		{
@@ -655,6 +795,11 @@
  *	zero for success
  */
  
+/*------------------------------------------------------------------------------
+	aac_ioctl()
+
+		Handle SCSI ioctls
+ *----------------------------------------------------------------------------*/
 static int aac_ioctl(Scsi_Device * scsi_dev_ptr, int cmd, void * arg)
 {
 	struct aac_dev *dev;
@@ -677,7 +822,7 @@
 
 static int aac_cfg_open(struct inode * inode, struct file * file )
 {
-	unsigned minor_number = MINOR(inode->i_rdev);
+	unsigned minor_number = iminor(inode);
 	if(minor_number >= aac_count)
 		return -ENODEV;
 	return 0;
@@ -713,7 +858,7 @@
  
 static int aac_cfg_ioctl(struct inode * inode,  struct file * file, unsigned int cmd, unsigned long arg )
 {
-	struct aac_dev *dev = aac_devices[MINOR(inode->i_rdev)];
+	struct aac_dev *dev = aac_devices[iminor(inode)];
 	return aac_do_ioctl(dev, cmd, (void *)arg);
 }
 
@@ -748,6 +893,7 @@
 	.highmem_io			= 1,
 #endif
 
+	.proc_name			= AAC_DRIVER_NAME,
 };
 
 #include "scsi_module.c"
@@ -775,43 +921,59 @@
  *	Bugs:	Only offset zero is handled
  */
 
-static int aac_procinfo(char *proc_buffer, char **start_ptr,off_t offset,
-			int bytes_available, int host_no, int write)
+static int aac_procinfo(
+	char *proc_buffer, char **start_ptr,off_t offset,
+	int bytes_available,
+	int host_no,
+	int write)
 {
-	struct aac_dev * dev;
+	struct aac_dev * dev = (struct aac_dev *)NULL;
 	int index, ret, tmp;
 
 	if(write || offset > 0)
 		return 0;
 	*start_ptr = proc_buffer;
-	ret = sprintf(proc_buffer,
-		  "Adaptec Raid Controller %d.%d-%d %s, scsi hba number %d\n",
+#	if (defined(AAC_DRIVER_BUILD))
+		ret = sprintf(proc_buffer,
+		  "Adaptec Raid Controller %d.%d-%d[%d]\n",
+		  AAC_DRIVER_VERSION >> 24,
+		  (AAC_DRIVER_VERSION >> 16) & 0xFF,
+		  AAC_DRIVER_VERSION & 0xFF,
+		  AAC_DRIVER_BUILD);
+#	else
+		ret = sprintf(proc_buffer,
+		  "Adaptec Raid Controller %d.%d-%d %s\n",
 		  AAC_DRIVER_VERSION >> 24,
 		  (AAC_DRIVER_VERSION >> 16) & 0xFF,
-		  (AAC_DRIVER_VERSION >> 8) & 0xFF,
-		  AAC_DRIVER_BUILD_DATE,
-		  host_no);
+		  AAC_DRIVER_VERSION & 0xFF,
+		  AAC_DRIVER_BUILD_DATE);
+#	endif
 	for (index = 0; index < aac_count; ++index) {
-		if (((dev = aac_devices[index]) != NULL) && dev->scsi_host_ptr->host_no == host_no)
+		if (((dev = aac_devices[index]) != (struct aac_dev *)NULL)
+		 && (dev->scsi_host_ptr->host_no == host_no)
+		) {
 			break;
+		}
 	}
-	if (index >= aac_count || dev == NULL)
+	if ((index >= aac_count) || (dev == (struct aac_dev *)NULL)) {
 		return ret;
+	}
+	ret += sprintf(proc_buffer + ret, "Vendor: %s Model: %s\n",
+	  aac_drivers[dev->cardtype].vname, aac_drivers[dev->cardtype].model);
 	tmp = dev->adapter_info.kernelrev;
 	ret += sprintf(proc_buffer + ret, "kernel: %d.%d-%d[%d]\n", 
-		tmp >> 24, (tmp >> 16) & 0xff, (tmp >> 8) & 0xff,
-		dev->adapter_info.kernelbuild);
+	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
+	  dev->adapter_info.kernelbuild);
 	tmp = dev->adapter_info.monitorrev;
 	ret += sprintf(proc_buffer + ret, "monitor: %d.%d-%d[%d]\n", 
-		tmp >> 24, (tmp >> 16) & 0xff, (tmp >> 8) & 0xff,
-		dev->adapter_info.monitorbuild);
+	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
+	  dev->adapter_info.monitorbuild);
 	tmp = dev->adapter_info.biosrev;
 	ret += sprintf(proc_buffer + ret, "bios: %d.%d-%d[%d]\n", 
-		tmp >> 24, (tmp >> 16) & 0xff, (tmp >> 8) & 0xff,
-		dev->adapter_info.biosbuild);
-	ret += sprintf(proc_buffer + ret, "serial: %x%x\n",
-		dev->adapter_info.serial[0],
-		dev->adapter_info.serial[1]);
+	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
+	  dev->adapter_info.biosbuild);
+	ret += sprintf(proc_buffer + ret, "serial: %x\n",
+	  dev->adapter_info.serial[0]);
 	return ret;
 }
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-02-13 23:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-13 22:37 [PATCH] aacraid changes for 2.4.24 kernel to add support of AMD64 (part 2) Salyzyn, Mark
2004-02-13 23:04 ` Christoph Hellwig
  -- strict thread matches above, loose matches on Subject: below --
2004-02-13 21:16 Salyzyn, Mark
2004-02-13 21:58 ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox