[SeaBIOS] [PATCH 5/6] virtio-mmio: add support for scsi devices.

Gerd Hoffmann posted 6 patches 9 weeks ago

[SeaBIOS] [PATCH 5/6] virtio-mmio: add support for scsi devices.

Posted by Gerd Hoffmann 9 weeks ago
Add new fields to struct virtio_lun_s for mmio support,
add mmio parameter to virtio_scsi_init_lun(), so both
pci and mmio devices can be handled.

Add and use bootprio_find_scsi_mmio_device() to figure
boot priority of devices connected to a virtio-mmio
scsi controller.

Finally add init_virtio_scsi_mmio() to initialize one
virtio-mmio scsi controller.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 src/hw/virtio-scsi.h |  1 +
 src/util.h           |  1 +
 src/boot.c           | 10 ++++++
 src/hw/virtio-mmio.c |  3 +-
 src/hw/virtio-scsi.c | 73 +++++++++++++++++++++++++++++++++++++-------
 5 files changed, 76 insertions(+), 12 deletions(-)

diff --git a/src/hw/virtio-scsi.h b/src/hw/virtio-scsi.h
index 7532cc98e56e..8f01de4cba99 100644
--- a/src/hw/virtio-scsi.h
+++ b/src/hw/virtio-scsi.h
@@ -43,5 +43,6 @@ struct virtio_scsi_resp_cmd {
 struct disk_op_s;
 int virtio_scsi_process_op(struct disk_op_s *op);
 void virtio_scsi_setup(void);
+void init_virtio_scsi_mmio(void *data);
 
 #endif /* _VIRTIO_SCSI_H */
diff --git a/src/util.h b/src/util.h
index 94592a2d2e8d..1c82e09ed87b 100644
--- a/src/util.h
+++ b/src/util.h
@@ -31,6 +31,7 @@ u8 is_bootprio_strict(void);
 struct pci_device;
 int bootprio_find_pci_device(struct pci_device *pci);
 int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun);
+int bootprio_find_scsi_mmio_device(void *mmio, int target, int lun);
 int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave);
 int bootprio_find_fdc_device(struct pci_device *pci, int port, int fdid);
 int bootprio_find_pci_rom(struct pci_device *pci, int instance);
diff --git a/src/boot.c b/src/boot.c
index 4f12988f687c..f2f084bea843 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -328,6 +328,16 @@ int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun)
     return find_prio(desc);
 }
 
+int bootprio_find_scsi_mmio_device(void *mmio, int target, int lun)
+{
+    if (!CONFIG_BOOTORDER)
+        return -1;
+    char desc[256];
+    snprintf(desc, sizeof(desc), "/virtio-mmio@%016x/*@0/*@%x,%x",
+             (u32)mmio, target, lun);
+    return find_prio(desc);
+}
+
 int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave)
 {
     if (CONFIG_CSM)
diff --git a/src/hw/virtio-mmio.c b/src/hw/virtio-mmio.c
index d9068c7c035b..3b514d944a9d 100644
--- a/src/hw/virtio-mmio.c
+++ b/src/hw/virtio-mmio.c
@@ -4,6 +4,7 @@
 #include "stacks.h" // run_thread
 #include "string.h" // memset
 #include "virtio-pci.h"
+#include "virtio-scsi.h"
 #include "virtio-ring.h"
 #include "virtio-mmio.h"
 
@@ -57,7 +58,7 @@ void virtio_mmio_setup(void)
             /* TODO */
             break;
         case 8: /* scsi */
-            /* TODO */
+            run_thread(init_virtio_scsi_mmio, mmio);
             break;
         default:
             break;
diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c
index a5332848b8c8..59f1c654d76b 100644
--- a/src/hw/virtio-scsi.c
+++ b/src/hw/virtio-scsi.c
@@ -22,10 +22,13 @@
 #include "virtio-pci.h"
 #include "virtio-ring.h"
 #include "virtio-scsi.h"
+#include "virtio-mmio.h"
 
 struct virtio_lun_s {
     struct drive_s drive;
     struct pci_device *pci;
+    void *mmio;
+    char name[16];
     struct vring_virtqueue *vq;
     struct vp_device *vp;
     u16 target;
@@ -94,7 +97,8 @@ virtio_scsi_process_op(struct disk_op_s *op)
 }
 
 static void
-virtio_scsi_init_lun(struct virtio_lun_s *vlun, struct pci_device *pci,
+virtio_scsi_init_lun(struct virtio_lun_s *vlun,
+                     struct pci_device *pci, void *mmio,
                      struct vp_device *vp, struct vring_virtqueue *vq,
                      u16 target, u16 lun)
 {
@@ -102,10 +106,15 @@ virtio_scsi_init_lun(struct virtio_lun_s *vlun, struct pci_device *pci,
     vlun->drive.type = DTYPE_VIRTIO_SCSI;
     vlun->drive.cntl_id = pci->bdf;
     vlun->pci = pci;
+    vlun->mmio = mmio;
     vlun->vp = vp;
     vlun->vq = vq;
     vlun->target = target;
     vlun->lun = lun;
+    if (vlun->pci)
+        snprintf(vlun->name, sizeof(vlun->name), "pci:%pP", vlun->pci);
+    if (vlun->mmio)
+        snprintf(vlun->name, sizeof(vlun->name), "mmio:%08x", (u32)vlun->mmio);
 }
 
 static int
@@ -114,12 +123,17 @@ virtio_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv)
     u8 skip_nonbootable = is_bootprio_strict();
     struct virtio_lun_s *tmpl_vlun =
         container_of(tmpl_drv, struct virtio_lun_s, drive);
-    int prio = bootprio_find_scsi_device(tmpl_vlun->pci, tmpl_vlun->target, tmpl_vlun->lun);
+    int prio = -1;
+
+    if (tmpl_vlun->pci)
+        prio = bootprio_find_scsi_device(tmpl_vlun->pci, tmpl_vlun->target, tmpl_vlun->lun);
+    if (tmpl_vlun->mmio)
+        prio = bootprio_find_scsi_mmio_device(tmpl_vlun->mmio, tmpl_vlun->target, tmpl_vlun->lun);
 
     if (skip_nonbootable && prio < 0) {
-        dprintf(1, "skipping init of a non-bootable virtio-scsi dev at %pP,"
+        dprintf(1, "skipping init of a non-bootable virtio-scsi dev at %s,"
                 " target %d, lun %d\n",
-                tmpl_vlun->pci, tmpl_vlun->target, tmpl_vlun->lun);
+                tmpl_vlun->name, tmpl_vlun->target, tmpl_vlun->lun);
         return -1;
     }
 
@@ -128,11 +142,12 @@ virtio_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv)
         warn_noalloc();
         return -1;
     }
-    virtio_scsi_init_lun(vlun, tmpl_vlun->pci, tmpl_vlun->vp, tmpl_vlun->vq,
-                         tmpl_vlun->target, lun);
+    virtio_scsi_init_lun(vlun, tmpl_vlun->pci, tmpl_vlun->mmio,tmpl_vlun->vp,
+                         tmpl_vlun->vq, tmpl_vlun->target, lun);
 
-    boot_lchs_find_scsi_device(vlun->pci, vlun->target, vlun->lun,
-                               &(vlun->drive.lchs));
+    if (vlun->pci)
+        boot_lchs_find_scsi_device(vlun->pci, vlun->target, vlun->lun,
+                                   &(vlun->drive.lchs));
     int ret = scsi_drive_setup(&vlun->drive, "virtio-scsi", prio);
     if (ret)
         goto fail;
@@ -144,13 +159,13 @@ fail:
 }
 
 static int
-virtio_scsi_scan_target(struct pci_device *pci, struct vp_device *vp,
+virtio_scsi_scan_target(struct pci_device *pci, void *mmio, struct vp_device *vp,
                         struct vring_virtqueue *vq, u16 target)
 {
 
     struct virtio_lun_s vlun0;
 
-    virtio_scsi_init_lun(&vlun0, pci, vp, vq, target, 0);
+    virtio_scsi_init_lun(&vlun0, pci, mmio, vp, vq, target, 0);
 
     int ret = scsi_rep_luns_scan(&vlun0.drive, virtio_scsi_add_lun);
     return ret < 0 ? 0 : ret;
@@ -198,7 +213,43 @@ init_virtio_scsi(void *data)
 
     int i, tot;
     for (tot = 0, i = 0; i < 256; i++)
-        tot += virtio_scsi_scan_target(pci, vp, vq, i);
+        tot += virtio_scsi_scan_target(pci, NULL, vp, vq, i);
+
+    if (!tot)
+        goto fail;
+
+    return;
+
+fail:
+    vp_reset(vp);
+    free(vp);
+    free(vq);
+}
+
+void
+init_virtio_scsi_mmio(void *mmio)
+{
+    dprintf(1, "found virtio-scsi-mmio at %p\n", mmio);
+    struct vring_virtqueue *vq = NULL;
+    struct vp_device *vp = malloc_high(sizeof(*vp));
+    if (!vp) {
+        warn_noalloc();
+        return;
+    }
+    vp_init_mmio(vp, mmio);
+    u8 status = VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER;
+
+    if (vp_find_vq(vp, 2, &vq) < 0 ) {
+        dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio);
+        goto fail;
+    }
+
+    status |= VIRTIO_CONFIG_S_DRIVER_OK;
+    vp_set_status(vp, status);
+
+    int i, tot;
+    for (tot = 0, i = 0; i < 256; i++)
+        tot += virtio_scsi_scan_target(NULL, mmio, vp, vq, i);
 
     if (!tot)
         goto fail;
-- 
2.18.2
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org