bk://linux-scsi.bkbits.net/scsi-misc-2.6
jejb@mulgrave.(none)|ChangeSet|20040511161645|61751 jejb

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/05/11 11:16:45-05:00 jejb@mulgrave.(none) 
#   Make st support the scsi_device timeout
#   
#   From: 	Brian King <brking@us.ibm.com>
# 
# drivers/scsi/st.h
#   2004/05/11 11:16:20-05:00 jejb@mulgrave.(none) +0 -1
#   Make st support the scsi_device timeout
# 
# drivers/scsi/st.c
#   2004/05/11 11:16:20-05:00 jejb@mulgrave.(none) +19 -19
#   Make st support the scsi_device timeout
# 
# ChangeSet
#   2004/05/11 10:33:58-05:00 alan@redhat.com 
#   [PATCH] PATCH: Do something about aacraid
#   
#   This is a fairly minimal fix for aacraid. It removes the happy cast
#   pointers to u32 garbage in the 2.6 code and replaces it with the working
#   2.4 equivalents. I've not backported any of the other changes from 2.4 to
#   2.6 yet, and some things have gone which are good to be gone (eg the
#   proc/scsi horror). There is a certain amount of white space noise caused
#   by realigning with the 2.4 code so I could see what was going on.
#   
#   Tested on a dual opteron
# 
# drivers/scsi/aacraid/sa.c
#   2004/05/10 15:21:30-05:00 alan@redhat.com +5 -0
#   PATCH: Do something about aacraid
# 
# drivers/scsi/aacraid/dpcsup.c
#   2004/05/10 15:23:18-05:00 alan@redhat.com +34 -19
#   PATCH: Do something about aacraid
# 
# drivers/scsi/aacraid/commsup.c
#   2004/05/10 15:16:08-05:00 alan@redhat.com +48 -33
#   PATCH: Do something about aacraid
# 
# drivers/scsi/aacraid/comminit.c
#   2004/05/10 15:11:56-05:00 alan@redhat.com +6 -3
#   PATCH: Do something about aacraid
# 
# drivers/scsi/aacraid/commctrl.c
#   2004/05/10 15:22:40-05:00 alan@redhat.com +20 -17
#   PATCH: Do something about aacraid
# 
# drivers/scsi/aacraid/aacraid.h
#   2004/05/10 15:02:37-05:00 alan@redhat.com +35 -122
#   PATCH: Do something about aacraid
# 
# drivers/scsi/aacraid/README
#   2004/05/10 15:20:16-05:00 alan@redhat.com +6 -2
#   PATCH: Do something about aacraid
# 
diff -Nru a/drivers/scsi/aacraid/README b/drivers/scsi/aacraid/README
--- a/drivers/scsi/aacraid/README	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/aacraid/README	Wed May 12 20:31:43 2004
@@ -38,15 +38,19 @@
 					(fixed 64bit and 64G memory model, changed confusing naming convention
 					 where fibs that go to the hardware are consistently called hw_fibs and
 					 not just fibs like the name of the driver tracking structure)
+Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas.
+
 Original Driver
 -------------------------
 Adaptec Unix OEM Product Group
 
 Mailing List
 -------------------------
-None currently. Also note this is very different to Brian's original driver
+linux-aacraid-devel@dell.com (Interested parties troll here)
+http://mbserver.adaptec.com/ (Currently more Community Support than Devel Support)
+Also note this is very different to Brian's original driver
 so don't expect him to support it.
-Adaptec does support this driver.  Contact either tech support or deanna bonds.
+Adaptec does support this driver.  Contact either tech support or Mark Salyzyn.
 
 Original by Brian Boerner February 2001
 Rewritten by Alan Cox, November 2001
diff -Nru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
--- a/drivers/scsi/aacraid/aacraid.h	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/aacraid/aacraid.h	Wed May 12 20:31:43 2004
@@ -1,18 +1,20 @@
-//#define dprintk(x) printk x
-#define dprintk(x)
+#if (!defined(dprintk))
+# define dprintk(x)
+#endif
 
 /*------------------------------------------------------------------------------
  *              D E F I N E S
  *----------------------------------------------------------------------------*/
+
 #define MAXIMUM_NUM_CONTAINERS	31
 #define MAXIMUM_NUM_ADAPTERS	8
 
-#define AAC_NUM_FIB	578
+#define AAC_NUM_FIB		578
 //#define AAC_NUM_IO_FIB	512
-#define AAC_NUM_IO_FIB	100
+#define AAC_NUM_IO_FIB		100
 
