diff options
| -rw-r--r-- | drivers/xen/xen-pciback/pci_stub.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 01793332f7e6..6331a95691a4 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include "conf_space.h" | 25 | #include "conf_space.h" |
| 26 | #include "conf_space_quirks.h" | 26 | #include "conf_space_quirks.h" |
| 27 | 27 | ||
| 28 | #define PCISTUB_DRIVER_NAME "pciback" | ||
| 29 | |||
| 28 | static char *pci_devs_to_hide; | 30 | static char *pci_devs_to_hide; |
| 29 | wait_queue_head_t xen_pcibk_aer_wait_queue; | 31 | wait_queue_head_t xen_pcibk_aer_wait_queue; |
| 30 | /*Add sem for sync AER handling and xen_pcibk remove/reconfigue ops, | 32 | /*Add sem for sync AER handling and xen_pcibk remove/reconfigue ops, |
| @@ -508,15 +510,18 @@ static void pcistub_device_id_add_list(struct pcistub_device_id *new, | |||
| 508 | kfree(new); | 510 | kfree(new); |
| 509 | } | 511 | } |
| 510 | 512 | ||
| 511 | static int pcistub_seize(struct pci_dev *dev) | 513 | static int pcistub_seize(struct pci_dev *dev, |
| 514 | struct pcistub_device_id *pci_dev_id) | ||
| 512 | { | 515 | { |
| 513 | struct pcistub_device *psdev; | 516 | struct pcistub_device *psdev; |
| 514 | unsigned long flags; | 517 | unsigned long flags; |
| 515 | int err = 0; | 518 | int err = 0; |
| 516 | 519 | ||
| 517 | psdev = pcistub_device_alloc(dev); | 520 | psdev = pcistub_device_alloc(dev); |
| 518 | if (!psdev) | 521 | if (!psdev) { |
| 522 | kfree(pci_dev_id); | ||
| 519 | return -ENOMEM; | 523 | return -ENOMEM; |
| 524 | } | ||
| 520 | 525 | ||
| 521 | spin_lock_irqsave(&pcistub_devices_lock, flags); | 526 | spin_lock_irqsave(&pcistub_devices_lock, flags); |
| 522 | 527 | ||
| @@ -537,8 +542,12 @@ static int pcistub_seize(struct pci_dev *dev) | |||
| 537 | 542 | ||
| 538 | spin_unlock_irqrestore(&pcistub_devices_lock, flags); | 543 | spin_unlock_irqrestore(&pcistub_devices_lock, flags); |
| 539 | 544 | ||
| 540 | if (err) | 545 | if (err) { |
| 546 | kfree(pci_dev_id); | ||
| 541 | pcistub_device_put(psdev); | 547 | pcistub_device_put(psdev); |
| 548 | } else if (pci_dev_id) | ||
| 549 | pcistub_device_id_add_list(pci_dev_id, pci_domain_nr(dev->bus), | ||
| 550 | dev->bus->number, dev->devfn); | ||
| 542 | 551 | ||
| 543 | return err; | 552 | return err; |
| 544 | } | 553 | } |
| @@ -547,11 +556,16 @@ static int pcistub_seize(struct pci_dev *dev) | |||
| 547 | * other functions that take the sysfs lock. */ | 556 | * other functions that take the sysfs lock. */ |
| 548 | static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) | 557 | static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) |
| 549 | { | 558 | { |
| 550 | int err = 0; | 559 | int err = 0, match; |
| 560 | struct pcistub_device_id *pci_dev_id = NULL; | ||
| 551 | 561 | ||
| 552 | dev_dbg(&dev->dev, "probing...\n"); | 562 | dev_dbg(&dev->dev, "probing...\n"); |
| 553 | 563 | ||
| 554 | if (pcistub_match(dev)) { | 564 | match = pcistub_match(dev); |
| 565 | |||
| 566 | if ((dev->driver_override && | ||
| 567 | !strcmp(dev->driver_override, PCISTUB_DRIVER_NAME)) || | ||
| 568 | match) { | ||
| 555 | 569 | ||
| 556 | if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL | 570 | if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL |
| 557 | && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { | 571 | && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { |
| @@ -562,8 +576,16 @@ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 562 | goto out; | 576 | goto out; |
| 563 | } | 577 | } |
| 564 | 578 | ||
| 579 | if (!match) { | ||
| 580 | pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_ATOMIC); | ||
| 581 | if (!pci_dev_id) { | ||
| 582 | err = -ENOMEM; | ||
| 583 | goto out; | ||
| 584 | } | ||
| 585 | } | ||
| 586 | |||
| 565 | dev_info(&dev->dev, "seizing device\n"); | 587 | dev_info(&dev->dev, "seizing device\n"); |
| 566 | err = pcistub_seize(dev); | 588 | err = pcistub_seize(dev, pci_dev_id); |
| 567 | } else | 589 | } else |
| 568 | /* Didn't find the device */ | 590 | /* Didn't find the device */ |
| 569 | err = -ENODEV; | 591 | err = -ENODEV; |
| @@ -975,7 +997,7 @@ static const struct pci_error_handlers xen_pcibk_error_handler = { | |||
| 975 | static struct pci_driver xen_pcibk_pci_driver = { | 997 | static struct pci_driver xen_pcibk_pci_driver = { |
| 976 | /* The name should be xen_pciback, but until the tools are updated | 998 | /* The name should be xen_pciback, but until the tools are updated |
| 977 | * we will keep it as pciback. */ | 999 | * we will keep it as pciback. */ |
| 978 | .name = "pciback", | 1000 | .name = PCISTUB_DRIVER_NAME, |
| 979 | .id_table = pcistub_ids, | 1001 | .id_table = pcistub_ids, |
| 980 | .probe = pcistub_probe, | 1002 | .probe = pcistub_probe, |
| 981 | .remove = pcistub_remove, | 1003 | .remove = pcistub_remove, |
