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

Reply via email to