aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2012-12-07 15:43:51 -0500
committerAlex Williamson <alex.williamson@redhat.com>2012-12-07 15:43:51 -0500
commit9a92c5091a42c565ede818fdf204c4f60004d0d8 (patch)
tree2b6d75e83a08b892c3500b09855feeaecc9d9f60 /drivers
parent05bf3aac930752408bf38a3f070061fc5f1b9c73 (diff)
vfio-pci: Enable device before attempting reset
Devices making use of PM reset are getting incorrectly identified as not supporting reset because pci_pm_reset() fails unless the device is in D0 power state. When first attached to vfio_pci devices are typically in an unknown power state. We can fix this by explicitly setting the power state or simply calling pci_enable_device() before attempting a pci_reset_function(). We need to enable the device anyway, so move this up in our vfio_pci_enable() function, which also simplifies the error path a bit. Note that pci_disable_device() does not explicitly set the power state, so there's no need to re-order vfio_pci_disable(). Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/vfio/pci/vfio_pci.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 306b90cf051f..b28e66c4376a 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -43,6 +43,10 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
43 u16 cmd; 43 u16 cmd;
44 u8 msix_pos; 44 u8 msix_pos;
45 45
46 ret = pci_enable_device(pdev);
47 if (ret)
48 return ret;
49
46 vdev->reset_works = (pci_reset_function(pdev) == 0); 50 vdev->reset_works = (pci_reset_function(pdev) == 0);
47 pci_save_state(pdev); 51 pci_save_state(pdev);
48 vdev->pci_saved_state = pci_store_saved_state(pdev); 52 vdev->pci_saved_state = pci_store_saved_state(pdev);
@@ -51,8 +55,11 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
51 __func__, dev_name(&pdev->dev)); 55 __func__, dev_name(&pdev->dev));
52 56
53 ret = vfio_config_init(vdev); 57 ret = vfio_config_init(vdev);
54 if (ret) 58 if (ret) {
55 goto out; 59 pci_load_and_free_saved_state(pdev, &vdev->pci_saved_state);
60 pci_disable_device(pdev);
61 return ret;
62 }
56 63
57 if (likely(!nointxmask)) 64 if (likely(!nointxmask))
58 vdev->pci_2_3 = pci_intx_mask_supported(pdev); 65 vdev->pci_2_3 = pci_intx_mask_supported(pdev);
@@ -77,17 +84,7 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
77 } else 84 } else
78 vdev->msix_bar = 0xFF; 85 vdev->msix_bar = 0xFF;
79 86
80 ret = pci_enable_device(pdev); 87 return 0;
81 if (ret)
82 goto out;
83
84 return ret;
85
86out:
87 kfree(vdev->pci_saved_state);
88 vdev->pci_saved_state = NULL;
89 vfio_config_free(vdev);
90 return ret;
91} 88}
92 89
93static void vfio_pci_disable(struct vfio_pci_device *vdev) 90static void vfio_pci_disable(struct vfio_pci_device *vdev)