From 2a3f9392f60ea1239ccfde2bf478d69d061b6169 Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Wed, 21 Sep 2005 10:36:15 +0000 Subject: dont use the scsi xfer in ami_done to figure out if we have to sync a buffer or not. this will allow us to issue arbitrary passthrough commands without needing them to come in via ami_scsi_raw_cmd. useful for management functionality... --- sys/dev/ic/ami.c | 78 +++++++++++++++++++++++------------------------------ sys/dev/ic/amivar.h | 7 +++-- 2 files changed, 38 insertions(+), 47 deletions(-) (limited to 'sys/dev/ic') diff --git a/sys/dev/ic/ami.c b/sys/dev/ic/ami.c index b9d0b78c6ae..7606fe0bc69 100644 --- a/sys/dev/ic/ami.c +++ b/sys/dev/ic/ami.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ami.c,v 1.81 2005/09/21 08:52:44 dlg Exp $ */ +/* $OpenBSD: ami.c,v 1.82 2005/09/21 10:36:14 dlg Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -1208,14 +1208,15 @@ ami_stimeout(v) printf("%s: timeout ccb %d\n", sc->sc_dev.dv_xname, cmd->acc_id); AMI_DPRINTF(AMI_D_CMD, ("timeout(%d) ", cmd->acc_id)); - if (xs->cmd->opcode != PREVENT_ALLOW && - xs->cmd->opcode != SYNCHRONIZE_CACHE) { + + /* XXX ccb might complete and overwrite this mem */ + if (ccb->ccb_data != NULL) { bus_dmamap_sync(sc->dmat, ccb->ccb_dmamap, 0, ccb->ccb_dmamap->dm_mapsize, - (xs->flags & SCSI_DATA_IN) ? - BUS_DMASYNC_POSTREAD : - BUS_DMASYNC_POSTWRITE); + (ccb->ccb_dir == AMI_CCB_IN) ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->dmat, ccb->ccb_dmamap); + ccb->ccb_data = NULL; } TAILQ_REMOVE(&sc->sc_ccbq, ccb, ccb_link); ami_put_ccb(ccb); @@ -1251,50 +1252,36 @@ ami_done(sc, idx) ccb->ccb_state = AMI_CCB_READY; TAILQ_REMOVE(&sc->sc_ccbq, ccb, ccb_link); - if (xs) { - timeout_del(&xs->stimeout); + /* dma sync cmd/pt/sglist */ - if (xs->cmd->opcode != PREVENT_ALLOW && - xs->cmd->opcode != SYNCHRONIZE_CACHE) - bus_dmamap_sync(sc->dmat, ccb->ccb_dmamap, 0, - ccb->ccb_dmamap->dm_mapsize, - (xs->flags & SCSI_DATA_IN) ? - BUS_DMASYNC_POSTREAD : - BUS_DMASYNC_POSTWRITE); + if (ccb->ccb_data != NULL) { + bus_dmamap_sync(sc->dmat, ccb->ccb_dmamap, 0, + ccb->ccb_dmamap->dm_mapsize, + (ccb->ccb_dir == AMI_CCB_IN) ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->dmat, ccb->ccb_dmamap); - ccb->ccb_xs = NULL; - } else { - struct ami_iocmd *cmd = ccb->ccb_cmd; - - switch (cmd->acc_cmd) { - case AMI_INQUIRY: - case AMI_EINQUIRY: - case AMI_EINQUIRY3: - bus_dmamap_sync(sc->dmat, ccb->ccb_dmamap, 0, - ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->dmat, ccb->ccb_dmamap); - break; - default: - /* no data */ - break; - } + ccb->ccb_data = NULL; } - if (ccb->ccb_wakeup) { - ccb->ccb_wakeup = 0; - wakeup(ccb); - } else - ami_put_ccb(ccb); - if (xs) { + timeout_del(&xs->stimeout); + xs->resid = 0; xs->flags |= ITSDONE; AMI_DPRINTF(AMI_D_CMD, ("scsi_done(%d) ", idx)); scsi_done(xs); + + ccb->ccb_xs = NULL; } + if (ccb->ccb_wakeup) { + ccb->ccb_wakeup = 0; + wakeup(ccb); + } else + ami_put_ccb(ccb); + AMI_UNLOCK_AMI(sc, lock); return (0); @@ -1337,7 +1324,6 @@ ami_scsi_raw_cmd(xs) u_int8_t channel = rsc->sc_channel, target = link->target; struct device *dev = link->device_softc; struct ami_ccb *ccb; - struct ami_iocmd *cmd; int error; ami_lock_t lock; char type; @@ -1371,12 +1357,14 @@ ami_scsi_raw_cmd(xs) return (COMPLETE); } - memset(ccb->ccb_pt, 0, sizeof(struct ami_passthrough)); - ccb->ccb_xs = xs; - ccb->ccb_len = xs->datalen; ccb->ccb_data = xs->data; + ccb->ccb_len = xs->datalen; + ccb->ccb_dir = (xs->flags & SCSI_DATA_IN) ? AMI_CCB_IN : AMI_CCB_OUT; + + ccb->ccb_cmd->acc_cmd = AMI_PASSTHRU; + memset(ccb->ccb_pt, 0, sizeof(struct ami_passthrough)); ccb->ccb_pt->apt_param = AMI_PTPARAM(AMI_TIMEOUT_6,1,0); ccb->ccb_pt->apt_channel = channel; ccb->ccb_pt->apt_target = target; @@ -1385,9 +1373,6 @@ ami_scsi_raw_cmd(xs) ccb->ccb_pt->apt_nsense = AMI_MAX_SENSE; ccb->ccb_pt->apt_datalen = xs->datalen; - cmd = ccb->ccb_cmd; - cmd->acc_cmd = AMI_PASSTHRU; - if ((error = ami_cmd(ccb, ((xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK), xs->flags & SCSI_POLL))) { xs->error = XS_DRIVER_STUFFUP; @@ -1570,8 +1555,11 @@ ami_scsi_cmd(xs) } ccb->ccb_xs = xs; - ccb->ccb_len = xs->datalen; ccb->ccb_data = xs->data; + ccb->ccb_len = xs->datalen; + ccb->ccb_dir = (xs->flags & SCSI_DATA_IN) ? + AMI_CCB_IN : AMI_CCB_OUT; + cmd = ccb->ccb_cmd; cmd->acc_mbox.amb_nsect = htole16(blockcnt); cmd->acc_mbox.amb_lba = htole32(blockno); diff --git a/sys/dev/ic/amivar.h b/sys/dev/ic/amivar.h index 728bade364b..468ec547044 100644 --- a/sys/dev/ic/amivar.h +++ b/sys/dev/ic/amivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amivar.h,v 1.25 2005/09/21 08:52:44 dlg Exp $ */ +/* $OpenBSD: amivar.h,v 1.26 2005/09/21 10:36:14 dlg Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -43,8 +43,11 @@ struct ami_ccb { enum { AMI_CCB_FREE, AMI_CCB_READY, AMI_CCB_QUEUED, AMI_CCB_PREQUEUED } ccb_state; - int ccb_len; void *ccb_data; + int ccb_len; + enum { + AMI_CCB_IN, AMI_CCB_OUT + } ccb_dir; bus_dmamap_t ccb_dmamap; }; -- cgit v1.2.3