summaryrefslogtreecommitdiff
path: root/sys/scsi/ss.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/scsi/ss.c')
-rw-r--r--sys/scsi/ss.c82
1 files changed, 33 insertions, 49 deletions
diff --git a/sys/scsi/ss.c b/sys/scsi/ss.c
index adfab839b45..ee4a49352d0 100644
--- a/sys/scsi/ss.c
+++ b/sys/scsi/ss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ss.c,v 1.76 2010/06/26 23:24:45 guenther Exp $ */
+/* $OpenBSD: ss.c,v 1.77 2010/06/30 00:02:00 dlg Exp $ */
/* $NetBSD: ss.c,v 1.10 1996/05/05 19:52:55 christos Exp $ */
/*
@@ -111,7 +111,7 @@ struct quirkdata ss_gen_quirks = {
};
void ssstrategy(struct buf *);
-void ssstart(void *);
+void ssstart(struct scsi_xfer *);
void ssdone(struct scsi_xfer *);
void ssminphys(struct buf *);
@@ -254,7 +254,7 @@ struct cfdriver ss_cd = {
struct scsi_device ss_switch = {
NULL,
- ssstart,
+ NULL,
NULL,
NULL,
};
@@ -353,9 +353,8 @@ ssattach(parent, self, aux)
/* XXX fill in the rest of the scan_io struct by calling the
compute_sizes routine */
- mtx_init(&ss->sc_start_mtx, IPL_BIO);
-
- timeout_set(&ss->timeout, ssstart, ss);
+ scsi_xsh_set(&ss->xsh, sc_link, ssstart);
+ timeout_set(&ss->timeout, (void (*)(void *))scsi_xsh_add, &ss->xsh);
/* Set up the buf queue for this device. */
ss->sc_bufq = bufq_init(BUFQ_DEFAULT);
@@ -591,7 +590,7 @@ ssstrategy(bp)
* not doing anything, otherwise just wait for completion
* (All a bit silly if we're only allowing 1 open but..)
*/
- ssstart(ss);
+ scsi_xsh_add(&ss->xsh);
device_unref(&ss->sc_dev);
return;
@@ -625,60 +624,45 @@ done:
* ssstart() is called at splbio
*/
void
-ssstart(v)
- void *v;
+ssstart(struct scsi_xfer *xs)
{
- struct ss_softc *ss = v;
- struct scsi_link *sc_link = ss->sc_link;
- struct scsi_xfer *xs;
+ struct scsi_link *sc_link = xs->sc_link;
+ struct ss_softc *ss = sc_link->device_softc;
struct buf *bp;
struct scsi_r_scanner *cdb;
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);
+ bp = BUFQ_DEQUEUE(ss->sc_bufq);
+ if (bp == NULL) {
+ scsi_xs_put(xs);
return;
}
- mtx_leave(&ss->sc_start_mtx);
- CLR(ss->flags, SSF_WAITING);
-restart:
- while (!ISSET(ss->flags, SSF_WAITING) &&
- (bp = BUFQ_DEQUEUE(ss->sc_bufq)) != NULL) {
- xs = scsi_xs_get(sc_link, SCSI_NOSLEEP);
- if (xs == NULL)
- break;
- if (ss->special.read) {
- (ss->special.read)(ss, xs, bp);
- } else {
- cdb = (struct scsi_r_scanner *)xs->cmd;
- xs->cmdlen = sizeof(*cdb);
+ if (ss->special.read) {
+ (ss->special.read)(ss, xs, bp);
+ } else {
+ cdb = (struct scsi_r_scanner *)xs->cmd;
+ xs->cmdlen = sizeof(*cdb);
- cdb->opcode = READ_BIG;
- _lto3b(bp->b_bcount, cdb->len);
+ cdb->opcode = READ_BIG;
+ _lto3b(bp->b_bcount, cdb->len);
- xs->data = bp->b_data;
- xs->datalen = bp->b_bcount;
- xs->flags |= SCSI_DATA_IN;
- xs->retries = 0;
- xs->timeout = 100000;
- xs->done = ssdone;
- xs->cookie = bp;
+ xs->data = bp->b_data;
+ xs->datalen = bp->b_bcount;
+ xs->flags |= SCSI_DATA_IN;
+ xs->retries = 0;
+ xs->timeout = 100000;
+ xs->done = ssdone;
+ xs->cookie = bp;
- 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;
+ scsi_xs_exec(xs);
}
- mtx_leave(&ss->sc_start_mtx);
+
+ if (ISSET(ss->flags, SSF_WAITING))
+ CLR(ss->flags, SSF_WAITING);
+ else if (BUFQ_PEEK(ss->sc_bufq))
+ scsi_xsh_add(&ss->xsh);
}
void
@@ -698,7 +682,7 @@ ssdone(struct scsi_xfer *xs)
/* The adapter is busy, requeue the buf and try it later. */
BUFQ_REQUEUE(ss->sc_bufq, bp);
scsi_xs_put(xs);
- SET(ss->flags, SSF_WAITING); /* break out of cdstart loop */
+ SET(ss->flags, SSF_WAITING);
timeout_add(&ss->timeout, 1);
return;