1- /* $NetBSD: pci.c,v 1.155 2019/10/14 00:20:09 jmcneill Exp $ */
1+ /* $NetBSD: pci.c,v 1.156 2019/10/15 13:27:11 jmcneill Exp $ */
22
33/*
44 * Copyright (c) 1995, 1996, 1997, 1998
3636 */
3737
3838#include <sys/cdefs.h>
39- __KERNEL_RCSID (0 , "$NetBSD: pci.c,v 1.155 2019/10/14 00:20:09 jmcneill Exp $" );
39+ __KERNEL_RCSID (0 , "$NetBSD: pci.c,v 1.156 2019/10/15 13:27:11 jmcneill Exp $" );
4040
4141#ifdef _KERNEL_OPT
4242#include "opt_pci.h"
@@ -695,17 +695,26 @@ pci_enumerate_bus(struct pci_softc *sc, const int *locators,
695695
696696 device_t bridgedev ;
697697 bool arien = false;
698+ bool downstream_port = false;
698699
699- /* Check PCIe ARI */
700+ /* Check PCIe ARI and port type */
700701 bridgedev = device_parent (sc -> sc_dev );
701702 if (device_is_a (bridgedev , "ppb" )) {
702703 struct ppb_softc * ppbsc = device_private (bridgedev );
703704 pci_chipset_tag_t ppbpc = ppbsc -> sc_pc ;
704705 pcitag_t ppbtag = ppbsc -> sc_tag ;
705- pcireg_t pciecap , reg ;
706+ pcireg_t pciecap , capreg , reg ;
706707
707708 if (pci_get_capability (ppbpc , ppbtag , PCI_CAP_PCIEXPRESS ,
708- & pciecap , NULL ) != 0 ) {
709+ & pciecap , & capreg ) != 0 ) {
710+ switch (PCIE_XCAP_TYPE (capreg )) {
711+ case PCIE_XCAP_TYPE_ROOT :
712+ case PCIE_XCAP_TYPE_DOWN :
713+ case PCIE_XCAP_TYPE_PCI2PCIE :
714+ downstream_port = true;
715+ break ;
716+ }
717+
709718 reg = pci_conf_read (ppbpc , ppbtag , pciecap
710719 + PCIE_DCSR2 );
711720 if ((reg & PCIE_DCSR2_ARI_FWD ) != 0 )
@@ -714,6 +723,11 @@ pci_enumerate_bus(struct pci_softc *sc, const int *locators,
714723 }
715724
716725 n = pci_bus_devorder (sc -> sc_pc , sc -> sc_bus , devs , __arraycount (devs ));
726+ if (downstream_port ) {
727+ /* PCIe downstream ports only have a single child device */
728+ n = 1 ;
729+ }
730+
717731 for (i = 0 ; i < n ; i ++ ) {
718732 device = devs [i ];
719733
0 commit comments