summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/scsi/scsi_base.c24
-rw-r--r--sys/scsi/scsiconf.h3
2 files changed, 18 insertions, 9 deletions
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c
index 167faf4d357..d13c2017556 100644
--- a/sys/scsi/scsi_base.c
+++ b/sys/scsi/scsi_base.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsi_base.c,v 1.194 2010/09/08 11:04:39 dlg Exp $ */
+/* $OpenBSD: scsi_base.c,v 1.195 2010/09/14 01:39:44 dlg Exp $ */
/* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */
/*
@@ -527,7 +527,9 @@ scsi_xsh_del(struct scsi_xshandler *xsh)
break;
case RUNQ_POOLQ:
TAILQ_REMOVE(&link->pool->queue, &xsh->ioh, q_entry);
- link->openings++;
+ link->pending--;
+ if (ISSET(link->state, SDEV_S_DYING) && link->pending == 0)
+ wakeup_one(&link->pending);
break;
default:
panic("unexpected xsh state %u", xsh->ioh.q_state);
@@ -552,9 +554,10 @@ scsi_xsh_runqueue(struct scsi_link *link)
runq = 0;
mtx_enter(&link->pool->mtx);
- while (!ISSET(link->state, SDEV_S_DYING) && link->openings &&
+ while (!ISSET(link->state, SDEV_S_DYING) &&
+ link->pending < link->openings &&
((ioh = TAILQ_FIRST(&link->queue)) != NULL)) {
- link->openings--;
+ link->pending++;
TAILQ_REMOVE(&link->queue, ioh, q_entry);
TAILQ_INSERT_TAIL(&link->pool->queue, ioh, q_entry);
@@ -681,11 +684,14 @@ scsi_link_shutdown(struct scsi_link *link)
xsh->link == link) {
TAILQ_REMOVE(&iopl->queue, &xsh->ioh, q_entry);
xsh->ioh.q_state = RUNQ_IDLE;
- link->openings++;
+ link->pending--;
TAILQ_INSERT_TAIL(&sleepers, &xsh->ioh, q_entry);
}
}
+
+ while (link->pending > 0)
+ msleep(&link->pending, &iopl->mtx, PRIBIO, "pendxs", 0);
mtx_leave(&iopl->mtx);
while ((ioh = TAILQ_FIRST(&sleepers)) != NULL) {
@@ -700,8 +706,8 @@ scsi_link_open(struct scsi_link *link)
int open = 0;
mtx_enter(&link->pool->mtx);
- if (link->openings) {
- link->openings--;
+ if (link->pending < link->openings) {
+ link->pending++;
open = 1;
}
mtx_leave(&link->pool->mtx);
@@ -713,7 +719,9 @@ void
scsi_link_close(struct scsi_link *link)
{
mtx_enter(&link->pool->mtx);
- link->openings++;
+ link->pending--;
+ if (ISSET(link->state, SDEV_S_DYING) && link->pending == 0)
+ wakeup_one(&link->pending);
mtx_leave(&link->pool->mtx);
scsi_xsh_runqueue(link);
diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h
index 89bfa4d426d..8cee11a3f72 100644
--- a/sys/scsi/scsiconf.h
+++ b/sys/scsi/scsiconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.h,v 1.137 2010/09/08 00:58:05 dlg Exp $ */
+/* $OpenBSD: scsiconf.h,v 1.138 2010/09/14 01:39:44 dlg Exp $ */
/* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */
/*
@@ -396,6 +396,7 @@ struct scsi_link {
struct scsi_runq queue;
u_int running;
+ u_short pending;
struct scsi_iopool *pool;
};