wifi: iwlwifi: pcie: clean up device removal work

We shouldn't access the device if we don't hold a reference,
and if - after locking - we see that it has no bus, we also
can't do anything, in fact, pci_stop_and_remove_bus_device()
will be a no-op.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20231207044813.6c0879e695f7.I1d3ce75ecad32a4cbf1b9dad61bfb7bc7821fdd9@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2023-12-07 04:50:11 +02:00
parent 268712dc3b
commit 47b17879f9

View File

@ -2107,18 +2107,29 @@ static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
container_of(wk, struct iwl_trans_pcie_removal, work);
struct pci_dev *pdev = removal->pdev;
static char *prop[] = {"EVENT=INACCESSIBLE", NULL};
struct pci_bus *bus = pdev->bus;
struct pci_bus *bus;
pci_lock_rescan_remove();
bus = pdev->bus;
/* in this case, something else already removed the device */
if (!bus)
goto out;
dev_err(&pdev->dev, "Device gone - attempting removal\n");
kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
pci_lock_rescan_remove();
pci_dev_put(pdev);
pci_stop_and_remove_bus_device(pdev);
if (removal->rescan && bus) {
pci_dev_put(pdev);
if (removal->rescan) {
if (bus->parent)
bus = bus->parent;
pci_rescan_bus(bus);
}
out:
pci_unlock_rescan_remove();
kfree(removal);