Skip to content

Commit dcd1245

Browse files
committed
Merge branch 'pci/hotplug'
- Remove unused cpcihp struct cpci_hp_controller_ops.hardware_test (Guilherme Giacomo Simoes) - Remove unused cpqphp struct ctrl_dbg.ctrl (Christophe JAILLET) - Clean up cpqphp PCIBIOS_* return value confusion (Ilpo Järvinen) - Use pci_bus_read_dev_vendor_id() instead of hand-coded presence detection in cpqphp (Ilpo Järvinen) - Simplify cpqphp enumeration, which is already simple-minded and doesn't handle devices below hot-added bridges (Ilpo Järvinen) - Retain a reference to the pci_bus for the lifetime of a pci_slot to avoid a use-after-free when the thunderbolt driver resets USB4 host routers on boot, causing hotplug remove/add of downstream docks or other devices (Lukas Wunner) * pci/hotplug: PCI: Fix use-after-free of slot->bus on hot remove PCI: cpqphp: Simplify PCI_ScanBusForNonBridge() PCI: cpqphp: Use define to read class/revision dword PCI: cpqphp: Use pci_bus_read_dev_vendor_id() to detect presence PCI: cpqphp: Fix PCIBIOS_* return value confusion PCI: cpqphp: Remove unused struct ctrl_dbg.ctrl PCI: cpcihp: Remove unused struct cpci_hp_controller_ops.hardware_test
2 parents 77ac2e2 + c7acef9 commit dcd1245

File tree

4 files changed

+22
-31
lines changed

4 files changed

+22
-31
lines changed

drivers/pci/hotplug/cpci_hotplug.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ struct cpci_hp_controller_ops {
4444
int (*enable_irq)(void);
4545
int (*disable_irq)(void);
4646
int (*check_irq)(void *dev_id);
47-
int (*hardware_test)(struct slot *slot, u32 value);
4847
u8 (*get_power)(struct slot *slot);
4948
int (*set_power)(struct slot *slot, int value);
5049
};

drivers/pci/hotplug/cpqphp_pci.c

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
*
1313
*/
1414

15+
#define pr_fmt(fmt) "cpqphp: " fmt
16+
1517
#include <linux/module.h>
1618
#include <linux/kernel.h>
19+
#include <linux/printk.h>
1720
#include <linux/types.h>
1821
#include <linux/slab.h>
1922
#include <linux/workqueue.h>
@@ -132,18 +135,6 @@ int cpqhp_unconfigure_device(struct pci_func *func)
132135
return 0;
133136
}
134137

135-
static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
136-
{
137-
u32 vendID = 0;
138-
139-
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
140-
return -1;
141-
if (PCI_POSSIBLE_ERROR(vendID))
142-
return -1;
143-
return pci_bus_read_config_dword(bus, devfn, offset, value);
144-
}
145-
146-
147138
/*
148139
* cpqhp_set_irq
149140
*
@@ -202,37 +193,37 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_
202193
{
203194
u16 tdevice;
204195
u32 work;
205-
u8 tbus;
196+
int ret = -1;
206197

207198
ctrl->pci_bus->number = bus_num;
208199

209200
for (tdevice = 0; tdevice < 0xFF; tdevice++) {
210201
/* Scan for access first */
211-
if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
202+
if (!pci_bus_read_dev_vendor_id(ctrl->pci_bus, tdevice, &work, 0))
203+
continue;
204+
ret = pci_bus_read_config_dword(ctrl->pci_bus, tdevice, PCI_CLASS_REVISION, &work);
205+
if (ret)
212206
continue;
213207
dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
214208
/* Yep we got one. Not a bridge ? */
215209
if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
216210
*dev_num = tdevice;
217211
dbg("found it !\n");
218212
return 0;
219-
}
220-
}
221-
for (tdevice = 0; tdevice < 0xFF; tdevice++) {
222-
/* Scan for access first */
223-
if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
224-
continue;
225-
dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
226-
/* Yep we got one. bridge ? */
227-
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
228-
pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
229-
/* XXX: no recursion, wtf? */
230-
dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
231-
return 0;
213+
} else {
214+
/*
215+
* XXX: Code whose debug printout indicated
216+
* recursion to buses underneath bridges might be
217+
* necessary was removed because it never did
218+
* any recursion.
219+
*/
220+
ret = 0;
221+
pr_warn("missing feature: bridge scan recursion not implemented\n");
232222
}
233223
}
234224

235-
return -1;
225+
226+
return ret;
236227
}
237228

238229

drivers/pci/hotplug/cpqphp_sysfs.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ static int spew_debug_info(struct controller *ctrl, char *data, int size)
123123
struct ctrl_dbg {
124124
int size;
125125
char *data;
126-
struct controller *ctrl;
127126
};
128127

129128
#define MAX_OUTPUT (4*PAGE_SIZE)

drivers/pci/slot.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static void pci_slot_release(struct kobject *kobj)
7979
up_read(&pci_bus_sem);
8080

8181
list_del(&slot->list);
82+
pci_bus_put(slot->bus);
8283

8384
kfree(slot);
8485
}
@@ -261,14 +262,15 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
261262
goto err;
262263
}
263264

264-
slot->bus = parent;
265+
slot->bus = pci_bus_get(parent);
265266
slot->number = slot_nr;
266267

267268
slot->kobj.kset = pci_slots_kset;
268269

269270
slot_name = make_slot_name(name);
270271
if (!slot_name) {
271272
err = -ENOMEM;
273+
pci_bus_put(slot->bus);
272274
kfree(slot);
273275
goto err;
274276
}

0 commit comments

Comments
 (0)