提交 e468b673 编写于 作者: A Alexander Yarygin 提交者: Cornelia Huck

s390x/ipl: Support IPL from selected SCSI device

If bootindex is specified for a device, we need to IPL from
it. Currently it works for ccw devices, but not for SCSI. To be able to
IPL from the specific device, pc-bios needs to know its address.
For this reason we add special QEMU_SCSI IPL type into the IPLB
structure, that contains the scsi device address.

We enhance the ipl block with a currently qemu-only parameter block
that allows us to specify a concrete scsi device.
Signed-off-by: NAlexander Yarygin <yarygin@linux.vnet.ibm.com>
Reviewed-by: NEric Farman <farman@linux.vnet.ibm.com>
Signed-off-by: NCornelia Huck <cornelia.huck@de.ibm.com>
上级 07c6f329
...@@ -217,6 +217,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) ...@@ -217,6 +217,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast( VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast(
OBJECT(qdev_get_parent_bus(dev_st)->parent), OBJECT(qdev_get_parent_bus(dev_st)->parent),
TYPE_VIRTIO_CCW_DEVICE); TYPE_VIRTIO_CCW_DEVICE);
SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
TYPE_SCSI_DEVICE);
if (ccw_dev) { if (ccw_dev) {
ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
ipl->iplb.blk0_len = ipl->iplb.blk0_len =
...@@ -225,6 +227,22 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) ...@@ -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.devno = cpu_to_be16(ccw_dev->sch->devno);
ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
return true; 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;
} }
} }
......
...@@ -46,6 +46,16 @@ struct IplBlockFcp { ...@@ -46,6 +46,16 @@ struct IplBlockFcp {
} QEMU_PACKED; } QEMU_PACKED;
typedef struct IplBlockFcp IplBlockFcp; 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 { union IplParameterBlock {
struct { struct {
uint32_t len; uint32_t len;
...@@ -59,6 +69,7 @@ union IplParameterBlock { ...@@ -59,6 +69,7 @@ union IplParameterBlock {
union { union {
IplBlockCcw ccw; IplBlockCcw ccw;
IplBlockFcp fcp; IplBlockFcp fcp;
IplBlockQemuScsi scsi;
}; };
} QEMU_PACKED; } QEMU_PACKED;
struct { struct {
...@@ -102,10 +113,12 @@ typedef struct S390IPLState S390IPLState; ...@@ -102,10 +113,12 @@ typedef struct S390IPLState S390IPLState;
#define S390_IPL_TYPE_FCP 0x00 #define S390_IPL_TYPE_FCP 0x00
#define S390_IPL_TYPE_CCW 0x02 #define S390_IPL_TYPE_CCW 0x02
#define S390_IPL_TYPE_QEMU_SCSI 0xff
#define S390_IPLB_HEADER_LEN 8 #define S390_IPLB_HEADER_LEN 8
#define S390_IPLB_MIN_CCW_LEN 200 #define S390_IPLB_MIN_CCW_LEN 200
#define S390_IPLB_MIN_FCP_LEN 384 #define S390_IPLB_MIN_FCP_LEN 384
#define S390_IPLB_MIN_QEMU_SCSI_LEN 200
static inline bool iplb_valid_len(IplParameterBlock *iplb) static inline bool iplb_valid_len(IplParameterBlock *iplb)
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册