Skip to content

Commit 73884a7

Browse files
Subbaraya Sundeepbjorn-helgaas
authored andcommitted
PCI: Do not use bus number zero from EA capability
As per PCIe r5.0, sec 7.8.5.2, fixed bus numbers of a bridge must be zero when no function that uses EA is located behind it. Hence, if EA supplies bus numbers of zero, assign bus numbers normally. A secondary bus can never have a bus number of zero, so setting a bridge's Secondary Bus Number to zero makes downstream devices unreachable. [bhelgaas: retain bool return value so "zero is invalid" logic is local] Fixes: 2dbce59 ("PCI: Assign bus numbers present in EA capability for bridges") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Subbaraya Sundeep <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Cc: [email protected] # v5.2+
1 parent c13704f commit 73884a7

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

drivers/pci/probe.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,14 +1090,15 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
10901090
* @sec: updated with secondary bus number from EA
10911091
* @sub: updated with subordinate bus number from EA
10921092
*
1093-
* If @dev is a bridge with EA capability, update @sec and @sub with
1094-
* fixed bus numbers from the capability and return true. Otherwise,
1095-
* return false.
1093+
* If @dev is a bridge with EA capability that specifies valid secondary
1094+
* and subordinate bus numbers, return true with the bus numbers in @sec
1095+
* and @sub. Otherwise return false.
10961096
*/
10971097
static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub)
10981098
{
10991099
int ea, offset;
11001100
u32 dw;
1101+
u8 ea_sec, ea_sub;
11011102

11021103
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
11031104
return false;
@@ -1109,8 +1110,13 @@ static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub)
11091110

11101111
offset = ea + PCI_EA_FIRST_ENT;
11111112
pci_read_config_dword(dev, offset, &dw);
1112-
*sec = dw & PCI_EA_SEC_BUS_MASK;
1113-
*sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT;
1113+
ea_sec = dw & PCI_EA_SEC_BUS_MASK;
1114+
ea_sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT;
1115+
if (ea_sec == 0 || ea_sub < ea_sec)
1116+
return false;
1117+
1118+
*sec = ea_sec;
1119+
*sub = ea_sub;
11141120
return true;
11151121
}
11161122

0 commit comments

Comments
 (0)