aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Haverkamp <markh@linux-foundation.org>2007-03-15 13:27:21 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-03-20 11:55:05 -0400
commit33bb3b296207ff4f9e3b8dddb623e645ee1b8809 (patch)
tree9f8ccb325f7880e64668e6d41671ff32949a4b12 /drivers
parentfe76df4235986cfacc2d3b71cef7c42bc1a6dd6c (diff)
[SCSI] aacraid: Fix ioctl handling when adapter resets
Received from Mark Salyzyn, Outstanding ioctl calls still have some problems with aborting cleanly in the face of a reset iop recovery action should the adapter ever enter into a Firmware Assert (BlinkLED) condition. The enclosed patch resolves some uncovered flawed handling. Signed-off-by: Mark Haverkamp <markh@linux-foundation.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/aacraid/commctrl.c7
-rw-r--r--drivers/scsi/aacraid/commsup.c20
2 files changed, 19 insertions, 8 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 83d5680e1326..3a8e7cac9ee2 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -64,6 +64,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
64 unsigned size; 64 unsigned size;
65 int retval; 65 int retval;
66 66
67 if (dev->in_reset) {
68 return -EBUSY;
69 }
67 fibptr = aac_fib_alloc(dev); 70 fibptr = aac_fib_alloc(dev);
68 if(fibptr == NULL) { 71 if(fibptr == NULL) {
69 return -ENOMEM; 72 return -ENOMEM;
@@ -469,6 +472,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
469 int i; 472 int i;
470 473
471 474
475 if (dev->in_reset) {
476 dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n"));
477 return -EBUSY;
478 }
472 if (!capable(CAP_SYS_ADMIN)){ 479 if (!capable(CAP_SYS_ADMIN)){
473 dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); 480 dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n"));
474 return -EPERM; 481 return -EPERM;
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index e67ff13eb359..c933df30f589 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -513,15 +513,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
513 } 513 }
514 udelay(5); 514 udelay(5);
515 } 515 }
516 } else if (down_interruptible(&fibptr->event_wait)) { 516 } else
517 spin_lock_irqsave(&fibptr->event_lock, flags); 517 (void)down_interruptible(&fibptr->event_wait);
518 if (fibptr->done == 0) { 518 spin_lock_irqsave(&fibptr->event_lock, flags);
519 fibptr->done = 2; /* Tell interrupt we aborted */ 519 if (fibptr->done == 0) {
520 spin_unlock_irqrestore(&fibptr->event_lock, flags); 520 fibptr->done = 2; /* Tell interrupt we aborted */
521 return -EINTR;
522 }
523 spin_unlock_irqrestore(&fibptr->event_lock, flags); 521 spin_unlock_irqrestore(&fibptr->event_lock, flags);
522 return -EINTR;
524 } 523 }
524 spin_unlock_irqrestore(&fibptr->event_lock, flags);
525 BUG_ON(fibptr->done == 0); 525 BUG_ON(fibptr->done == 0);
526 526
527 if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ 527 if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){
@@ -1062,7 +1062,7 @@ static int _aac_reset_adapter(struct aac_dev *aac)
1062 /* 1062 /*
1063 * Loop through the fibs, close the synchronous FIBS 1063 * Loop through the fibs, close the synchronous FIBS
1064 */ 1064 */
1065 for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { 1065 for (retval = 1, index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) {
1066 struct fib *fib = &aac->fibs[index]; 1066 struct fib *fib = &aac->fibs[index];
1067 if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && 1067 if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
1068 (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) { 1068 (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) {
@@ -1071,8 +1071,12 @@ static int _aac_reset_adapter(struct aac_dev *aac)
1071 up(&fib->event_wait); 1071 up(&fib->event_wait);
1072 spin_unlock_irqrestore(&fib->event_lock, flagv); 1072 spin_unlock_irqrestore(&fib->event_lock, flagv);
1073 schedule(); 1073 schedule();
1074 retval = 0;
1074 } 1075 }
1075 } 1076 }
1077 /* Give some extra time for ioctls to complete. */
1078 if (retval == 0)
1079 ssleep(2);
1076 index = aac->cardtype; 1080 index = aac->cardtype;
1077 1081
1078 /* 1082 /*