diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2012-12-12 16:10:02 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2012-12-26 11:49:28 +0200 |
commit | bbef882cc1938fa5a6e1b36a50d79ce5c0cefb81 (patch) | |
tree | 8d07df207beb51343bc8804e4d0776720410ddf5 /hw/pci | |
parent | 812d2594d558f7c4f95c99c8fc58adc47ab68eb3 (diff) |
msi: add API to get notified about pending bit poll
Update all users.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci')
-rw-r--r-- | hw/pci/msix.c | 13 | ||||
-rw-r--r-- | hw/pci/msix.h | 3 | ||||
-rw-r--r-- | hw/pci/pci.h | 4 |
3 files changed, 18 insertions, 2 deletions
diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 073e22c315..a285d18197 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -191,6 +191,11 @@ static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr, unsigned size) { PCIDevice *dev = opaque; + if (dev->msix_vector_poll_notifier) { + unsigned vector_start = addr * 8; + unsigned vector_end = MIN(addr + size * 8, dev->msix_entries_nr); + dev->msix_vector_poll_notifier(dev, vector_start, vector_end); + } return pci_get_long(dev->msix_pba + addr); } @@ -513,7 +518,8 @@ static void msix_unset_notifier_for_vector(PCIDevice *dev, unsigned int vector) int msix_set_vector_notifiers(PCIDevice *dev, MSIVectorUseNotifier use_notifier, - MSIVectorReleaseNotifier release_notifier) + MSIVectorReleaseNotifier release_notifier, + MSIVectorPollNotifier poll_notifier) { int vector, ret; @@ -521,6 +527,7 @@ int msix_set_vector_notifiers(PCIDevice *dev, dev->msix_vector_use_notifier = use_notifier; dev->msix_vector_release_notifier = release_notifier; + dev->msix_vector_poll_notifier = poll_notifier; if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & (MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) { @@ -531,6 +538,9 @@ int msix_set_vector_notifiers(PCIDevice *dev, } } } + if (dev->msix_vector_poll_notifier) { + dev->msix_vector_poll_notifier(dev, 0, dev->msix_entries_nr); + } return 0; undo: @@ -557,4 +567,5 @@ void msix_unset_vector_notifiers(PCIDevice *dev) } dev->msix_vector_use_notifier = NULL; dev->msix_vector_release_notifier = NULL; + dev->msix_vector_poll_notifier = NULL; } diff --git a/hw/pci/msix.h b/hw/pci/msix.h index ff07ae2e8f..ea85d02264 100644 --- a/hw/pci/msix.h +++ b/hw/pci/msix.h @@ -36,6 +36,7 @@ void msix_reset(PCIDevice *dev); int msix_set_vector_notifiers(PCIDevice *dev, MSIVectorUseNotifier use_notifier, - MSIVectorReleaseNotifier release_notifier); + MSIVectorReleaseNotifier release_notifier, + MSIVectorPollNotifier poll_notifier); void msix_unset_vector_notifiers(PCIDevice *dev); #endif diff --git a/hw/pci/pci.h b/hw/pci/pci.h index 3152050856..72927e3149 100644 --- a/hw/pci/pci.h +++ b/hw/pci/pci.h @@ -187,6 +187,9 @@ typedef void (*PCIINTxRoutingNotifier)(PCIDevice *dev); typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector, MSIMessage msg); typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector); +typedef void (*MSIVectorPollNotifier)(PCIDevice *dev, + unsigned int vector_start, + unsigned int vector_end); struct PCIDevice { DeviceState qdev; @@ -271,6 +274,7 @@ struct PCIDevice { /* MSI-X notifiers */ MSIVectorUseNotifier msix_vector_use_notifier; MSIVectorReleaseNotifier msix_vector_release_notifier; + MSIVectorPollNotifier msix_vector_poll_notifier; }; void pci_register_bar(PCIDevice *pci_dev, int region_num, |