PATCH: Do something about aacraid

From: Alan Cox
Date: Mon May 10 2004 - 17:00:05 EST


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


diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.6/drivers/scsi/aacraid/aacraid.h linux-2.6.6/drivers/scsi/aacraid/aacraid.h
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/aacraid.h 2004-05-10 03:32:26.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/aacraid.h 2004-05-10 21:02:37.000000000 +0100
@@ -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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.6/drivers/scsi/aacraid/commctrl.c linux-2.6.6/drivers/scsi/aacraid/commctrl.c
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/commctrl.c 2004-05-10 03:32:28.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/commctrl.c 2004-05-10 21:22:40.000000000 +0100
@@ -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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.6/drivers/scsi/aacraid/comminit.c linux-2.6.6/drivers/scsi/aacraid/comminit.c
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/comminit.c 2004-05-10 03:31:59.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/comminit.c 2004-05-10 21:11:56.000000000 +0100
@@ -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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.6/drivers/scsi/aacraid/commsup.c linux-2.6.6/drivers/scsi/aacraid/commsup.c
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/commsup.c 2004-05-10 03:32:54.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/commsup.c 2004-05-10 21:16:08.000000000 +0100
@@ -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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.6/drivers/scsi/aacraid/dpcsup.c linux-2.6.6/drivers/scsi/aacraid/dpcsup.c
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/dpcsup.c 2004-05-10 03:32:29.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/dpcsup.c 2004-05-10 21:23:18.000000000 +0100
@@ -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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.6/drivers/scsi/aacraid/README linux-2.6.6/drivers/scsi/aacraid/README
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/README 2004-05-10 03:32:00.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/README 2004-05-10 21:20:16.000000000 +0100
@@ -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@xxxxxxxxxxx> 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@xxxxxxxx (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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.6/drivers/scsi/aacraid/sa.c linux-2.6.6/drivers/scsi/aacraid/sa.c
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/sa.c 2004-05-10 03:32:39.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/sa.c 2004-05-10 21:21:30.000000000 +0100
@@ -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
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/