diff options
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 23 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 15 | ||||
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 10 |
3 files changed, 38 insertions, 10 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 255421de9d1a..14d7aa9b7df3 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/completion.h> | 38 | #include <linux/completion.h> |
39 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
40 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> /* ssleep prototype */ |
42 | #include <linux/kthread.h> | 42 | #include <linux/kthread.h> |
43 | #include <asm/semaphore.h> | 43 | #include <asm/semaphore.h> |
44 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
@@ -140,7 +140,8 @@ cleanup: | |||
140 | fibptr->hw_fib_pa = hw_fib_pa; | 140 | fibptr->hw_fib_pa = hw_fib_pa; |
141 | fibptr->hw_fib = hw_fib; | 141 | fibptr->hw_fib = hw_fib; |
142 | } | 142 | } |
143 | aac_fib_free(fibptr); | 143 | if (retval != -EINTR) |
144 | aac_fib_free(fibptr); | ||
144 | return retval; | 145 | return retval; |
145 | } | 146 | } |
146 | 147 | ||
@@ -621,7 +622,13 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
621 | 622 | ||
622 | actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); | 623 | actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); |
623 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 624 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
624 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); | 625 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in " |
626 | "Raw SRB command calculated fibsize=%d " | ||
627 | "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d " | ||
628 | "issued fibsize=%d\n", | ||
629 | actual_fibsize, user_srbcmd->sg.count, | ||
630 | sizeof(struct aac_srb), sizeof(struct sgentry), | ||
631 | fibsize)); | ||
625 | rcode = -EINVAL; | 632 | rcode = -EINVAL; |
626 | goto cleanup; | 633 | goto cleanup; |
627 | } | 634 | } |
@@ -663,6 +670,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
663 | psg->count = cpu_to_le32(sg_indx+1); | 670 | psg->count = cpu_to_le32(sg_indx+1); |
664 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); | 671 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); |
665 | } | 672 | } |
673 | if (status == -EINTR) { | ||
674 | rcode = -EINTR; | ||
675 | goto cleanup; | ||
676 | } | ||
666 | 677 | ||
667 | if (status != 0){ | 678 | if (status != 0){ |
668 | dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); | 679 | dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); |
@@ -696,8 +707,10 @@ cleanup: | |||
696 | for(i=0; i <= sg_indx; i++){ | 707 | for(i=0; i <= sg_indx; i++){ |
697 | kfree(sg_list[i]); | 708 | kfree(sg_list[i]); |
698 | } | 709 | } |
699 | aac_fib_complete(srbfib); | 710 | if (rcode != -EINTR) { |
700 | aac_fib_free(srbfib); | 711 | aac_fib_complete(srbfib); |
712 | aac_fib_free(srbfib); | ||
713 | } | ||
701 | 714 | ||
702 | return rcode; | 715 | return rcode; |
703 | } | 716 | } |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 3f27419c66af..c67da1321133 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -464,6 +464,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
464 | dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); | 464 | dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); |
465 | dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); | 465 | dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); |
466 | 466 | ||
467 | if (!dev->queues) | ||
468 | return -ENODEV; | ||
467 | q = &dev->queues->queue[AdapNormCmdQueue]; | 469 | q = &dev->queues->queue[AdapNormCmdQueue]; |
468 | 470 | ||
469 | if(wait) | 471 | if(wait) |
@@ -527,8 +529,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
527 | } | 529 | } |
528 | udelay(5); | 530 | udelay(5); |
529 | } | 531 | } |
530 | } else | 532 | } else if (down_interruptible(&fibptr->event_wait)) { |
531 | down(&fibptr->event_wait); | 533 | spin_lock_irqsave(&fibptr->event_lock, flags); |
534 | if (fibptr->done == 0) { | ||
535 | fibptr->done = 2; /* Tell interrupt we aborted */ | ||
536 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
537 | return -EINTR; | ||
538 | } | ||
539 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
540 | } | ||
532 | BUG_ON(fibptr->done == 0); | 541 | BUG_ON(fibptr->done == 0); |
533 | 542 | ||
534 | if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ | 543 | if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ |
@@ -795,7 +804,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
795 | 804 | ||
796 | /* Sniff for container changes */ | 805 | /* Sniff for container changes */ |
797 | 806 | ||
798 | if (!dev) | 807 | if (!dev || !dev->fsa_dev) |
799 | return; | 808 | return; |
800 | container = (u32)-1; | 809 | container = (u32)-1; |
801 | 810 | ||
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index b2a5c7262f36..8335f07b7720 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
@@ -124,10 +124,15 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
124 | } else { | 124 | } else { |
125 | unsigned long flagv; | 125 | unsigned long flagv; |
126 | spin_lock_irqsave(&fib->event_lock, flagv); | 126 | spin_lock_irqsave(&fib->event_lock, flagv); |
127 | fib->done = 1; | 127 | if (!fib->done) |
128 | fib->done = 1; | ||
128 | up(&fib->event_wait); | 129 | up(&fib->event_wait); |
129 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 130 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
130 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 131 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
132 | if (fib->done == 2) { | ||
133 | aac_fib_complete(fib); | ||
134 | aac_fib_free(fib); | ||
135 | } | ||
131 | } | 136 | } |
132 | consumed++; | 137 | consumed++; |
133 | spin_lock_irqsave(q->lock, flags); | 138 | spin_lock_irqsave(q->lock, flags); |
@@ -316,7 +321,8 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) | |||
316 | unsigned long flagv; | 321 | unsigned long flagv; |
317 | dprintk((KERN_INFO "event_wait up\n")); | 322 | dprintk((KERN_INFO "event_wait up\n")); |
318 | spin_lock_irqsave(&fib->event_lock, flagv); | 323 | spin_lock_irqsave(&fib->event_lock, flagv); |
319 | fib->done = 1; | 324 | if (!fib->done) |
325 | fib->done = 1; | ||
320 | up(&fib->event_wait); | 326 | up(&fib->event_wait); |
321 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 327 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
322 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 328 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |