Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159340602
D57431.id179188.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D57431.id179188.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
@@ -31,10 +31,10 @@
/*
* We have two ways to create a pci_dev (pdev):
* (1) coming from the device_attach DEVMETHOD, and
- * (2) the other from manual creation via lkpinew_pci_dev().
+ * (2) from manual creation via lkpinew_pci_dev(), in which case
+ * we have no driver (pdev->pdrv).
*
* Only devices from (1) end up on our LinuxKPI global pci_devices list.
- * All others are "place fillers" -- XXX if only "place filler" was always true.
*/
#include <sys/param.h>
@@ -109,7 +109,6 @@
static int linux_backlight_update_status(device_t dev, struct backlight_props *props);
static int linux_backlight_get_info(device_t dev, struct backlight_info *info);
static void lkpi_pcim_iomap_table_release(struct device *, void *);
-static void lkpinew_pci_dev_release(struct device *);
static device_method_t pci_methods[] = {
DEVMETHOD(device_probe, linux_pci_probe),
@@ -342,52 +341,33 @@
return (found);
}
+/*
+ * Shared function releasing the bus resources which can be built independent
+ * of the way we allocate/initialization the pdev [pci_upstream_bridge(),
+ * pcie_find_root_port()].
+ */
static void
-lkpi_pci_dev_release(struct device *dev)
+lkpi_pci_dev_bus_release(struct pci_dev *pdev)
{
- struct pci_dev *pdev;
-
- /*
- * The very first we have to free all the dynamic
- * resource which are on the devres list.
- * Otherwise we risk that supporting infrastructure
- * is gone and we panic 'randomly'.
- */
- lkpi_devres_release_free_list(dev);
-
- /*
- * Now undo linux_pci_attach_device() in reverse-ish
- * order.
- */
- pdev = to_pci_dev(dev);
-
- /*
- * pdrv->remove happens before pci_put_dev() in
- * linux_pci_detach_device(), which means the driver should have
- * cleaned up before we get here; see irqents and mmio below.
- */
-
- /* Clear the hierarchy recursively to root. */
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); ? */
+ pci_dev_put(pdev->root);
pdev->root = NULL;
}
+}
- spin_lock(&pci_lock);
- list_del(&pdev->links);
- spin_unlock(&pci_lock);
-
- linux_pdev_dma_uninit(pdev);
+/* Release resources acquired by lkpifill_pci_dev(). */
+static void
+lkpi_pci_dev_fill_release(struct device *dev)
+{
+ struct pci_dev *pdev;
- /* irq? */
+ pdev = to_pci_dev(dev);
- /* Undo lkpifill_pci_dev(). */
- /* devres is gone already; went at the very top. */
if (!list_empty_careful(&pdev->dev.irqents)) {
dev_warn(&pdev->dev, "%s: driver did not clean up; "
"leaking IRQs\n", __func__);
@@ -414,6 +394,47 @@
free(pdev->bus, M_DEVBUF);
kfree(pdev->path_name);
+}
+
+static void
+lkpi_pci_dev_release(struct device *dev)
+{
+ struct pci_dev *pdev;
+
+ /*
+ * The very first we have to free all the dynamic
+ * resource which are on the devres list.
+ * Otherwise we risk that supporting infrastructure
+ * is gone and we panic 'randomly'.
+ */
+ lkpi_devres_release_free_list(dev);
+
+ /*
+ * Now undo linux_pci_attach_device() in reverse-ish
+ * order.
+ */
+ pdev = to_pci_dev(dev);
+
+ /*
+ * pdrv->remove happens before pci_put_dev() in
+ * linux_pci_detach_device(), which means the driver should have
+ * cleaned up before we get here; see irqents and mmio below.
+ */
+
+ /* Clear the hierarchy recursively to root. */
+ lkpi_pci_dev_bus_release(pdev);
+
+ spin_lock(&pci_lock);
+ list_del(&pdev->links);
+ spin_unlock(&pci_lock);
+
+ linux_pdev_dma_uninit(pdev);
+
+ /* irq? */
+
+ /* Undo lkpifill_pci_dev(). */
+ /* devres is gone already; went at the very top. */
+ lkpi_pci_dev_fill_release(dev);
/*
* Very last do an internal hack in order to signal
@@ -482,24 +503,22 @@
return (0);
}
+/*
+ * This is the .release function called when the kobj reference drops to 0.
+ * There should be no direct calls of this.
+ */
static void
lkpinew_pci_dev_release(struct device *dev)
{
struct pci_dev *pdev;
- int i;
pdev = to_pci_dev(dev);
- if (pdev->root != NULL)
- pci_dev_put(pdev->root);
- if (pdev->bus->self != pdev && pdev->bus->self != NULL)
- pci_dev_put(pdev->bus->self);
- free(pdev->bus, M_DEVBUF);
- if (pdev->msi_desc != NULL) {
- for (i = pci_msi_count(pdev->dev.bsddev) - 1; i >= 0; i--)
- free(pdev->msi_desc[i], M_DEVBUF);
- free(pdev->msi_desc, M_DEVBUF);
- }
- kfree(pdev->path_name);
+
+ /* The root/bus structure could be built up w/o us having asked for it. */
+ lkpi_pci_dev_bus_release(pdev);
+ /* Cleanup the lkpifill_pci_dev() resources. */
+ lkpi_pci_dev_fill_release(dev);
+
free(pdev, M_DEVBUF);
}
@@ -744,7 +763,7 @@
pdev->bus->self = NULL;
}
if (pdev->root != NULL) {
- lkpinew_pci_dev_release(&pdev->root->dev); /* pci_dev_put(pdev->root); ? */
+ pci_dev_put(pdev->root);
pdev->root = NULL;
}
err_list_add:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jun 14, 1:19 AM (19 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33749613
Default Alt Text
D57431.id179188.diff (4 KB)
Attached To
Mode
D57431: LinuxKPI: pci: cleanup lkpinew_pci_dev_release()
Attached
Detach File
Event Timeline
Log In to Comment