|
@@ -54,6 +54,8 @@ EXPORT_SYMBOL(vmbus_loglevel);
|
|
|
/* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
|
|
|
/* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
|
|
|
|
|
|
+static int pci_probe_error;
|
|
|
+static struct completion probe_event;
|
|
|
|
|
|
static void get_channel_info(struct hv_device *device,
|
|
|
struct hv_device_info *info)
|
|
@@ -722,19 +724,19 @@ void vmbus_child_device_unregister(struct hv_device *device_obj)
|
|
|
static int __devinit hv_pci_probe(struct pci_dev *pdev,
|
|
|
const struct pci_device_id *ent)
|
|
|
{
|
|
|
- int err;
|
|
|
-
|
|
|
hv_pci_dev = pdev;
|
|
|
|
|
|
- err = pci_enable_device(pdev);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
+ pci_probe_error = pci_enable_device(pdev);
|
|
|
+ if (pci_probe_error)
|
|
|
+ goto probe_cleanup;
|
|
|
|
|
|
- err = vmbus_bus_init(pdev);
|
|
|
- if (err)
|
|
|
+ pci_probe_error = vmbus_bus_init(pdev);
|
|
|
+ if (pci_probe_error)
|
|
|
pci_disable_device(pdev);
|
|
|
|
|
|
- return err;
|
|
|
+probe_cleanup:
|
|
|
+ complete(&probe_event);
|
|
|
+ return pci_probe_error;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -757,7 +759,21 @@ static struct pci_driver hv_bus_driver = {
|
|
|
|
|
|
static int __init hv_pci_init(void)
|
|
|
{
|
|
|
- return pci_register_driver(&hv_bus_driver);
|
|
|
+ int ret;
|
|
|
+ init_completion(&probe_event);
|
|
|
+ ret = pci_register_driver(&hv_bus_driver);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ /*
|
|
|
+ * All the vmbus initialization occurs within the
|
|
|
+ * hv_pci_probe() function. Wait for hv_pci_probe()
|
|
|
+ * to complete.
|
|
|
+ */
|
|
|
+ wait_for_completion(&probe_event);
|
|
|
+
|
|
|
+ if (pci_probe_error)
|
|
|
+ pci_unregister_driver(&hv_bus_driver);
|
|
|
+ return pci_probe_error;
|
|
|
}
|
|
|
|
|
|
|