summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-03-13 10:31:54 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-03-13 10:31:54 +0000
commitcd977f3e1aaccaf58a4991bc3dea8b72cd0b8b16 (patch)
tree663e521c96a1b84e3279c827550d5c6265eab871 /sys/dev/ic
parent311012181f00b16a7dc6b1e230a3250ad30d550c (diff)
Decouple the sizes of the request and response queues, and reduce the size of
the response queue to half the size of the request queue (with a minimum of 64 entries). This matches what isp(4) is doing and seems to be necessary for the onboard 1040B found on the Origin 200 (sgi).
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/qlw.c40
-rw-r--r--sys/dev/ic/qlwvar.h5
2 files changed, 27 insertions, 18 deletions
diff --git a/sys/dev/ic/qlw.c b/sys/dev/ic/qlw.c
index f2d09853f56..159c7e02da0 100644
--- a/sys/dev/ic/qlw.c
+++ b/sys/dev/ic/qlw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlw.c,v 1.10 2014/03/08 18:42:42 kettenis Exp $ */
+/* $OpenBSD: qlw.c,v 1.11 2014/03/13 10:31:53 kettenis Exp $ */
/*
* Copyright (c) 2011 David Gwynne <dlg@openbsd.org>
@@ -217,16 +217,24 @@ qlw_attach(struct qlw_softc *sc)
printf("couldn't get firmware status: %x\n", sc->sc_mbox[0]);
return (ENXIO);
}
- sc->sc_maxcmds = sc->sc_mbox[2];
- if (sc->sc_maxcmds > 512)
- sc->sc_maxcmds = 512;
+ sc->sc_maxrequests = sc->sc_mbox[2];
+ if (sc->sc_maxrequests > 512)
+ sc->sc_maxrequests = 512;
for (bus = 0; bus < sc->sc_numbusses; bus++) {
- if (sc->sc_max_queue_depth[bus] > sc->sc_maxcmds)
- sc->sc_max_queue_depth[bus] = sc->sc_maxcmds;
+ if (sc->sc_max_queue_depth[bus] > sc->sc_maxrequests)
+ sc->sc_max_queue_depth[bus] = sc->sc_maxrequests;
}
+ /*
+ * On some 1020/1040 variants the response queue is limited to
+ * 256 entries. We don't really need all that many anyway.
+ */
+ sc->sc_maxresponses = sc->sc_maxrequests / 2;
+ if (sc->sc_maxresponses < 64)
+ sc->sc_maxresponses = 64;
+
/* We may need up to 3 request entries per SCSI command. */
- sc->sc_maxccbs = sc->sc_maxcmds / 3;
+ sc->sc_maxccbs = sc->sc_maxrequests / 3;
/* Allegedly the FIFO is busted on the 1040A. */
if (sc->sc_isp_type == QLW_ISP1040A)
@@ -307,7 +315,7 @@ qlw_attach(struct qlw_softc *sc)
}
sc->sc_mbox[0] = QLW_MBOX_INIT_REQ_QUEUE_A64;
- sc->sc_mbox[1] = sc->sc_maxcmds;
+ sc->sc_mbox[1] = sc->sc_maxrequests;
qlw_mbox_putaddr(sc->sc_mbox, sc->sc_requests);
sc->sc_mbox[4] = 0;
if (qlw_mbox(sc, 0x00df, 0x0001)) {
@@ -316,7 +324,7 @@ qlw_attach(struct qlw_softc *sc)
}
sc->sc_mbox[0] = QLW_MBOX_INIT_RSP_QUEUE_A64;
- sc->sc_mbox[1] = sc->sc_maxcmds;
+ sc->sc_mbox[1] = sc->sc_maxresponses;
qlw_mbox_putaddr(sc->sc_mbox, sc->sc_responses);
sc->sc_mbox[5] = 0;
if (qlw_mbox(sc, 0x00ef, 0x0001)) {
@@ -687,7 +695,7 @@ qlw_handle_intr(struct qlw_softc *sc, u_int16_t isr, u_int16_t info)
scsi_done(ccb->ccb_xs);
sc->sc_last_resp_id++;
- sc->sc_last_resp_id %= sc->sc_maxcmds;
+ sc->sc_last_resp_id %= sc->sc_maxresponses;
} while (sc->sc_last_resp_id != rspin);
qlw_queue_write(sc, QLW_RESP_OUT, rspin);
@@ -790,7 +798,7 @@ qlw_scsi_cmd(struct scsi_xfer *xs)
bus = qlw_xs_bus(sc, xs);
if (sc->sc_marker_required[bus]) {
req = sc->sc_next_req_id++;
- if (sc->sc_next_req_id == sc->sc_maxcmds)
+ if (sc->sc_next_req_id == sc->sc_maxrequests)
sc->sc_next_req_id = 0;
DPRINTF(QLW_D_IO, "%s: writing marker at request %d\n",
@@ -807,7 +815,7 @@ qlw_scsi_cmd(struct scsi_xfer *xs)
}
req = sc->sc_next_req_id++;
- if (sc->sc_next_req_id == sc->sc_maxcmds)
+ if (sc->sc_next_req_id == sc->sc_maxrequests)
sc->sc_next_req_id = 0;
offset = (req * QLW_QUEUE_ENTRY_SIZE);
@@ -826,7 +834,7 @@ qlw_scsi_cmd(struct scsi_xfer *xs)
while (seg < ccb->ccb_dmamap->dm_nsegs) {
req = sc->sc_next_req_id++;
- if (sc->sc_next_req_id == sc->sc_maxcmds)
+ if (sc->sc_next_req_id == sc->sc_maxrequests)
sc->sc_next_req_id = 0;
offset = (req * QLW_QUEUE_ENTRY_SIZE);
@@ -898,7 +906,7 @@ qlw_scsi_cmd_poll(struct qlw_softc *sc)
ccb = qlw_handle_resp(sc, sc->sc_last_resp_id);
sc->sc_last_resp_id++;
- if (sc->sc_last_resp_id == sc->sc_maxcmds)
+ if (sc->sc_last_resp_id == sc->sc_maxresponses)
sc->sc_last_resp_id = 0;
qlw_queue_write(sc, QLW_RESP_OUT, sc->sc_last_resp_id);
@@ -1627,13 +1635,13 @@ qlw_alloc_ccbs(struct qlw_softc *sc)
return (1);
}
- sc->sc_requests = qlw_dmamem_alloc(sc, sc->sc_maxcmds *
+ sc->sc_requests = qlw_dmamem_alloc(sc, sc->sc_maxrequests *
QLW_QUEUE_ENTRY_SIZE);
if (sc->sc_requests == NULL) {
printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
goto free_ccbs;
}
- sc->sc_responses = qlw_dmamem_alloc(sc, sc->sc_maxcmds *
+ sc->sc_responses = qlw_dmamem_alloc(sc, sc->sc_maxresponses *
QLW_QUEUE_ENTRY_SIZE);
if (sc->sc_responses == NULL) {
printf("%s: unable to allocate rcb dmamem\n", DEVNAME(sc));
diff --git a/sys/dev/ic/qlwvar.h b/sys/dev/ic/qlwvar.h
index 15bbeb75809..beefc58ba9d 100644
--- a/sys/dev/ic/qlwvar.h
+++ b/sys/dev/ic/qlwvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlwvar.h,v 1.8 2014/03/08 18:30:54 kettenis Exp $ */
+/* $OpenBSD: qlwvar.h,v 1.9 2014/03/13 10:31:53 kettenis Exp $ */
/*
* Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
@@ -104,8 +104,9 @@ struct qlw_softc {
u_int16_t sc_mbox[8];
int sc_mbox_pending;
- int sc_maxcmds;
+ int sc_maxrequests;
struct qlw_dmamem *sc_requests;
+ int sc_maxresponses;
struct qlw_dmamem *sc_responses;
int sc_maxccbs;
struct qlw_ccb *sc_ccbs;