summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2005-09-21 10:36:15 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2005-09-21 10:36:15 +0000
commit2a3f9392f60ea1239ccfde2bf478d69d061b6169 (patch)
treed409dab97688529defd15102064e275db488253f /sys/dev/ic
parent6255f47b924c8d6bd87d07ef65b47738758b88e0 (diff)
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...
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/ami.c78
-rw-r--r--sys/dev/ic/amivar.h7
2 files changed, 38 insertions, 47 deletions
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;
};