-#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1)
-#define AAC_MAX_LUN	(8)
+#define AAC_MAX_TARGET 		(MAXIMUM_NUM_CONTAINERS+1)
+#define AAC_MAX_LUN		(8)
 
 #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
 
@@ -241,92 +243,6 @@
 };
 
 /*
- * Implement our own version of these so we have 64 bit compatability
- * The adapter uses these and can only handle 32 bit addresses
- */
-
-struct aac_list_head {
-	u32 next;
-	u32 prev;
-};
-
-#define AAC_INIT_LIST_HEAD(ptr) do { \
-	(ptr)->next = (u32)(ulong)(ptr); \
-	(ptr)->prev = (u32)(ulong)(ptr); \
-} while (0)
-/**
- * aac_list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static __inline__ int aac_list_empty(struct aac_list_head *head)
-{
-	return head->next == ((u32)(ulong)head);
-}
-
-/*
- * Insert a new entry between two known consecutive entries. 
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static __inline__ void aac_list_add(struct aac_list_head * n,
-	struct aac_list_head * prev,
-	struct aac_list_head * next)
-{
-	next->prev = (u32)(ulong)n;
-	n->next = (u32)(ulong)next;
-	n->prev = (u32)(ulong)prev;
-	prev->next = (u32)(ulong)n;
-}
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static __inline__ void aac_list_add_tail(struct aac_list_head *n, struct aac_list_head *head)
-{
-	aac_list_add(n, (struct aac_list_head*)(ulong)(head->prev), head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static __inline__ void __aac_list_del(struct aac_list_head * p,
-				  struct aac_list_head * n)
-{
-	n->prev = (u32)(ulong)p;
-	p->next = (u32)(ulong)n;
-}
-
-/**
- * aac_list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
- */
-static __inline__ void aac_list_del(struct aac_list_head *entry)
-{
-	__aac_list_del((struct aac_list_head*)(ulong)entry->prev,(struct aac_list_head*)(ulong) entry->next);
-	entry->next = entry->prev = 0;
-}
-
-/**
- * aac_list_entry - get the struct for this entry
- * @ptr:	the &struct list_head pointer.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the list_struct within the struct.
- */
-#define aac_list_entry(ptr, type, member) \
-	((type *)((char *)(ptr)-(ulong)(&((type *)0)->member)))
-
-/*
  *	Assign type values to the FSA communication data structures
  */
 
@@ -339,11 +255,11 @@
 #define		FsaNormal	1
 #define		FsaHigh		2
 
-
 /*
  * Define the FIB. The FIB is the where all the requested data and
  * command information are put to the application on the FSA adapter.
  */
+
 struct aac_fibhdr {
 	u32 XferState;			// Current transfer state for this CCB
 	u16 Command;			// Routing information for the destination
@@ -359,13 +275,9 @@
 		    u32 _ReceiverTimeStart; 	// Timestamp for receipt of fib
 		    u32 _ReceiverTimeDone;	// Timestamp for completion of fib
 		} _s;
-		struct aac_list_head _FibLinks;	// Used to link Adapter Initiated Fibs on the host
-//		struct list_head _FibLinks;	// Used to link Adapter Initiated Fibs on the host
 	} _u;
 };
 
-#define FibLinks			_u._FibLinks
-
 #define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr))
 
 
@@ -558,12 +470,11 @@
 	spinlock_t		lockdata;	/* Actual lock (used only on one side of the lock) */
 	unsigned long		SavedIrql;     	/* Previous IRQL when the spin lock is taken */
 	u32			padding;	/* Padding - FIXME - can remove I believe */
-	struct aac_list_head 	cmdq;	   	/* A queue of FIBs which need to be prcessed by the FS thread. This is */
-//	struct list_head 	cmdq;	   	/* A queue of FIBs which need to be prcessed by the FS thread. This is */
-                                		        /* only valid for command queues which receive entries from the adapter. */
-	struct list_head	pendingq;		/* A queue of outstanding fib's to the adapter. */
-	u32			numpending;		/* Number of entries on outstanding queue. */
-	struct aac_dev *	dev;			/* Back pointer to adapter structure */
+	struct list_head 	cmdq;	   	/* A queue of FIBs which need to be prcessed by the FS thread. This is */
+                                		/* only valid for command queues which receive entries from the adapter. */
+	struct list_head	pendingq;	/* A queue of outstanding fib's to the adapter. */
+	u32			numpending;	/* Number of entries on outstanding queue. */
+	struct aac_dev *	dev;		/* Back pointer to adapter structure */
 };
 
 /*
@@ -744,7 +655,7 @@
 	struct semaphore 	wait_sem;	// this is used to wait for the next fib to arrive.
 	int			wait;		// Set to true when thread is in WaitForSingleObject
 	unsigned long		count;		// total number of FIBs on FibList
-	struct aac_list_head	hw_fib_list;	// this holds hw_fibs which should be 32 bit addresses
+	struct list_head	fib_list;	// this holds fibs and their attachd hw_fibs
 };
 
 struct fsa_scsi_hba {
@@ -781,7 +692,11 @@
 	 *	Outstanding I/O queue.
 	 */
 	struct list_head	queue;
