pci_find_cap_method(): limit number of iterations for finding a capability
Powered down device might return 0xff of extended config registers reads, causing loop. PR: 283815 Reviewed by: imp Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D48348
This commit is contained in:
+5
-2
@@ -1519,6 +1519,7 @@ pci_find_cap_method(device_t dev, device_t child, int capability,
|
||||
pcicfgregs *cfg = &dinfo->cfg;
|
||||
uint32_t status;
|
||||
uint8_t ptr;
|
||||
int cnt;
|
||||
|
||||
/*
|
||||
* Check the CAP_LIST bit of the PCI status register first.
|
||||
@@ -1545,9 +1546,11 @@ pci_find_cap_method(device_t dev, device_t child, int capability,
|
||||
ptr = pci_read_config(child, ptr, 1);
|
||||
|
||||
/*
|
||||
* Traverse the capabilities list.
|
||||
* Traverse the capabilities list. Limit by total theoretical
|
||||
* maximum number of caps: capability needs at least id and
|
||||
* next registers, and any type X header cannot contain caps.
|
||||
*/
|
||||
while (ptr != 0) {
|
||||
for (cnt = 0; ptr != 0 && cnt < (PCIE_REGMAX - 0x40) / 2; cnt++) {
|
||||
if (pci_read_config(child, ptr + PCICAP_ID, 1) == capability) {
|
||||
if (capreg != NULL)
|
||||
*capreg = ptr;
|
||||
|
||||
Reference in New Issue
Block a user