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>
(cherry picked from commit 838fb84f83
)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
stable-2.11
parent
b2ca602627
commit
b68ef5920a
|
@ -40,6 +40,13 @@ static Property ccw_device_properties[] = {
|
|||
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)
|
||||
{
|
||||
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->refill_ids = ccw_device_refill_ids;
|
||||
dc->props = ccw_device_properties;
|
||||
dc->reset = ccw_device_reset;
|
||||
}
|
||||
|
||||
const VMStateDescription vmstate_ccw_dev = {
|
||||
|
|
|
@ -1057,10 +1057,12 @@ 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);
|
||||
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
|
||||
|
||||
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)
|
||||
|
@ -1714,12 +1716,13 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
|
|||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
|
||||
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_CLASS(klass);
|
||||
|
||||
k->unplug = virtio_ccw_busdev_unplug;
|
||||
dc->realize = virtio_ccw_busdev_realize;
|
||||
dc->unrealize = virtio_ccw_busdev_unrealize;
|
||||
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 = {
|
||||
|
|
|
@ -77,6 +77,7 @@ typedef struct VirtIOCCWDeviceClass {
|
|||
CCWDeviceClass parent_class;
|
||||
void (*realize)(VirtioCcwDevice *dev, Error **errp);
|
||||
void (*unrealize)(VirtioCcwDevice *dev, Error **errp);
|
||||
void (*parent_reset)(DeviceState *dev);
|
||||
} VirtIOCCWDeviceClass;
|
||||
|
||||
/* Performance improves when virtqueue kick processing is decoupled from the
|
||||
|
|
Loading…
Reference in New Issue