[RFC PATCH 6/8] spapr_vscsi: add VOF disk nodes to the device tree

[email protected]
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
From: Utkarsh Verma <[email protected]>

Populate the vSCSI device tree node with child disk nodes for VOF
guests.

This lets Open Firmware clients such as GRUB open fully-qualified
paths like /vdevice/v-scsi@.../disk@<srp-lun> for attached vSCSI
disks.

Each child node is named from the encoded SRP LUN and includes a reg
property with the 64-bit LUN value, along with device_type set to
"block".

AI-used-for: code
Signed-off-by: Utkarsh Verma <[email protected]>
---
 hw/scsi/spapr_vscsi.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index b4c8f94d22..03f5f27f5f 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -1243,6 +1243,8 @@ void spapr_vscsi_create(SpaprVioBus *bus)
 
 static int spapr_vscsi_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
 {
+    VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
+    BusChild *kid;
     int ret;
 
     ret = fdt_setprop_cell(fdt, node_off, "#address-cells", 2);
@@ -1255,6 +1257,44 @@ static int spapr_vscsi_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
         return ret;
     }
 
+    /*
+     * In VOF mode, add a child FDT node for each attached SCSI disk so that OF
+     * clients (e.g. GRUB via VOF) can open a fully-qualified path like
+     * /vdevice/v-scsi@.../disk@<srp-lun>.
+     */
+    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+    if (spapr->vof) {
+        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+            SCSIDevice *sdev = SCSI_DEVICE(kid->child);
+            char disk_name[32];
+            uint64_t srp_lun;
+            uint32_t reg[2];
+            int disk_off;
+
+            srp_lun = ((uint64_t)(0x8000 | (sdev->id << 8) |
+                                   (sdev->channel << 5) | sdev->lun)) << 48;
+
+            snprintf(disk_name, sizeof(disk_name), "disk@%"PRIx64, srp_lun);
+
+            disk_off = fdt_add_subnode(fdt, node_off, disk_name);
+            if (disk_off < 0) {
+                return disk_off;
+            }
+
+            reg[0] = cpu_to_be32((uint32_t)(srp_lun >> 32));
+            reg[1] = cpu_to_be32((uint32_t)(srp_lun & 0xFFFFFFFF));
+            ret = fdt_setprop(fdt, disk_off, "reg", reg, sizeof(reg));
+            if (ret < 0) {
+                return ret;
+            }
+
+            ret = fdt_setprop_string(fdt, disk_off, "device_type", "block");
+            if (ret < 0) {
+                return ret;
+            }
+        }
+    }
+
     return 0;
 }
 
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.