From 41a1e3dc595a5b7b5f0166f0ddc7ea31238314d0 Mon Sep 17 00:00:00 2001 From: Mike Belopuhov Date: Fri, 25 Oct 2013 16:21:36 +0000 Subject: 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 --- sys/dev/pci/mpii.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'sys/dev/pci') 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 */ -- cgit v1.2.3