summaryrefslogtreecommitdiff
path: root/sys/dev/ic/ami.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/ami.c')
-rw-r--r--sys/dev/ic/ami.c121
1 files changed, 68 insertions, 53 deletions
diff --git a/sys/dev/ic/ami.c b/sys/dev/ic/ami.c
index eff07d81355..93cae7c0d56 100644
--- a/sys/dev/ic/ami.c
+++ b/sys/dev/ic/ami.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ami.c,v 1.107 2006/01/29 00:48:19 krw Exp $ */
+/* $OpenBSD: ami.c,v 1.108 2006/03/13 11:11:55 dlg Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -1367,7 +1367,7 @@ ami_scsi_cmd(struct scsi_xfer *xs)
u_int32_t blockno, blockcnt;
struct scsi_rw *rw;
struct scsi_rw_big *rwb;
- int error, flags;
+ int error;
int s;
AMI_DPRINTF(AMI_D_CMD, ("ami_scsi_cmd "));
@@ -1443,7 +1443,36 @@ ami_scsi_cmd(struct scsi_xfer *xs)
case SYNCHRONIZE_CACHE:
AMI_DPRINTF(AMI_D_CMD, ("SYNCHRONIZE CACHE "));
- error++;
+
+ ccb = ami_get_ccb(sc);
+ if (ccb == NULL) {
+ xs->error = XS_DRIVER_STUFFUP;
+ scsi_done(xs);
+ splx(s);
+ return (COMPLETE);
+ }
+
+ ccb->ccb_xs = xs;
+ if (xs->timeout < 30000)
+ xs->timeout = 30000; /* at least 30sec */
+
+ cmd = &ccb->ccb_cmd;
+ cmd->acc_cmd = AMI_FLUSH;
+
+ if (ami_cmd(ccb, (xs->flags & SCSI_NOSLEEP) ?
+ BUS_DMA_NOWAIT : BUS_DMA_WAITOK, xs->flags & SCSI_POLL)) {
+ xs->error = XS_DRIVER_STUFFUP;
+ scsi_done(xs);
+ splx(s);
+ return (COMPLETE);
+ }
+
+ splx(s);
+ if (xs->flags & SCSI_POLL)
+ return (COMPLETE);
+ else
+ return (SUCCESSFULLY_QUEUED);
+
case READ_COMMAND:
if (!error) {
AMI_DPRINTF(AMI_D_CMD, ("READ "));
@@ -1465,41 +1494,40 @@ ami_scsi_cmd(struct scsi_xfer *xs)
error++;
}
- flags = xs->flags;
- if (xs->cmd->opcode != SYNCHRONIZE_CACHE) {
- /* A read or write operation. */
- if (xs->cmdlen == 6) {
- rw = (struct scsi_rw *)xs->cmd;
- blockno = _3btol(rw->addr) &
- (SRW_TOPADDR << 16 | 0xffff);
- blockcnt = rw->length ? rw->length : 0x100;
- } else {
- rwb = (struct scsi_rw_big *)xs->cmd;
- blockno = _4btol(rwb->addr);
- blockcnt = _2btol(rwb->length);
- /* TODO: reflect DPO & FUA flags */
- if (xs->cmd->opcode == WRITE_BIG &&
- rwb->byte2 & 0x18)
- flags |= 0;
- }
- if (blockno >= sc->sc_hdr[target].hd_size ||
- blockno + blockcnt > sc->sc_hdr[target].hd_size) {
- printf("%s: out of bounds %u-%u >= %u\n",
- sc->sc_dev.dv_xname, blockno, blockcnt,
- sc->sc_hdr[target].hd_size);
- xs->error = XS_DRIVER_STUFFUP;
- scsi_done(xs);
- splx(s);
- return (COMPLETE);
- }
+ /* A read or write operation. */
+ if (xs->cmdlen == 6) {
+ rw = (struct scsi_rw *)xs->cmd;
+ blockno = _3btol(rw->addr) &
+ (SRW_TOPADDR << 16 | 0xffff);
+ blockcnt = rw->length ? rw->length : 0x100;
+ } else {
+ rwb = (struct scsi_rw_big *)xs->cmd;
+ blockno = _4btol(rwb->addr);
+ blockcnt = _2btol(rwb->length);
+#if 0
+ /* TODO: reflect DPO & FUA flags */
+ if (xs->cmd->opcode == WRITE_BIG &&
+ rwb->byte2 & 0x18)
+ flags |= 0;
+#endif
}
- if ((ccb = ami_get_ccb(sc)) == NULL) {
- AMI_DPRINTF(AMI_D_CMD, ("no more ccbs "));
+ if (blockno >= sc->sc_hdr[target].hd_size ||
+ blockno + blockcnt > sc->sc_hdr[target].hd_size) {
+ printf("%s: out of bounds %u-%u >= %u\n",
+ sc->sc_dev.dv_xname, blockno, blockcnt,
+ sc->sc_hdr[target].hd_size);
+ xs->error = XS_DRIVER_STUFFUP;
+ scsi_done(xs);
+ splx(s);
+ return (COMPLETE);
+ }
+
+ ccb = ami_get_ccb(sc);
+ if (ccb == NULL) {
xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
splx(s);
- __asm __volatile(".globl _bpamiccb\n_bpamiccb:");
return (COMPLETE);
}
@@ -1515,11 +1543,6 @@ ami_scsi_cmd(struct scsi_xfer *xs)
cmd->acc_mbox.amb_data = 0;
switch (xs->cmd->opcode) {
- case SYNCHRONIZE_CACHE:
- cmd->acc_cmd = AMI_FLUSH;
- if (xs->timeout < 30000)
- xs->timeout = 30000; /* at least 30sec */
- break;
case READ_COMMAND: case READ_BIG:
cmd->acc_cmd = AMI_READ;
break;
@@ -1528,24 +1551,16 @@ ami_scsi_cmd(struct scsi_xfer *xs)
break;
}
- if ((error = ami_cmd(ccb, ((flags & SCSI_NOSLEEP)?
- BUS_DMA_NOWAIT : BUS_DMA_WAITOK), flags & SCSI_POLL))) {
-
- AMI_DPRINTF(AMI_D_CMD, ("failed %p ", xs));
- __asm __volatile(".globl _bpamifail\n_bpamifail:");
- if (flags & SCSI_POLL) {
- splx(s);
- return (TRY_AGAIN_LATER);
- } else {
- xs->error = XS_DRIVER_STUFFUP;
- scsi_done(xs);
- splx(s);
- return (COMPLETE);
- }
+ if (ami_cmd(ccb, (xs->flags & SCSI_NOSLEEP) ?
+ BUS_DMA_NOWAIT : BUS_DMA_WAITOK, xs->flags & SCSI_POLL)) {
+ xs->error = XS_DRIVER_STUFFUP;
+ scsi_done(xs);
+ splx(s);
+ return (COMPLETE);
}
splx(s);
- if (flags & SCSI_POLL)
+ if (xs->flags & SCSI_POLL)
return (COMPLETE);
else
return (SUCCESSFULLY_QUEUED);