summaryrefslogtreecommitdiffstats
path: root/drivers/virtio
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2014-10-14 10:40:35 +1030
committerRusty Russell <rusty@rustcorp.com.au>2014-10-15 10:24:55 +1030
commitc6716bae52f97347e25166c6270aa98693d9212c (patch)
tree0a8cf01f68e1eb0c0e403c24e9fbf1d76ccb3568 /drivers/virtio
parent016c98c6fe0c914d12e2e242b2bccde6d6dea54b (diff)
downloadlinux-c6716bae52f97347e25166c6270aa98693d9212c.tar.gz
linux-c6716bae52f97347e25166c6270aa98693d9212c.tar.bz2
linux-c6716bae52f97347e25166c6270aa98693d9212c.zip
virtio-pci: move freeze/restore to virtio core
This is in preparation to extending config changed event handling in core. Wrapping these in an API also seems to make for a cleaner code. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/virtio')
-rw-r--r--drivers/virtio/virtio.c54
-rw-r--r--drivers/virtio/virtio_pci.c54
2 files changed, 56 insertions, 52 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 3980687401f6..8216b7311092 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -248,6 +248,60 @@ void virtio_config_changed(struct virtio_device *dev)
}
EXPORT_SYMBOL_GPL(virtio_config_changed);
+#ifdef CONFIG_PM_SLEEP
+int virtio_device_freeze(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
+
+ if (drv && drv->freeze)
+ return drv->freeze(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_device_freeze);
+
+int virtio_device_restore(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ /* We always start by resetting the device, in case a previous
+ * driver messed it up. */
+ dev->config->reset(dev);
+
+ /* Acknowledge that we've seen the device. */
+ add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+
+ /* Maybe driver failed before freeze.
+ * Restore the failed status, for debugging. */
+ if (dev->failed)
+ add_status(dev, VIRTIO_CONFIG_S_FAILED);
+
+ if (!drv)
+ return 0;
+
+ /* We have a driver! */
+ add_status(dev, VIRTIO_CONFIG_S_DRIVER);
+
+ dev->config->finalize_features(dev);
+
+ if (drv->restore) {
+ int ret = drv->restore(dev);
+ if (ret) {
+ add_status(dev, VIRTIO_CONFIG_S_FAILED);
+ return ret;
+ }
+ }
+
+ /* Finally, tell the device we're all set */
+ add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_device_restore);
+#endif
+
static int virtio_init(void)
{
if (bus_register(&virtio_bus) != 0)
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index f39f4e772e6a..d34ebfa604f3 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -57,9 +57,6 @@ struct virtio_pci_device
/* Vectors allocated, excluding per-vq vectors if any */
unsigned msix_used_vectors;
- /* Status saved during hibernate/restore */
- u8 saved_status;
-
/* Whether we have vector per vq */
bool per_vq_vectors;
};
@@ -764,16 +761,9 @@ static int virtio_pci_freeze(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
- struct virtio_driver *drv;
int ret;
- drv = container_of(vp_dev->vdev.dev.driver,
- struct virtio_driver, driver);
-
- ret = 0;
- vp_dev->saved_status = vp_get_status(&vp_dev->vdev);
- if (drv && drv->freeze)
- ret = drv->freeze(&vp_dev->vdev);
+ ret = virtio_device_freeze(&vp_dev->vdev);
if (!ret)
pci_disable_device(pci_dev);
@@ -784,54 +774,14 @@ static int virtio_pci_restore(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
- struct virtio_driver *drv;
- unsigned status = 0;
int ret;
- drv = container_of(vp_dev->vdev.dev.driver,
- struct virtio_driver, driver);
-
ret = pci_enable_device(pci_dev);
if (ret)
return ret;
pci_set_master(pci_dev);
- /* We always start by resetting the device, in case a previous
- * driver messed it up. */
- vp_reset(&vp_dev->vdev);
-
- /* Acknowledge that we've seen the device. */
- status |= VIRTIO_CONFIG_S_ACKNOWLEDGE;
- vp_set_status(&vp_dev->vdev, status);
-
- /* Maybe driver failed before freeze.
- * Restore the failed status, for debugging. */
- status |= vp_dev->saved_status & VIRTIO_CONFIG_S_FAILED;
- vp_set_status(&vp_dev->vdev, status);
-
- if (!drv)
- return 0;
-
- /* We have a driver! */
- status |= VIRTIO_CONFIG_S_DRIVER;
- vp_set_status(&vp_dev->vdev, status);
-
- vp_finalize_features(&vp_dev->vdev);
-
- if (drv->restore) {
- ret = drv->restore(&vp_dev->vdev);
- if (ret) {
- status |= VIRTIO_CONFIG_S_FAILED;
- vp_set_status(&vp_dev->vdev, status);
- return ret;
- }
- }
-
- /* Finally, tell the device we're all set */
- status |= VIRTIO_CONFIG_S_DRIVER_OK;
- vp_set_status(&vp_dev->vdev, status);
-
- return ret;
+ return virtio_device_restore(&vp_dev->vdev);
}
static const struct dev_pm_ops virtio_pci_pm_ops = {