diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2013-10-25 16:21:36 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2013-10-25 16:21:36 +0000 |
commit | 41a1e3dc595a5b7b5f0166f0ddc7ea31238314d0 (patch) | |
tree | 78b961f7d5a2cf66b7d2c9912de4929d79693f05 | |
parent | 475b0d3738ebcfa564f4a43056b99848830f7a7a (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.c | 9 |
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 */ |