diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2010-09-20 04:08:37 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2010-09-20 04:08:37 +0000 |
commit | 36e3f19d595a230b93ffdb5ca94a1952ec951a59 (patch) | |
tree | 64e444ef80a2f2d96d29c76634af040f67963829 /sys/dev/ic/ciss.c | |
parent | 340e8f61d07f63c64df3a56dfd9d1762ed08772a (diff) |
bus_dmamap_sync was using xs->flags to determine which direction
to sync the map. unfortunately xs is not set for internal ciss
commands, so this is a null deref. it wasnt until kettenis made
bus_dmamap_sync a real function which needed its arguments evaluated
that this became a real problem though.
hit by mcbride@ and sakurai-san. fixed by krw@ over my shoulder
when we figured out which specific chunk of code was faulting.
tested by sakurai-san
ok krw@ deraadt@
Diffstat (limited to 'sys/dev/ic/ciss.c')
-rw-r--r-- | sys/dev/ic/ciss.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/sys/dev/ic/ciss.c b/sys/dev/ic/ciss.c index db0d134426f..54f86414a94 100644 --- a/sys/dev/ic/ciss.c +++ b/sys/dev/ic/ciss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ciss.c,v 1.61 2010/07/07 10:12:13 dlg Exp $ */ +/* $OpenBSD: ciss.c,v 1.62 2010/09/20 04:08:36 dlg Exp $ */ /* * Copyright (c) 2005,2006 Michael Shalayeff @@ -615,6 +615,7 @@ ciss_done(struct ciss_ccb *ccb) { struct ciss_softc *sc = ccb->ccb_sc; struct scsi_xfer *xs = ccb->ccb_xs; + struct ciss_cmd *cmd = &ccb->ccb_cmd; ciss_lock_t lock; int error = 0; @@ -625,7 +626,6 @@ ciss_done(struct ciss_ccb *ccb) sc->sc_dev.dv_xname, ccb, ccb->ccb_state, CISS_CCB_BITS); return 1; } - lock = CISS_LOCK(sc); ccb->ccb_state = CISS_CCB_READY; @@ -634,14 +634,14 @@ ciss_done(struct ciss_ccb *ccb) if (ccb->ccb_data) { bus_dmamap_sync(sc->dmat, ccb->ccb_dmamap, 0, - ccb->ccb_dmamap->dm_mapsize, (xs->flags & SCSI_DATA_IN) ? + ccb->ccb_dmamap->dm_mapsize, (cmd->flags & CISS_CDB_IN) ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->dmat, ccb->ccb_dmamap); } if (xs) { xs->resid = 0; - scsi_done(ccb->ccb_xs); + scsi_done(xs); } CISS_UNLOCK(sc, lock); |