@@ -1612,6 +1612,10 @@ static int virtblk_restore(struct virtio_device *vdev)
struct virtio_blk *vblk = vdev->priv;
int ret;
+ ret = virtio_device_reset_and_restore_status(vdev);
+ if (ret)
+ return ret;
+
ret = init_vq(vdev->priv);
if (ret)
return ret;
@@ -218,6 +218,10 @@ static int virtrng_restore(struct virtio_device *vdev)
{
int err;
+ err = virtio_device_reset_and_restore_status(vdev);
+ if (err)
+ return err;
+
err = probe_common(vdev);
if (!err) {
struct virtrng_info *vi = vdev->priv;
@@ -2132,6 +2132,10 @@ static int virtcons_restore(struct virtio_device *vdev)
portdev = vdev->priv;
+ ret = virtio_device_reset_and_restore_status(vdev);
+ if (ret)
+ return ret;
+
ret = init_vqs(portdev);
if (ret)
return ret;
@@ -536,6 +536,10 @@ static int virtcrypto_restore(struct virtio_device *vdev)
struct virtio_crypto *vcrypto = vdev->priv;
int err;
+ err = virtio_device_reset_and_restore_status(vdev);
+ if (err)
+ return err;
+
err = virtcrypto_init_vqs(vcrypto);
if (err)
return err;
@@ -251,6 +251,12 @@ static int virtio_i2c_freeze(struct virtio_device *vdev)
static int virtio_i2c_restore(struct virtio_device *vdev)
{
+ int ret;
+
+ ret = virtio_device_reset_and_restore_status(vdev);
+ if (ret)
+ return ret;
+
return virtio_i2c_setup_vqs(vdev->priv);
}
@@ -6693,6 +6693,10 @@ static __maybe_unused int virtnet_restore(struct virtio_device *vdev)
struct virtnet_info *vi = vdev->priv;
int err;
+ err = virtio_device_reset_and_restore_status(vdev);
+ if (err)
+ return err;
+
err = virtnet_restore_up(vdev);
if (err)
return err;
@@ -1016,6 +1016,10 @@ static int virtscsi_restore(struct virtio_device *vdev)
struct virtio_scsi *vscsi = shost_priv(sh);
int err;
+ err = virtio_device_reset_and_restore_status(vdev);
+ if (err)
+ return err;
+
err = virtscsi_init(vdev, vscsi);
if (err)
return err;
@@ -549,7 +549,7 @@ int virtio_device_freeze(struct virtio_device *dev)
}
EXPORT_SYMBOL_GPL(virtio_device_freeze);
-int virtio_device_restore(struct virtio_device *dev)
+int virtio_device_reset_and_restore_status(struct virtio_device *dev)
{
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
int ret;
@@ -574,23 +574,34 @@ int virtio_device_restore(struct virtio_device *dev)
ret = dev->config->finalize_features(dev);
if (ret)
- goto err;
+ return ret;
ret = virtio_features_ok(dev);
if (ret)
- goto err;
+ return ret;
- if (drv->restore) {
- ret = drv->restore(dev);
- if (ret)
- goto err;
- }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_device_reset_and_restore_status);
- /* If restore didn't do it, mark device DRIVER_OK ourselves. */
- if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
- virtio_device_ready(dev);
+int virtio_device_restore(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
- virtio_config_core_enable(dev);
+ if (drv) {
+ if (drv->restore) {
+ ret = drv->restore(dev);
+ if (ret)
+ goto err;
+ }
+
+ /* If restore didn't do it, mark device DRIVER_OK ourselves. */
+ if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
+ virtio_device_ready(dev);
+
+ virtio_config_core_enable(dev);
+ }
return 0;
@@ -1163,6 +1163,10 @@ static int virtballoon_restore(struct virtio_device *vdev)
struct virtio_balloon *vb = vdev->priv;
int ret;
+ ret = virtio_device_reset_and_restore_status(vdev);
+ if (ret)
+ return ret;
+
ret = init_vqs(vdev->priv);
if (ret)
return ret;
@@ -374,6 +374,10 @@ static int virtinput_restore(struct virtio_device *vdev)
struct virtio_input *vi = vdev->priv;
int err;
+ err = virtio_device_reset_and_restore_status(vdev);
+ if (err)
+ return err;
+
err = virtinput_init_vqs(vi);
if (err)
return err;
@@ -3018,6 +3018,10 @@ static int virtio_mem_restore(struct virtio_device *vdev)
struct virtio_mem *vm = vdev->priv;
int ret;
+ ret = virtio_device_reset_and_restore_status(vdev);
+ if (ret)
+ return ret;
+
ret = virtio_mem_init_vq(vm);
if (ret)
return ret;
@@ -175,6 +175,7 @@ void virtio_config_driver_enable(struct virtio_device *dev);
#ifdef CONFIG_PM_SLEEP
int virtio_device_freeze(struct virtio_device *dev);
+int virtio_device_reset_and_restore_status(struct virtio_device *dev);
int virtio_device_restore(struct virtio_device *dev);
#endif
void virtio_reset_device(struct virtio_device *dev);
@@ -412,6 +412,10 @@ static int virtsnd_restore(struct virtio_device *vdev)
struct virtio_snd *snd = vdev->priv;
int rc;
+ rc = virtio_device_reset_and_restore_status(vdev);
+ if (rc)
+ return rc;
+
rc = virtsnd_find_vqs(snd);
if (rc)
return rc;