-
+	/*
+	 *	And for the internal issue/reply queues (we may be able
+	 *	to merge these two)
+	 */
+	struct list_head	fiblink;
 	void 			*data;
 	struct hw_fib		*hw_fib;		/* Actual shared object */
 	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
@@ -836,19 +751,19 @@
 /*
  * Supported Options
  */
-#define AAC_OPT_SNAPSHOT	cpu_to_le32(1)
-#define AAC_OPT_CLUSTERS	cpu_to_le32(1<<1)
-#define AAC_OPT_WRITE_CACHE	cpu_to_le32(1<<2)
-#define AAC_OPT_64BIT_DATA	cpu_to_le32(1<<3)
-#define AAC_OPT_HOST_TIME_FIB	cpu_to_le32(1<<4)
-#define AAC_OPT_RAID50		cpu_to_le32(1<<5)
-#define AAC_OPT_4GB_WINDOW	cpu_to_le32(1<<6)
-#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7)
-#define AAC_OPT_SOFT_ERR_REPORT	cpu_to_le32(1<<8)
-#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9)
-#define AAC_OPT_SGMAP_HOST64	cpu_to_le32(1<<10)
-#define AAC_OPT_ALARM		cpu_to_le32(1<<11)
-#define AAC_OPT_NONDASD		cpu_to_le32(1<<12)
+#define AAC_OPT_SNAPSHOT		cpu_to_le32(1)
+#define AAC_OPT_CLUSTERS		cpu_to_le32(1<<1)
+#define AAC_OPT_WRITE_CACHE		cpu_to_le32(1<<2)
+#define AAC_OPT_64BIT_DATA		cpu_to_le32(1<<3)
+#define AAC_OPT_HOST_TIME_FIB		cpu_to_le32(1<<4)
+#define AAC_OPT_RAID50			cpu_to_le32(1<<5)
+#define AAC_OPT_4GB_WINDOW		cpu_to_le32(1<<6)
+#define AAC_OPT_SCSI_UPGRADEABLE 	cpu_to_le32(1<<7)
+#define AAC_OPT_SOFT_ERR_REPORT		cpu_to_le32(1<<8)
+#define AAC_OPT_SUPPORTED_RECONDITION 	cpu_to_le32(1<<9)
+#define AAC_OPT_SGMAP_HOST64		cpu_to_le32(1<<10)
+#define AAC_OPT_ALARM			cpu_to_le32(1<<11)
+#define AAC_OPT_NONDASD			cpu_to_le32(1<<12)
 
 struct aac_dev
 {
@@ -862,11 +777,10 @@
 	 */	
 	dma_addr_t		hw_fib_pa;
 	struct hw_fib		*hw_fib_va;
-	ulong			fib_base_va;
+	struct hw_fib		*aif_base_va;
 	/*
 	 *	Fib Headers
 	 */
-// dmb	struct fib              fibs[AAC_NUM_FIB]; /* Doing it here takes up too much from the scsi pool*/
 	struct fib              *fibs;
 
 	struct fib		*free_fib;
@@ -887,7 +801,6 @@
 	unsigned long		fsrev;		/* Main driver's revision number */
 	
 	struct aac_init		*init;		/* Holds initialization info to communicate with adapter */
-//	void *			init_pa; 	/* Holds physical address of the init struct */
 	dma_addr_t		init_pa; 	/* Holds physical address of the init struct */
 	
 	struct pci_dev		*pdev;		/* Our PCI interface */
@@ -898,7 +811,7 @@
 
 	struct Scsi_Host	*scsi_host_ptr;
 	struct fsa_scsi_hba	fsa_dev;
-	int			thread_pid;
+	pid_t			thread_pid;
 	int			cardtype;
 	
 	/*
diff -Nru a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
--- a/drivers/scsi/aacraid/commctrl.c	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/aacraid/commctrl.c	Wed May 12 20:31:43 2004
@@ -148,7 +148,7 @@
 		 *	the list to 0.
 		 */
 		fibctx->count = 0;
-		AAC_INIT_LIST_HEAD(&fibctx->hw_fib_list);
+		INIT_LIST_HEAD(&fibctx->fib_list);
 		fibctx->jiffies = jiffies/HZ;
 		/*
 		 *	Now add this context onto the adapter's 
@@ -179,7 +179,7 @@
 {
 	struct fib_ioctl f;
 	struct aac_fib_context *fibctx, *aifcp;
-	struct hw_fib * hw_fib;
+	struct fib *fib;
 	int status;
 	struct list_head * entry;
 	int found;
@@ -222,25 +222,27 @@
 	 *	-EAGAIN
 	 */
 return_fib:
-	if (!aac_list_empty(&fibctx->hw_fib_list)) {
-		struct aac_list_head * entry;
+	if (!list_empty(&fibctx->fib_list)) {
+		struct list_head * entry;
 		/*
 		 *	Pull the next fib from the fibs
 		 */
-		entry = (struct aac_list_head*)(ulong)fibctx->hw_fib_list.next;
-		aac_list_del(entry);
+		entry = fibctx->fib_list.next;
+		list_del(entry);
 		
-		hw_fib = aac_list_entry(entry, struct hw_fib, header.FibLinks);
+		fib = list_entry(entry, struct fib, fiblink);
 		fibctx->count--;
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		if (copy_to_user(f.fib, hw_fib, sizeof(struct hw_fib))) {
-			kfree(hw_fib);
+		if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) {
+			kfree(fib->hw_fib);
+			kfree(fib);
 			return -EFAULT;
 		}	
 		/*
 		 *	Free the space occupied by this copy of the fib.
 		 */
-		kfree(hw_fib);
+		kfree(fib->hw_fib);
+		kfree(fib);
 		status = 0;
 		fibctx->jiffies = jiffies/HZ;
 	} else {
@@ -262,24 +264,25 @@
 
 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
 {
-	struct hw_fib *hw_fib;
+	struct fib *fib;
 
 	/*
 	 *	First free any FIBs that have not been consumed.
 	 */
-	while (!aac_list_empty(&fibctx->hw_fib_list)) {
-		struct aac_list_head * entry;
+	while (!list_empty(&fibctx->fib_list)) {
+		struct list_head * entry;
 		/*
 		 *	Pull the next fib from the fibs
 		 */
-		entry = (struct aac_list_head*)(ulong)(fibctx->hw_fib_list.next);
-		aac_list_del(entry);
-		hw_fib = aac_list_entry(entry, struct hw_fib, header.FibLinks);
+		entry = fibctx->fib_list.next;
+		list_del(entry);
+		fib = list_entry(entry, struct fib, fiblink);
 		fibctx->count--;
 		/*
 		 *	Free the space occupied by this copy of the fib.
 		 */
-		kfree(hw_fib);
+		kfree(fib->hw_fib);
+		kfree(fib);
 	}
 	/*
 	 *	Remove the Context from the AdapterFibContext List
diff -Nru a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
--- a/drivers/scsi/aacraid/comminit.c	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/aacraid/comminit.c	Wed May 12 20:31:43 2004
@@ -81,9 +81,9 @@
 	 *	Adapter Fibs are the first thing allocated so that they
 	 *	start page aligned
 	 */
-	dev->fib_base_va = (ulong)base;
+	dev->aif_base_va = (struct hw_fib *)base;
 	
-	init->AdapterFibsVirtualAddress = cpu_to_le32((u32)(ulong)phys);
+	init->AdapterFibsVirtualAddress = cpu_to_le32(0);
 	init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
 	init->AdapterFibsSize = cpu_to_le32(fibsize);
 	init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
@@ -94,6 +94,9 @@
 	 * mapping system, but older Firmware did, and had *troubles* dealing
 	 * with the math overloading past 32 bits, thus we must limit this
 	 * field.
+	 *
+	 * FIXME: this assumes the memory is mapped zero->n, which isnt
+	 * always true on real computers.
 	 */
 	if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) {
 		init->HostPhysMemPages = 
@@ -140,7 +143,7 @@
 	q->dev = dev;
 	INIT_LIST_HEAD(&q->pendingq);
 	init_waitqueue_head(&q->cmdready);
-	AAC_INIT_LIST_HEAD(&q->cmdq);
+	INIT_LIST_HEAD(&q->cmdq);
 	init_waitqueue_head(&q->qfull);
 	spin_lock_init(&q->lockdata);
 	q->lock = &q->lockdata;
diff -Nru a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
--- a/drivers/scsi/aacraid/commsup.c	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/aacraid/commsup.c	Wed May 12 20:31:43 2004
@@ -133,13 +133,10 @@
 	unsigned long flags;
 	spin_lock_irqsave(&dev->fib_lock, flags);
 	fibptr = dev->free_fib;	
-	while(!fibptr){
-		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
-		spin_lock_irqsave(&dev->fib_lock, flags);
-		fibptr = dev->free_fib;	
-	}
+	/* Cannot sleep here or you get hangs. Instead we did the
+	   maths at compile time. */
+	if(!fibptr)
+		BUG();
 	dev->free_fib = fibptr->next;
 	spin_unlock_irqrestore(&dev->fib_lock, flags);
 	/*
@@ -290,7 +287,7 @@
 	}
 }   
 
-/*Command thread: *
+/**
  *	aac_queue_get		-	get the next free QE
  *	@dev: Adapter
  *	@index: Returned index
@@ -450,8 +447,7 @@
 	 *	Map the fib into 32bits by using the fib number
 	 */
 
-//	hw_fib->header.SenderFibAddress = ((u32)(fibptr-dev->fibs)) << 1;
-	hw_fib->header.SenderFibAddress = cpu_to_le32((u32)(ulong)fibptr->hw_fib_pa);
+	hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr-dev->fibs)) << 1);
 	hw_fib->header.SenderData = (u32)(fibptr - dev->fibs);
 	/*
 	 *	Set FIB state to indicate where it came from and if we want a
@@ -492,7 +488,7 @@
 	dprintk((KERN_DEBUG "  Command =               %d.\n", hw_fib->header.Command));
 	dprintk((KERN_DEBUG "  XferState  =            %x.\n", 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=%xl\n",(ulong)fibptr->hw_fib_pa));
+	dprintk((KERN_DEBUG "  hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
 	dprintk((KERN_DEBUG "  fib being sent=%p\n",fibptr));
 	/*
 	 *	Fill in the Callback and CallbackContext if we are not
@@ -806,8 +802,8 @@
  
 int aac_command_thread(struct aac_dev * dev)
 {
-	struct hw_fib *hw_fib, *newfib;
-	struct fib fibptr; /* for error logging */
+	struct hw_fib *hw_fib, *hw_newfib;
+	struct fib *fib, *newfib;
 	struct aac_queue_block *queues = dev->queues;
 	struct aac_fib_context *fibctx;
 	unsigned long flags;
@@ -828,42 +824,44 @@
 	 *	Let the DPC know it has a place to send the AIF's to.
 	 */
 	dev->aif_thread = 1;
-	memset(&fibptr, 0, sizeof(struct fib));
 	add_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
 	set_current_state(TASK_INTERRUPTIBLE);
 	while(1) 
 	{
 		spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
-		while(!aac_list_empty(&(queues->queue[HostNormCmdQueue].cmdq))) {
-			struct aac_list_head *entry;
+		while(!list_empty(&(queues->queue[HostNormCmdQueue].cmdq))) {
+			struct list_head *entry;
 			struct aac_aifcmd * aifcmd;
 
 			set_current_state(TASK_RUNNING);
 		
-			entry = (struct aac_list_head*)(ulong)(queues->queue[HostNormCmdQueue].cmdq.next);
-			dprintk(("aacraid: Command thread: removing fib from cmdq (%p)\n",entry));
-			aac_list_del(entry);
+			entry = queues->queue[HostNormCmdQueue].cmdq.next;
+			list_del(entry);
 			
 			spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
-			hw_fib = aac_list_entry(entry, struct hw_fib, header.FibLinks);
+			fib = list_entry(entry, struct fib, fiblink);
 			/*
 			 *	We will process the FIB here or pass it to a 
 			 *	worker thread that is TBD. We Really can't 
 			 *	do anything at this point since we don't have
 			 *	anything defined for this thread to do.
 			 */
-			memset(&fibptr, 0, sizeof(struct fib));
-			fibptr.type = FSAFS_NTC_FIB_CONTEXT;
-			fibptr.size = sizeof( struct fib );
-			fibptr.hw_fib = hw_fib;
-			fibptr.data = hw_fib->data;
-			fibptr.dev = dev;
+			hw_fib = fib->hw_fib;
+			memset(fib, 0, sizeof(struct fib));
+			fib->type = FSAFS_NTC_FIB_CONTEXT;
+			fib->size = sizeof( struct fib );
+			fib->hw_fib = hw_fib;
+			fib->data = hw_fib->data;
+			fib->dev = dev;
 			/*
 			 *	We only handle AifRequest fibs from the adapter.
 			 */
 			aifcmd = (struct aac_aifcmd *) hw_fib->data;
-			if (aifcmd->command == le16_to_cpu(AifCmdDriverNotify)) {
-				aac_handle_aif(dev, &fibptr);
+			if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
+				/* Handle Driver Notify Events */
+				aac_handle_aif(dev, fib);
+				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
+				fib_adapter_complete(fib, sizeof(u32));
 			} else {
 				struct list_head *entry;
 				/* The u32 here is important and intended. We are using
@@ -872,6 +870,10 @@
 				u32 time_now, time_last;
 				unsigned long flagv;
 				
+				/* Sniff events */
+				if (aifcmd->command == cpu_to_le32(AifCmdEventNotify))
+					aac_handle_aif(dev, fib);
+				
 				time_now = jiffies/HZ;
 
 				spin_lock_irqsave(&dev->fib_lock, flagv);
@@ -893,6 +895,11 @@
 					 */
 					if (fibctx->count > 20)
 					{
+						/*
+						 * It's *not* jiffies folks,
+						 * but jiffies / HZ so do not
+						 * panic ...
+						 */
 						time_last = fibctx->jiffies;
 						/*
 						 * Has it been > 2 minutes 
@@ -909,17 +916,20 @@
 					 * Warning: no sleep allowed while
 					 * holding spinlock
 					 */
-					newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);
-					if (newfib) {
+					hw_newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);
+					newfib = kmalloc(sizeof(struct fib), GFP_ATOMIC);
+					if (newfib && hw_newfib) {
 						/*
 						 * Make the copy of the FIB
 						 */
-						memcpy(newfib, hw_fib, sizeof(struct hw_fib));
+						memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib));
+						memcpy(newfib, fib, sizeof(struct fib));
+						newfib->hw_fib = hw_newfib;
 						/*
 						 * Put the FIB onto the
 						 * fibctx's fibs
 						 */
-						aac_list_add_tail(&newfib->header.FibLinks, &fibctx->hw_fib_list);
+						list_add_tail(&newfib->fiblink, &fibctx->fib_list);
 						fibctx->count++;
 						/* 
 						 * Set the event to wake up the
@@ -928,6 +938,10 @@
 						up(&fibctx->wait_sem);
 					} else {
 						printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");
+						if(newfib)
+							kfree(newfib);
+						if(hw_newfib)
+							kfree(hw_newfib);
 					}
 					entry = entry->next;
 				}
@@ -935,10 +949,11 @@
 				 *	Set the status of this FIB
 				 */
 				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
-				fib_adapter_complete(&fibptr, sizeof(u32));
+				fib_adapter_complete(fib, sizeof(u32));
 				spin_unlock_irqrestore(&dev->fib_lock, flagv);
 			}
 			spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
+			kfree(fib);
 		}
 		/*
 		 *	There are no more AIF's
diff -Nru a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
--- a/drivers/scsi/aacraid/dpcsup.c	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/aacraid/dpcsup.c	Wed May 12 20:31:43 2004
@@ -70,12 +70,12 @@
 	 */
 	while(aac_consumer_get(dev, q, &entry))
 	{
-		u32 fast ;
-		fast = (entry->addr & cpu_to_le32(0x01));
-		hwfib = (struct hw_fib *)((char *)dev->hw_fib_va + 
-				((entry->addr & ~0x01) - dev->hw_fib_pa));
-		fib = &dev->fibs[hwfib->header.SenderData];
-
+		int fast;
+		u32 index = le32_to_cpu(entry->addr);
+		fast = index & 0x01;
+		fib = &dev->fibs[index >> 1];
+		hwfib = fib->hw_fib;
+		
 		aac_consumer_free(dev, q, HostNormRespQueue);
 		/*
 		 *	Remove this fib from the Outstanding I/O queue.
@@ -169,29 +169,44 @@
 	 */
 	while(aac_consumer_get(dev, q, &entry))
 	{
+		struct fib fibctx;
 		struct hw_fib * hw_fib;
-		hw_fib = (struct hw_fib *)((char *)dev->hw_fib_va + 
-				((entry->addr & ~0x01) - dev->hw_fib_pa));
-
-		if (dev->aif_thread) {
-		        aac_list_add_tail(&hw_fib->header.FibLinks, &q->cmdq);
+		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
+		 */
+		if (dev->aif_thread)
+			if((fib = kmalloc(sizeof(struct fib), GFP_ATOMIC)) == NULL)
+				fib = &fibctx;
+		
+		memset(fib, 0, sizeof(struct fib));
+		INIT_LIST_HEAD(&fib->fiblink);
+		fib->type = FSAFS_NTC_FIB_CONTEXT;
+		fib->size = sizeof(struct fib);
+		fib->hw_fib = hw_fib;
+		fib->data = hw_fib->data;
+		fib->dev = dev;
+		
+				
+		if (dev->aif_thread && fib != &fibctx) {
+		        list_add_tail(&fib->fiblink, &q->cmdq);
 	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
 		        wake_up_interruptible(&q->cmdready);
 		} else {
-			struct fib fibctx;
 	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
 			spin_unlock_irqrestore(q->lock, flags);
-			memset(&fibctx, 0, sizeof(struct fib));
-			fibctx.type = FSAFS_NTC_FIB_CONTEXT;
-			fibctx.size = sizeof(struct fib);
-			fibctx.hw_fib = hw_fib;
-			fibctx.data = hw_fib->data;
-			fibctx.dev = dev;
 			/*
 			 *	Set the status of this FIB
 			 */
 			*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
-			fib_adapter_complete(&fibctx, sizeof(u32));
+			fib_adapter_complete(fib, sizeof(u32));
 			spin_lock_irqsave(q->lock, flags);
 		}		
 	}
diff -Nru a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
--- a/drivers/scsi/aacraid/sa.c	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/aacraid/sa.c	Wed May 12 20:31:43 2004
@@ -419,6 +419,11 @@
 	 *	Start any kernel threads needed
 	 */
 	dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
+	if (dev->thread_pid < 0) {
+		printk(KERN_ERR "aacraid: Unable to create command thread.\n");
+		return -1;
+	}
+
 	/*
 	 *	Tell the adapter that all is configure, and it can start 
 	 *	accepting requests
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/st.c	Wed May 12 20:31:43 2004
@@ -486,7 +486,7 @@
 		   tape_name(STp), forward ? "forward" : "backward"));
 
 	SRpnt = st_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE,
-			   STp->timeout, MAX_RETRIES, TRUE);
+			   STp->device->timeout, MAX_RETRIES, TRUE);
 	if (!SRpnt)
 		return (STp->buffer)->syscall_result;
 
@@ -544,7 +544,7 @@
 		cmd[4] = blks;
 
 		SRpnt = st_do_scsi(NULL, STp, cmd, transfer, SCSI_DATA_WRITE,
-				   STp->timeout, MAX_WRITE_RETRIES, TRUE);
+				   STp->device->timeout, MAX_WRITE_RETRIES, TRUE);
 		if (!SRpnt)
 			return (STp->buffer)->syscall_result;
 
@@ -867,7 +867,7 @@
 		memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
 		cmd[0] = READ_BLOCK_LIMITS;
 
-		SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, SCSI_DATA_READ, STp->timeout,
+		SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, SCSI_DATA_READ, STp->device->timeout,
 				   MAX_READY_RETRIES, TRUE);
 		if (!SRpnt) {
 			retval = (STp->buffer)->syscall_result;
@@ -894,7 +894,7 @@
 	cmd[0] = MODE_SENSE;
 	cmd[4] = 12;
 
-	SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, SCSI_DATA_READ, STp->timeout,
+	SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, SCSI_DATA_READ, STp->device->timeout,
 			   MAX_READY_RETRIES, TRUE);
 	if (!SRpnt) {
 		retval = (STp->buffer)->syscall_result;
@@ -1116,7 +1116,7 @@
 		cmd[4] = 1 + STp->two_fm;
 
 		SRpnt = st_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE,
-				   STp->timeout, MAX_WRITE_RETRIES, TRUE);
+				   STp->device->timeout, MAX_WRITE_RETRIES, TRUE);
 		if (!SRpnt) {
 			result = (STp->buffer)->syscall_result;
 			goto out;
@@ -1509,7 +1509,7 @@
 		cmd[4] = blks;
 
 		SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
-				   STp->timeout, MAX_WRITE_RETRIES, !async_write);
+				   STp->device->timeout, MAX_WRITE_RETRIES, !async_write);
 		if (!SRpnt) {
 			retval = STbp->syscall_result;
 			goto out;
@@ -1679,7 +1679,7 @@
 
 	SRpnt = *aSRpnt;
 	SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, SCSI_DATA_READ,
-			   STp->timeout, MAX_RETRIES, TRUE);
+			   STp->device->timeout, MAX_RETRIES, TRUE);
 	release_buffering(STp);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
@@ -2081,7 +2081,7 @@
 			DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
 			       (value & ~MT_ST_SET_LONG_TIMEOUT)));
 		} else {
-			STp->timeout = value * HZ;
+			STp->device->timeout = value * HZ;
 			DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
 				name, value) );
 		}
@@ -2189,7 +2189,7 @@
 	cmd[4] = 255;
 
 	SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ,
-			   STp->timeout, 0, TRUE);
+			   STp->device->timeout, 0, TRUE);
 	if (SRpnt == NULL)
 		return (STp->buffer)->syscall_result;
 
@@ -2220,7 +2220,7 @@
 	(STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
 
 	SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE,
-			   (slow ? STp->long_timeout : STp->timeout), 0, TRUE);
+			   (slow ? STp->long_timeout : STp->device->timeout), 0, TRUE);
 	if (SRpnt == NULL)
 		return (STp->buffer)->syscall_result;
 
@@ -2332,7 +2332,7 @@
 	}
 	if (STp->immediate) {
 		cmd[1] = 1;	/* Don't wait for completion */
-		timeout = STp->timeout;
+		timeout = STp->device->timeout;
 	}
 	else
 		timeout = STp->long_timeout;
@@ -2512,7 +2512,7 @@
 		cmd[2] = (arg >> 16);
 		cmd[3] = (arg >> 8);
 		cmd[4] = arg;
-		timeout = STp->timeout;
+		timeout = STp->device->timeout;
                 DEBC(
                      if (cmd_in == MTWEOF)
                                printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
@@ -2530,7 +2530,7 @@
 		cmd[0] = REZERO_UNIT;
 		if (STp->immediate) {
 			cmd[1] = 1;	/* Don't wait for completion */
-			timeout = STp->timeout;
+			timeout = STp->device->timeout;
 		}
                 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
 		fileno = blkno = at_sm = 0;
@@ -2543,7 +2543,7 @@
 		cmd[0] = START_STOP;
 		if (STp->immediate) {
 			cmd[1] = 1;	/* Don't wait for completion */
-			timeout = STp->timeout;
+			timeout = STp->device->timeout;
 		}
 		cmd[4] = 3;
                 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
@@ -2576,7 +2576,7 @@
 		cmd[1] = (arg ? 1 : 0);	/* Long erase with non-zero argument */
 		if (STp->immediate) {
 			cmd[1] |= 2;	/* Don't wait for completion */
-			timeout = STp->timeout;
+			timeout = STp->device->timeout;
 		}
 		else
 			timeout = STp->long_timeout * 8;
@@ -2628,7 +2628,7 @@
 		(STp->buffer)->b_data[9] = (ltmp >> 16);
 		(STp->buffer)->b_data[10] = (ltmp >> 8);
 		(STp->buffer)->b_data[11] = ltmp;
-		timeout = STp->timeout;
+		timeout = STp->device->timeout;
                 DEBC(
 			if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
 				printk(ST_DEB_MSG
@@ -2809,7 +2809,7 @@
 		if (!logical && !STp->scsi2_logical)
 			scmd[1] = 1;
 	}
-	SRpnt = st_do_scsi(NULL, STp, scmd, 20, SCSI_DATA_READ, STp->timeout,
+	SRpnt = st_do_scsi(NULL, STp, scmd, 20, SCSI_DATA_READ, STp->device->timeout,
 			   MAX_READY_RETRIES, TRUE);
 	if (!SRpnt)
 		return (STp->buffer)->syscall_result;
@@ -2911,7 +2911,7 @@
 	}
 	if (STp->immediate) {
 		scmd[1] |= 1;		/* Don't wait for completion */
-		timeout = STp->timeout;
+		timeout = STp->device->timeout;
 	}
 
 	SRpnt = st_do_scsi(NULL, STp, scmd, 0, SCSI_DATA_NONE,
@@ -3832,7 +3832,7 @@
 	tpnt->partition = 0;
 	tpnt->new_partition = 0;
 	tpnt->nbr_partitions = 0;
-	tpnt->timeout = ST_TIMEOUT;
+	tpnt->device->timeout = ST_TIMEOUT;
 	tpnt->long_timeout = ST_LONG_TIMEOUT;
 	tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
 
diff -Nru a/drivers/scsi/st.h b/drivers/scsi/st.h
--- a/drivers/scsi/st.h	Wed May 12 20:31:43 2004
+++ b/drivers/scsi/st.h	Wed May 12 20:31:43 2004
@@ -100,7 +100,6 @@
 	unsigned char c_algo;			/* compression algorithm */
 	unsigned char pos_unknown;			/* after reset position unknown */
 	int tape_type;
-	int timeout;		/* timeout for normal commands */
 	int long_timeout;	/* timeout for commands known to take long time */
 
 	unsigned long max_pfn;	/* the maximum page number reachable by the HBA */