On 8/31/2026 3:49 PM, [email protected] wrote:
From: Jared Rossi <[email protected]>

Add logic to identify a virtio-pci scsi controller and target lun with
assigned bootindex, then build IPLB for it.

Unfence PCI case for scsi devices in BIOS.

Signed-off-by: Jared Rossi <[email protected]>
---
  hw/s390x/ipl.c          | 37 +++++++++++++++++++++++++++++++++++++
  pc-bios/s390-ccw/main.c |  3 +++
  2 files changed, 40 insertions(+)

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 6969e11b27..0cab043b12 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -402,6 +402,7 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, 
int *devtype)
  }
#define PCI_DEVTYPE_VIRTIO 0x05
+#define PCI_DEVTYPE_SCSI         0x06
static S390PCIBusDevice *s390_get_pci_device(DeviceState *dev_st, int *devtype)
  {
@@ -417,6 +418,26 @@ static S390PCIBusDevice *s390_get_pci_device(DeviceState 
*dev_st, int *devtype)
              if (pbdev) {
                  tmp_dt = PCI_DEVTYPE_VIRTIO;
              }
+        } else {
+            SCSIDevice *sd = (SCSIDevice *)
+                object_dynamic_cast(OBJECT(dev_st), TYPE_SCSI_DEVICE);
+            if (sd) {
+                SCSIBus *sbus = scsi_bus_from_device(sd);
+                VirtIODevice *vdev = (VirtIODevice *)
+                    object_dynamic_cast(OBJECT(sbus->qbus.parent),
+                                                TYPE_VIRTIO_DEVICE);
Small nit: indentation is not quite right here.
TYPE_VIRTIO_DEVICE should align with OBJECT in the line above.

+                if (vdev) {
+                    pci_dev = (PCIDevice *)
+                        
object_dynamic_cast(OBJECT(qdev_get_parent_bus(DEVICE(vdev))->parent),
+                                            TYPE_PCI_DEVICE);
+                    if (pci_dev) {
+                        pbdev = s390_pci_find_dev_by_pci(s390_get_phb(), 
pci_dev);
+                        if (pbdev) {
+                            tmp_dt = PCI_DEVTYPE_SCSI;
+                        }
+                    }
+                }
+            }
          }
      }
      if (devtype) {
@@ -621,6 +642,22 @@ static bool s390_build_iplb(DeviceState *dev_st, 
IplParameterBlock *iplb)
              iplb->pbt = S390_IPL_TYPE_PCI;
              iplb->pci.fid = cpu_to_be32(pbdev->fid);
              break;
+        case PCI_DEVTYPE_SCSI:
+            sd = SCSI_DEVICE(dev_st);
+            scsi_lp = object_property_get_str(OBJECT(sd), "loadparm", NULL);
+            if (scsi_lp && strlen(scsi_lp) > 0) {
+                lp = scsi_lp;
+            }
+            iplb->len = cpu_to_be32(S390_IPLB_MIN_PCI_LEN);
+            iplb->blk0_len =
+                cpu_to_be32(S390_IPLB_MIN_PCI_LEN - S390_IPLB_HEADER_LEN);
+            iplb->pbt = S390_IPL_TYPE_QEMU_SCSI;
+            iplb->scsi.lun = cpu_to_be32(sd->lun);
+            iplb->scsi.target = cpu_to_be16(sd->id);
+            iplb->scsi.channel = cpu_to_be16(sd->channel);
+            iplb->scsi.bus = S390_IPL_TYPE_PCI;
+            iplb->scsi.fid = cpu_to_be32(pbdev->fid);
+            break;
          default:
              return false;
          }
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index a2a24b024f..d2a2ac3138 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -267,6 +267,9 @@ static bool find_boot_device(void)
              blk_schid.ssid = iplb->scsi.ssid & 0x3;
              found = find_subch(iplb->scsi.devno);
              break;
+        case S390_IPL_TYPE_PCI:
+            found = find_fid(iplb->scsi.fid);
+            break;
          default:
              puts("Unrecognized SCSI controller");
              break;


Reply via email to