summaryrefslogtreecommitdiff
path: root/sys/scsi/scsi_base.c
diff options
context:
space:
mode:
authorbriggs <briggs@cvs.openbsd.org>1996-01-14 21:44:31 +0000
committerbriggs <briggs@cvs.openbsd.org>1996-01-14 21:44:31 +0000
commit431724c0fbbfa636c72a978587ddc06d8ee3b114 (patch)
tree8d59958cac3ed495eefb18e2de35a93e99160db6 /sys/scsi/scsi_base.c
parent0fb02d5a856594b81d3674e5f3647302ff3689e5 (diff)
From NetBSD: (required for last change to scsi_base.c in case we get
"command aborted" status) Handle cases like the following: - controller calls scsi_done() with error XS_TIMEOUT - scsi_done() calls sddone() - sddone() calls disk_unbusy() - scsi_done() calls controller to retry command (missing the call to disk_busy()) - controller calls scsi_done() - scsi_done() calls sddone() - sddone() calls disk_busy(), which panics because of the imbalance. Bug noticed by Leo Weppleman, who also suggested this fix; pass an additional boolean argument ("complete") to the device's "done" routine, with a value of `0' passed from the previous call to "done", and add an additional call to "done" when the xfer resources are freed.
Diffstat (limited to 'sys/scsi/scsi_base.c')
-rw-r--r--sys/scsi/scsi_base.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c
index 05a95a99ca0..3539a0d1511 100644
--- a/sys/scsi/scsi_base.c
+++ b/sys/scsi/scsi_base.c
@@ -1,4 +1,4 @@
-/* $NetBSD: scsi_base.c,v 1.30 1995/09/26 19:26:55 thorpej Exp $ */
+/* $NetBSD: scsi_base.c,v 1.31 1996/01/12 22:43:29 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995 Charles Hannum. All rights reserved.
@@ -335,10 +335,14 @@ scsi_done(xs)
* If the device has it's own done routine, call it first.
* If it returns a legit error value, return that, otherwise
* it wants us to continue with normal processing.
+ *
+ * Make sure the upper-level driver knows that this might not
+ * actually be the last time they hear from us. We need to get
+ * status back.
*/
if (sc_link->device->done) {
SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n"));
- error = (*sc_link->device->done) (xs);
+ error = (*sc_link->device->done)(xs, 0);
if (error == EJUSTRETURN)
goto done;
SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n"));
@@ -369,6 +373,15 @@ retry:
}
}
done:
+ if (sc_link->device->done) {
+ /*
+ * Tell the device the operation is actually complete.
+ * No more will happen with this xfer. This for
+ * notification of the upper-level driver only; they
+ * won't be returning any meaningful information to us.
+ */
+ (void)(*sc_link->device->done)(xs, 1);
+ }
scsi_free_xs(xs, SCSI_NOSLEEP);
}