Skip to content

Commit ff57b45

Browse files
Gavin Shanozbenh
authored andcommitted
powerpc/eeh: Do probe on pci_dn
Originally, EEH core probes on device_node or pci_dev to populate EEH devices and PEs, which conflicts with the fact: SRIOV VFs are usually enabled and created by PF's driver and they don't have the corresponding device_nodes. Instead, SRIOV VFs have dynamically created pci_dn, which can be used for EEH probe. The patch reworks EEH probe for PowerNV and pSeries platforms to do probing based on pci_dn, instead of pci_dev or device_node any more. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
1 parent e8e9b34 commit ff57b45

File tree

8 files changed

+172
-138
lines changed

8 files changed

+172
-138
lines changed

arch/powerpc/include/asm/eeh.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,7 @@ struct eeh_ops {
207207
char *name;
208208
int (*init)(void);
209209
int (*post_init)(void);
210-
void* (*of_probe)(struct device_node *dn, void *flag);
211-
int (*dev_probe)(struct pci_dev *dev, void *flag);
210+
void* (*probe)(struct pci_dn *pdn, void *data);
212211
int (*set_option)(struct eeh_pe *pe, int option);
213212
int (*get_pe_addr)(struct eeh_pe *pe);
214213
int (*get_state)(struct eeh_pe *pe, int *state);
@@ -287,8 +286,8 @@ int __exit eeh_ops_unregister(const char *name);
287286
int eeh_check_failure(const volatile void __iomem *token);
288287
int eeh_dev_check_failure(struct eeh_dev *edev);
289288
void eeh_addr_cache_build(void);
290-
void eeh_add_device_early(struct device_node *);
291-
void eeh_add_device_tree_early(struct device_node *);
289+
void eeh_add_device_early(struct pci_dn *);
290+
void eeh_add_device_tree_early(struct pci_dn *);
292291
void eeh_add_device_late(struct pci_dev *);
293292
void eeh_add_device_tree_late(struct pci_bus *);
294293
void eeh_add_sysfs_files(struct pci_bus *);
@@ -346,9 +345,9 @@ static inline int eeh_check_failure(const volatile void __iomem *token)
346345

347346
static inline void eeh_addr_cache_build(void) { }
348347

349-
static inline void eeh_add_device_early(struct device_node *dn) { }
348+
static inline void eeh_add_device_early(struct pci_dn *pdn) { }
350349

351-
static inline void eeh_add_device_tree_early(struct device_node *dn) { }
350+
static inline void eeh_add_device_tree_early(struct pci_dn *pdn) { }
352351

353352
static inline void eeh_add_device_late(struct pci_dev *dev) { }
354353

arch/powerpc/kernel/eeh.c

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ static struct notifier_block eeh_reboot_nb = {
969969
int eeh_init(void)
970970
{
971971
struct pci_controller *hose, *tmp;
972-
struct device_node *phb;
972+
struct pci_dn *pdn;
973973
static int cnt = 0;
974974
int ret = 0;
975975

@@ -1004,20 +1004,9 @@ int eeh_init(void)
10041004
return ret;
10051005

10061006
/* Enable EEH for all adapters */
1007-
if (eeh_has_flag(EEH_PROBE_MODE_DEVTREE)) {
1008-
list_for_each_entry_safe(hose, tmp,
1009-
&hose_list, list_node) {
1010-
phb = hose->dn;
1011-
traverse_pci_devices(phb, eeh_ops->of_probe, NULL);
1012-
}
1013-
} else if (eeh_has_flag(EEH_PROBE_MODE_DEV)) {
1014-
list_for_each_entry_safe(hose, tmp,
1015-
&hose_list, list_node)
1016-
pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL);
1017-
} else {
1018-
pr_warn("%s: Invalid probe mode %x",
1019-
__func__, eeh_subsystem_flags);
1020-
return -EINVAL;
1007+
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1008+
pdn = hose->pci_data;
1009+
traverse_pci_dn(pdn, eeh_ops->probe, NULL);
10211010
}
10221011

10231012
/*
@@ -1043,7 +1032,7 @@ core_initcall_sync(eeh_init);
10431032

10441033
/**
10451034
* eeh_add_device_early - Enable EEH for the indicated device_node
1046-
* @dn: device node for which to set up EEH
1035+
* @pdn: PCI device node for which to set up EEH
10471036
*
10481037
* This routine must be used to perform EEH initialization for PCI
10491038
* devices that were added after system boot (e.g. hotplug, dlpar).
@@ -1053,44 +1042,41 @@ core_initcall_sync(eeh_init);
10531042
* on the CEC architecture, type of the device, on earlier boot
10541043
* command-line arguments & etc.
10551044
*/
1056-
void eeh_add_device_early(struct device_node *dn)
1045+
void eeh_add_device_early(struct pci_dn *pdn)
10571046
{
10581047
struct pci_controller *phb;
1048+
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
10591049

1060-
/*
1061-
* If we're doing EEH probe based on PCI device, we
1062-
* would delay the probe until late stage because
1063-
* the PCI device isn't available this moment.
1064-
*/
1065-
if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))
1066-
return;
1067-
1068-
if (!of_node_to_eeh_dev(dn))
1050+
if (!edev)
10691051
return;
1070-
phb = of_node_to_eeh_dev(dn)->phb;
10711052

10721053
/* USB Bus children of PCI devices will not have BUID's */
1073-
if (NULL == phb || 0 == phb->buid)
1054+
phb = edev->phb;
1055+
if (NULL == phb ||
1056+
(eeh_has_flag(EEH_PROBE_MODE_DEVTREE) && 0 == phb->buid))
10741057
return;
10751058

1076-
eeh_ops->of_probe(dn, NULL);
1059+
eeh_ops->probe(pdn, NULL);
10771060
}
10781061

