On 8/31/26 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(+)
Tested-by: Eric Farman <[email protected]>
Reviewed-by: Eric Farman <[email protected]>
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);
+ 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;