msix: clear pending bit of an unused vector

PCI spec states:
if a masked vector has its Pending bit set, and the associated
underlying interrupt events are somehow satisfied (usually by software
though the exact manner is function-specific), the function must clear
the Pending bit, to avoid sending a spurious interrupt message later
when software unmasks the vector.

In our case this happens if vector becomes unused.
Clear pending bit in this case.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Michael S. Tsirkin 2009-11-25 12:24:14 +02:00
parent 1f944c661a
commit 98304c846d
1 changed files with 17 additions and 10 deletions

View File

@ -105,14 +105,6 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
return 0;
}
static void msix_free_irq_entries(PCIDevice *dev)
{
int vector;
for (vector = 0; vector < dev->msix_entries_nr; ++vector)
dev->msix_entry_used[vector] = 0;
}
/* Handle MSI-X capability config write. */
void msix_write_config(PCIDevice *dev, uint32_t addr,
uint32_t val, int len)
@ -271,6 +263,16 @@ err_index:
return ret;
}
static void msix_free_irq_entries(PCIDevice *dev)
{
int vector;
for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
dev->msix_entry_used[vector] = 0;
msix_clr_pending(dev, vector);
}
}
/* Clean up resources for the device. */
int msix_uninit(PCIDevice *dev)
{
@ -387,8 +389,13 @@ int msix_vector_use(PCIDevice *dev, unsigned vector)
/* Mark vector as unused. */
void msix_vector_unuse(PCIDevice *dev, unsigned vector)
{
if (vector < dev->msix_entries_nr && dev->msix_entry_used[vector])
--dev->msix_entry_used[vector];
if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) {
return;
}
if (--dev->msix_entry_used[vector]) {
return;
}
msix_clr_pending(dev, vector);
}
void msix_unuse_all_vectors(PCIDevice *dev)