mirror of https://gitee.com/openkylin/qemu.git
s390x/css: Unplug handler of virtual css bridge
The previous patch moved virtual css bridge and bus out from virtio-ccw, but kept the direct reference of virtio-ccw specific unplug function inside css-bridge.c. To make the virtual css bus and bridge useful for non-virtio devices, this introduces a common unplug function pointer "unplug" to call specific virtio-ccw unplug parts. Thus, the tight coupling to virtio-ccw can be removed. This unplug pointer is a member of CCWDeviceClass, which is introduced as an abstract device layer called "ccw-device". This layer is between DeviceState and specific devices which are plugged in virtual css bus, like virtio-ccw device. The specific unplug handlers should be assigned to "unplug" during initialization. Signed-off-by: Jing Liu <liujbjl@linux.vnet.ibm.com> Reviewed-by: Sascha Silbe <silbe@linux.vnet.ibm.com> Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> Reviewed-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
dd70bd0d4c
commit
b804e8a62a
|
@ -9,6 +9,7 @@ obj-y += css.o
|
|||
obj-y += s390-virtio-ccw.o
|
||||
obj-y += virtio-ccw.o
|
||||
obj-y += css-bridge.o
|
||||
obj-y += ccw-device.o
|
||||
obj-y += s390-pci-bus.o s390-pci-inst.o
|
||||
obj-y += s390-skeys.o
|
||||
obj-$(CONFIG_KVM) += s390-skeys-kvm.o
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Common device infrastructure for devices in the virtual css
|
||||
*
|
||||
* Copyright 2016 IBM Corp.
|
||||
* Author(s): Jing Liu <liujbjl@linux.vnet.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or (at
|
||||
* your option) any later version. See the COPYING file in the top-level
|
||||
* directory.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "ccw-device.h"
|
||||
|
||||
static const TypeInfo ccw_device_info = {
|
||||
.name = TYPE_CCW_DEVICE,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(CcwDevice),
|
||||
.class_size = sizeof(CCWDeviceClass),
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void ccw_device_register(void)
|
||||
{
|
||||
type_register_static(&ccw_device_info);
|
||||
}
|
||||
|
||||
type_init(ccw_device_register)
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Common device infrastructure for devices in the virtual css
|
||||
*
|
||||
* Copyright 2016 IBM Corp.
|
||||
* Author(s): Jing Liu <liujbjl@linux.vnet.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or (at
|
||||
* your option) any later version. See the COPYING file in the top-level
|
||||
* directory.
|
||||
*/
|
||||
|
||||
#ifndef HW_S390X_CCW_DEVICE_H
|
||||
#define HW_S390X_CCW_DEVICE_H
|
||||
#include "qom/object.h"
|
||||
#include "hw/qdev-core.h"
|
||||
#include "hw/s390x/css.h"
|
||||
|
||||
typedef struct CcwDevice {
|
||||
DeviceState parent_obj;
|
||||
SubchDev *sch;
|
||||
/* <cssid>.<ssid>.<device number> */
|
||||
CssDevId bus_id;
|
||||
} CcwDevice;
|
||||
|
||||
typedef struct CCWDeviceClass {
|
||||
DeviceClass parent_class;
|
||||
void (*unplug)(HotplugHandler *, DeviceState *, Error **);
|
||||
} CCWDeviceClass;
|
||||
|
||||
static inline CcwDevice *to_ccw_dev_fast(DeviceState *d)
|
||||
{
|
||||
return container_of(d, CcwDevice, parent_obj);
|
||||
}
|
||||
|
||||
#define TYPE_CCW_DEVICE "ccw-device"
|
||||
|
||||
#define CCW_DEVICE(obj) OBJECT_CHECK(CcwDevice, (obj), TYPE_CCW_DEVICE)
|
||||
#define CCW_DEVICE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(CCWDeviceClass, (obj), TYPE_CCW_DEVICE)
|
||||
#define CCW_DEVICE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(CCWDeviceClass, (klass), TYPE_CCW_DEVICE)
|
||||
|
||||
#endif
|
|
@ -11,13 +11,48 @@
|
|||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "virtio-ccw.h"
|
||||
#include "hw/hotplug.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "hw/s390x/css.h"
|
||||
#include "ccw-device.h"
|
||||
#include "hw/s390x/css-bridge.h"
|
||||
|
||||
/*
|
||||
* Invoke device-specific unplug handler, disable the subchannel
|
||||
* (including sending a channel report to the guest) and remove the
|
||||
* device from the virtual css bus.
|
||||
*/
|
||||
static void ccw_device_unplug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(dev);
|
||||
CCWDeviceClass *k = CCW_DEVICE_GET_CLASS(ccw_dev);
|
||||
SubchDev *sch = ccw_dev->sch;
|
||||
Error *err = NULL;
|
||||
|
||||
if (k->unplug) {
|
||||
k->unplug(hotplug_dev, dev, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We should arrive here only for device_del, since we don't support
|
||||
* direct hot(un)plug of channels.
|
||||
*/
|
||||
assert(sch != NULL);
|
||||
/* Subchannel is now disabled and no longer valid. */
|
||||
sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
|
||||
PMCW_FLAGS_MASK_DNV);
|
||||
|
||||
css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
|
||||
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static void virtual_css_bus_reset(BusState *qbus)
|
||||
{
|
||||
/* This should actually be modelled via the generic css */
|
||||
|
@ -65,7 +100,7 @@ static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
|
|||
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
hc->unplug = virtio_ccw_busdev_unplug;
|
||||
hc->unplug = ccw_device_unplug;
|
||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||
}
|
||||
|
||||
|
|
|
@ -221,12 +221,14 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
|
|||
|
||||
dev_st = get_boot_device(0);
|
||||
if (dev_st) {
|
||||
VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast(
|
||||
OBJECT(qdev_get_parent_bus(dev_st)->parent),
|
||||
VirtioCcwDevice *virtio_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) {
|
||||
if (virtio_ccw_dev) {
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(virtio_ccw_dev);
|
||||
|
||||
ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
|
||||
ipl->iplb.blk0_len =
|
||||
cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
|
||||
|
@ -238,7 +240,7 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
|
|||
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;
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(scsi_ccw);
|
||||
|
||||
ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
|
||||
ipl->iplb.blk0_len =
|
||||
|
@ -247,8 +249,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
|
|||
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;
|
||||
ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
|
||||
ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,8 @@ static int virtio_ccw_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
|
|||
int n, bool assign)
|
||||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
SubchDev *sch = dev->sch;
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(dev);
|
||||
SubchDev *sch = ccw_dev->sch;
|
||||
uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
|
||||
|
||||
return s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
|
||||
|
@ -194,6 +195,8 @@ static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
|
|||
|
||||
static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev)
|
||||
{
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(dev);
|
||||
|
||||
virtio_ccw_stop_ioeventfd(dev);
|
||||
virtio_reset(vdev);
|
||||
if (dev->indicators) {
|
||||
|
@ -208,7 +211,7 @@ static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev)
|
|||
release_indicator(&dev->routes.adapter, dev->summary_indicator);
|
||||
dev->summary_indicator = NULL;
|
||||
}
|
||||
dev->sch->thinint_active = false;
|
||||
ccw_dev->sch->thinint_active = false;
|
||||
}
|
||||
|
||||
static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,
|
||||
|
@ -664,7 +667,8 @@ static void virtio_sch_disable_cb(SubchDev *sch)
|
|||
static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
|
||||
{
|
||||
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
|
||||
SubchDev *sch = css_create_virtual_sch(dev->bus_id, errp);
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(dev);
|
||||
SubchDev *sch = css_create_virtual_sch(ccw_dev->bus_id, errp);
|
||||
Error *err = NULL;
|
||||
|
||||
if (!sch) {
|
||||
|
@ -676,14 +680,14 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
|
|||
sch->disable_cb = virtio_sch_disable_cb;
|
||||
sch->id.reserved = 0xff;
|
||||
sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
|
||||
dev->sch = sch;
|
||||
ccw_dev->sch = sch;
|
||||
dev->indicators = NULL;
|
||||
dev->revision = -1;
|
||||
css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
|
||||
|
||||
trace_virtio_ccw_new_device(
|
||||
sch->cssid, sch->ssid, sch->schid, sch->devno,
|
||||
dev->bus_id.valid ? "user-configured" : "auto-configured");
|
||||
ccw_dev->bus_id.valid ? "user-configured" : "auto-configured");
|
||||
|
||||
if (k->realize) {
|
||||
k->realize(dev, &err);
|
||||
|
@ -691,14 +695,15 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
|
|||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
|
||||
dev->sch = NULL;
|
||||
ccw_dev->sch = NULL;
|
||||
g_free(sch);
|
||||
}
|
||||
}
|
||||
|
||||
static int virtio_ccw_exit(VirtioCcwDevice *dev)
|
||||
{
|
||||
SubchDev *sch = dev->sch;
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(dev);
|
||||
SubchDev *sch = ccw_dev->sch;
|
||||
|
||||
if (sch) {
|
||||
css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
|
||||
|
@ -879,7 +884,9 @@ static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp)
|
|||
*/
|
||||
static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
|
||||
{
|
||||
return container_of(d, VirtioCcwDevice, parent_obj);
|
||||
CcwDevice *ccw_dev = to_ccw_dev_fast(d);
|
||||
|
||||
return container_of(ccw_dev, VirtioCcwDevice, parent_obj);
|
||||
}
|
||||
|
||||
static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
|
||||
|
@ -908,7 +915,8 @@ static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
|
|||
static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
|
||||
{
|
||||
VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
|
||||
SubchDev *sch = dev->sch;
|
||||
CcwDevice *ccw_dev = to_ccw_dev_fast(d);
|
||||
SubchDev *sch = ccw_dev->sch;
|
||||
uint64_t indicators;
|
||||
|
||||
/* queue indicators + secondary indicators */
|
||||
|
@ -966,9 +974,10 @@ static void virtio_ccw_reset(DeviceState *d)
|
|||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(d);
|
||||
|
||||
virtio_ccw_reset_virtio(dev, vdev);
|
||||
css_reset_sch(dev->sch);
|
||||
css_reset_sch(ccw_dev->sch);
|
||||
}
|
||||
|
||||
static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
|
||||
|
@ -984,7 +993,7 @@ static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
|
|||
|
||||
static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
|
||||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
CcwDevice *dev = CCW_DEVICE(d);
|
||||
|
||||
return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
|
||||
}
|
||||
|
@ -992,8 +1001,9 @@ static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
|
|||
static int virtio_ccw_get_mappings(VirtioCcwDevice *dev)
|
||||
{
|
||||
int r;
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(dev);
|
||||
|
||||
if (!dev->sch->thinint_active) {
|
||||
if (!ccw_dev->sch->thinint_active) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1125,8 @@ static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
|
|||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
|
||||
bool with_irqfd = dev->sch->thinint_active && kvm_irqfds_enabled();
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(d);
|
||||
bool with_irqfd = ccw_dev->sch->thinint_active && kvm_irqfds_enabled();
|
||||
int r, n;
|
||||
|
||||
if (with_irqfd && assigned) {
|
||||
|
@ -1174,7 +1185,8 @@ static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f)
|
|||
static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
|
||||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
SubchDev *s = dev->sch;
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(d);
|
||||
SubchDev *s = ccw_dev->sch;
|
||||
VirtIODevice *vdev = virtio_ccw_get_vdev(s);
|
||||
|
||||
subch_device_save(s, f);
|
||||
|
@ -1208,7 +1220,8 @@ static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
|
|||
static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
|
||||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
SubchDev *s = dev->sch;
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(d);
|
||||
SubchDev *s = ccw_dev->sch;
|
||||
VirtIODevice *vdev = virtio_ccw_get_vdev(s);
|
||||
int len;
|
||||
|
||||
|
@ -1253,7 +1266,8 @@ static void virtio_ccw_device_plugged(DeviceState *d, Error **errp)
|
|||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
|
||||
SubchDev *sch = dev->sch;
|
||||
CcwDevice *ccw_dev = CCW_DEVICE(d);
|
||||
SubchDev *sch = ccw_dev->sch;
|
||||
int n = virtio_get_num_queues(vdev);
|
||||
|
||||
if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) {
|
||||
|
@ -1297,7 +1311,7 @@ static void virtio_ccw_device_unplugged(DeviceState *d)
|
|||
/**************** Virtio-ccw Bus Device Descriptions *******************/
|
||||
|
||||
static Property virtio_ccw_net_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
|
@ -1326,7 +1340,7 @@ static const TypeInfo virtio_ccw_net = {
|
|||
};
|
||||
|
||||
static Property virtio_ccw_blk_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
|
@ -1355,7 +1369,7 @@ static const TypeInfo virtio_ccw_blk = {
|
|||
};
|
||||
|
||||
static Property virtio_ccw_serial_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
|
@ -1384,7 +1398,7 @@ static const TypeInfo virtio_ccw_serial = {
|
|||
};
|
||||
|
||||
static Property virtio_ccw_balloon_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
|
@ -1413,7 +1427,7 @@ static const TypeInfo virtio_ccw_balloon = {
|
|||
};
|
||||
|
||||
static Property virtio_ccw_scsi_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
|
@ -1443,7 +1457,7 @@ static const TypeInfo virtio_ccw_scsi = {
|
|||
|
||||
#ifdef CONFIG_VHOST_SCSI
|
||||
static Property vhost_ccw_scsi_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
VIRTIO_CCW_MAX_REV),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
|
@ -1481,7 +1495,7 @@ static void virtio_ccw_rng_instance_init(Object *obj)
|
|||
}
|
||||
|
||||
static Property virtio_ccw_rng_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
|
@ -1525,32 +1539,20 @@ static int virtio_ccw_busdev_exit(DeviceState *dev)
|
|||
return _info->exit(_dev);
|
||||
}
|
||||
|
||||
void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
|
||||
SubchDev *sch = _dev->sch;
|
||||
VirtioCcwDevice *_dev = to_virtio_ccw_dev_fast(dev);
|
||||
|
||||
virtio_ccw_stop_ioeventfd(_dev);
|
||||
|
||||
/*
|
||||
* We should arrive here only for device_del, since we don't support
|
||||
* direct hot(un)plug of channels, but only through virtio.
|
||||
*/
|
||||
assert(sch != NULL);
|
||||
/* Subchannel is now disabled and no longer valid. */
|
||||
sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
|
||||
PMCW_FLAGS_MASK_DNV);
|
||||
|
||||
css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
|
||||
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
|
||||
|
||||
k->unplug = virtio_ccw_busdev_unplug;
|
||||
dc->realize = virtio_ccw_busdev_realize;
|
||||
dc->exit = virtio_ccw_busdev_exit;
|
||||
dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
|
||||
|
@ -1558,7 +1560,7 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
|
|||
|
||||
static const TypeInfo virtio_ccw_device_info = {
|
||||
.name = TYPE_VIRTIO_CCW_DEVICE,
|
||||
.parent = TYPE_DEVICE,
|
||||
.parent = TYPE_CCW_DEVICE,
|
||||
.instance_size = sizeof(VirtioCcwDevice),
|
||||
.class_init = virtio_ccw_device_class_init,
|
||||
.class_size = sizeof(VirtIOCCWDeviceClass),
|
||||
|
@ -1610,7 +1612,7 @@ static const TypeInfo virtio_ccw_bus_info = {
|
|||
|
||||
#ifdef CONFIG_VIRTFS
|
||||
static Property virtio_ccw_9p_properties[] = {
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <hw/s390x/s390_flic.h>
|
||||
#include <hw/s390x/css.h>
|
||||
#include "ccw-device.h"
|
||||
#include "hw/s390x/css-bridge.h"
|
||||
|
||||
#define VIRTIO_CCW_CU_TYPE 0x3832
|
||||
#define VIRTIO_CCW_CHPID_TYPE 0x32
|
||||
|
@ -65,7 +67,7 @@ typedef struct VirtioBusClass VirtioCcwBusClass;
|
|||
typedef struct VirtioCcwDevice VirtioCcwDevice;
|
||||
|
||||
typedef struct VirtIOCCWDeviceClass {
|
||||
DeviceClass parent_class;
|
||||
CCWDeviceClass parent_class;
|
||||
void (*realize)(VirtioCcwDevice *dev, Error **errp);
|
||||
int (*exit)(VirtioCcwDevice *dev);
|
||||
} VirtIOCCWDeviceClass;
|
||||
|
@ -76,9 +78,7 @@ typedef struct VirtIOCCWDeviceClass {
|
|||
#define VIRTIO_CCW_FLAG_USE_IOEVENTFD (1 << VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT)
|
||||
|
||||
struct VirtioCcwDevice {
|
||||
DeviceState parent_obj;
|
||||
SubchDev *sch;
|
||||
CssDevId bus_id;
|
||||
CcwDevice parent_obj;
|
||||
int revision;
|
||||
uint32_t max_rev;
|
||||
VirtioBusState bus;
|
||||
|
@ -101,9 +101,6 @@ static inline int virtio_ccw_rev_max(VirtioCcwDevice *dev)
|
|||
return dev->max_rev;
|
||||
}
|
||||
|
||||
void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp);
|
||||
|
||||
/* virtio-scsi-ccw */
|
||||
|
||||
#define TYPE_VIRTIO_SCSI_CCW "virtio-scsi-ccw"
|
||||
|
|
Loading…
Reference in New Issue