diff options
author | Mark Haverkamp <markh@linux-foundation.org> | 2007-03-15 13:27:45 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-03-20 11:56:03 -0400 |
commit | 03d4433721880bf1972c924b168e4e1dd3c59d53 (patch) | |
tree | 820ad2f8aea551d03e7ff8751aba7dfe1f674bcd /drivers/scsi/aacraid/dpcsup.c | |
parent | f2b1a06ad46209c6e631e3099138d1fa3f14d3a8 (diff) |
[SCSI] aacraid: Improved error handling
Received from Mark Salyzyn,
This set of fixes improve error handling stability of the driver. A popular
manifestation of the problems is an NULL pointer reference in the interrupt
handler when referencing portions of the scsi command context, or in the
scsi_done handling when an offlined device is referenced.
The aacraid driver currently does not get notification of orphaned command
completions due to devices going offline. The driver also fails to handle the
commands that are finished by the error handler, and thus can complete again
later at the hands of the adapter causing situations of completion of an
invalid scsi command context. Test Unit Ready calls abort assuming that the
abort was successful, but are not, and thus when the interrupt from the adapter
occurs, they reference invalid command contexts. We add in a TIMED_OUT flag to
inform the aacraid FIB context that the interrupt service should merely release
the driver resources and not complete the command up. We take advantage of this
with the abort handler as well for select abortable commands. And we detect and
react if a command that can not be aborted is currently still outstanding to
the controller when reissued by the retry mechanism.
Signed-off-by: Mark Haverkamp <markh@linux-foundation.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/dpcsup.c')
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index 26f4d563d959..4e53f9db1b2c 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
7 | * | 7 | * |
8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -84,11 +84,13 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
84 | * continue. The caller has already been notified that | 84 | * continue. The caller has already been notified that |
85 | * the fib timed out. | 85 | * the fib timed out. |
86 | */ | 86 | */ |
87 | if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) | 87 | dev->queues->queue[AdapNormCmdQueue].numpending--; |
88 | dev->queues->queue[AdapNormCmdQueue].numpending--; | 88 | |
89 | else { | 89 | if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { |
90 | printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); | 90 | spin_unlock_irqrestore(q->lock, flags); |
91 | printk(KERN_DEBUG"aacraid: hwfib=%p fib index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); | 91 | aac_fib_complete(fib); |
92 | aac_fib_free(fib); | ||
93 | spin_lock_irqsave(q->lock, flags); | ||
92 | continue; | 94 | continue; |
93 | } | 95 | } |
94 | spin_unlock_irqrestore(q->lock, flags); | 96 | spin_unlock_irqrestore(q->lock, flags); |
@@ -281,14 +283,14 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) | |||
281 | * continue. The caller has already been notified that | 283 | * continue. The caller has already been notified that |
282 | * the fib timed out. | 284 | * the fib timed out. |
283 | */ | 285 | */ |
284 | if ((fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { | 286 | dev->queues->queue[AdapNormCmdQueue].numpending--; |
285 | printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); | 287 | |
286 | printk(KERN_DEBUG"aacraid: hwfib=%p index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); | 288 | if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { |
289 | aac_fib_complete(fib); | ||
290 | aac_fib_free(fib); | ||
287 | return 0; | 291 | return 0; |
288 | } | 292 | } |
289 | 293 | ||
290 | dev->queues->queue[AdapNormCmdQueue].numpending--; | ||
291 | |||
292 | if (fast) { | 294 | if (fast) { |
293 | /* | 295 | /* |
294 | * Doctor the fib | 296 | * Doctor the fib |