summaryrefslogtreecommitdiff
path: root/sys/dev/ic/iha.c
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2003-03-29 23:28:50 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2003-03-29 23:28:50 +0000
commita3caa98392df798be3a81daf3bdaeb6a09776413 (patch)
tree6dce757b3c53ce00c61d3a1c36f3c0a538e08383 /sys/dev/ic/iha.c
parentfa6d320b863c487d67b4160bad23b6d94653982a (diff)
A few final (I hope) tweaks to the dma fixes.
1) Return XS_DRIVER_STUFFUP if request sense cannot be loaded. 2) Try to avoid bus_dmamap_unload()'ing maps that have already been unloaded. 3) Try to avoid bus_dmamap_load()'ing maps that are loaded. 4) Be extra paranoid and ensure bus_dmamap_sync()'s are done before a bus_dmamap_unload().
Diffstat (limited to 'sys/dev/ic/iha.c')
-rw-r--r--sys/dev/ic/iha.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/sys/dev/ic/iha.c b/sys/dev/ic/iha.c
index 50c23095fad..f5f9f367426 100644
--- a/sys/dev/ic/iha.c
+++ b/sys/dev/ic/iha.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: iha.c,v 1.19 2003/03/29 17:52:01 krw Exp $ */
+/* $OpenBSD: iha.c,v 1.20 2003/03/29 23:28:49 krw Exp $ */
/*-------------------------------------------------------------------------
*
* Device driver for the INI-9XXXU/UW or INIC-940/950 PCI SCSI Controller.
@@ -223,9 +223,6 @@ iha_setup_sg_list(sc, pScb)
int i, error, nseg = pScb->SCB_DataDma->dm_nsegs;
if (nseg > 1) {
- pScb->SCB_Flags |= FLAG_SG;
- bzero(pScb->SCB_SGList, sizeof(pScb->SCB_SGList));
-
error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_SGDma,
pScb->SCB_SGList, sizeof(pScb->SCB_SGList), NULL,
(pScb->SCB_Flags & SCSI_NOSLEEP) ?
@@ -236,6 +233,13 @@ iha_setup_sg_list(sc, pScb)
return (error);
}
+ /*
+ * Only set FLAG_SG when SCB_SGDma is loaded so iha_scsi_done
+ * will not unload an unloaded map.
+ */
+ pScb->SCB_Flags |= FLAG_SG;
+ bzero(pScb->SCB_SGList, sizeof(pScb->SCB_SGList));
+
pScb->SCB_SGIdx = 0;
pScb->SCB_SGCount = nseg;
@@ -323,6 +327,10 @@ iha_scsi_cmd(xs)
xs->error = XS_DRIVER_STUFFUP;
return (COMPLETE);
}
+ bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
+ 0, pScb->SCB_BufChars,
+ (pScb->SCB_Flags & SCSI_DATA_IN) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
error = iha_setup_sg_list(sc, pScb);
if (error) {
@@ -331,10 +339,6 @@ iha_scsi_cmd(xs)
return (COMPLETE);
}
- bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
- 0, pScb->SCB_BufChars,
- (pScb->SCB_Flags & SCSI_DATA_IN) ?
- BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
}
/*
@@ -839,8 +843,24 @@ iha_push_sense_request(sc, pScb)
struct scsi_sense *sensecmd;
int error;
- pScb->SCB_Flags &= SCSI_POLL | SCSI_NOSLEEP;
- pScb->SCB_Flags |= FLAG_RSENS | SCSI_DATA_IN;
+ /* First sync & unload any existing DataDma and SGDma maps */
+ if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) {
+ bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
+ 0, pScb->SCB_BufChars,
+ ((pScb->SCB_Flags & SCSI_DATA_IN) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
+ bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
+ /* Don't unload this map again until it is reloaded */
+ pScb->SCB_Flags &= ~(SCSI_DATA_IN | SCSI_DATA_OUT);
+ }
+ if ((pScb->SCB_Flags & FLAG_SG) != 0) {
+ bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
+ 0, sizeof(pScb->SCB_SGList),
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma);
+ /* Don't unload this map again until it is reloaded */
+ pScb->SCB_Flags &= ~FLAG_SG;
+ }
pScb->SCB_BufChars = sizeof(pScb->SCB_ScsiSenseData);
pScb->SCB_BufCharsLeft = sizeof(pScb->SCB_ScsiSenseData);
@@ -855,19 +875,18 @@ iha_push_sense_request(sc, pScb)
sc_print_addr(pScb->SCB_Xs->sc_link);
printf("error %d loading request sense buffer dma map\n",
error);
- return (1);
+ return (error);
}
+ bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
+ 0, pScb->SCB_BufChars, BUS_DMASYNC_PREREAD);
+
+ /* Save _POLL and _NOSLEEP flags. */
+ pScb->SCB_Flags &= SCSI_POLL | SCSI_NOSLEEP;
+ pScb->SCB_Flags |= FLAG_RSENS | SCSI_DATA_IN;
error = iha_setup_sg_list(sc, pScb);
- if (error) {
- bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
+ if (error)
return (error);
- }
-
- bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
- 0, pScb->SCB_BufChars,
- (pScb->SCB_Flags & SCSI_DATA_IN) ?
- BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
pScb->SCB_Ident &= ~MSG_IDENTIFY_DISCFLAG;
@@ -921,7 +940,10 @@ iha_scsi_label:
if ((pScb->SCB_Flags & FLAG_RSENS) != 0)
/* Check condition on check condition*/
pScb->SCB_HaStat = HOST_BAD_PHAS;
- else if (iha_push_sense_request(sc, pScb) == 0)
+ else if (iha_push_sense_request(sc, pScb) != 0)
+ /* Could not push sense request */
+ pScb->SCB_HaStat = HOST_BAD_PHAS;
+ else
/* REQUEST SENSE ready to process */
goto iha_scsi_label;
break;