mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
s390x/ccw: make sure all ccw devices are properly reset
Thomas reported that the subchannel for a 3270 device that ended up in a broken state (status pending even though not enabled) did not get out of that state even after a reboot (which involves a subsytem reset). The reason for this is that the 3270 device did not define a reset handler. Let's fix this by introducing a base reset handler (set up for all ccw devices) that resets the subchannel and have virtio-ccw call its virtio-specific reset procedure in addition to that. CC: qemu-stable@nongnu.org Reported-by: Thomas Huth <thuth@redhat.com> Suggested-by: Christian Borntraeger <borntraeger@de.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Tested-by: Thomas Huth <thuth@redhat.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Reviewed-by: Halil Pasic <pasic@linux.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
0c53057adb
commit
838fb84f83
3 changed files with 15 additions and 3 deletions
|
@ -40,6 +40,13 @@ static Property ccw_device_properties[] = {
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void ccw_device_reset(DeviceState *d)
|
||||||
|
{
|
||||||
|
CcwDevice *ccw_dev = CCW_DEVICE(d);
|
||||||
|
|
||||||
|
css_reset_sch(ccw_dev->sch);
|
||||||
|
}
|
||||||
|
|
||||||
static void ccw_device_class_init(ObjectClass *klass, void *data)
|
static void ccw_device_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
@ -48,6 +55,7 @@ static void ccw_device_class_init(ObjectClass *klass, void *data)
|
||||||
k->realize = ccw_device_realize;
|
k->realize = ccw_device_realize;
|
||||||
k->refill_ids = ccw_device_refill_ids;
|
k->refill_ids = ccw_device_refill_ids;
|
||||||
dc->props = ccw_device_properties;
|
dc->props = ccw_device_properties;
|
||||||
|
dc->reset = ccw_device_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VMStateDescription vmstate_ccw_dev = {
|
const VMStateDescription vmstate_ccw_dev = {
|
||||||
|
|
|
@ -1058,10 +1058,12 @@ static void virtio_ccw_reset(DeviceState *d)
|
||||||
{
|
{
|
||||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
|
VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
|
||||||
CcwDevice *ccw_dev = CCW_DEVICE(d);
|
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
virtio_ccw_reset_virtio(dev, vdev);
|
virtio_ccw_reset_virtio(dev, vdev);
|
||||||
css_reset_sch(ccw_dev->sch);
|
if (vdc->parent_reset) {
|
||||||
|
vdc->parent_reset(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
|
static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
|
||||||
|
@ -1715,12 +1717,13 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
|
CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
|
||||||
|
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_CLASS(klass);
|
||||||
|
|
||||||
k->unplug = virtio_ccw_busdev_unplug;
|
k->unplug = virtio_ccw_busdev_unplug;
|
||||||
dc->realize = virtio_ccw_busdev_realize;
|
dc->realize = virtio_ccw_busdev_realize;
|
||||||
dc->unrealize = virtio_ccw_busdev_unrealize;
|
dc->unrealize = virtio_ccw_busdev_unrealize;
|
||||||
dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
|
dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
|
||||||
dc->reset = virtio_ccw_reset;
|
device_class_set_parent_reset(dc, virtio_ccw_reset, &vdc->parent_reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo virtio_ccw_device_info = {
|
static const TypeInfo virtio_ccw_device_info = {
|
||||||
|
|
|
@ -77,6 +77,7 @@ typedef struct VirtIOCCWDeviceClass {
|
||||||
CCWDeviceClass parent_class;
|
CCWDeviceClass parent_class;
|
||||||
void (*realize)(VirtioCcwDevice *dev, Error **errp);
|
void (*realize)(VirtioCcwDevice *dev, Error **errp);
|
||||||
void (*unrealize)(VirtioCcwDevice *dev, Error **errp);
|
void (*unrealize)(VirtioCcwDevice *dev, Error **errp);
|
||||||
|
void (*parent_reset)(DeviceState *dev);
|
||||||
} VirtIOCCWDeviceClass;
|
} VirtIOCCWDeviceClass;
|
||||||
|
|
||||||
/* Performance improves when virtqueue kick processing is decoupled from the
|
/* Performance improves when virtqueue kick processing is decoupled from the
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue