summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2006-06-12 14:06:06 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2006-06-12 14:06:06 +0000
commita05e27ce903d0096d08735c27f18df94e6254279 (patch)
tree0e8422f1dfb4195e20d338fd65c49b7952dff205 /sys/dev/ic
parent6bd48e46af8eb5cb552c4a1a5e1b55f92d293313 (diff)
fix sgl loading. there were a few issues, the main ones being:
- when the sgl grew too large it became bigger than the maximum frame size that the ioc would deal with, and then it would just stop doing io. i was using the wrong field from iocfacts to figure out how large an sgl should be. - chained sgls were broken cos i was including the current chain element in the calculation of the offset to the next chain element. big ok from marco@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/mpi.c26
-rw-r--r--sys/dev/ic/mpivar.h3
2 files changed, 19 insertions, 10 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c
index ef2a1679f11..81f57a725c8 100644
--- a/sys/dev/ic/mpi.c
+++ b/sys/dev/ic/mpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi.c,v 1.34 2006/06/12 12:31:58 dlg Exp $ */
+/* $OpenBSD: mpi.c,v 1.35 2006/06/12 14:06:05 dlg Exp $ */
/*
* Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org>
@@ -517,7 +517,8 @@ mpi_intr(void *arg)
reply = NULL;
}
- DNPRINTF(MPI_D_INTR, "%s: mpi_intr id: %d\n", DEVNAME(sc), id);
+ DNPRINTF(MPI_D_INTR, "%s: mpi_intr id: %d reply: %p\n",
+ DEVNAME(sc), id, reply);
ccb = &sc->sc_ccbs[id];
@@ -1139,11 +1140,11 @@ mpi_load_xs(struct mpi_ccb *ccb)
DEVNAME(sc), sge->sg_hdr,
sge->sg_hi_addr, sge->sg_lo_addr);
- if ((dmap->dm_nsegs - i) > sc->sc_maxchdepth) {
- nce = &nsge[sc->sc_maxchdepth - 1];
- addr = ((u_int8_t *)nce - (u_int8_t *)ce) / 4;
+ if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
+ nce = &nsge[sc->sc_chain_len - 1];
+ addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
addr = addr << 16 |
- sizeof(struct mpi_sge) * sc->sc_maxchdepth;
+ sizeof(struct mpi_sge) * sc->sc_chain_len;
} else {
nce = NULL;
addr = sizeof(struct mpi_sge) *
@@ -1582,13 +1583,20 @@ mpi_iocfacts(struct mpi_softc *sc)
DNPRINTF(MPI_D_MISC, "%s: first sgl len: %d\n", DEVNAME(sc),
sc->sc_first_sgl_len);
+ sc->sc_chain_len = (letoh16(ifp.request_frame_size) * 4) /
+ sizeof(struct mpi_sge);
+ DNPRINTF(MPI_D_MISC, "%s: chain len: %d\n", DEVNAME(sc),
+ sc->sc_chain_len);
+
/* the sgl tailing the io cmd loses an entry to the chain element. */
sc->sc_max_sgl_len = MPI_MAX_SGL - 1;
/* the sgl chains lose an entry for each chain element */
sc->sc_max_sgl_len -= (MPI_MAX_SGL - sc->sc_first_sgl_len) /
- sc->sc_maxchdepth;
- DNPRINTF(MPI_D_MISC, "%s: max sgl len: %d\n",
- DEVNAME(sc), sc->sc_max_sgl_len);
+ sc->sc_chain_len;
+ DNPRINTF(MPI_D_MISC, "%s: max sgl len: %d\n", DEVNAME(sc),
+ sc->sc_max_sgl_len);
+
+ /* XXX we're ignoring the max chain depth */
return (0);
}
diff --git a/sys/dev/ic/mpivar.h b/sys/dev/ic/mpivar.h
index 092ad3916ee..df848e1d94a 100644
--- a/sys/dev/ic/mpivar.h
+++ b/sys/dev/ic/mpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpivar.h,v 1.9 2006/06/12 03:46:12 marco Exp $ */
+/* $OpenBSD: mpivar.h,v 1.10 2006/06/12 14:06:05 dlg Exp $ */
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
@@ -102,6 +102,7 @@ struct mpi_softc {
int sc_maxcmds;
int sc_maxchdepth;
int sc_first_sgl_len;
+ int sc_chain_len;
int sc_max_sgl_len;
int sc_buswidth;