X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Faacraid%2Fcommsup.c;h=3f36dbaa2bb32b1452ee2267dd4d2cc7eb83f584;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=0465af27ffa19c42bb27c8a487d442b137889fb6;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 0465af27f..3f36dbaa2 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -102,7 +102,7 @@ int fib_setup(struct aac_dev * dev) fibptr->next = fibptr+1; /* Forward chain the fibs */ init_MUTEX_LOCKED(&fibptr->event_wait); spin_lock_init(&fibptr->event_lock); - hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); + hw_fib_va->header.XferState = 0xffffffff; hw_fib_va->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); fibptr->hw_fib_pa = hw_fib_pa; hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + sizeof(struct hw_fib)); @@ -133,13 +133,10 @@ struct fib * fib_alloc(struct aac_dev *dev) 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); /* @@ -151,7 +148,7 @@ struct fib * fib_alloc(struct aac_dev *dev) * Null out fields that depend on being zero at the start of * each I/O */ - fibptr->hw_fib->header.XferState = cpu_to_le32(0); + fibptr->hw_fib->header.XferState = 0; fibptr->callback = NULL; fibptr->callback_data = NULL; @@ -178,7 +175,8 @@ void fib_free(struct fib * fibptr) } else { if (fibptr->hw_fib->header.XferState != 0) { printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", - (void*)fibptr, fibptr->hw_fib->header.XferState); + (void*)fibptr, + le32_to_cpu(fibptr->hw_fib->header.XferState)); } fibptr->next = fibptr->dev->free_fib; fibptr->dev->free_fib = fibptr; @@ -218,7 +216,7 @@ void fib_dealloc(struct fib * fibptr) struct hw_fib *hw_fib = fibptr->hw_fib; if(hw_fib->header.StructType != FIB_MAGIC) BUG(); - hw_fib->header.XferState = cpu_to_le32(0); + hw_fib->header.XferState = 0; } /* @@ -290,7 +288,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr } } -/*Command thread: * +/** * aac_queue_get - get the next free QE * @dev: Adapter * @index: Returned index @@ -347,7 +345,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f * in the queue entry. */ if (map) - entry->addr = fibptr->hw_fib_pa; + entry->addr = cpu_to_le32(fibptr->hw_fib_pa); return 0; } @@ -421,13 +419,13 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_queue * q; unsigned long flags = 0; - if (!(le32_to_cpu(hw_fib->header.XferState) & HostOwned)) + if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) return -EBUSY; /* * There are 5 cases with the wait and reponse requested flags. * The only invalid cases are if the caller requests to wait and * does not request a response and if the caller does not want a - * response and the Fibis not allocated from pool. If a response + * response and the Fib is not allocated from pool. If a response * is not requesed the Fib will just be deallocaed by the DPC * routine when the response comes back from the adapter. No * further processing will be done besides deleting the Fib. We @@ -450,8 +448,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority * 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 +489,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority 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 @@ -570,12 +567,6 @@ int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entr return(status); } -int aac_consumer_avail(struct aac_dev *dev, struct aac_queue * q) -{ - return (le32_to_cpu(*q->headers.producer) != le32_to_cpu(*q->headers.consumer)); -} - - /** * aac_consumer_free - free consumer entry * @dev: Adapter @@ -636,7 +627,7 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size) struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_dev * dev = fibptr->dev; unsigned long nointr = 0; - if (le32_to_cpu(hw_fib->header.XferState) == 0) + if (hw_fib->header.XferState == 0) return 0; /* * If we plan to do anything check the structure type first. @@ -708,7 +699,7 @@ int fib_complete(struct fib * fibptr) * Check for a fib which has already been completed */ - if (hw_fib->header.XferState == cpu_to_le32(0)) + if (hw_fib->header.XferState == 0) return 0; /* * If we plan to do anything check the structure type first. @@ -765,35 +756,13 @@ void aac_printf(struct aac_dev *dev, u32 val) length = 255; if (cp[length] != 0) cp[length] = 0; - if (level == LOG_HIGH_ERROR) + if (level == LOG_AAC_HIGH_ERROR) printk(KERN_WARNING "aacraid:%s", cp); else printk(KERN_INFO "aacraid:%s", cp); memset(cp, 0, 256); } - -/** - * aac_handle_aif - Handle a message from the firmware - * @dev: Which adapter this fib is from - * @fibptr: Pointer to fibptr from adapter - * - * This routine handles a driver notify fib from the adapter and - * dispatches it to the appropriate routine for handling. - */ - -static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) -{ - struct hw_fib * hw_fib = fibptr->hw_fib; - /* - * Set the status of this FIB to be Invalid parameter. - * - * *(u32 *)fib->data = ST_INVAL; - */ - *(u32 *)hw_fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(fibptr, sizeof(u32)); -} - /** * aac_command_thread - command processing thread * @dev: Adapter to monitor @@ -806,8 +775,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) 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 +797,43 @@ int aac_command_thread(struct aac_dev * dev) * 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 */ + *(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 @@ -893,6 +863,11 @@ int aac_command_thread(struct aac_dev * dev) */ 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 +884,20 @@ int aac_command_thread(struct aac_dev * dev) * 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 +906,10 @@ int aac_command_thread(struct aac_dev * dev) 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 +917,11 @@ int aac_command_thread(struct aac_dev * dev) * 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