diff options
Diffstat (limited to 'drivers/virtio/virtio_pci.c')
-rw-r--r-- | drivers/virtio/virtio_pci.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 3d1bf41e8892..03d1984bd363 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -169,11 +169,29 @@ static void vp_set_status(struct virtio_device *vdev, u8 status) | |||
169 | iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | 169 | iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); |
170 | } | 170 | } |
171 | 171 | ||
172 | /* wait for pending irq handlers */ | ||
173 | static void vp_synchronize_vectors(struct virtio_device *vdev) | ||
174 | { | ||
175 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
176 | int i; | ||
177 | |||
178 | if (vp_dev->intx_enabled) | ||
179 | synchronize_irq(vp_dev->pci_dev->irq); | ||
180 | |||
181 | for (i = 0; i < vp_dev->msix_vectors; ++i) | ||
182 | synchronize_irq(vp_dev->msix_entries[i].vector); | ||
183 | } | ||
184 | |||
172 | static void vp_reset(struct virtio_device *vdev) | 185 | static void vp_reset(struct virtio_device *vdev) |
173 | { | 186 | { |
174 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 187 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
175 | /* 0 status means a reset. */ | 188 | /* 0 status means a reset. */ |
176 | iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | 189 | iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); |
190 | /* Flush out the status write, and flush in device writes, | ||
191 | * including MSi-X interrupts, if any. */ | ||
192 | ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); | ||
193 | /* Flush pending VQ/configuration callbacks. */ | ||
194 | vp_synchronize_vectors(vdev); | ||
177 | } | 195 | } |
178 | 196 | ||
179 | /* the notify function used when creating a virt queue */ | 197 | /* the notify function used when creating a virt queue */ |