Module Name: src Committed By: mlelstv Date: Sat Feb 22 09:57:09 UTC 2025
Modified Files: src/sys/dev/pci: ld_virtio.c Log Message: Query device for id string. To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.39 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.38 src/sys/dev/pci/ld_virtio.c:1.39 --- src/sys/dev/pci/ld_virtio.c:1.38 Sat Feb 22 09:55:31 2025 +++ src/sys/dev/pci/ld_virtio.c Sat Feb 22 09:57:09 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_virtio.c,v 1.38 2025/02/22 09:55:31 mlelstv Exp $ */ +/* $NetBSD: ld_virtio.c,v 1.39 2025/02/22 09:57:09 mlelstv Exp $ */ /* * Copyright (c) 2010 Minoura Makoto. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.38 2025/02/22 09:55:31 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.39 2025/02/22 09:57:09 mlelstv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -178,6 +178,7 @@ struct ld_virtio_softc { kcondvar_t sc_sync_wait; kmutex_t sc_sync_wait_lock; uint8_t sc_sync_status; + uint8_t *sc_typename; uint32_t sc_max_discard_sectors; uint32_t sc_max_discard_seg; @@ -208,6 +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_discard(struct ld_softc *, struct buf *); static int @@ -427,6 +429,11 @@ 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) + ld->sc_typename = sc->sc_typename; + else + ld->sc_typename = __UNCONST("Virtio Block Device"); + if (features & VIRTIO_BLK_F_DISCARD) { ld->sc_discard = ld_virtio_discard; sc->sc_max_discard_sectors = virtio_read_device_config_4(vsc, @@ -451,6 +458,98 @@ err: } static int +ld_virtio_info(struct ld_softc *ld) +{ + struct ld_virtio_softc *sc = device_private(ld->sc_dv); + struct virtio_softc *vsc = sc->sc_virtio; + struct virtqueue *vq = &sc->sc_vq; + struct virtio_blk_req *vr; + int r; + int slot; + uint8_t id_data[20]; /* virtio v1.2 5.2.6 */ + + if (sc->sc_typename != NULL) { + kmem_strfree(sc->sc_typename); + sc->sc_typename = NULL; + } + + r = virtio_enqueue_prep(vsc, vq, &slot); + if (r != 0) + return r; + + vr = &sc->sc_reqs[slot]; + KASSERT(vr->vr_bp == NULL); + + r = bus_dmamap_load(virtio_dmat(vsc), vr->vr_payload, + id_data, sizeof(id_data), NULL, + BUS_DMA_READ|BUS_DMA_NOWAIT); + if (r != 0) { + aprint_error_dev(sc->sc_dev, + "payload dmamap failed, error code %d\n", r); + virtio_enqueue_abort(vsc, vq, slot); + return r; + } + + 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; + } + + vr->vr_bp = DUMMY_VR_BP; + vr->vr_hdr.type = virtio_rw32(vsc, VIRTIO_BLK_T_GET_ID); + vr->vr_hdr.ioprio = virtio_rw32(vsc, 0); + vr->vr_hdr.sector = virtio_rw64(vsc, 0); + + bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts, + 0, sizeof(struct virtio_blk_req_hdr), + BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(virtio_dmat(vsc), vr->vr_payload, + 0, sizeof(id_data), + BUS_DMASYNC_PREREAD); + bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts, + offsetof(struct virtio_blk_req, vr_status), + sizeof(uint8_t), + BUS_DMASYNC_PREREAD); + + virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts, + 0, sizeof(struct virtio_blk_req_hdr), + true); + virtio_enqueue(vsc, vq, slot, vr->vr_payload, false); + virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts, + offsetof(struct virtio_blk_req, vr_status), + sizeof(uint8_t), + false); + virtio_enqueue_commit(vsc, vq, slot, true); + + mutex_enter(&sc->sc_sync_wait_lock); + while (sc->sc_sync_use != SYNC_DONE) + cv_wait(&sc->sc_sync_wait, &sc->sc_sync_wait_lock); + + if (sc->sc_sync_status == VIRTIO_BLK_S_OK) + r = 0; + else + r = EIO; + + sc->sc_sync_use = SYNC_FREE; + 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; + + sc->sc_typename = kmem_strndup(id_data, sizeof(id_data), KM_NOSLEEP); + + return 0; +} + +static int ld_virtio_start(struct ld_softc *ld, struct buf *bp) { /* splbio */ @@ -734,6 +833,9 @@ ld_virtio_detach(device_t self, int flag ldenddetach(ld); + if (sc->sc_typename != NULL) + kmem_strfree(sc->sc_typename); + cv_destroy(&sc->sc_sync_wait); mutex_destroy(&sc->sc_sync_wait_lock);