Commit 838fb84f authored by Cornelia Huck's avatar Cornelia Huck
Browse files

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: default avatarThomas Huth <thuth@redhat.com>
Suggested-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: default avatarThomas Huth <thuth@redhat.com>
Tested-by: default avatarThomas Huth <thuth@redhat.com>
Acked-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: default avatarHalil Pasic <pasic@linux.ibm.com>
Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parent 0c53057a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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 = {
+6 −3
Original line number Diff line number Diff line
@@ -1058,10 +1058,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)
@@ -1715,12 +1717,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 = {
+1 −0
Original line number Diff line number Diff line
@@ -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