Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167374777
D57430.id180254.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D57430.id180254.diff
View Options
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -613,7 +613,7 @@
pdev->irq = pdev->dev.irq;
error = linux_pdev_dma_init(pdev);
if (error)
- goto out_dma_init;
+ goto err_dma_init;
spin_lock(&pci_lock);
list_add(&pdev->links, &pci_devices);
@@ -628,7 +628,7 @@
pbus = lkpinew_pci_dev(parent);
if (pbus == NULL) {
error = ENXIO;
- goto out_dma_init;
+ goto err_list_add;
}
}
pcie_find_root_port(pbus);
@@ -643,20 +643,52 @@
if (pdrv != NULL) {
error = pdrv->probe(pdev, id);
if (error)
- goto out_probe;
+ goto err_probe;
}
return (0);
-/* XXX the cleanup does not match the allocation up there. */
-out_probe:
- free(pdev->bus, M_DEVBUF);
- spin_lock_destroy(&pdev->pcie_cap_lock);
- linux_pdev_dma_uninit(pdev);
-out_dma_init:
+err_probe:
+ /*
+ * If we get here we know that lkpifill_pci_dev() succeeded.
+ * That means we have a ref on the dev and a release function set.
+ * We also know the driver probe failed, which means no resources should
+ * be allocated by the driver (unless the driver did not cleanup).
+ * That means we could simply call pci_dev_put(pdev) and let the release
+ * function do its job. For now do it manually until some other parts
+ * are sorted first.
+ */
+ if (pdev->bus->self != pdev) {
+ pci_dev_put(pdev->bus->self);
+ pdev->bus->self = NULL;
+ }
+ if (pdev->root != NULL) {
+ lkpinew_pci_dev_release(&pdev->root->dev); /* pci_dev_put(pdev->root); ? */
+ pdev->root = NULL;
+ }
+err_list_add:
spin_lock(&pci_lock);
list_del(&pdev->links);
spin_unlock(&pci_lock);
- put_device(&pdev->dev);
+ linux_pdev_dma_uninit(pdev);
+err_dma_init:
+ /*
+ * Undo lkpifill_pci_dev(); we can ignore some bits like
+ * lists/tailq/devres as they are not filled yet.
+ */
+ spin_lock_destroy(&pdev->dev.devres_lock);
+ spin_lock_destroy(&pdev->pcie_cap_lock);
+ if (pdev->msi_desc != NULL) {
+ for (int i = pci_msi_count(pdev->dev.bsddev) - 1; i >= 0; i--)
+ free(pdev->msi_desc[i], M_DEVBUF);
+ free(pdev->msi_desc, M_DEVBUF);
+ }
+ free(pdev->bus, M_DEVBUF);
+ kfree(pdev->path_name);
+
+ /* Bandaid, just to be sure. */
+ pdev->dev.release = NULL;
+ kobject_put(&pdev->dev.kobj);
+
return (-error);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 22, 11:06 AM (14 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34212644
Default Alt Text
D57430.id180254.diff (2 KB)
Attached To
Mode
D57430: LinuxKPI: pci: cleanup the error path in linux_pci_attach_device()
Attached
Detach File
Event Timeline
Log In to Comment