diff options
author | Mark Haverkamp <markh@linux-foundation.org> | 2007-03-15 13:27:21 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-03-20 11:55:05 -0400 |
commit | 33bb3b296207ff4f9e3b8dddb623e645ee1b8809 (patch) | |
tree | 9f8ccb325f7880e64668e6d41671ff32949a4b12 /drivers/scsi/aacraid | |
parent | fe76df4235986cfacc2d3b71cef7c42bc1a6dd6c (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/scsi/aacraid')
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 7 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 20 |
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 | /* |