10791062
/**
10801063
* eeh_add_device_tree_early - Enable EEH for the indicated device
1081-
* @dn: device node
1064+
* @pdn: PCI device node
10821065
*
10831066
* This routine must be used to perform EEH initialization for the
10841067
* indicated PCI device that was added after system boot (e.g.
10851068
* hotplug, dlpar).
10861069
*/
1087-
void eeh_add_device_tree_early(struct device_node *dn)
1070+
void eeh_add_device_tree_early(struct pci_dn *pdn)
10881071
{
1089-
struct device_node *sib;
1072+
struct pci_dn *n;
1073+
1074+
if (!pdn)
1075+
return;
10901076

1091-
for_each_child_of_node(dn, sib)
1092-
eeh_add_device_tree_early(sib);
1093-
eeh_add_device_early(dn);
1077+
list_for_each_entry(n, &pdn->child_list, list)
1078+
eeh_add_device_tree_early(n);
1079+
eeh_add_device_early(pdn);
10941080
}
10951081
EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
10961082

@@ -1144,13 +1130,6 @@ void eeh_add_device_late(struct pci_dev *dev)
11441130
edev->pdev = dev;
11451131
dev->dev.archdata.edev = edev;
11461132

1147-
/*
1148-
* We have to do the EEH probe here because the PCI device
1149-
* hasn't been created yet in the early stage.
1150-
*/
1151-
if (eeh_has_flag(EEH_PROBE_MODE_DEV))
1152-
eeh_ops->dev_probe(dev, NULL);
1153-
11541133
eeh_addr_cache_insert_dev(dev);
11551134
}
11561135

arch/powerpc/kernel/of_platform.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static int of_pci_phb_probe(struct platform_device *dev)
7272

7373
/* Register devices with EEH */
7474
if (dev->dev.of_node->child)
75-
eeh_add_device_tree_early(dev->dev.of_node);
75+
eeh_add_device_tree_early(PCI_DN(dev->dev.of_node));
7676

7777
/* Scan the bus */
7878
pcibios_scan_phb(phb);

arch/powerpc/kernel/pci-hotplug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
7575
struct pci_dev *dev;
7676
struct device_node *dn = pci_bus_to_OF_node(bus);
7777

