summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2010-01-11 08:56:18 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2010-01-11 08:56:18 +0000
commit218050fc1c8872a184201cf171493a3a8847bf4d (patch)
tree46b8bada6fe22fd1183fb954651120e0d632295e
parentf22c79ddda0813dd716d5fd3cc20a01b2dfcb6ed (diff)
Bring mutex protections to ststart, cdstart and ssstart, as already
done in sd. Make names consistant across all three. ok dlg@ tested (cd) & ok beck@
-rw-r--r--sys/scsi/cd.c38
-rw-r--r--sys/scsi/ss.c34
-rw-r--r--sys/scsi/ssvar.h7
-rw-r--r--sys/scsi/st.c45
4 files changed, 84 insertions, 40 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c
index 2ea0cbddcef..918e3f77f05 100644
--- a/sys/scsi/cd.c
+++ b/sys/scsi/cd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd.c,v 1.159 2010/01/11 00:44:40 krw Exp $ */
+/* $OpenBSD: cd.c,v 1.160 2010/01/11 08:56:17 krw Exp $ */
/* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */
/*
@@ -110,8 +110,9 @@ struct cd_softc {
daddr64_t disksize; /* total number sectors */
} sc_params;
struct buf sc_buf_queue;
- struct mutex sc_queue_mtx;
+ struct mutex sc_buf_mtx;
struct mutex sc_start_mtx;
+ u_int sc_start_count;
struct timeout sc_timeout;
void *sc_cdpwrhook; /* our power hook */
};
@@ -215,7 +216,7 @@ cdattach(struct device *parent, struct device *self, void *aux)
SC_DEBUG(sc_link, SDEV_DB2, ("cdattach:\n"));
- mtx_init(&sc->sc_queue_mtx, IPL_BIO);
+ mtx_init(&sc->sc_buf_mtx, IPL_BIO);
mtx_init(&sc->sc_start_mtx, IPL_BIO);
/*
@@ -525,9 +526,9 @@ cdstrategy(struct buf *bp)
/*
* Place it in the queue of disk activities for this disk
*/
- mtx_enter(&sc->sc_queue_mtx);
+ mtx_enter(&sc->sc_buf_mtx);
disksort(&sc->sc_buf_queue, bp);
- mtx_leave(&sc->sc_queue_mtx);
+ mtx_leave(&sc->sc_buf_mtx);
/*
* Tell the device to get going on the transfer if it's
@@ -557,13 +558,13 @@ cd_buf_dequeue(struct cd_softc *sc)
{
struct buf *bp;
- mtx_enter(&sc->sc_queue_mtx);
+ mtx_enter(&sc->sc_buf_mtx);
bp = sc->sc_buf_queue.b_actf;
if (bp != NULL)
sc->sc_buf_queue.b_actf = bp->b_actf;
if (sc->sc_buf_queue.b_actf == NULL)
sc->sc_buf_queue.b_actb = &sc->sc_buf_queue.b_actf;
- mtx_leave(&sc->sc_queue_mtx);
+ mtx_leave(&sc->sc_buf_mtx);
return (bp);
}
@@ -571,12 +572,12 @@ cd_buf_dequeue(struct cd_softc *sc)
void
cd_buf_requeue(struct cd_softc *sc, struct buf *bp)
{
- mtx_enter(&sc->sc_queue_mtx);
+ mtx_enter(&sc->sc_buf_mtx);
bp->b_actf = sc->sc_buf_queue.b_actf;
sc->sc_buf_queue.b_actf = bp;
if (bp->b_actf == NULL)
sc->sc_buf_queue.b_actb = &bp->b_actf;
- mtx_leave(&sc->sc_queue_mtx);
+ mtx_leave(&sc->sc_buf_mtx);
}
/*
@@ -610,10 +611,15 @@ cdstart(void *v)
int s;
SC_DEBUG(sc_link, SDEV_DB2, ("cdstart\n"));
- /*
- * Check if the device has room for another command
- */
+ mtx_enter(&sc->sc_start_mtx);
+ sc->sc_start_count++;
+ if (sc->sc_start_count > 1) {
+ mtx_leave(&sc->sc_start_mtx);
+ return;
+ }
+ mtx_leave(&sc->sc_start_mtx);
+restart:
CLR(sc->sc_flags, CDF_WAITING);
while (!ISSET(sc->sc_flags, CDF_WAITING) &&
(bp = cd_buf_dequeue(sc)) != NULL) {
@@ -694,6 +700,14 @@ cdstart(void *v)
scsi_xs_exec(xs);
}
+ mtx_enter(&sc->sc_start_mtx);
+ sc->sc_start_count--;
+ if (sc->sc_start_count != 0) {
+ sc->sc_start_count = 1;
+ mtx_leave(&sc->sc_start_mtx);
+ goto restart;
+ }
+ mtx_leave(&sc->sc_start_mtx);
}
void
diff --git a/sys/scsi/ss.c b/sys/scsi/ss.c
index 900431f23a3..60095431053 100644
--- a/sys/scsi/ss.c
+++ b/sys/scsi/ss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ss.c,v 1.66 2010/01/09 21:12:06 dlg Exp $ */
+/* $OpenBSD: ss.c,v 1.67 2010/01/11 08:56:17 krw Exp $ */
/* $NetBSD: ss.c,v 1.10 1996/05/05 19:52:55 christos Exp $ */
/*
@@ -354,8 +354,8 @@ ssattach(parent, self, aux)
/* XXX fill in the rest of the scan_io struct by calling the
compute_sizes routine */
- mtx_init(&ss->queue_mtx, IPL_BIO);
- mtx_init(&ss->start_mtx, IPL_BIO);
+ mtx_init(&ss->sc_buf_mtx, IPL_BIO);
+ mtx_init(&ss->sc_start_mtx, IPL_BIO);
timeout_set(&ss->timeout, ssstart, ss);
@@ -610,13 +610,13 @@ ss_buf_enqueue(struct ss_softc *ss, struct buf *bp)
{
struct buf *dp;
- mtx_enter(&ss->queue_mtx);
+ mtx_enter(&ss->sc_buf_mtx);
dp = &ss->buf_queue;
bp->b_actf = NULL;
bp->b_actb = dp->b_actb;
*dp->b_actb = bp;
dp->b_actb = &bp->b_actf;
- mtx_leave(&ss->queue_mtx);
+ mtx_leave(&ss->sc_buf_mtx);
}
struct buf *
@@ -624,13 +624,13 @@ ss_buf_dequeue(struct ss_softc *ss)
{
struct buf *bp;
- mtx_enter(&ss->queue_mtx);
+ mtx_enter(&ss->sc_buf_mtx);
bp = ss->buf_queue.b_actf;
if (bp != NULL)
ss->buf_queue.b_actf = bp->b_actf;
if (ss->buf_queue.b_actf == NULL)
ss->buf_queue.b_actb = &ss->buf_queue.b_actf;
- mtx_leave(&ss->queue_mtx);
+ mtx_leave(&ss->sc_buf_mtx);
return (bp);
}
@@ -638,12 +638,12 @@ ss_buf_dequeue(struct ss_softc *ss)
void
ss_buf_requeue(struct ss_softc *ss, struct buf *bp)
{
- mtx_enter(&ss->queue_mtx);
+ mtx_enter(&ss->sc_buf_mtx);
bp->b_actf = ss->buf_queue.b_actf;
ss->buf_queue.b_actf = bp;
if (bp->b_actf == NULL)
ss->buf_queue.b_actb = &bp->b_actf;
- mtx_leave(&ss->queue_mtx);
+ mtx_leave(&ss->sc_buf_mtx);
}
@@ -673,6 +673,14 @@ ssstart(v)
SC_DEBUG(sc_link, SDEV_DB2, ("ssstart\n"));
+ mtx_enter(&ss->sc_start_mtx);
+ ss->sc_start_count++;
+ if (ss->sc_start_count > 1) {
+ mtx_leave(&ss->sc_start_mtx);
+ return;
+ }
+ mtx_leave(&ss->sc_start_mtx);
+restart:
CLR(ss->flags, SSF_WAITING);
while (!ISSET(ss->flags, SSF_WAITING) &&
(bp = ss_buf_dequeue(ss)) != NULL) {
@@ -701,6 +709,14 @@ ssstart(v)
scsi_xs_exec(xs);
}
}
+ mtx_enter(&ss->sc_start_mtx);
+ ss->sc_start_count--;
+ if (ss->sc_start_count != 0) {
+ ss->sc_start_count = 1;
+ mtx_leave(&ss->sc_start_mtx);
+ goto restart;
+ }
+ mtx_leave(&ss->sc_start_mtx);
}
void
diff --git a/sys/scsi/ssvar.h b/sys/scsi/ssvar.h
index 7af6756a314..6f1f783eefe 100644
--- a/sys/scsi/ssvar.h
+++ b/sys/scsi/ssvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssvar.h,v 1.14 2010/01/09 21:12:06 dlg Exp $ */
+/* $OpenBSD: ssvar.h,v 1.15 2010/01/11 08:56:17 krw Exp $ */
/* $NetBSD: ssvar.h,v 1.2 1996/03/30 21:47:11 christos Exp $ */
/*
@@ -74,8 +74,9 @@ struct ss_softc {
const struct quirkdata *quirkdata; /* if we have a rogue entry */
struct ss_special special; /* special handlers for spec. devices */
struct timeout timeout;
- struct mutex queue_mtx;
- struct mutex start_mtx;
+ struct mutex sc_buf_mtx;
+ struct mutex sc_start_mtx;
+ u_int sc_start_count;
};
struct buf *ss_buf_dequeue(struct ss_softc *);
diff --git a/sys/scsi/st.c b/sys/scsi/st.c
index 6525da556ff..9aca15a5a79 100644
--- a/sys/scsi/st.c
+++ b/sys/scsi/st.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: st.c,v 1.89 2010/01/09 21:12:06 dlg Exp $ */
+/* $OpenBSD: st.c,v 1.90 2010/01/11 08:56:17 krw Exp $ */
/* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */
/*
@@ -218,8 +218,9 @@ struct st_softc {
struct buf buf_queue; /* the queue of pending IO operations */
struct timeout sc_timeout;
- struct mutex queue_mtx;
- struct mutex start_mtx;
+ struct mutex sc_buf_mtx;
+ struct mutex sc_start_mtx;
+ u_int sc_start_count;
};
@@ -339,8 +340,8 @@ stattach(struct device *parent, struct device *self, void *aux)
st_identify_drive(st, sa->sa_inqbuf);
printf("\n");
- mtx_init(&st->queue_mtx, IPL_BIO);
- mtx_init(&st->start_mtx, IPL_BIO);
+ mtx_init(&st->sc_buf_mtx, IPL_BIO);
+ mtx_init(&st->sc_start_mtx, IPL_BIO);
timeout_set(&st->sc_timeout, ststart, st);
@@ -919,13 +920,13 @@ st_buf_enqueue(struct st_softc *st, struct buf *bp)
{
struct buf *dp;
- mtx_enter(&st->queue_mtx);
+ mtx_enter(&st->sc_buf_mtx);
dp = &st->buf_queue;
bp->b_actf = NULL;
bp->b_actb = dp->b_actb;
*dp->b_actb = bp;
dp->b_actb = &bp->b_actf;
- mtx_leave(&st->queue_mtx);
+ mtx_leave(&st->sc_buf_mtx);
}
struct buf *
@@ -933,13 +934,13 @@ st_buf_dequeue(struct st_softc *st)
{
struct buf *bp;
- mtx_enter(&st->queue_mtx);
+ mtx_enter(&st->sc_buf_mtx);
bp = st->buf_queue.b_actf;
if (bp != NULL)
st->buf_queue.b_actf = bp->b_actf;
if (st->buf_queue.b_actf == NULL)
st->buf_queue.b_actb = &st->buf_queue.b_actf;
- mtx_leave(&st->queue_mtx);
+ mtx_leave(&st->sc_buf_mtx);
return (bp);
}
@@ -947,12 +948,12 @@ st_buf_dequeue(struct st_softc *st)
void
st_buf_requeue(struct st_softc *st, struct buf *bp)
{
- mtx_enter(&st->queue_mtx);
+ mtx_enter(&st->sc_buf_mtx);
bp->b_actf = st->buf_queue.b_actf;
st->buf_queue.b_actf = bp;
if (bp->b_actf == NULL)
st->buf_queue.b_actb = &bp->b_actf;
- mtx_leave(&st->queue_mtx);
+ mtx_leave(&st->sc_buf_mtx);
}
@@ -985,11 +986,14 @@ ststart(void *v)
if (st->flags & ST_DYING)
return;
- /*
- * See if there is a buf to do and we are not already
- * doing one
- */
-
+ mtx_enter(&st->sc_start_mtx);
+ st->sc_start_count++;
+ if (st->sc_start_count > 1) {
+ mtx_leave(&st->sc_start_mtx);
+ return;
+ }
+ mtx_leave(&st->sc_start_mtx);
+restart:
CLR(st->flags, ST_WAITING);
while (!ISSET(st->flags, ST_WAITING) &&
(bp = st_buf_dequeue(st)) != NULL) {
@@ -1114,6 +1118,15 @@ ststart(void *v)
*/
scsi_xs_exec(xs);
} /* go back and see if we can cram more work in.. */
+
+ mtx_enter(&st->sc_start_mtx);
+ st->sc_start_count--;
+ if (st->sc_start_count != 0) {
+ st->sc_start_count = 1;
+ mtx_leave(&st->sc_start_mtx);
+ goto restart;
+ }
+ mtx_leave(&st->sc_start_mtx);
}
void