diff options
-rw-r--r-- | sys/dev/ic/ami.c | 64 | ||||
-rw-r--r-- | sys/dev/ic/amivar.h | 4 |
2 files changed, 32 insertions, 36 deletions
diff --git a/sys/dev/ic/ami.c b/sys/dev/ic/ami.c index 745eb7a3975..b37c55308b1 100644 --- a/sys/dev/ic/ami.c +++ b/sys/dev/ic/ami.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ami.c,v 1.75 2005/09/19 04:11:03 krw Exp $ */ +/* $OpenBSD: ami.c,v 1.76 2005/09/19 07:45:28 dlg Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -171,7 +171,7 @@ ami_put_ccb(ccb) struct ami_softc *sc = ccb->ccb_sc; ccb->ccb_state = AMI_CCB_FREE; - ccb->ccb_done = NULL; + ccb->ccb_wakeup = 0; ccb->ami_pt.idata = NULL; TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link); } @@ -1071,8 +1071,12 @@ ami_cmd(ccb, flags, wait) if ((error = sc->sc_poll(sc, ccb->ccb_cmd))) { AMI_DPRINTF(AMI_D_MISC, ("pf ")); } - /* always free ccb */ - ami_put_ccb(ccb); + if (ccb->ccb_data) + bus_dmamap_unload(sc->dmat, dmap); + if (ccb->ccb_wakeup) + ccb->ccb_wakeup = 0; + else + ami_put_ccb(ccb); } else if ((error = ami_start(ccb, wait))) { AMI_DPRINTF(AMI_D_DMA, ("error=%d ", error)); __asm __volatile(".globl _bpamierr\n_bpamierr:"); @@ -1258,12 +1262,11 @@ ami_done(sc, idx) } } - if (ccb->ccb_done) { - *ccb->ccb_done = 1; - wakeup((void *)ccb->ccb_done); - } - - ami_put_ccb(ccb); + if (ccb->ccb_wakeup) { + ccb->ccb_wakeup = 0; + wakeup(ccb); + } else + ami_put_ccb(ccb); if (xs) { xs->resid = 0; @@ -1318,7 +1321,6 @@ ami_scsi_raw_cmd(xs) struct ami_passthrough *ps; int error; int direction; - volatile int done = 0; ami_lock_t lock; void *idata; bus_dmamap_t idatamap; @@ -1425,7 +1427,6 @@ ami_scsi_raw_cmd(xs) ccb->ccb_xs = xs; ccb->ccb_len = xs->datalen; ccb->ccb_data = NULL; - ccb->ccb_done = &done; ps->apt_param = AMI_PTPARAM(AMI_TIMEOUT_6,1,0); ps->apt_channel = channel; @@ -1443,8 +1444,8 @@ ami_scsi_raw_cmd(xs) if (ccb->ami_pt.dir == AMI_PT_OUT) memcpy(ccb->ami_pt.idata + sizeof *ps, xs->data, xs->datalen); - if (xs->flags & SCSI_POLL) - done = 1; /* Don't wait for completion twice. */ + if ((xs->flags & SCSI_POLL) == 0) + ccb->ccb_wakeup = 1; if ((error = ami_cmd(ccb, ((xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK), xs->flags & SCSI_POLL))) { @@ -1471,10 +1472,12 @@ ami_scsi_raw_cmd(xs) memcpy(xs->data, idata + sizeof *ps, xs->datalen); scsi_done(xs); - } + } else { + while (ccb->ccb_wakeup) + tsleep(ccb, PRIBIO, "ami_pt", 0); - while (!done) - tsleep((void *)&done, PRIBIO, "ami_pt", 0); + ami_put_ccb(ccb); + } ami_freemem(idata, sc->dmat, &idatamap, idataseg, NBPG, 1, "ami raw"); @@ -1823,7 +1826,6 @@ ami_drv_inq(sc, ch, tg, page, inqbuf) bus_dma_segment_t idataseg[1]; paddr_t pa; int error = 0; - volatile int done = 0; ccb = ami_get_ccb(sc); if (ccb == NULL) @@ -1840,7 +1842,7 @@ ami_drv_inq(sc, ch, tg, page, inqbuf) pp = idata + sizeof *ps; ccb->ccb_data = NULL; - ccb->ccb_done = &done; + ccb->ccb_wakeup = 1; cmd = ccb->ccb_cmd; cmd->acc_cmd = AMI_PASSTHRU; @@ -1869,12 +1871,10 @@ ami_drv_inq(sc, ch, tg, page, inqbuf) ps->apt_datalen = sizeof(struct scsi_inquiry_data); if (ami_cmd(ccb, BUS_DMA_WAITOK, 0) == 0) { - while (!done) - if (tsleep((void *)&done, PRIBIO, "ami_drv_inq", - 15 * hz) == EWOULDBLOCK) { - error = EINVAL; - goto bail; - } + while (ccb->ccb_wakeup) + tsleep(ccb, PRIBIO, "ami_drv_inq", 0); + + ami_put_ccb(ccb); if (ps->apt_scsistat == 0x00) { memcpy(inqbuf, pp, sizeof(struct scsi_inquiry_data)); @@ -1913,7 +1913,6 @@ ami_mgmt(sc, opcode, par1, par2, par3, size, buffer) bus_dma_segment_t idataseg[1]; paddr_t pa; int error = 0; - volatile int done = 0; ccb = ami_get_ccb(sc); if (ccb == NULL) @@ -1928,7 +1927,7 @@ ami_mgmt(sc, opcode, par1, par2, par3, size, buffer) pa = idataseg[0].ds_addr; ccb->ccb_data = NULL; - ccb->ccb_done = &done; + ccb->ccb_wakeup = 1; cmd = ccb->ccb_cmd; cmd->acc_cmd = opcode; @@ -1950,12 +1949,10 @@ ami_mgmt(sc, opcode, par1, par2, par3, size, buffer) cmd->acc_io.aio_data = htole32(pa); if (ami_cmd(ccb, BUS_DMA_WAITOK, 0) == 0) { - while (!done) - if (tsleep((void *)&done, PRIBIO,"ami_mgmt", - 15 * hz) == EWOULDBLOCK) { - error = EINVAL; - goto bail; - } + while (ccb->ccb_wakeup) + tsleep(ccb, PRIBIO,"ami_mgmt", 0); + + ami_put_ccb(ccb); /* XXX how do commands fail? */ @@ -1965,7 +1962,6 @@ ami_mgmt(sc, opcode, par1, par2, par3, size, buffer) else error = EINVAL; -bail: ami_freemem(idata, sc->dmat, &idatamap, idataseg, NBPG, (size / NBPG) + 1, "ami mgmt"); diff --git a/sys/dev/ic/amivar.h b/sys/dev/ic/amivar.h index 6c057e88224..6202d9b9c8d 100644 --- a/sys/dev/ic/amivar.h +++ b/sys/dev/ic/amivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amivar.h,v 1.22 2005/09/15 05:33:39 krw Exp $ */ +/* $OpenBSD: amivar.h,v 1.23 2005/09/19 07:45:28 dlg Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -42,7 +42,7 @@ struct ami_ccb { #define AMI_PT_IN (0x00) #define AMI_PT_OUT (0x01) } ami_pt; - volatile int *ccb_done; + volatile int ccb_wakeup; TAILQ_ENTRY(ami_ccb) ccb_link; enum { AMI_CCB_FREE, AMI_CCB_READY, AMI_CCB_QUEUED, AMI_CCB_PREQUEUED |