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 # # 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 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 */