aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2006-11-21 10:40:31 -0800
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-11-22 12:29:17 -0600
commitd18b448fc2caf0d719bd4bd34fb1856be89c8ef7 (patch)
tree58b3acc299b6182f3c2f0d58464b1680c41a6cdf
parent33524b70e8f3dd55a4ba78ad81742c7814e7b0ed (diff)
[SCSI] aacraid: Abort management FIBs
Received from Mark Salyzyn: Add code to abort outstanding management ioctl fibs when the blinkLED recovery is performed. This code is 'clunky' and does not have any real feedback in that the reset could progress before the user application has gotten it's notification of command completion. We put a schedule() call to delay just the right amount for most cases, because we tried a spin and still managed to find cases where we would spin forever waiting for the management application to acknowledge the impending doom surrounding the cause of the BlinkLED. Will cause an oops in the context of the management application if we proceed too quickly. I view this as the lesser of many evils since currently if there are outstanding management ioctls during a need to reset/recover the adapter, the management application just locks up and waits forever. The best practices fix for this problem not going to be simple or easy (at least the fixes I imagine today); and we found a balance between the needs of the driver to proceed, and the applications that locked or confused that would hold back the driver. I just do not like the idea of a kernel oops in an application to deal with low priority, sluggish or misbehaving applications. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/aacraid/commsup.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 0fd462a876f..4893a6d06a3 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1102,6 +1102,20 @@ static int _aac_reset_adapter(struct aac_dev *aac)
goto out;
}
+ /*
+ * Loop through the fibs, close the synchronous FIBS
+ */
+ for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) {
+ struct fib *fib = &aac->fibs[index];
+ if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
+ (fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) {
+ unsigned long flagv;
+ spin_lock_irqsave(&fib->event_lock, flagv);
+ up(&fib->event_wait);
+ spin_unlock_irqrestore(&fib->event_lock, flagv);
+ schedule();
+ }
+ }
index = aac->cardtype;
/*