Skip to content

Commit

Permalink
[SCSI] aacraid: Fix ioctl handling when adapter resets
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Haverkamp authored and James Bottomley committed Mar 20, 2007
1 parent fe76df4 commit 33bb3b2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
7 changes: 7 additions & 0 deletions drivers/scsi/aacraid/commctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 12 additions & 8 deletions drivers/scsi/aacraid/commsup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)){
Expand Down Expand Up @@ -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))) {
Expand All @@ -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;

/*
Expand Down

0 comments on commit 33bb3b2

Please sign in to comment.