From 01464a3fdf91c041a381d93a1b6fefbdb819a46f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 2 Dec 2025 16:13:49 +0100 Subject: PCI/portdrv: Fix potential resource leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pcie_port_probe_service() unconditionally calls get_device() (unless it fails). So drop that reference also unconditionally as it's fine for a PCIe driver to not have a remove callback. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Uwe Kleine-König Signed-off-by: Bjorn Helgaas Reviewed-by: Ilpo Järvinen Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/e1c68c3b3f1af8427e98ca5e2c79f8bf0ebe2ce4.1764688034.git.u.kleine-koenig@baylibre.com --- drivers/pci/pcie/portdrv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 38a41ccf79b9..a0991da48213 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -557,10 +557,10 @@ static int pcie_port_remove_service(struct device *dev) pciedev = to_pcie_device(dev); driver = to_service_driver(dev->driver); - if (driver && driver->remove) { + if (driver && driver->remove) driver->remove(pciedev); - put_device(dev); - } + + put_device(dev); return 0; } -- cgit v1.2.3 From 15fff3b799ffa38970c6d58dc8dd0aaf3317fab7 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 2 Dec 2025 16:13:50 +0100 Subject: PCI/portdrv: Drop empty shutdown callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .shutdown() is an optional callback and the core only calls it if the pointer in struct device_driver is non-NULL. So make nothing in a bit shorter time and remove the empty function. Signed-off-by: Uwe Kleine-König Signed-off-by: Uwe Kleine-König Signed-off-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron Reviewed-by: Ilpo Järvinen Link: https://patch.msgid.link/283fef06ac51efbb7df25f347d6f3a2967f96429.1764688034.git.u.kleine-koenig@baylibre.com --- drivers/pci/pcie/portdrv.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index a0991da48213..348d90315570 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -564,17 +564,6 @@ static int pcie_port_remove_service(struct device *dev) return 0; } -/** - * pcie_port_shutdown_service - shut down given PCI Express port service - * @dev: PCI Express port service device to handle - * - * If PCI Express port service driver is registered with - * pcie_port_service_register(), this function will be called by the driver core - * when device_shutdown() is called for the port service device associated - * with the driver. - */ -static void pcie_port_shutdown_service(struct device *dev) {} - /** * pcie_port_service_register - register PCI Express port service driver * @new: PCI Express port service driver to register @@ -588,7 +577,6 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) new->driver.bus = &pcie_port_bus_type; new->driver.probe = pcie_port_probe_service; new->driver.remove = pcie_port_remove_service; - new->driver.shutdown = pcie_port_shutdown_service; return driver_register(&new->driver); } -- cgit v1.2.3 From 0c1594df40a00a1e3ce8d4ce8c17838de1ec29f2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 2 Dec 2025 16:13:51 +0100 Subject: PCI/portdrv: Don't check for the driver's and device's bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ensures that the match function is only called for drivers and devices of the right bus. So drop the useless check. Signed-off-by: Uwe Kleine-König Signed-off-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/09ca261912a37d2b253f43359a5dfeec42c016dc.1764688034.git.u.kleine-koenig@baylibre.com --- drivers/pci/pci-driver.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 7c2d9d596258..e6ccaf0a762f 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1704,14 +1704,8 @@ EXPORT_SYMBOL(pci_bus_type); #ifdef CONFIG_PCIEPORTBUS static int pcie_port_bus_match(struct device *dev, const struct device_driver *drv) { - struct pcie_device *pciedev; - const struct pcie_port_service_driver *driver; - - if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) - return 0; - - pciedev = to_pcie_device(dev); - driver = to_service_driver(drv); + struct pcie_device *pciedev = to_pcie_device(dev); + const struct pcie_port_service_driver *driver = to_service_driver(drv); if (driver->service != pciedev->service) return 0; -- cgit v1.2.3 From 61df4929a74bfd4aed712d09b681378b470b6224 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 2 Dec 2025 16:13:52 +0100 Subject: PCI/portdrv: Move pcie_port_bus_type to pcie source file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conceptually the pci_express bus doesn't belong in generic PCI code. Move pcie_port_bus_match() and pcie_port_bus_type to pcie/portdrv.c. Signed-off-by: Uwe Kleine-König Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/420d771f0091dea7cf18f445b94301576dcee4c8.1764688034.git.u.kleine-koenig@baylibre.com --- drivers/pci/pci-driver.c | 22 ---------------------- drivers/pci/pcie/portdrv.c | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e6ccaf0a762f..2cc4e9e6f5ef 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1701,28 +1701,6 @@ const struct bus_type pci_bus_type = { }; EXPORT_SYMBOL(pci_bus_type); -#ifdef CONFIG_PCIEPORTBUS -static int pcie_port_bus_match(struct device *dev, const struct device_driver *drv) -{ - struct pcie_device *pciedev = to_pcie_device(dev); - const struct pcie_port_service_driver *driver = to_service_driver(drv); - - if (driver->service != pciedev->service) - return 0; - - if (driver->port_type != PCIE_ANY_PORT && - driver->port_type != pci_pcie_type(pciedev->port)) - return 0; - - return 1; -} - -const struct bus_type pcie_port_bus_type = { - .name = "pci_express", - .match = pcie_port_bus_match, -}; -#endif - static int __init pci_driver_init(void) { int ret; diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 348d90315570..0127e3dc768f 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -508,6 +508,21 @@ static void pcie_port_device_remove(struct pci_dev *dev) pci_free_irq_vectors(dev); } +static int pcie_port_bus_match(struct device *dev, const struct device_driver *drv) +{ + struct pcie_device *pciedev = to_pcie_device(dev); + const struct pcie_port_service_driver *driver = to_service_driver(drv); + + if (driver->service != pciedev->service) + return 0; + + if (driver->port_type != PCIE_ANY_PORT && + driver->port_type != pci_pcie_type(pciedev->port)) + return 0; + + return 1; +} + /** * pcie_port_probe_service - probe driver for given PCI Express port service * @dev: PCI Express port service device to probe against @@ -564,6 +579,11 @@ static int pcie_port_remove_service(struct device *dev) return 0; } +const struct bus_type pcie_port_bus_type = { + .name = "pci_express", + .match = pcie_port_bus_match, +}; + /** * pcie_port_service_register - register PCI Express port service driver * @new: PCI Express port service driver to register -- cgit v1.2.3 From 9d29a9c06f3e88e47ae43a26b61eebe7372dbee3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 2 Dec 2025 16:13:53 +0100 Subject: PCI/portdrv: Don't check for valid device and driver in bus callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ensures that in .probe() and .remove() both dev and dev->driver are valid. So drop the respective check. Signed-off-by: Uwe Kleine-König Signed-off-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/2cc2e15e05318b9f0d7b6a2b69b3169d2a6f0bd3.1764688034.git.u.kleine-koenig@baylibre.com --- drivers/pci/pcie/portdrv.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 0127e3dc768f..7bd48c5da133 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -537,9 +537,6 @@ static int pcie_port_probe_service(struct device *dev) struct pcie_port_service_driver *driver; int status; - if (!dev || !dev->driver) - return -ENODEV; - driver = to_service_driver(dev->driver); if (!driver || !driver->probe) return -ENODEV; @@ -567,9 +564,6 @@ static int pcie_port_remove_service(struct device *dev) struct pcie_device *pciedev; struct pcie_port_service_driver *driver; - if (!dev || !dev->driver) - return 0; - pciedev = to_pcie_device(dev); driver = to_service_driver(dev->driver); if (driver && driver->remove) -- cgit v1.2.3 From cba202aa355d2c6297d55c9d5dacceae01266b9c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 2 Dec 2025 16:13:54 +0100 Subject: PCI/portdrv: Use bus-type functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of assigning the probe function for each driver individually, use .probe() and .remove() from the pci_express bus. Rename the functions for consistency. Signed-off-by: Uwe Kleine-König Signed-off-by: Bjorn Helgaas Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/83d1edc7d619423331fa6802f0e7da3919a308a9.1764688034.git.u.kleine-koenig@baylibre.com --- drivers/pci/pcie/portdrv.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 7bd48c5da133..88af0dacf351 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -524,14 +524,14 @@ static int pcie_port_bus_match(struct device *dev, const struct device_driver *d } /** - * pcie_port_probe_service - probe driver for given PCI Express port service + * pcie_port_bus_probe - probe driver for given PCI Express port service * @dev: PCI Express port service device to probe against * * If PCI Express port service driver is registered with * pcie_port_service_register(), this function will be called by the driver core * whenever match is found between the driver and a port service device. */ -static int pcie_port_probe_service(struct device *dev) +static int pcie_port_bus_probe(struct device *dev) { struct pcie_device *pciedev; struct pcie_port_service_driver *driver; @@ -551,7 +551,7 @@ static int pcie_port_probe_service(struct device *dev) } /** - * pcie_port_remove_service - detach driver from given PCI Express port service + * pcie_port_bus_remove - detach driver from given PCI Express port service * @dev: PCI Express port service device to handle * * If PCI Express port service driver is registered with @@ -559,7 +559,7 @@ static int pcie_port_probe_service(struct device *dev) * when device_unregister() is called for the port service device associated * with the driver. */ -static int pcie_port_remove_service(struct device *dev) +static void pcie_port_bus_remove(struct device *dev) { struct pcie_device *pciedev; struct pcie_port_service_driver *driver; @@ -570,12 +570,13 @@ static int pcie_port_remove_service(struct device *dev) driver->remove(pciedev); put_device(dev); - return 0; } const struct bus_type pcie_port_bus_type = { .name = "pci_express", .match = pcie_port_bus_match, + .probe = pcie_port_bus_probe, + .remove = pcie_port_bus_remove, }; /** @@ -589,8 +590,6 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) new->driver.name = new->name; new->driver.bus = &pcie_port_bus_type; - new->driver.probe = pcie_port_probe_service; - new->driver.remove = pcie_port_remove_service; return driver_register(&new->driver); } -- cgit v1.2.3