PATCH: revised aacraid driver patch

From: Alan Cox
Date: Wed May 12 2004 - 16:49:21 EST


This fixes a problem with AMD64 iommu compatibility and now (with the
block layer patch) passes the test sets on a dual opteron.

Alan


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-11 20:20:48.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/aachba.c linux-2.6.6/drivers/scsi/aacraid/aachba.c
--- linux.vanilla-2.6.6/drivers/scsi/aacraid/aachba.c 2004-05-10 03:32:29.000000000 +0100
+++ linux-2.6.6/drivers/scsi/aacraid/aachba.c 2004-05-11 19:30:08.000000000 +0100
@@ -514,11 +514,12 @@
dev->nondasd_support = (nondasd!=0);
}
if(dev->nondasd_support != 0){
- printk(KERN_INFO"%s%d: Non-DASD support enabled\n",dev->name, dev->id);
+ printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
}

dev->pae_support = 0;
if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
+ printk(KERN_INFO "%s%d: 64bit support enabled.\n", dev->name, dev->id);
dev->pae_support = 1;
}

@@ -726,7 +727,10 @@
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
+ {
+ dprintk("read queued.\n");
return 0;
+ }

printk(KERN_WARNING "aac_read: fib_send failed with status: %d.\n", status);
/*
@@ -832,7 +836,10 @@
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
+ {
+ dprintk("write queued.\n");
return 0;
+ }

printk(KERN_WARNING "aac_write: fib_send failed with status: %d\n", status);
/*
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-11 19:22:22.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-11 20:20:37.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,11 +94,19 @@
* mapping system, but older Firmware did, and had *troubles* dealing
* with the math overloading past 32 bits, thus we must limit this
* field.
+ *
+ * This assumes the memory is mapped zero->n, which isnt
+ * always true on real computers. It also has some slight problems
+ * with the GART on x86-64. I've btw never tried DMA from PCI space
+ * on this platform but don't be suprised if its problematic.
*/
+#ifndef CONFIG_GART_IOMMU
if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) {
init->HostPhysMemPages =
cpu_to_le32(num_physpages << (PAGE_SHIFT-12));
- } else {
+ } else
+#endif
+ {
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
}

@@ -140,7 +148,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-11 19:22:22.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-11 19:22:22.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-11 19:22:22.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/