aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/virtio/virtio_pci.c')
-rw-r--r--drivers/virtio/virtio_pci.c110
1 files changed, 104 insertions, 6 deletions
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index baabb7937ec2..635e1efb3792 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -55,6 +55,10 @@ struct virtio_pci_device
55 unsigned msix_vectors; 55 unsigned msix_vectors;
56 /* Vectors allocated, excluding per-vq vectors if any */ 56 /* Vectors allocated, excluding per-vq vectors if any */
57 unsigned msix_used_vectors; 57 unsigned msix_used_vectors;
58
59 /* Status saved during hibernate/restore */
60 u8 saved_status;
61
58 /* Whether we have vector per vq */ 62 /* Whether we have vector per vq */
59 bool per_vq_vectors; 63 bool per_vq_vectors;
60}; 64};
@@ -414,8 +418,8 @@ static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
414 vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); 418 vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
415 419
416 /* create the vring */ 420 /* create the vring */
417 vq = vring_new_virtqueue(info->num, VIRTIO_PCI_VRING_ALIGN, 421 vq = vring_new_virtqueue(info->num, VIRTIO_PCI_VRING_ALIGN, vdev,
418 vdev, info->queue, vp_notify, callback, name); 422 true, info->queue, vp_notify, callback, name);
419 if (!vq) { 423 if (!vq) {
420 err = -ENOMEM; 424 err = -ENOMEM;
421 goto out_activate_queue; 425 goto out_activate_queue;
@@ -716,19 +720,114 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)
716} 720}
717 721
718#ifdef CONFIG_PM 722#ifdef CONFIG_PM
719static int virtio_pci_suspend(struct pci_dev *pci_dev, pm_message_t state) 723static int virtio_pci_suspend(struct device *dev)
720{ 724{
725 struct pci_dev *pci_dev = to_pci_dev(dev);
726
721 pci_save_state(pci_dev); 727 pci_save_state(pci_dev);
722 pci_set_power_state(pci_dev, PCI_D3hot); 728 pci_set_power_state(pci_dev, PCI_D3hot);
723 return 0; 729 return 0;
724} 730}
725 731
726static int virtio_pci_resume(struct pci_dev *pci_dev) 732static int virtio_pci_resume(struct device *dev)
727{ 733{
734 struct pci_dev *pci_dev = to_pci_dev(dev);
735
728 pci_restore_state(pci_dev); 736 pci_restore_state(pci_dev);
729 pci_set_power_state(pci_dev, PCI_D0); 737 pci_set_power_state(pci_dev, PCI_D0);
730 return 0; 738 return 0;
731} 739}
740
741static int virtio_pci_freeze(struct device *dev)
742{
743 struct pci_dev *pci_dev = to_pci_dev(dev);
744 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
745 struct virtio_driver *drv;
746 int ret;
747
748 drv = container_of(vp_dev->vdev.dev.driver,
749 struct virtio_driver, driver);
750
751 ret = 0;
752 vp_dev->saved_status = vp_get_status(&vp_dev->vdev);
753 if (drv && drv->freeze)
754 ret = drv->freeze(&vp_dev->vdev);
755
756 if (!ret)
757 pci_disable_device(pci_dev);
758 return ret;
759}
760
761static int restore_common(struct device *dev)
762{
763 struct pci_dev *pci_dev = to_pci_dev(dev);
764 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
765 int ret;
766
767 ret = pci_enable_device(pci_dev);
768 if (ret)
769 return ret;
770 pci_set_master(pci_dev);
771 vp_finalize_features(&vp_dev->vdev);
772
773 return ret;
774}
775
776static int virtio_pci_thaw(struct device *dev)
777{
778 struct pci_dev *pci_dev = to_pci_dev(dev);
779 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
780 struct virtio_driver *drv;
781 int ret;
782
783 ret = restore_common(dev);
784 if (ret)
785 return ret;
786
787 drv = container_of(vp_dev->vdev.dev.driver,
788 struct virtio_driver, driver);
789
790 if (drv && drv->thaw)
791 ret = drv->thaw(&vp_dev->vdev);
792 else if (drv && drv->restore)
793 ret = drv->restore(&vp_dev->vdev);
794
795 /* Finally, tell the device we're all set */
796 if (!ret)
797 vp_set_status(&vp_dev->vdev, vp_dev->saved_status);
798
799 return ret;
800}
801
802static int virtio_pci_restore(struct device *dev)
803{
804 struct pci_dev *pci_dev = to_pci_dev(dev);
805 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
806 struct virtio_driver *drv;
807 int ret;
808
809 drv = container_of(vp_dev->vdev.dev.driver,
810 struct virtio_driver, driver);
811
812 ret = restore_common(dev);
813 if (!ret && drv && drv->restore)
814 ret = drv->restore(&vp_dev->vdev);
815
816 /* Finally, tell the device we're all set */
817 if (!ret)
818 vp_set_status(&vp_dev->vdev, vp_dev->saved_status);
819
820 return ret;
821}
822
823static const struct dev_pm_ops virtio_pci_pm_ops = {
824 .suspend = virtio_pci_suspend,
825 .resume = virtio_pci_resume,
826 .freeze = virtio_pci_freeze,
827 .thaw = virtio_pci_thaw,
828 .restore = virtio_pci_restore,
829 .poweroff = virtio_pci_suspend,
830};
732#endif 831#endif
733 832
734static struct pci_driver virtio_pci_driver = { 833static struct pci_driver virtio_pci_driver = {
@@ -737,8 +836,7 @@ static struct pci_driver virtio_pci_driver = {
737 .probe = virtio_pci_probe, 836 .probe = virtio_pci_probe,
738 .remove = __devexit_p(virtio_pci_remove), 837 .remove = __devexit_p(virtio_pci_remove),
739#ifdef CONFIG_PM 838#ifdef CONFIG_PM
740 .suspend = virtio_pci_suspend, 839 .driver.pm = &virtio_pci_pm_ops,
741 .resume = virtio_pci_resume,
742#endif 840#endif
743}; 841};
744 842