[PATCH v2] x86/early-quirks: Scan all functions in early_pci_scan_bus()

Thorsten Blum <[email protected]>
Newsgroups org.kernel.vger.linux-pci,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
early_pci_scan_bus() stops scanning a PCI slot when check_dev_quirk()
returns nonzero, which avoids probing functions 1-7 on single-function
devices, but also stops scanning when a function is absent on a
multifunction device.

This can skip early quirks on multifunction devices with holes in their
function numbering.

On iMac13,1 and iMac13,2, the BCM4331 AirPort card is behind root port
00:1c.3, also documented by the model list in commit abb2bafd295f
("x86/quirks: Add early quirk to reset Apple AirPort card").

Public lspci output for 2012 iMacs [1][2] shows that 00:1c.0, 00:1c.2,
00:1c.3 and 00:1c.4 are present, but 00:1c.1 is missing. The old code
stops at 00:1c.1 and never reaches 00:1c.3, so the AirPort reset quirk
is silently skipped on these machines.

Check function 0 first, and if it indicates a multifunction device, scan
functions 1-7 independently so that absent functions do not cause later
ones to be skipped.

Fixes: 15650a2f644a ("x86/PCI: fixup early quirk probing")
Cc: [email protected]
Signed-off-by: Thorsten Blum <[email protected]>
Link: https://forum.libreelec.tv/thread/26799-wifi-not-detected-on-2012-imac-in-11-0/ [1]
Link: https://zoringroup.com/forum/5/7170/ [2]
---
Changes in v2:
- Add iMac13,x background information and supporting links (Lukas)
- v1: https://lore.kernel.org/r/[email protected]/
---
 arch/x86/kernel/early-quirks.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 6b6f32f40cbe..c641f38eca3a 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -795,12 +795,14 @@ static void __init early_pci_scan_bus(int bus)
 	int slot, func;
 
 	/* Poor man's PCI discovery */
-	for (slot = 0; slot < 32; slot++)
-		for (func = 0; func < 8; func++) {
-			/* Only probe function 0 on single fn devices */
-			if (check_dev_quirk(bus, slot, func))
-				break;
-		}
+	for (slot = 0; slot < 32; slot++) {
+		/* Only multifunction devices may have functions 1-7 */
+		if (check_dev_quirk(bus, slot, 0))
+			continue;
+
+		for (func = 1; func < 8; func++)
+			check_dev_quirk(bus, slot, func);
+	}
 }
 
 void __init early_quirks(void)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.