diff options
-rw-r--r-- | sys/arch/sparc64/dev/vdsk.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/sys/arch/sparc64/dev/vdsk.c b/sys/arch/sparc64/dev/vdsk.c index e9506e0a4a0..a04d01a7bf7 100644 --- a/sys/arch/sparc64/dev/vdsk.c +++ b/sys/arch/sparc64/dev/vdsk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vdsk.c,v 1.33 2013/05/12 19:33:01 krw Exp $ */ +/* $OpenBSD: vdsk.c,v 1.34 2014/01/22 21:35:58 dlg Exp $ */ /* * Copyright (c) 2009, 2011 Mark Kettenis * @@ -158,6 +158,7 @@ struct vdsk_softc { struct vdsk_dring *sc_vd; struct vdsk_soft_desc *sc_vsd; + struct scsi_iopool sc_iopool; struct scsi_adapter sc_switch; struct scsi_link sc_link; @@ -198,6 +199,9 @@ void vdsk_send_attr_info(struct vdsk_softc *); void vdsk_send_dring_reg(struct vdsk_softc *); void vdsk_send_rdx(struct vdsk_softc *); +void * vdsk_io_get(void *); +void vdsk_io_put(void *, void *); + void vdsk_scsi_cmd(struct scsi_xfer *); int vdsk_dev_probe(struct scsi_link *); void vdsk_dev_free(struct scsi_link *); @@ -340,6 +344,8 @@ vdsk_attach(struct device *parent, struct device *self, void *aux) if (sc->sc_vio_state != VIO_ESTABLISHED) return; + scsi_iopool_init(&sc->sc_iopool, sc, vdsk_io_get, vdsk_io_put); + sc->sc_switch.scsi_cmd = vdsk_scsi_cmd; sc->sc_switch.scsi_minphys = scsi_minphys; sc->sc_switch.dev_probe = vdsk_dev_probe; @@ -351,6 +357,7 @@ vdsk_attach(struct device *parent, struct device *self, void *aux) sc->sc_link.luns = 1; /* XXX slices should be presented as luns? */ sc->sc_link.adapter_target = 2; sc->sc_link.openings = sc->sc_vd->vd_nentries - 1; + sc->sc_link.pool = &sc->sc_iopool; bzero(&saa, sizeof(saa)); saa.saa_sc_link = &sc->sc_link; @@ -656,6 +663,9 @@ vdsk_rx_vio_rdx(struct vdsk_softc *sc, struct vio_msg_tag *tag) DPRINTF(("CTRL/0x%02x/RDX (VIO)\n", tag->stype)); break; } + + if (sc->sc_vio_state == VIO_ESTABLISHED) + scsi_iopool_run(&sc->sc_iopool); } void @@ -718,7 +728,6 @@ vdsk_rx_vio_dring_data(struct vdsk_softc *sc, struct vio_msg_tag *tag) sc->sc_vd->vd_desc[cons++].hdr.dstate = VIO_DESC_FREE; cons &= (sc->sc_vd->vd_nentries - 1); - sc->sc_tx_cnt--; } sc->sc_tx_cons = cons; break; @@ -917,6 +926,40 @@ vdsk_dring_free(bus_dma_tag_t t, struct vdsk_dring *vd) free(vd, M_DEVBUF); } +void * +vdsk_io_get(void *xsc) +{ + struct vdsk_softc *sc = xsc; + void *rv = sc; /* just has to be !NULL */ + int s; + + s = splbio(); + if (sc->sc_vio_state != VIO_ESTABLISHED && + sc->sc_tx_cnt >= sc->sc_vd->vd_nentries) + rv = NULL; + else + sc->sc_tx_cnt++; + splx(s); + + return (rv); +} + +void +vdsk_io_put(void *xsc, void *io) +{ + struct vdsk_softc *sc = xsc; + int s; + +#ifdef DIAGNOSTIC + if (sc != io) + panic("vsdk_io_put: unexpected io"); +#endif + + s = splbio(); + sc->sc_tx_cnt--; + splx(s); +} + void vdsk_scsi_cmd(struct scsi_xfer *xs) { @@ -1005,14 +1048,6 @@ vdsk_scsi_cmd(struct scsi_xfer *xs) int timeout; s = splbio(); - if (sc->sc_vio_state != VIO_ESTABLISHED || - sc->sc_tx_cnt >= sc->sc_vd->vd_nentries) { - xs->error = XS_NO_CCB; - scsi_done(xs); - splx(s); - return; - } - desc = sc->sc_tx_prod; ncookies = 0; @@ -1055,7 +1090,6 @@ vdsk_scsi_cmd(struct scsi_xfer *xs) sc->sc_tx_prod++; sc->sc_tx_prod &= (sc->sc_vd->vd_nentries - 1); - sc->sc_tx_cnt++; bzero(&dm, sizeof(dm)); dm.tag.type = VIO_TYPE_DATA; |