78-
eeh_add_device_tree_early(dn);
78+
eeh_add_device_tree_early(PCI_DN(dn));
7979

8080
mode = PCI_PROBE_NORMAL;
8181
if (ppc_md.pci_probe_mode)

arch/powerpc/platforms/powernv/eeh-powernv.c

Lines changed: 111 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,82 @@ static int pnv_eeh_post_init(void)
286286
return ret;
287287
}
288288

289+
static int pnv_eeh_cap_start(struct pci_dn *pdn)
290+
{
291+
u32 status;
292+
293+
if (!pdn)
294+
return 0;
295+
296+
pnv_pci_cfg_read(pdn, PCI_STATUS, 2, &status);
297+
if (!(status & PCI_STATUS_CAP_LIST))
298+
return 0;
299+
300+
return PCI_CAPABILITY_LIST;
301+
}
302+
303+
static int pnv_eeh_find_cap(struct pci_dn *pdn, int cap)
304+
{
305+
int pos = pnv_eeh_cap_start(pdn);
306+
int cnt = 48; /* Maximal number of capabilities */
307+
u32 id;
308+
309+
if (!pos)
310+
return 0;
311+
312+
while (cnt--) {
313+
pnv_pci_cfg_read(pdn, pos, 1, &pos);
314+
if (pos < 0x40)
315+
break;
316+
317+
pos &= ~3;
318+
pnv_pci_cfg_read(pdn, pos + PCI_CAP_LIST_ID, 1, &id);
319+
if (id == 0xff)
320+
break;
321+
322+
/* Found */
323+
if (id == cap)
324+
return pos;
325+
326+
/* Next one */
327+
pos += PCI_CAP_LIST_NEXT;
328+
}
329+
330+
return 0;
331+
}
332+
333+
static int pnv_eeh_find_ecap(struct pci_dn *pdn, int cap)
334+
{
335+
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
336+
u32 header;
337+
int pos = 256, ttl = (4096 - 256) / 8;
338+
339+
if (!edev || !edev->pcie_cap)
340+
return 0;
341+
if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
342+
return 0;
343+
else if (!header)
344+
return 0;
345+
346+
while (ttl-- > 0) {
347+
if (PCI_EXT_CAP_ID(header) == cap && pos)
348+
return pos;
349+
350+
pos = PCI_EXT_CAP_NEXT(header);
351+
if (pos < 256)
352+
break;
353+
354+
if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
355+
break;
356+
}
357+
358+
return 0;
359+
}
360+
289361
/**
290-
* pnv_eeh_dev_probe - Do probe on PCI device
291-
* @dev: PCI device
292-
* @flag: unused
362+
* pnv_eeh_probe - Do probe on PCI device
363+
* @pdn: PCI device node
364+
* @data: unused
293365
*
294366
* When EEH module is installed during system boot, all PCI devices
295367
* are checked one by one to see if it supports EEH. The function
@@ -303,12 +375,12 @@ static int pnv_eeh_post_init(void)
303375
* was possiblly triggered by EEH core, the binding between EEH device
304376
* and the PCI device isn't built yet.
305377
*/
306-
static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
378+
static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
307379
{
308-
struct pci_controller *hose = pci_bus_to_host(dev->bus);
380+
struct pci_controller *hose = pdn->phb;
309381
struct pnv_phb *phb = hose->private_data;
310-
struct device_node *dn = pci_device_to_OF_node(dev);
311-
struct eeh_dev *edev = of_node_to_eeh_dev(dn);
382+
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
383+
uint32_t pcie_flags;
312384
int ret;
313385

314386
/*
@@ -317,40 +389,42 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
317389
* the root bridge. So it's not reasonable to continue
318390
* the probing.
319391
*/
320-
if (!dn || !edev || edev->pe)
321-
return 0;
392+
if (!edev || edev->pe)
393+
return NULL;
322394

323395
/* Skip for PCI-ISA bridge */
324-
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
325-
return 0;
396+
if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA)
397+
return NULL;
326398

