diff options
author | Mark Haverkamp | 2007-03-15 10:27:21 -0700 |
---|---|---|
committer | James Bottomley | 2007-03-20 10:55:05 -0500 |
commit | 33bb3b296207ff4f9e3b8dddb623e645ee1b8809 (patch) | |
tree | 9f8ccb325f7880e64668e6d41671ff32949a4b12 /drivers | |
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')
-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) unsigned size; int retval; + if (dev->in_reset) { + return -EBUSY; + } fibptr = aac_fib_alloc(dev); if(fibptr == NULL) { return -ENOMEM; @@ -469,6 +472,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) int i; + if (dev->in_reset) { + dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n")); + return -EBUSY; + } if (!capable(CAP_SYS_ADMIN)){ dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); 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, } udelay(5); } - } else if (down_interruptible(&fibptr->event_wait)) { - spin_lock_irqsave(&fibptr->event_lock, flags); - if (fibptr->done == 0) { - fibptr->done = 2; /* Tell interrupt we aborted */ - spin_unlock_irqrestore(&fibptr->event_lock, flags); - return -EINTR; - } + } else + (void)down_interruptible(&fibptr->event_wait); + spin_lock_irqsave(&fibptr->event_lock, flags); + if (fibptr->done == 0) { + fibptr->done = 2; /* Tell interrupt we aborted */ spin_unlock_irqrestore(&fibptr->event_lock, flags); + return -EINTR; } + spin_unlock_irqrestore(&fibptr->event_lock, flags); BUG_ON(fibptr->done == 0); if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ @@ -1062,7 +1062,7 @@ static int _aac_reset_adapter(struct aac_dev *aac) /* * Loop through the fibs, close the synchronous FIBS */ - for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { + for (retval = 1, index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { struct fib *fib = &aac->fibs[index]; if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) { @@ -1071,8 +1071,12 @@ static int _aac_reset_adapter(struct aac_dev *aac) up(&fib->event_wait); spin_unlock_irqrestore(&fib->event_lock, flagv); schedule(); + retval = 0; } } + /* Give some extra time for ioctls to complete. */ + if (retval == 0) + ssleep(2); index = aac->cardtype; /* |