Module Name: src Committed By: jdolecek Date: Mon Mar 13 21:06:51 UTC 2017
Modified Files: src/sys/dev/pci: vioscsi.c Log Message: several small tweaks: - use MSIX if available - fix off-by-one for nluns/ntargets (code inspection, not actual effect) - when virtio_enqueue_reserve() fails, do not execute vioscsi_req_put() and hence virtio_dequeue_commit() as there is nothing to commit, just unload the xs and return; also report XS_RESOURCE_SHORTAGE, it's semi-normal situation - set status/resid in vioscsi_req_done() before the switch, so that the override for VIRTIO_SCSI_S_BAD_TARGET actually has effect - g/c vioscsi_req_put(), call the appropriate cleanup routines directly - stop initializing id/task_attr in vioscsi_req_get(), it's overwritten in vioscsi_scsipi_request() anyway To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/dev/pci/vioscsi.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/vioscsi.c diff -u src/sys/dev/pci/vioscsi.c:1.10 src/sys/dev/pci/vioscsi.c:1.11 --- src/sys/dev/pci/vioscsi.c:1.10 Mon Mar 13 20:47:38 2017 +++ src/sys/dev/pci/vioscsi.c Mon Mar 13 21:06:50 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vioscsi.c,v 1.10 2017/03/13 20:47:38 jdolecek Exp $ */ +/* $NetBSD: vioscsi.c,v 1.11 2017/03/13 21:06:50 jdolecek Exp $ */ /* $OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $ */ /* @@ -18,7 +18,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.10 2017/03/13 20:47:38 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.11 2017/03/13 21:06:50 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -85,7 +85,6 @@ static int vioscsi_vq_done(struct virtq static void vioscsi_req_done(struct vioscsi_softc *, struct virtio_softc *, struct vioscsi_req *); static struct vioscsi_req *vioscsi_req_get(struct vioscsi_softc *); -static void vioscsi_req_put(struct vioscsi_softc *, struct vioscsi_req *); static const char *const vioscsi_vq_names[] = { "control", @@ -133,6 +132,8 @@ vioscsi_attach(device_t parent, device_t vsc->sc_intrhand = virtio_vq_intr; vsc->sc_flags = 0; + vsc->sc_flags |= VIRTIO_F_PCI_INTR_MSIX; + features = virtio_negotiate_features(vsc, 0); snprintb(buf, sizeof(buf), VIRTIO_COMMON_FLAG_BITS, features); aprint_normal(": Features: %s\n", buf); @@ -193,8 +194,8 @@ vioscsi_attach(device_t parent, device_t chan->chan_adapter = adapt; chan->chan_bustype = &scsi_bustype; chan->chan_channel = 0; - chan->chan_ntargets = max_target; - chan->chan_nluns = max_lun; + chan->chan_ntargets = max_target + 1; + chan->chan_nluns = max_lun + 1; chan->chan_id = 0; chan->chan_flags = SCSIPI_CHAN_NOSETTLE; @@ -223,7 +224,7 @@ vioscsi_scsipi_request(struct scsipi_cha struct scsipi_periph *periph; struct vioscsi_req *vr; struct virtio_scsi_req_hdr *req; - struct virtqueue *vq = &sc->sc_vqs[2]; + struct virtqueue *vq = &sc->sc_vqs[VIOSCSI_VQ_REQUEST]; int slot, error; DPRINTF(("%s: enter\n", __func__)); @@ -325,10 +326,10 @@ vioscsi_scsipi_request(struct scsipi_cha default: aprint_error_dev(sc->sc_dev, "error %d loading DMA map\n", error); - stuffup: +stuffup: xs->error = XS_DRIVER_STUFFUP; nomore: - vioscsi_req_put(sc, vr); + /* nothing else to free */ scsipi_done(xs); return; } @@ -340,7 +341,9 @@ nomore: error = virtio_enqueue_reserve(vsc, vq, slot, nsegs); if (error) { DPRINTF(("%s: error reserving %d\n", __func__, error)); - goto stuffup; + bus_dmamap_unload(vsc->sc_dmat, vr->vr_data); + xs->error = XS_RESOURCE_SHORTAGE; + goto nomore; } bus_dmamap_sync(vsc->sc_dmat, vr->vr_control, @@ -411,6 +414,9 @@ vioscsi_req_done(struct vioscsi_softc *s bus_dmamap_sync(vsc->sc_dmat, vr->vr_data, 0, xs->datalen, XS2DMAPOST(xs)); + xs->status = vr->vr_res.status; + xs->resid = vr->vr_res.residual; + switch (vr->vr_res.response) { case VIRTIO_SCSI_S_OK: sense_len = MIN(sizeof(xs->sense), vr->vr_res.sense_len); @@ -433,14 +439,12 @@ vioscsi_req_done(struct vioscsi_softc *s break; } - xs->status = vr->vr_res.status; - xs->resid = vr->vr_res.residual; - DPRINTF(("%s: done %d, %d, %d\n", __func__, xs->error, xs->status, xs->resid)); + bus_dmamap_unload(vsc->sc_dmat, vr->vr_data); vr->vr_xs = NULL; - vioscsi_req_put(sc, vr); + scsipi_done(xs); } @@ -460,7 +464,11 @@ vioscsi_vq_done(struct virtqueue *vq) break; DPRINTF(("%s: slot=%d\n", __func__, slot)); + vioscsi_req_done(sc, vsc, &sc->sc_reqs[slot]); + + virtio_dequeue_commit(vsc, vq, slot); + ret = 1; } @@ -484,28 +492,11 @@ vioscsi_req_get(struct vioscsi_softc *sc KASSERT(slot < sc->sc_nreqs); vr = &sc->sc_reqs[slot]; - vr->vr_req.id = slot; - vr->vr_req.task_attr = VIRTIO_SCSI_S_SIMPLE; - DPRINTF(("%s: %p, %d\n", __func__, vr, slot)); return vr; } -static void -vioscsi_req_put(struct vioscsi_softc *sc, struct vioscsi_req *vr) -{ - struct virtio_softc *vsc = device_private(device_parent(sc->sc_dev)); - struct virtqueue *vq = &sc->sc_vqs[2]; - int slot = vr - sc->sc_reqs; - - DPRINTF(("%s: %p, %d\n", __func__, vr, slot)); - - bus_dmamap_unload(vsc->sc_dmat, vr->vr_data); - - virtio_dequeue_commit(vsc, vq, slot); -} - int vioscsi_alloc_reqs(struct vioscsi_softc *sc, struct virtio_softc *vsc, int qsize, uint32_t seg_max)