diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/ami.c | 237 |
1 files changed, 105 insertions, 132 deletions
diff --git a/sys/dev/ic/ami.c b/sys/dev/ic/ami.c index 87e98f45f26..feee64e0d5b 100644 --- a/sys/dev/ic/ami.c +++ b/sys/dev/ic/ami.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ami.c,v 1.111 2006/03/13 22:11:23 brad Exp $ */ +/* $OpenBSD: ami.c,v 1.112 2006/03/14 11:44:08 dlg Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -1386,19 +1386,58 @@ ami_scsi_cmd(struct scsi_xfer *xs) xs->error = XS_NOERROR; switch (xs->cmd->opcode) { + case READ_COMMAND: + case READ_BIG: + case WRITE_COMMAND: + case WRITE_BIG: + /* deal with io outside the switch */ + break; + + case SYNCHRONIZE_CACHE: + s = splbio(); + ccb = ami_get_ccb(sc); + splx(s); + if (ccb == NULL) { + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); + 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; + + s = splbio(); + error = ami_cmd(ccb, (xs->flags & SCSI_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK, xs->flags & SCSI_POLL); + splx(s); + if (error) { + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); + return (COMPLETE); + } + + if (xs->flags & SCSI_POLL) + return (COMPLETE); + else + return (SUCCESSFULLY_QUEUED); + case TEST_UNIT_READY: /* save off sd? after autoconf */ if (!cold) /* XXX bogus */ strlcpy(sc->sc_hdr[target].dev, dev->dv_xname, sizeof(sc->sc_hdr[target].dev)); - case START_STOP: #if 0 case VERIFY: #endif + case PREVENT_ALLOW: AMI_DPRINTF(AMI_D_CMD, ("opc %d tgt %d ", xs->cmd->opcode, target)); - break; + return (COMPLETE); case REQUEST_SENSE: AMI_DPRINTF(AMI_D_CMD, ("REQUEST SENSE tgt %d ", target)); @@ -1409,7 +1448,8 @@ ami_scsi_cmd(struct scsi_xfer *xs) *(u_int32_t*)sd.info = htole32(0); sd.extra_len = 0; ami_copy_internal_data(xs, &sd, sizeof sd); - break; + scsi_done(xs); + return (COMPLETE); case INQUIRY: AMI_DPRINTF(AMI_D_CMD, ("INQUIRY tgt %d ", target)); @@ -1424,7 +1464,8 @@ ami_scsi_cmd(struct scsi_xfer *xs) target); strlcpy(inq.revision, " ", sizeof inq.revision); ami_copy_internal_data(xs, &inq, sizeof inq); - break; + scsi_done(xs); + return (COMPLETE); case READ_CAPACITY: AMI_DPRINTF(AMI_D_CMD, ("READ CAPACITY tgt %d ", target)); @@ -1432,146 +1473,78 @@ ami_scsi_cmd(struct scsi_xfer *xs) _lto4b(sc->sc_hdr[target].hd_size - 1, rcd.addr); _lto4b(AMI_SECTOR_SIZE, rcd.length); ami_copy_internal_data(xs, &rcd, sizeof rcd); - break; - - case PREVENT_ALLOW: - AMI_DPRINTF(AMI_D_CMD, ("PREVENT/ALLOW ")); + scsi_done(xs); return (COMPLETE); - case SYNCHRONIZE_CACHE: - AMI_DPRINTF(AMI_D_CMD, ("SYNCHRONIZE CACHE ")); - - s = splbio(); - ccb = ami_get_ccb(sc); - splx(s); - if (ccb == NULL) { - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - 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; - - s = splbio(); - error = ami_cmd(ccb, (xs->flags & SCSI_NOSLEEP) ? - BUS_DMA_NOWAIT : BUS_DMA_WAITOK, xs->flags & SCSI_POLL); - splx(s); - if (error) { - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - return (COMPLETE); - } - - if (xs->flags & SCSI_POLL) - return (COMPLETE); - else - return (SUCCESSFULLY_QUEUED); - - case READ_COMMAND: - if (!error) { - AMI_DPRINTF(AMI_D_CMD, ("READ ")); - error++; - } - case READ_BIG: - if (!error) { - AMI_DPRINTF(AMI_D_CMD, ("READ BIG ")); - error++; - } - case WRITE_COMMAND: - if (!error) { - AMI_DPRINTF(AMI_D_CMD, ("WRITE ")); - error++; - } - case WRITE_BIG: - if (!error) { - AMI_DPRINTF(AMI_D_CMD, ("WRITE BIG ")); - error++; - } + default: + AMI_DPRINTF(AMI_D_CMD, ("unsupported scsi command %#x tgt %d ", + xs->cmd->opcode, target)); + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); + 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); + /* 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; + /* TODO: reflect DPO & FUA flags */ + if (xs->cmd->opcode == WRITE_BIG && rwb->byte2 & 0x18) + flags |= 0; #endif - } - - 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); - return (COMPLETE); - } + } - s = splbio(); - ccb = ami_get_ccb(sc); - splx(s); - if (ccb == NULL) { - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - return (COMPLETE); - } + 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); + return (COMPLETE); + } - ccb->ccb_xs = xs; - ccb->ccb_len = xs->datalen; - ccb->ccb_dir = (xs->flags & SCSI_DATA_IN) ? - AMI_CCB_IN : AMI_CCB_OUT; - ccb->ccb_data = xs->data; - cmd = &ccb->ccb_cmd; - cmd->acc_mbox.amb_nsect = htole16(blockcnt); - cmd->acc_mbox.amb_lba = htole32(blockno); - cmd->acc_mbox.amb_ldn = target; - cmd->acc_mbox.amb_data = 0; - - switch (xs->cmd->opcode) { - case READ_COMMAND: case READ_BIG: - cmd->acc_cmd = AMI_READ; - break; - case WRITE_COMMAND: case WRITE_BIG: - cmd->acc_cmd = AMI_WRITE; - break; - } + s = splbio(); + ccb = ami_get_ccb(sc); + splx(s); + if (ccb == NULL) { + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); + return (COMPLETE); + } - s = splbio(); - error = ami_cmd(ccb, (xs->flags & SCSI_NOSLEEP) ? - BUS_DMA_NOWAIT : BUS_DMA_WAITOK, xs->flags & SCSI_POLL); - splx(s); - if (error) { - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - return (COMPLETE); - } + ccb->ccb_xs = xs; + ccb->ccb_len = xs->datalen; + ccb->ccb_dir = (xs->flags & SCSI_DATA_IN) ? AMI_CCB_IN : AMI_CCB_OUT; + ccb->ccb_data = xs->data; - if (xs->flags & SCSI_POLL) - return (COMPLETE); - else - return (SUCCESSFULLY_QUEUED); + cmd = &ccb->ccb_cmd; + cmd->acc_cmd = (xs->flags & SCSI_DATA_IN) ? AMI_READ : AMI_WRITE; + cmd->acc_mbox.amb_nsect = htole16(blockcnt); + cmd->acc_mbox.amb_lba = htole32(blockno); + cmd->acc_mbox.amb_ldn = target; + cmd->acc_mbox.amb_data = 0; - default: - AMI_DPRINTF(AMI_D_CMD, ("unsupported scsi command %#x tgt %d ", - xs->cmd->opcode, target)); + s = splbio(); + error = ami_cmd(ccb, (xs->flags & SCSI_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK, xs->flags & SCSI_POLL); + splx(s); + if (error) { xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); + return (COMPLETE); } - return (COMPLETE); + if (xs->flags & SCSI_POLL) + return (COMPLETE); + else + return (SUCCESSFULLY_QUEUED); } int |