Module Name: src Committed By: mlelstv Date: Sat Feb 22 16:53:37 UTC 2025
Modified Files: src/sys/dev/pci: ld_virtio.c Log Message: For fetching id data: - actually enter synchronous mode. - add and use polling support, which is necessary during attach. - exit synchronous mode on errors. To generate a diff of this commit: cvs rdiff -u -r1.39 -r1.40 src/sys/dev/pci/ld_virtio.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/ld_virtio.c diff -u src/sys/dev/pci/ld_virtio.c:1.39 src/sys/dev/pci/ld_virtio.c:1.40 --- src/sys/dev/pci/ld_virtio.c:1.39 Sat Feb 22 09:57:09 2025 +++ src/sys/dev/pci/ld_virtio.c Sat Feb 22 16:53:37 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_virtio.c,v 1.39 2025/02/22 09:57:09 mlelstv Exp $ */ +/* $NetBSD: ld_virtio.c,v 1.40 2025/02/22 16:53:37 mlelstv Exp $ */ /* * Copyright (c) 2010 Minoura Makoto. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.39 2025/02/22 09:57:09 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.40 2025/02/22 16:53:37 mlelstv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -209,7 +209,7 @@ static int ld_virtio_vq_done(struct virt static int ld_virtio_dump(struct ld_softc *, void *, int, int); static int ld_virtio_start(struct ld_softc *, struct buf *); static int ld_virtio_ioctl(struct ld_softc *, u_long, void *, int32_t, bool); -static int ld_virtio_info(struct ld_softc *); +static int ld_virtio_info(struct ld_softc *, bool); static int ld_virtio_discard(struct ld_softc *, struct buf *); static int @@ -429,7 +429,7 @@ ld_virtio_attach(device_t parent, device ld->sc_start = ld_virtio_start; ld->sc_ioctl = ld_virtio_ioctl; - if (ld_virtio_info(ld) == 0) + if (ld_virtio_info(ld, true) == 0) ld->sc_typename = sc->sc_typename; else ld->sc_typename = __UNCONST("Virtio Block Device"); @@ -457,8 +457,8 @@ err: return; } -static int -ld_virtio_info(struct ld_softc *ld) +static int __used +ld_virtio_info(struct ld_softc *ld, bool poll) { struct ld_virtio_softc *sc = device_private(ld->sc_dv); struct virtio_softc *vsc = sc->sc_virtio; @@ -467,15 +467,29 @@ ld_virtio_info(struct ld_softc *ld) int r; int slot; uint8_t id_data[20]; /* virtio v1.2 5.2.6 */ + bool unload = false; if (sc->sc_typename != NULL) { kmem_strfree(sc->sc_typename); sc->sc_typename = NULL; } + mutex_enter(&sc->sc_sync_wait_lock); + while (sc->sc_sync_use != SYNC_FREE) { + if (poll) { + mutex_exit(&sc->sc_sync_wait_lock); + ld_virtio_vq_done(vq); + mutex_enter(&sc->sc_sync_wait_lock); + continue; + } + cv_wait(&sc->sc_sync_wait, &sc->sc_sync_wait_lock); + } + sc->sc_sync_use = SYNC_BUSY; + mutex_exit(&sc->sc_sync_wait_lock); + r = virtio_enqueue_prep(vsc, vq, &slot); if (r != 0) - return r; + goto done; vr = &sc->sc_reqs[slot]; KASSERT(vr->vr_bp == NULL); @@ -487,15 +501,16 @@ ld_virtio_info(struct ld_softc *ld) aprint_error_dev(sc->sc_dev, "payload dmamap failed, error code %d\n", r); virtio_enqueue_abort(vsc, vq, slot); - return r; + goto done; } + unload = true; KASSERT(vr->vr_payload->dm_nsegs <= sc->sc_seg_max); r = virtio_enqueue_reserve(vsc, vq, slot, vr->vr_payload->dm_nsegs + VIRTIO_BLK_CTRL_SEGMENTS); if (r != 0) { bus_dmamap_unload(virtio_dmat(vsc), vr->vr_payload); - return r; + goto done; } vr->vr_bp = DUMMY_VR_BP; @@ -524,9 +539,17 @@ ld_virtio_info(struct ld_softc *ld) false); virtio_enqueue_commit(vsc, vq, slot, true); +done: mutex_enter(&sc->sc_sync_wait_lock); - while (sc->sc_sync_use != SYNC_DONE) + while (sc->sc_sync_use != SYNC_DONE) { + if (poll) { + mutex_exit(&sc->sc_sync_wait_lock); + ld_virtio_vq_done(vq); + mutex_enter(&sc->sc_sync_wait_lock); + continue; + } cv_wait(&sc->sc_sync_wait, &sc->sc_sync_wait_lock); + } if (sc->sc_sync_status == VIRTIO_BLK_S_OK) r = 0; @@ -537,16 +560,16 @@ ld_virtio_info(struct ld_softc *ld) cv_broadcast(&sc->sc_sync_wait); mutex_exit(&sc->sc_sync_wait_lock); - bus_dmamap_sync(virtio_dmat(vsc), vr->vr_payload, - 0, sizeof(id_data), BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(virtio_dmat(vsc), vr->vr_payload); - - if (r != 0) - return r; + if (unload) { + bus_dmamap_sync(virtio_dmat(vsc), vr->vr_payload, + 0, sizeof(id_data), BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(virtio_dmat(vsc), vr->vr_payload); + } - sc->sc_typename = kmem_strndup(id_data, sizeof(id_data), KM_NOSLEEP); + if (r == 0) + sc->sc_typename = kmem_strndup(id_data, sizeof(id_data), KM_NOSLEEP); - return 0; + return r; } static int