diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/xen/xen-pciback/pci_stub.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 79a9e4d66819..01793332f7e6 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -478,6 +478,36 @@ static int __init pcistub_init_devices_late(void) return 0; } +static void pcistub_device_id_add_list(struct pcistub_device_id *new, + int domain, int bus, unsigned int devfn) +{ + struct pcistub_device_id *pci_dev_id; + unsigned long flags; + int found = 0; + + spin_lock_irqsave(&device_ids_lock, flags); + + list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) { + if (pci_dev_id->domain == domain && pci_dev_id->bus == bus && + pci_dev_id->devfn == devfn) { + found = 1; + break; + } + } + + if (!found) { + new->domain = domain; + new->bus = bus; + new->devfn = devfn; + list_add_tail(&new->slot_list, &pcistub_device_ids); + } + + spin_unlock_irqrestore(&device_ids_lock, flags); + + if (found) + kfree(new); +} + static int pcistub_seize(struct pci_dev *dev) { struct pcistub_device *psdev; @@ -1012,7 +1042,6 @@ static inline int str_to_quirk(const char *buf, int *domain, int *bus, int static int pcistub_device_id_add(int domain, int bus, int slot, int func) { struct pcistub_device_id *pci_dev_id; - unsigned long flags; int rc = 0, devfn = PCI_DEVFN(slot, func); if (slot < 0) { @@ -1042,16 +1071,10 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func) if (!pci_dev_id) return -ENOMEM; - pci_dev_id->domain = domain; - pci_dev_id->bus = bus; - pci_dev_id->devfn = devfn; - pr_debug("wants to seize %04x:%02x:%02x.%d\n", domain, bus, slot, func); - spin_lock_irqsave(&device_ids_lock, flags); - list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids); - spin_unlock_irqrestore(&device_ids_lock, flags); + pcistub_device_id_add_list(pci_dev_id, domain, bus, devfn); return 0; } |