diff options
Diffstat (limited to 'sys/scsi/ss.c')
-rw-r--r-- | sys/scsi/ss.c | 82 |
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; |