diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-01-22 21:35:59 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-01-22 21:35:59 +0000 |
commit | 0f58b37e309c199d57fa60bb690fb14213f629ed (patch) | |
tree | 651df58d1d474993d18a3cca9f4c3d6227f3d27c /sys/arch | |
parent | d712ebae60f4ef56334baf2edb5fdfca7de84d9b (diff) |
this gets rid of NO_CCB in vdsk. it considers space on the tx ring
as the resource the iopool is managing, but gated by the availability
of the service domain. it takes advantage of the newly available
scsi_iopool_run() interface to restart io when the domain providing
a disk comes back.
ok kettenis@
Diffstat (limited to 'sys/arch')
-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; |