diff options
-rw-r--r-- | hw/s390x/ipl.c | 18 | ||||
-rw-r--r-- | hw/s390x/ipl.h | 13 |
2 files changed, 31 insertions, 0 deletions
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index e6bf7cf7c0..78998cdbad 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -217,6 +217,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast( OBJECT(qdev_get_parent_bus(dev_st)->parent), TYPE_VIRTIO_CCW_DEVICE); + SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st), + TYPE_SCSI_DEVICE); if (ccw_dev) { ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); ipl->iplb.blk0_len = @@ -225,6 +227,22 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; return true; + } else if (sd) { + SCSIBus *bus = scsi_bus_from_device(sd); + VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus); + VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw, vdev); + VirtioCcwDevice *ccw = &scsi_ccw->parent_obj; + + ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); + ipl->iplb.blk0_len = + cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN); + ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI; + ipl->iplb.scsi.lun = cpu_to_be32(sd->lun); + ipl->iplb.scsi.target = cpu_to_be16(sd->id); + ipl->iplb.scsi.channel = cpu_to_be16(sd->channel); + ipl->iplb.scsi.devno = cpu_to_be16(ccw->sch->devno); + ipl->iplb.scsi.ssid = ccw->sch->ssid & 3; + return true; } } diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index 9aa4d942a7..ed3f2c8a43 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -46,6 +46,16 @@ struct IplBlockFcp { } QEMU_PACKED; typedef struct IplBlockFcp IplBlockFcp; +struct IplBlockQemuScsi { + uint32_t lun; + uint16_t target; + uint16_t channel; + uint8_t reserved0[77]; + uint8_t ssid; + uint16_t devno; +} QEMU_PACKED; +typedef struct IplBlockQemuScsi IplBlockQemuScsi; + union IplParameterBlock { struct { uint32_t len; @@ -59,6 +69,7 @@ union IplParameterBlock { union { IplBlockCcw ccw; IplBlockFcp fcp; + IplBlockQemuScsi scsi; }; } QEMU_PACKED; struct { @@ -102,10 +113,12 @@ typedef struct S390IPLState S390IPLState; #define S390_IPL_TYPE_FCP 0x00 #define S390_IPL_TYPE_CCW 0x02 +#define S390_IPL_TYPE_QEMU_SCSI 0xff #define S390_IPLB_HEADER_LEN 8 #define S390_IPLB_MIN_CCW_LEN 200 #define S390_IPLB_MIN_FCP_LEN 384 +#define S390_IPLB_MIN_QEMU_SCSI_LEN 200 static inline bool iplb_valid_len(IplParameterBlock *iplb) { |