goto probe_failed;
}
- /*
- * Ensure devices are listed in devices_kset in correct order
- * It's important to move Dev to the end of devices_kset before
- * calling .probe, because it could be recursive and parent Dev
- * should always go first
- */
- devices_kset_move_last(dev);
-
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
}
EXPORT_SYMBOL_GPL(driver_attach);
+void *vfio_pci_driver_ptr = (void *)0xdeadfeed;
+EXPORT_SYMBOL(vfio_pci_driver_ptr);
+
/*
* __device_release_driver() must be called with @dev lock held.
* When called for a USB interface, @dev->parent lock must be held as well.
dev->bus->remove(dev);
else if (drv->remove)
drv->remove(dev);
+ /*
+ * A concurrent invocation of the same function might
+ * have released the driver successfully while this one
+ * was waiting, so check for that.
+ * LP: #1792099
+ *
+ * Limit this to the vfio_pci_driver as some drivers NULL
+ * out this pointer in their remove() function.
+ * LP: #1803942
+ */
+ if (drv == vfio_pci_driver_ptr && dev->driver != drv)
+ return;
device_links_driver_cleanup(dev);
dma_deconfigure(dev);