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); + 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; -- 2.54.0
