Module Name:    src
Committed By:   jmcneill
Date:           Sun Jun 30 09:30:45 UTC 2024

Modified Files:
        src/sys/dev/pci: pci_resource.c

Log Message:
pci_resource: Make unexpected bus numbers in bridges non-fatal.

Firmware bugs happen. Log a warning and continue instead of panicing.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/pci/pci_resource.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/pci_resource.c
diff -u src/sys/dev/pci/pci_resource.c:1.4 src/sys/dev/pci/pci_resource.c:1.5
--- src/sys/dev/pci/pci_resource.c:1.4	Sun Nov 12 13:56:20 2023
+++ src/sys/dev/pci/pci_resource.c	Sun Jun 30 09:30:45 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_resource.c,v 1.4 2023/11/12 13:56:20 jmcneill Exp $ */
+/* $NetBSD: pci_resource.c,v 1.5 2024/06/30 09:30:45 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca>
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_resource.c,v 1.4 2023/11/12 13:56:20 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_resource.c,v 1.5 2024/06/30 09:30:45 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -136,7 +136,7 @@ struct pci_resources {
 	vmem_t		*pr_res[NUM_PCI_RANGES];
 };
 
-static void	pci_resource_scan_bus(struct pci_resources *,
+static int	pci_resource_scan_bus(struct pci_resources *,
 		    struct pci_device *, uint8_t);
 
 #define	PCI_SBDF_FMT			"%04x:%02x:%02x.%u"
@@ -524,7 +524,11 @@ pci_resource_scan_device(struct pci_reso
 		bridge_bus = pci_conf_read(pr->pr_pc, tag, PCI_BRIDGE_BUS_REG);
 		sec_bus = PCI_BRIDGE_BUS_NUM_SECONDARY(bridge_bus);
 		if (sec_bus <= pr->pr_endbus) {
-			pci_resource_scan_bus(pr, pd, sec_bus);
+			if (pci_resource_scan_bus(pr, pd, sec_bus) != 0) {
+				DPRINT("PCI: " PCI_SBDF_FMT " bus %u "
+				       "already scanned (firmware bug!)\n",
+				       PCI_SBDF_FMT_ARGS(pr, pd), sec_bus);
+			}
 		}
 	}
 
@@ -536,7 +540,7 @@ pci_resource_scan_device(struct pci_reso
  *
  *   Enumerate devices on a bus, recursively.
  */
-static void
+static int
 pci_resource_scan_bus(struct pci_resources *pr,
     struct pci_device *bridge_dev, uint8_t busno)
 {
@@ -552,8 +556,7 @@ pci_resource_scan_bus(struct pci_resourc
 		 * Firmware has configured more than one bridge with the
 		 * same secondary bus number.
 		 */
-		panic("Bus %u already scanned (firmware bug!)", busno);
-		return;
+		return EINVAL;
 	}
 
 	pb = pci_new_bus(pr, busno, bridge_dev);
@@ -570,6 +573,8 @@ pci_resource_scan_bus(struct pci_resourc
 			pci_resource_scan_device(pr, pb, devno, funcno);
 		}
 	}
+
+	return 0;
 }
 
 /*

Reply via email to