Commit 33bb3b29 authored by Mark Haverkamp's avatar Mark Haverkamp Committed by James Bottomley

[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: default avatarMark Haverkamp <markh@linux-foundation.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent fe76df42
...@@ -64,6 +64,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) ...@@ -64,6 +64,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
unsigned size; unsigned size;
int retval; int retval;
if (dev->in_reset) {
return -EBUSY;
}
fibptr = aac_fib_alloc(dev); fibptr = aac_fib_alloc(dev);
if(fibptr == NULL) { if(fibptr == NULL) {
return -ENOMEM; return -ENOMEM;
...@@ -469,6 +472,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -469,6 +472,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
int i; int i;
if (dev->in_reset) {
dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n"));
return -EBUSY;
}
if (!capable(CAP_SYS_ADMIN)){ if (!capable(CAP_SYS_ADMIN)){
dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n"));
return -EPERM; return -EPERM;
......
...@@ -513,15 +513,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, ...@@ -513,15 +513,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
} }
udelay(5); udelay(5);
} }
} else if (down_interruptible(&fibptr->event_wait)) { } else
spin_lock_irqsave(&fibptr->event_lock, flags); (void)down_interruptible(&fibptr->event_wait);
if (fibptr->done == 0) { spin_lock_irqsave(&fibptr->event_lock, flags);
fibptr->done = 2; /* Tell interrupt we aborted */ if (fibptr->done == 0) {
spin_unlock_irqrestore(&fibptr->event_lock, flags); fibptr->done = 2; /* Tell interrupt we aborted */
return -EINTR;
}
spin_unlock_irqrestore(&fibptr->event_lock, flags); spin_unlock_irqrestore(&fibptr->event_lock, flags);
return -EINTR;
} }
spin_unlock_irqrestore(&fibptr->event_lock, flags);
BUG_ON(fibptr->done == 0); BUG_ON(fibptr->done == 0);
if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){
...@@ -1062,7 +1062,7 @@ static int _aac_reset_adapter(struct aac_dev *aac) ...@@ -1062,7 +1062,7 @@ static int _aac_reset_adapter(struct aac_dev *aac)
/* /*
* Loop through the fibs, close the synchronous FIBS * 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]; struct fib *fib = &aac->fibs[index];
if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
(fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) { (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) {
...@@ -1071,8 +1071,12 @@ static int _aac_reset_adapter(struct aac_dev *aac) ...@@ -1071,8 +1071,12 @@ static int _aac_reset_adapter(struct aac_dev *aac)
up(&fib->event_wait); up(&fib->event_wait);
spin_unlock_irqrestore(&fib->event_lock, flagv); spin_unlock_irqrestore(&fib->event_lock, flagv);
schedule(); schedule();
retval = 0;
} }
} }
/* Give some extra time for ioctls to complete. */
if (retval == 0)
ssleep(2);
index = aac->cardtype; index = aac->cardtype;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment