summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2013-10-25 16:21:36 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2013-10-25 16:21:36 +0000
commit41a1e3dc595a5b7b5f0166f0ddc7ea31238314d0 (patch)
tree78b961f7d5a2cf66b7d2c9912de4929d79693f05
parent475b0d3738ebcfa564f4a43056b99848830f7a7a (diff)
fix an off by one when calculating the length of an sgl segment
that our chain scatter-gather element is pointing to. the bug was observed by pedro martelletto with some particular firmware doing raid 0. the fix wouldn't have been possible without extensive debugging and spec conformance verification done by pedro. tested by pedro, dlg and myself, ok dlg
-rw-r--r--sys/dev/pci/mpii.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/sys/dev/pci/mpii.c b/sys/dev/pci/mpii.c
index 916a9be1c7a..cf664b5d539 100644
--- a/sys/dev/pci/mpii.c
+++ b/sys/dev/pci/mpii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpii.c,v 1.69 2013/01/25 04:25:21 dlg Exp $ */
+/* $OpenBSD: mpii.c,v 1.70 2013/10/25 16:21:35 mikeb Exp $ */
/*
* Copyright (c) 2010, 2012 Mike Belopuhov
* Copyright (c) 2009 James Giannoules
@@ -747,9 +747,8 @@ mpii_load_xs(struct mpii_ccb *ccb)
return (1);
}
- /* safe default staring flags */
+ /* safe default starting flags */
flags = MPII_SGE_FL_TYPE_SIMPLE | MPII_SGE_FL_SIZE_64;
- /* if data out */
if (xs->flags & SCSI_DATA_OUT)
flags |= MPII_SGE_FL_DIR_OUT;
@@ -759,8 +758,8 @@ mpii_load_xs(struct mpii_ccb *ccb)
sge->sg_hdr |= htole32(MPII_SGE_FL_LAST);
/* offset to the chain sge from the beginning */
io->chain_offset = ((caddr_t)csge - (caddr_t)io) / 4;
- /* lenght of the chain buffer */
- len = (dmap->dm_nsegs - i - 1) * sizeof(*sge);
+ /* length of the sgl segment we're pointing to */
+ len = (dmap->dm_nsegs - i) * sizeof(*sge);
csge->sg_hdr = htole32(MPII_SGE_FL_TYPE_CHAIN |
MPII_SGE_FL_SIZE_64 | len);
/* address of the next sge */