git: d3e03d235e31 - main - bhyve: scan PCI device functions to find host LPC

From: Corvin Köhne <corvink_at_FreeBSD.org>
Date: Fri, 31 Mar 2023 06:03:34 UTC
The branch main has been updated by corvink:

URL: https://cgit.FreeBSD.org/src/commit/?id=d3e03d235e3133f79ff9e3879fd4ed61ace38d73

commit d3e03d235e3133f79ff9e3879fd4ed61ace38d73
Author:     Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2023-03-29 07:45:11 +0000
Commit:     Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2023-03-31 06:00:06 +0000

    bhyve: scan PCI device functions to find host LPC
    
    At least on some AMD devices the host LPC bridge could be located as
    seperate function of another PCI device.
    
    Fixes:                  f4ceaff56ddaacc151df07d2d205a2d7fcb736a8
    MFC after:              1 week
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D39310
---
 usr.sbin/bhyve/pci_lpc.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/usr.sbin/bhyve/pci_lpc.c b/usr.sbin/bhyve/pci_lpc.c
index 3b42947369a2..02105ef01bdf 100644
--- a/usr.sbin/bhyve/pci_lpc.c
+++ b/usr.sbin/bhyve/pci_lpc.c
@@ -461,10 +461,22 @@ pci_lpc_get_sel(struct pcisel *const sel)
 	memset(sel, 0, sizeof(*sel));
 
 	for (uint8_t slot = 0; slot <= PCI_SLOTMAX; ++slot) {
+		uint8_t max_func = 0;
+
 		sel->pc_dev = slot;
-		if ((read_config(sel, PCIR_CLASS, 1) == PCIC_BRIDGE) &&
-		    (read_config(sel, PCIR_SUBCLASS, 1) == PCIS_BRIDGE_ISA)) {
-			return (0);
+		sel->pc_func = 0;
+
+		if (read_config(sel, PCIR_HDRTYPE, 1) & PCIM_MFDEV)
+			max_func = PCI_FUNCMAX;
+
+		for (uint8_t func = 0; func <= max_func; ++func) {
+			sel->pc_func = func;
+
+			if ((read_config(sel, PCIR_CLASS, 1) == PCIC_BRIDGE) &&
+			    (read_config(sel, PCIR_SUBCLASS, 1) ==
+				PCIS_BRIDGE_ISA)) {
+				return (0);
+			}
 		}
 	}