mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
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: 2dbce59011
("PCI: Assign bus numbers present in EA capability for bridges")
Link: https://lore.kernel.org/r/1572850664-9861-1-git-send-email-sundeep.lkml@gmail.com
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org # v5.2+
This commit is contained in:
parent
c13704f568
commit
73884a7082
@ -1090,14 +1090,15 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
|
||||
* @sec: updated with secondary bus number from EA
|
||||
* @sub: updated with subordinate bus number from EA
|
||||
*
|
||||
* If @dev is a bridge with EA capability, update @sec and @sub with
|
||||
* fixed bus numbers from the capability and return true. Otherwise,
|
||||
* return false.
|
||||
* If @dev is a bridge with EA capability that specifies valid secondary
|
||||
* and subordinate bus numbers, return true with the bus numbers in @sec
|
||||
* and @sub. Otherwise return false.
|
||||
*/
|
||||
static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub)
|
||||
{
|
||||
int ea, offset;
|
||||
u32 dw;
|
||||
u8 ea_sec, ea_sub;
|
||||
|
||||
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
|
||||
return false;
|
||||
@ -1109,8 +1110,13 @@ static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub)
|
||||
|
||||
offset = ea + PCI_EA_FIRST_ENT;
|
||||
pci_read_config_dword(dev, offset, &dw);
|
||||
*sec = dw & PCI_EA_SEC_BUS_MASK;
|
||||
*sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT;
|
||||
ea_sec = dw & PCI_EA_SEC_BUS_MASK;
|
||||
ea_sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT;
|
||||
if (ea_sec == 0 || ea_sub < ea_sec)
|
||||
return false;
|
||||
|
||||
*sec = ea_sec;
|
||||
*sub = ea_sub;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user