diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-01-17 17:11:11 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-01-17 17:11:11 +0000 |
commit | dad55f14f79438635b953b729c55add8921be7db (patch) | |
tree | ba6b8ec698e42ccd326f2c4f3aee08b09b263890 /sys/arch/sparc64 | |
parent | 32bf7bcdae0a4061c6898533d5d43ed9cad946d6 (diff) |
Implement SYNCHRONIZE CACHE and make SCSI_POLL work while we're there.
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r-- | sys/arch/sparc64/dev/vdsk.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/sys/arch/sparc64/dev/vdsk.c b/sys/arch/sparc64/dev/vdsk.c index 321a4890046..26af51b70df 100644 --- a/sys/arch/sparc64/dev/vdsk.c +++ b/sys/arch/sparc64/dev/vdsk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vdsk.c,v 1.5 2009/01/16 23:57:45 kettenis Exp $ */ +/* $OpenBSD: vdsk.c,v 1.6 2009/01/17 17:11:10 kettenis Exp $ */ /* * Copyright (c) 2009 Mark Kettenis * @@ -880,6 +880,10 @@ vdsk_scsi_cmd(struct scsi_xfer *xs) operation = VD_OP_BWRITE; break; + case SYNCHRONIZE_CACHE: + operation = VD_OP_FLUSH; + break; + case INQUIRY: return (vdsk_scsi_inq(xs)); case READ_CAPACITY: @@ -915,7 +919,8 @@ vdsk_scsi_cmd(struct scsi_xfer *xs) vaddr_t va; paddr_t pa; int len, ncookies; - int desc; + int desc, s; + int timeout; KASSERT(sc->sc_tx_cnt < sc->sc_vd->vd_nentries); @@ -962,8 +967,8 @@ vdsk_scsi_cmd(struct scsi_xfer *xs) sc->sc_vsd[desc].vsd_xs = xs; - desc++; - desc &= (sc->sc_vd->vd_nentries - 1); + sc->sc_tx_prod++; + sc->sc_tx_prod &= (sc->sc_vd->vd_nentries - 1); sc->sc_tx_cnt++; bzero(&dm, sizeof(dm)); @@ -973,14 +978,25 @@ vdsk_scsi_cmd(struct scsi_xfer *xs) dm.tag.sid = sc->sc_local_sid; dm.seq_no = sc->sc_seq_no++; dm.dring_ident = sc->sc_dring_ident; - dm.start_idx = sc->sc_tx_prod; - dm.end_idx = sc->sc_tx_prod; + dm.start_idx = dm.end_idx = desc; vdsk_sendmsg(sc, &dm, sizeof(dm)); - sc->sc_tx_prod = desc; -} + if (!ISSET(xs->flags, SCSI_POLL)) + return (SUCCESSFULLY_QUEUED); - return (SUCCESSFULLY_QUEUED); + s = splbio(); + timeout = 1000; + do { + if (vdsk_rx_intr(sc) && + sc->sc_vd->vd_desc[desc].status == VIO_DESC_FREE) + break; + + delay(1000); + } while(--timeout > 0); + splx(s); + + return (COMPLETE); +} } int |