327399
/* Initialize eeh device */
328-
edev->class_code = dev->class;
400+
edev->class_code = pdn->class_code;
329401
edev->mode &= 0xFFFFFF00;
330-
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
402+
edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
403+
edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
404+
edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
405+
if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
331406
edev->mode |= EEH_DEV_BRIDGE;
332-
edev->pcix_cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
333-
if (pci_is_pcie(dev)) {
334-
edev->pcie_cap = pci_pcie_cap(dev);
335-
336-
if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
337-
edev->mode |= EEH_DEV_ROOT_PORT;
338-
else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)
339-
edev->mode |= EEH_DEV_DS_PORT;
340-
341-
edev->aer_cap = pci_find_ext_capability(dev,
342-
PCI_EXT_CAP_ID_ERR);
407+
if (edev->pcie_cap) {
408+
pnv_pci_cfg_read(pdn, edev->pcie_cap + PCI_EXP_FLAGS,
409+
2, &pcie_flags);
410+
pcie_flags = (pcie_flags & PCI_EXP_FLAGS_TYPE) >> 4;
411+
if (pcie_flags == PCI_EXP_TYPE_ROOT_PORT)
412+
edev->mode |= EEH_DEV_ROOT_PORT;
413+
else if (pcie_flags == PCI_EXP_TYPE_DOWNSTREAM)
414+
edev->mode |= EEH_DEV_DS_PORT;
415+
}
343416
}
344417

345-
edev->config_addr = ((dev->bus->number << 8) | dev->devfn);
346-
edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff);
418+
edev->config_addr = (pdn->busno << 8) | (pdn->devfn);
419+
edev->pe_config_addr = phb->ioda.pe_rmap[edev->config_addr];
347420

348421
/* Create PE */
349422
ret = eeh_add_to_parent_pe(edev);
350423
if (ret) {
351-
pr_warn("%s: Can't add PCI dev %s to parent PE (%d)\n",
352-
__func__, pci_name(dev), ret);
353-
return ret;
424+
pr_warn("%s: Can't add PCI dev %04x:%02x:%02x.%01x to parent PE (%d)\n",
425+
__func__, hose->global_number, pdn->busno,
426+
PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn), ret);
427+
return NULL;
354428
}
355429

356430
/*
@@ -369,8 +443,10 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
369443
* Broadcom Austin 4-ports NICs (14e4:1657)
370444
* Broadcom Shiner 2-ports 10G NICs (14e4:168e)
371445
*/
372-
if ((dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x1657) ||
373-
(dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x168e))
446+
if ((pdn->vendor_id == PCI_VENDOR_ID_BROADCOM &&
447+
pdn->device_id == 0x1657) ||
448+
(pdn->vendor_id == PCI_VENDOR_ID_BROADCOM &&
449+
pdn->device_id == 0x168e))
374450
edev->pe->state |= EEH_PE_CFG_RESTRICTED;
375451

376452
/*
@@ -380,7 +456,8 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
380456
* to PE reset.
381457
*/
382458
if (!edev->pe->bus)
383-
edev->pe->bus = dev->bus;
459+
edev->pe->bus = pci_find_bus(hose->global_number,
460+
pdn->busno);
384461

385462
/*
386463
* Enable EEH explicitly so that we will do EEH check
@@ -391,7 +468,7 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
391468
/* Save memory bars */
392469
eeh_save_bars(edev);
393470

394-
return 0;
471+
return NULL;
395472
}
396473

397474
/**
@@ -1432,8 +1509,7 @@ static struct eeh_ops pnv_eeh_ops = {
14321509
.name = "powernv",
14331510
.init = pnv_eeh_init,
14341511
.post_init = pnv_eeh_post_init,
1435-
.of_probe = NULL,
1436-
.dev_probe = pnv_eeh_dev_probe,
1512+
.probe = pnv_eeh_probe,
14371513
.set_option = pnv_eeh_set_option,
14381514
.get_pe_addr = pnv_eeh_get_pe_addr,
14391515
.get_state = pnv_eeh_get_state,

0 commit comments

Comments
 (0)