diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2006-06-12 14:06:06 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2006-06-12 14:06:06 +0000 |
commit | a05e27ce903d0096d08735c27f18df94e6254279 (patch) | |
tree | 0e8422f1dfb4195e20d338fd65c49b7952dff205 /sys/dev/ic | |
parent | 6bd48e46af8eb5cb552c4a1a5e1b55f92d293313 (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.c | 26 | ||||
-rw-r--r-- | sys/dev/ic/mpivar.h | 3 |
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; |