diff options
36 files changed, 250 insertions, 88 deletions
@@ -21,6 +21,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 7.x IS SLOW: developers choose to disable these features on build machines to maximize performance. +20070930: + The PCI code has been made aware of PCI domains. This means that + the location strings as used by pciconf(8) etc are now in the + following format: pci<domain>:<bus>:<device>[:<function>]. It + also means that consumers of <sys/pciio.h> potentially need to + be recompiled; this includes the hal and xorg-server ports. + 20070928: The caching daemon (cached) was renamed to nscd. nscd.conf configuration file should be used instead of cached.conf and diff --git a/share/man/man4/pci.4 b/share/man/man4/pci.4 index db03d91..dd77630 100644 --- a/share/man/man4/pci.4 +++ b/share/man/man4/pci.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 24, 1999 +.Dd September 30, 2007 .Dt PCI 4 .Os .Sh NAME @@ -109,7 +109,7 @@ structure consists of the following elements: .Bl -tag -width pd_vendor .It pc_sel .Tn PCI -bus, slot and function. +domain, bus, slot and function. .It pd_name .Tn PCI device driver name. @@ -150,7 +150,7 @@ which consists of the following items: .Bl -tag -width pc_subvendor .It pc_sel .Tn PCI -bus, slot and function. +domain, bus, slot and function. .It pc_hdr .Tn PCI header type. @@ -257,9 +257,10 @@ structure consists of the following fields: .It pi_sel A .Va pcisel -structure which specifies the bus, slot and function the user would like to -query. -If the specific bus is not found, errno will be set to ENODEV and -1 returned from the ioctl. +structure which specifies the domain, bus, slot and function the user would +like to query. +If the specific bus is not found, errno will be set to ENODEV and -1 returned +from the ioctl. .It pi_reg The .Tn PCI diff --git a/share/man/man9/pci.9 b/share/man/man9/pci.9 index 781614c..21dfbbe 100644 --- a/share/man/man9/pci.9 +++ b/share/man/man9/pci.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 22, 2005 +.Dd September 30, 2007 .Dt PCI 9 .Os .Sh NAME @@ -39,6 +39,7 @@ .Nm pci_set_powerstate , .Nm pci_get_powerstate , .Nm pci_find_bsf , +.Nm pci_find_dbsf , .Nm pci_find_device .Nd PCI bus interface .Sh SYNOPSIS @@ -65,6 +66,8 @@ .Ft device_t .Fn pci_find_bsf "uint8_t bus" "uint8_t slot" "uint8_t func" .Ft device_t +.Fn pci_find_dbsf "uint32_t domain" "uint8_t bus" "uint8_t slot" "uint8_t func" +.Ft device_t .Fn pci_find_device "uint16_t vendor" "uint16_t device" .Sh DESCRIPTION The @@ -198,6 +201,30 @@ The number actually refers to the number of the device on the bus, which does not necessarily indicate its geographic location in terms of a physical slot. +Note that in case the system has multiple PCI domains, +the +.Fn pci_find_bsf +function only searches the first one. +Actually, it is equivalent to: +.Bd -literal -offset indent +pci_find_dbsf(0, bus, slot, func); +.Ed +.Pp +The +.Fn pci_find_dbsf +function looks up the +.Vt device_t +of a PCI device, given its +.Fa domain , +.Fa bus , +.Fa slot , +and +.Fa func . +The +.Fa slot +number actually refers to the number of the device on the bus, +which does not necessarily indicate its geographic location +in terms of a physical slot. .Pp The .Fn pci_find_device diff --git a/sys/amd64/amd64/legacy.c b/sys/amd64/amd64/legacy.c index 2247c9b..f719611 100644 --- a/sys/amd64/amd64/legacy.c +++ b/sys/amd64/amd64/legacy.c @@ -207,6 +207,9 @@ legacy_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) struct legacy_device *atdev = DEVTOAT(child); switch (which) { + case LEGACY_IVAR_PCIDOMAIN: + *result = 0; + break; case LEGACY_IVAR_PCIBUS: *result = atdev->lg_pcibus; break; @@ -223,6 +226,8 @@ legacy_write_ivar(device_t dev, device_t child, int which, uintptr_t value) struct legacy_device *atdev = DEVTOAT(child); switch (which) { + case LEGACY_IVAR_PCIDOMAIN: + return EINVAL; case LEGACY_IVAR_PCIBUS: atdev->lg_pcibus = value; break; diff --git a/sys/amd64/include/legacyvar.h b/sys/amd64/include/legacyvar.h index 91f784f..5ab7b35 100644 --- a/sys/amd64/include/legacyvar.h +++ b/sys/amd64/include/legacyvar.h @@ -30,12 +30,14 @@ #define _MACHINE_LEGACYVAR_H_ enum legacy_device_ivars { + LEGACY_IVAR_PCIDOMAIN, LEGACY_IVAR_PCIBUS }; #define LEGACY_ACCESSOR(var, ivar, type) \ __BUS_ACCESSOR(legacy, var, LEGACY, ivar, type) +LEGACY_ACCESSOR(pcidomain, PCIDOMAIN, uint32_t) LEGACY_ACCESSOR(pcibus, PCIBUS, uint32_t) #undef LEGACY_ACCESSOR diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c index d07c18d..4a514f4 100644 --- a/sys/amd64/pci/pci_bus.c +++ b/sys/amd64/pci/pci_bus.c @@ -276,6 +276,9 @@ legacy_pcib_read_ivar(device_t dev, device_t child, int which, { switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return 0; case PCIB_IVAR_BUS: *result = legacy_get_pcibus(dev); return 0; @@ -289,6 +292,8 @@ legacy_pcib_write_ivar(device_t dev, device_t child, int which, { switch (which) { + case PCIB_IVAR_DOMAIN: + return EINVAL; case PCIB_IVAR_BUS: legacy_set_pcibus(dev, value); return 0; diff --git a/sys/arm/xscale/i80321/i80321_pci.c b/sys/arm/xscale/i80321/i80321_pci.c index 6eb96b9..24b21db 100644 --- a/sys/arm/xscale/i80321/i80321_pci.c +++ b/sys/arm/xscale/i80321/i80321_pci.c @@ -250,8 +250,10 @@ i80321_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct i80321_pci_softc *sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); case PCIB_IVAR_BUS: - *result = sc->sc_busno; return (0); @@ -265,6 +267,8 @@ i80321_write_ivar(device_t dev, device_t child, int which, uintptr_t result) struct i80321_pci_softc * sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + return (EINVAL); case PCIB_IVAR_BUS: sc->sc_busno = result; return (0); diff --git a/sys/arm/xscale/i8134x/i81342_pci.c b/sys/arm/xscale/i8134x/i81342_pci.c index 8c79241..754cb07 100644 --- a/sys/arm/xscale/i8134x/i81342_pci.c +++ b/sys/arm/xscale/i8134x/i81342_pci.c @@ -481,8 +481,10 @@ i81342_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct i81342_pci_softc *sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); case PCIB_IVAR_BUS: - *result = sc->sc_busno; return (0); @@ -496,6 +498,8 @@ i81342_write_ivar(device_t dev, device_t child, int which, uintptr_t result) struct i81342_pci_softc * sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + return (EINVAL); case PCIB_IVAR_BUS: sc->sc_busno = result; return (0); diff --git a/sys/arm/xscale/ixp425/ixp425_pci.c b/sys/arm/xscale/ixp425/ixp425_pci.c index 0ba3fac..aa40b90 100644 --- a/sys/arm/xscale/ixp425/ixp425_pci.c +++ b/sys/arm/xscale/ixp425/ixp425_pci.c @@ -229,6 +229,9 @@ ixppcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); case PCIB_IVAR_BUS: *result = sc->sc_bus; return (0); @@ -244,6 +247,8 @@ ixppcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + return (EINVAL); case PCIB_IVAR_BUS: sc->sc_bus = value; return (0); diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c index c909ac5..ed22417 100644 --- a/sys/dev/acpica/acpi_pci.c +++ b/sys/dev/acpica/acpi_pci.c @@ -275,17 +275,19 @@ acpi_pci_probe(device_t dev) static int acpi_pci_attach(device_t dev) { - int busno; + int busno, domain; /* * Since there can be multiple independantly numbered PCI * busses on systems with multiple PCI domains, we can't use * the unit number to decide which bus we are probing. We ask - * the parent pcib what our bus number is. + * the parent pcib what our domain and bus numbers are. */ + domain = pcib_get_domain(dev); busno = pcib_get_bus(dev); if (bootverbose) - device_printf(dev, "physical bus=%d\n", busno); + device_printf(dev, "domain=%d, physical bus=%d\n", + domain, busno); /* * First, PCI devices are added as in the normal PCI bus driver. @@ -297,7 +299,7 @@ acpi_pci_attach(device_t dev) * pci_add_children() doesn't find. We currently just ignore * these devices. */ - pci_add_children(dev, busno, sizeof(struct acpi_pci_devinfo)); + pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo)); AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1, acpi_pci_save_handle, dev, NULL); diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c index 036b25e..2865dea 100644 --- a/sys/dev/acpica/acpi_pcib_acpi.c +++ b/sys/dev/acpica/acpi_pcib_acpi.c @@ -259,6 +259,9 @@ acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) struct acpi_hpcib_softc *sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); case PCIB_IVAR_BUS: *result = sc->ap_bus; return (0); @@ -278,6 +281,8 @@ acpi_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) struct acpi_hpcib_softc *sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + return (EINVAL); case PCIB_IVAR_BUS: sc->ap_bus = value; return (0); diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index b0576bb..a662cf0 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -2181,13 +2181,14 @@ static int bge_has_multiple_ports(struct bge_softc *sc) { device_t dev = sc->bge_dev; - u_int b, s, f, fscan; + u_int b, d, f, fscan, s; + d = pci_get_domain(dev); b = pci_get_bus(dev); s = pci_get_slot(dev); f = pci_get_function(dev); for (fscan = 0; fscan <= PCI_FUNCMAX; fscan++) - if (fscan != f && pci_find_bsf(b, s, fscan) != NULL) + if (fscan != f && pci_find_dbsf(d, b, s, fscan) != NULL) return (1); return (0); } diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index cb85837..e7fdcad 100644 --- a/sys/dev/cardbus/cardbus.c +++ b/sys/dev/cardbus/cardbus.c @@ -162,12 +162,13 @@ cardbus_attach_card(device_t cbdev) { device_t brdev = device_get_parent(cbdev); device_t child; + int bus, domain, slot, func; int cardattached = 0; - int bus, slot, func; int cardbusfunchigh = 0; cardbus_detach_card(cbdev); /* detach existing cards */ POWER_ENABLE_SOCKET(brdev, cbdev); + domain = pcib_get_domain(cbdev); bus = pcib_get_bus(cbdev); slot = 0; /* For each function, set it up and try to attach a driver to it */ @@ -175,7 +176,7 @@ cardbus_attach_card(device_t cbdev) struct cardbus_devinfo *dinfo; dinfo = (struct cardbus_devinfo *) - pci_read_device(brdev, bus, slot, func, + pci_read_device(brdev, domain, bus, slot, func, sizeof(struct cardbus_devinfo)); if (dinfo == NULL) continue; diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index f511ebb..7b8fb62 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -1470,6 +1470,9 @@ cbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result) struct cbb_softc *sc = device_get_softc(brdev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = sc->domain; + return (0); case PCIB_IVAR_BUS: *result = sc->secbus; return (0); @@ -1483,6 +1486,8 @@ cbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value) struct cbb_softc *sc = device_get_softc(brdev); switch (which) { + case PCIB_IVAR_DOMAIN: + return (EINVAL); case PCIB_IVAR_BUS: sc->secbus = value; return (0); diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c index 8ad7e54..73a52b0 100644 --- a/sys/dev/pccbb/pccbb_pci.c +++ b/sys/dev/pccbb/pccbb_pci.c @@ -316,6 +316,7 @@ cbb_pci_attach(device_t brdev) sc->dev = brdev; sc->cbdev = NULL; sc->exca[0].pccarddev = NULL; + sc->domain = pci_get_domain(brdev); sc->secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1); sc->subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1); sc->pribus = pcib_get_bus(parent); @@ -346,6 +347,8 @@ cbb_pci_attach(device_t brdev) /*Sysctls*/ sctx = device_get_sysctl_ctx(brdev); soid = device_get_sysctl_tree(brdev); + SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain", + CTLFLAG_RD, &sc->domain, 0, "Domain number"); SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus", CTLFLAG_RD, &sc->pribus, 0, "Primary bus number"); SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus", diff --git a/sys/dev/pccbb/pccbbvar.h b/sys/dev/pccbb/pccbbvar.h index c8201a2..ef2d82f 100644 --- a/sys/dev/pccbb/pccbbvar.h +++ b/sys/dev/pccbb/pccbbvar.h @@ -62,6 +62,7 @@ struct cbb_softc { void *intrhand; bus_space_tag_t bst; bus_space_handle_t bsh; + uint32_t domain; unsigned int pribus; unsigned int secbus; unsigned int subbus; diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index d8b8ab0..e110b3a 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -274,15 +274,25 @@ TUNABLE_INT("hw.pci.honor_msi_blacklist", &pci_honor_msi_blacklist); SYSCTL_INT(_hw_pci, OID_AUTO, honor_msi_blacklist, CTLFLAG_RD, &pci_honor_msi_blacklist, 1, "Honor chipset blacklist for MSI"); -/* Find a device_t by bus/slot/function */ +/* Find a device_t by bus/slot/function in domain 0 */ device_t pci_find_bsf(uint8_t bus, uint8_t slot, uint8_t func) { + + return (pci_find_dbsf(0, bus, slot, func)); +} + +/* Find a device_t by domain/bus/slot/function */ + +device_t +pci_find_dbsf(uint32_t domain, uint8_t bus, uint8_t slot, uint8_t func) +{ struct pci_devinfo *dinfo; STAILQ_FOREACH(dinfo, &pci_devq, pci_links) { - if ((dinfo->cfg.bus == bus) && + if ((dinfo->cfg.domain == domain) && + (dinfo->cfg.bus == bus) && (dinfo->cfg.slot == slot) && (dinfo->cfg.func == func)) { return (dinfo->cfg.dev); @@ -416,7 +426,7 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg) /* read configuration header into pcicfgregs structure */ struct pci_devinfo * -pci_read_device(device_t pcib, int b, int s, int f, size_t size) +pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size) { #define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) pcicfgregs *cfg = NULL; @@ -434,6 +444,7 @@ pci_read_device(device_t pcib, int b, int s, int f, size_t size) cfg = &devlist_entry->cfg; + cfg->domain = d; cfg->bus = b; cfg->slot = s; cfg->func = f; @@ -465,6 +476,7 @@ pci_read_device(device_t pcib, int b, int s, int f, size_t size) STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links); + devlist_entry->conf.pc_sel.pc_domain = cfg->domain; devlist_entry->conf.pc_sel.pc_bus = cfg->bus; devlist_entry->conf.pc_sel.pc_dev = cfg->slot; devlist_entry->conf.pc_sel.pc_func = cfg->func; @@ -551,9 +563,10 @@ pci_read_extcap(device_t pcib, pcicfgregs *cfg) 4); if (addr != MSI_INTEL_ADDR_BASE) device_printf(pcib, - "HT Bridge at %d:%d:%d has non-default MSI window 0x%llx\n", - cfg->bus, cfg->slot, - cfg->func, (long long)addr); + "HT Bridge at pci%d:%d:%d:%d has non-default MSI window 0x%llx\n", + cfg->domain, cfg->bus, + cfg->slot, cfg->func, + (long long)addr); } /* Enable MSI -> HT mapping. */ @@ -730,9 +743,9 @@ pci_read_vpd(device_t pcib, pcicfgregs *cfg) if (remain > (0x7f*4 - vrs.off)) { end = 1; printf( - "pci%d:%d:%d: invalid vpd data, remain %#x\n", - cfg->bus, cfg->slot, cfg->func, - remain); + "pci%d:%d:%d:%d: invalid vpd data, remain %#x\n", + cfg->domain, cfg->bus, cfg->slot, + cfg->func, remain); } name = byte & 0x7f; } else { @@ -797,8 +810,10 @@ pci_read_vpd(device_t pcib, pcicfgregs *cfg) * if this happens, we can't trust the rest * of the VPD. */ - printf("pci%d:%d:%d: bad keyword length: %d\n", - cfg->bus, cfg->slot, cfg->func, dflen); + printf( + "pci%d:%d:%d:%d: bad keyword length: %d\n", + cfg->domain, cfg->bus, cfg->slot, + cfg->func, dflen); cksumvalid = 0; end = 1; break; @@ -831,9 +846,9 @@ pci_read_vpd(device_t pcib, pcicfgregs *cfg) cksumvalid = 1; else { printf( - "pci%d:%d:%d: bad VPD cksum, remain %hhu\n", - cfg->bus, cfg->slot, cfg->func, - vrs.cksum); + "pci%d:%d:%d:%d: bad VPD cksum, remain %hhu\n", + cfg->domain, cfg->bus, cfg->slot, + cfg->func, vrs.cksum); cksumvalid = 0; end = 1; break; @@ -902,8 +917,9 @@ pci_read_vpd(device_t pcib, pcicfgregs *cfg) break; default: - printf("pci%d:%d:%d: invalid state: %d\n", - cfg->bus, cfg->slot, cfg->func, state); + printf("pci%d:%d:%d:%d: invalid state: %d\n", + cfg->domain, cfg->bus, cfg->slot, cfg->func, + state); end = 1; break; } @@ -1947,9 +1963,9 @@ pci_set_powerstate_method(device_t dev, device_t child, int state) if (bootverbose) printf( - "pci%d:%d:%d: Transition from D%d to D%d\n", - dinfo->cfg.bus, dinfo->cfg.slot, dinfo->cfg.func, - oldstate, state); + "pci%d:%d:%d:%d: Transition from D%d to D%d\n", + dinfo->cfg.domain, dinfo->cfg.bus, dinfo->cfg.slot, + dinfo->cfg.func, oldstate, state); PCI_WRITE_CONFIG(dev, child, cfg->pp.pp_status, status, 2); if (delay) @@ -2105,8 +2121,8 @@ pci_print_verbose(struct pci_devinfo *dinfo) printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", cfg->vendor, cfg->device, cfg->revid); - printf("\tbus=%d, slot=%d, func=%d\n", - cfg->bus, cfg->slot, cfg->func); + printf("\tdomain=%d, bus=%d, slot=%d, func=%d\n", + cfg->domain, cfg->bus, cfg->slot, cfg->func); printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", cfg->baseclass, cfg->subclass, cfg->progif, cfg->hdrtype, cfg->mfdev); @@ -2243,7 +2259,8 @@ pci_add_map(device_t pcib, device_t bus, device_t dev, return (barlen); if ((u_long)base != base) { device_printf(bus, - "pci%d:%d:%d bar %#x too many address bits", b, s, f, reg); + "pci%d:%d:%d:%d bar %#x too many address bits", + pci_get_domain(dev), b, s, f, reg); return (barlen); } @@ -2295,8 +2312,8 @@ pci_add_map(device_t pcib, device_t bus, device_t dev, if ((u_long)start != start) { /* Wait a minute! this platform can't do this address. */ device_printf(bus, - "pci%d.%d.%x bar %#x start %#jx, too many bits.", - b, s, f, reg, (uintmax_t)start); + "pci%d:%d.%d.%x bar %#x start %#jx, too many bits.", + pci_get_domain(dev), b, s, f, reg, (uintmax_t)start); resource_list_release(rl, bus, dev, type, reg, res); return (barlen); } @@ -2381,8 +2398,9 @@ pci_assign_interrupt(device_t bus, device_t dev, int force_route) /* Let the user override the IRQ with a tunable. */ irq = PCI_INVALID_IRQ; - snprintf(tunable_name, sizeof(tunable_name), "hw.pci%d.%d.INT%c.irq", - cfg->bus, cfg->slot, cfg->intpin + 'A' - 1); + snprintf(tunable_name, sizeof(tunable_name), + "hw.pci%d.%d.%d.INT%c.irq", + cfg->domain, cfg->bus, cfg->slot, cfg->intpin + 'A' - 1); if (TUNABLE_INT_FETCH(tunable_name, &irq) && (irq >= 255 || irq <= 0)) irq = PCI_INVALID_IRQ; @@ -2468,7 +2486,7 @@ pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask) } void -pci_add_children(device_t dev, int busno, size_t dinfo_size) +pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size) { #define REG(n, w) PCIB_READ_CONFIG(pcib, busno, s, f, n, w) device_t pcib = device_get_parent(dev); @@ -2490,7 +2508,8 @@ pci_add_children(device_t dev, int busno, size_t dinfo_size) if (hdrtype & PCIM_MFDEV) pcifunchigh = PCI_FUNCMAX; for (f = 0; f <= pcifunchigh; f++) { - dinfo = pci_read_device(pcib, busno, s, f, dinfo_size); + dinfo = pci_read_device(pcib, domain, busno, s, f, + dinfo_size); if (dinfo != NULL) { pci_add_child(dev, dinfo); } @@ -2524,19 +2543,21 @@ pci_probe(device_t dev) static int pci_attach(device_t dev) { - int busno; + int busno, domain; /* * Since there can be multiple independantly numbered PCI * busses on systems with multiple PCI domains, we can't use * the unit number to decide which bus we are probing. We ask - * the parent pcib what our bus number is. + * the parent pcib what our domain and bus numbers are. */ + domain = pcib_get_domain(dev); busno = pcib_get_bus(dev); if (bootverbose) - device_printf(dev, "physical bus=%d\n", busno); + device_printf(dev, "domain=%d, physical bus=%d\n", + domain, busno); - pci_add_children(dev, busno, sizeof(struct pci_devinfo)); + pci_add_children(dev, domain, busno, sizeof(struct pci_devinfo)); return (bus_generic_attach(dev)); } @@ -2659,8 +2680,9 @@ pci_driver_added(device_t dev, driver_t *driver) dinfo = device_get_ivars(child); pci_print_verbose(dinfo); if (bootverbose) - printf("pci%d:%d:%d: reprobing on driver added\n", - dinfo->cfg.bus, dinfo->cfg.slot, dinfo->cfg.func); + printf("pci%d:%d:%d:%d: reprobing on driver added\n", + dinfo->cfg.domain, dinfo->cfg.bus, dinfo->cfg.slot, + dinfo->cfg.func); pci_cfg_restore(child, dinfo); if (device_probe_and_attach(child) != 0) pci_cfg_save(child, dinfo, 1); @@ -3126,6 +3148,9 @@ pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) case PCI_IVAR_IRQ: *result = cfg->intline; break; + case PCI_IVAR_DOMAIN: + *result = cfg->domain; + break; case PCI_IVAR_BUS: *result = cfg->bus; break; @@ -3178,6 +3203,7 @@ pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) case PCI_IVAR_PROGIF: case PCI_IVAR_REVID: case PCI_IVAR_IRQ: + case PCI_IVAR_DOMAIN: case PCI_IVAR_BUS: case PCI_IVAR_SLOT: case PCI_IVAR_FUNCTION: @@ -3224,12 +3250,12 @@ DB_SHOW_COMMAND(pciregs, db_pci_dump) name = device_get_name(dinfo->cfg.dev); p = &dinfo->conf; - db_printf("%s%d@pci%d:%d:%d:\tclass=0x%06x card=0x%08x " + db_printf("%s%d@pci%d:%d:%d:%d:\tclass=0x%06x card=0x%08x " "chip=0x%08x rev=0x%02x hdr=0x%02x\n", (name && *name) ? name : "none", (name && *name) ? (int)device_get_unit(dinfo->cfg.dev) : none_count++, - p->pc_sel.pc_bus, p->pc_sel.pc_dev, + p->pc_sel.pc_domain, p->pc_sel.pc_bus, p->pc_sel.pc_dev, p->pc_sel.pc_func, (p->pc_class << 16) | (p->pc_subclass << 8) | p->pc_progif, (p->pc_subdevice << 16) | p->pc_subvendor, diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index e5204e0..033ea74 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -147,6 +147,7 @@ pcib_attach_common(device_t dev) * Get current bridge configuration. */ sc->command = pci_read_config(dev, PCIR_COMMAND, 1); + sc->domain = pci_get_domain(dev); sc->secbus = pci_read_config(dev, PCIR_SECBUS_1, 1); sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1); sc->secstat = pci_read_config(dev, PCIR_SECSTAT_1, 2); @@ -257,6 +258,7 @@ pcib_attach_common(device_t dev) sc->flags |= PCIB_SUBTRACTIVE; if (bootverbose) { + device_printf(dev, " domain %d\n", sc->domain); device_printf(dev, " secondary bus %d\n", sc->secbus); device_printf(dev, " subordinate bus %d\n", sc->subbus); device_printf(dev, " I/O decode 0x%x-0x%x\n", sc->iobase, sc->iolimit); @@ -309,6 +311,9 @@ pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) struct pcib_softc *sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = sc->domain; + return(0); case PCIB_IVAR_BUS: *result = sc->secbus; return(0); @@ -322,9 +327,11 @@ pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) struct pcib_softc *sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + return(EINVAL); case PCIB_IVAR_BUS: sc->secbus = value; - break; + return(0); } return(ENOENT); } diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h index 7045119..f7ccc19 100644 --- a/sys/dev/pci/pci_private.h +++ b/sys/dev/pci/pci_private.h @@ -38,7 +38,8 @@ */ DECLARE_CLASS(pci_driver); -void pci_add_children(device_t dev, int busno, size_t dinfo_size); +void pci_add_children(device_t dev, int domain, int busno, + size_t dinfo_size); void pci_add_child(device_t bus, struct pci_devinfo *dinfo); void pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask); @@ -84,7 +85,7 @@ struct resource *pci_alloc_resource(device_t dev, device_t child, void pci_delete_resource(device_t dev, device_t child, int type, int rid); struct resource_list *pci_get_resource_list (device_t dev, device_t child); -struct pci_devinfo *pci_read_device(device_t pcib, int b, int s, int f, +struct pci_devinfo *pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size); void pci_print_verbose(struct pci_devinfo *dinfo); int pci_freecfg(struct pci_devinfo *dinfo); diff --git a/sys/dev/pci/pci_user.c b/sys/dev/pci/pci_user.c index 469dc40..78b7608 100644 --- a/sys/dev/pci/pci_user.c +++ b/sys/dev/pci/pci_user.c @@ -125,6 +125,11 @@ pci_conf_match(struct pci_match_conf *matches, int num_matches, * comparison. If the comparison fails, we don't have a * match, go on to the next item if there is one. */ + if (((matches[i].flags & PCI_GETCONF_MATCH_DOMAIN) != 0) + && (match_buf->pc_sel.pc_domain != + matches[i].pc_sel.pc_domain)) + continue; + if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0) && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus)) continue; @@ -388,8 +393,9 @@ getconfexit: * Look up the grandparent, i.e. the bridge device, * so that we can issue configuration space cycles. */ - pcidev = pci_find_bsf(io->pi_sel.pc_bus, - io->pi_sel.pc_dev, io->pi_sel.pc_func); + pcidev = pci_find_dbsf(io->pi_sel.pc_domain, + io->pi_sel.pc_bus, io->pi_sel.pc_dev, + io->pi_sel.pc_func); if (pcidev) { device_t busdev, brdev; diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h index aea476d..c375e3e 100644 --- a/sys/dev/pci/pcib_private.h +++ b/sys/dev/pci/pcib_private.h @@ -48,6 +48,7 @@ struct pcib_softc #define PCIB_SUBTRACTIVE 0x1 #define PCIB_DISABLE_MSI 0x2 uint16_t command; /* command register */ + uint32_t domain; /* domain number */ uint8_t secbus; /* secondary bus number */ uint8_t subbus; /* subordinate bus number */ pci_addr_t pmembase; /* base address of prefetchable memory */ diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 13401d2..1aec1b5 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -34,6 +34,7 @@ /* some PCI bus constants */ +#define PCI_DOMAINMAX 65535 /* highest supported domain number */ #define PCI_BUSMAX 255 /* highest supported bus number */ #define PCI_SLOTMAX 31 /* highest supported slot number */ #define PCI_FUNCMAX 7 /* highest supported function number */ @@ -146,6 +147,7 @@ typedef struct pcicfg { uint8_t mfdev; /* multi-function device (from hdrtype reg) */ uint8_t nummaps; /* actual number of PCI maps used */ + uint32_t domain; /* PCI domain */ uint8_t bus; /* config space bus address */ uint8_t slot; /* config space slot address */ uint8_t func; /* config space function number */ @@ -227,6 +229,7 @@ enum pci_device_ivars { PCI_IVAR_REVID, PCI_IVAR_INTPIN, PCI_IVAR_IRQ, + PCI_IVAR_DOMAIN, PCI_IVAR_BUS, PCI_IVAR_SLOT, PCI_IVAR_FUNCTION, @@ -255,6 +258,7 @@ PCI_ACCESSOR(progif, PROGIF, uint8_t) PCI_ACCESSOR(revid, REVID, uint8_t) PCI_ACCESSOR(intpin, INTPIN, uint8_t) PCI_ACCESSOR(irq, IRQ, uint8_t) +PCI_ACCESSOR(domain, DOMAIN, uint32_t) PCI_ACCESSOR(bus, BUS, uint8_t) PCI_ACCESSOR(slot, SLOT, uint8_t) PCI_ACCESSOR(function, FUNCTION, uint8_t) @@ -288,12 +292,14 @@ pci_write_config(device_t dev, int reg, uint32_t val, int width) /*typedef enum pci_device_ivars pcib_device_ivars;*/ enum pcib_device_ivars { + PCIB_IVAR_DOMAIN, PCIB_IVAR_BUS }; #define PCIB_ACCESSOR(var, ivar, type) \ __BUS_ACCESSOR(pcib, var, PCIB, ivar, type) +PCIB_ACCESSOR(domain, DOMAIN, uint32_t) PCIB_ACCESSOR(bus, BUS, uint32_t) #undef PCIB_ACCESSOR @@ -442,6 +448,7 @@ pci_msix_count(device_t dev) } device_t pci_find_bsf(uint8_t, uint8_t, uint8_t); +device_t pci_find_dbsf(uint32_t, uint8_t, uint8_t, uint8_t); device_t pci_find_device(uint16_t, uint16_t); /* diff --git a/sys/i386/i386/legacy.c b/sys/i386/i386/legacy.c index 0cd4dc5..142fc0a 100644 --- a/sys/i386/i386/legacy.c +++ b/sys/i386/i386/legacy.c @@ -228,6 +228,9 @@ legacy_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) struct legacy_device *atdev = DEVTOAT(child); switch (which) { + case LEGACY_IVAR_PCIDOMAIN: + *result = 0; + break; case LEGACY_IVAR_PCIBUS: *result = atdev->lg_pcibus; break; @@ -244,6 +247,8 @@ legacy_write_ivar(device_t dev, device_t child, int which, uintptr_t value) struct legacy_device *atdev = DEVTOAT(child); switch (which) { + case LEGACY_IVAR_PCIDOMAIN: + return EINVAL; case LEGACY_IVAR_PCIBUS: atdev->lg_pcibus = value; break; diff --git a/sys/i386/include/legacyvar.h b/sys/i386/include/legacyvar.h index 91f784f..5ab7b35 100644 --- a/sys/i386/include/legacyvar.h +++ b/sys/i386/include/legacyvar.h @@ -30,12 +30,14 @@ #define _MACHINE_LEGACYVAR_H_ enum legacy_device_ivars { + LEGACY_IVAR_PCIDOMAIN, LEGACY_IVAR_PCIBUS }; #define LEGACY_ACCESSOR(var, ivar, type) \ __BUS_ACCESSOR(legacy, var, LEGACY, ivar, type) +LEGACY_ACCESSOR(pcidomain, PCIDOMAIN, uint32_t) LEGACY_ACCESSOR(pcibus, PCIBUS, uint32_t) #undef LEGACY_ACCESSOR diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c index 0501c46..e0c8fbd 100644 --- a/sys/i386/pci/pci_bus.c +++ b/sys/i386/pci/pci_bus.c @@ -488,6 +488,9 @@ legacy_pcib_read_ivar(device_t dev, device_t child, int which, { switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return 0; case PCIB_IVAR_BUS: *result = legacy_get_pcibus(dev); return 0; @@ -501,6 +504,8 @@ legacy_pcib_write_ivar(device_t dev, device_t child, int which, { switch (which) { + case PCIB_IVAR_DOMAIN: + return EINVAL; case PCIB_IVAR_BUS: legacy_set_pcibus(dev, value); return 0; diff --git a/sys/powerpc/powermac/grackle.c b/sys/powerpc/powermac/grackle.c index 9b3cffa..f606b65 100644 --- a/sys/powerpc/powermac/grackle.c +++ b/sys/powerpc/powermac/grackle.c @@ -345,10 +345,12 @@ grackle_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); case PCIB_IVAR_BUS: *result = sc->sc_bus; return (0); - break; } return (ENOENT); diff --git a/sys/powerpc/powermac/uninorth.c b/sys/powerpc/powermac/uninorth.c index 97bd80d..f3b0996 100644 --- a/sys/powerpc/powermac/uninorth.c +++ b/sys/powerpc/powermac/uninorth.c @@ -329,10 +329,12 @@ uninorth_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = device_get_unit(dev); + return (0); case PCIB_IVAR_BUS: *result = sc->sc_bus; return (0); - break; } return (ENOENT); diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c index 58ec72c..9455882 100644 --- a/sys/sparc64/pci/apb.c +++ b/sys/sparc64/pci/apb.c @@ -184,6 +184,8 @@ apb_attach(device_t dev) ofw_pcib_gen_setup(dev); if (bootverbose) { + device_printf(dev, " domain %d\n", + sc->sc_bsc.ops_pcib_sc.domain); device_printf(dev, " secondary bus %d\n", sc->sc_bsc.ops_pcib_sc.secbus); device_printf(dev, " subordinate bus %d\n", diff --git a/sys/sparc64/pci/ofw_pcibus.c b/sys/sparc64/pci/ofw_pcibus.c index a3e1e8b..0a03696 100644 --- a/sys/sparc64/pci/ofw_pcibus.c +++ b/sys/sparc64/pci/ofw_pcibus.c @@ -174,17 +174,19 @@ ofw_pcibus_attach(device_t dev) struct ofw_pci_register pcir; struct ofw_pcibus_devinfo *dinfo; phandle_t node, child; - u_int slot, busno, func; + u_int busno, domain, func, slot; pcib = device_get_parent(dev); + domain = pcib_get_domain(dev); /* * Ask the bridge for the bus number - in some cases, we need to * renumber buses, so the firmware information cannot be trusted. */ busno = pcib_get_bus(dev); if (bootverbose) - device_printf(dev, "physical bus=%d\n", busno); + device_printf(dev, "domain=%d, physical bus=%d\n", + domain, busno); node = ofw_bus_get_node(dev); for (child = OF_child(node); child != 0; child = OF_peer(child)) { @@ -192,11 +194,12 @@ ofw_pcibus_attach(device_t dev) continue; slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi); func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi); - if (pci_find_bsf(busno, slot, func) != NULL) + /* Some OFW device trees contain dupes. */ + if (pci_find_dbsf(domain, busno, slot, func) != NULL) continue; ofw_pcibus_setup_device(pcib, busno, slot, func); dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, - busno, slot, func, sizeof(*dinfo)); + domain, busno, slot, func, sizeof(*dinfo)); if (dinfo == NULL) continue; if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) != diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index be6a4e3..0c2c92d 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -1030,6 +1030,9 @@ psycho_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); case PCIB_IVAR_BUS: *result = sc->sc_pci_secbus; return (0); diff --git a/sys/sun4v/sun4v/hv_pci.c b/sys/sun4v/sun4v/hv_pci.c index 6f2073f..d4ed288 100644 --- a/sys/sun4v/sun4v/hv_pci.c +++ b/sys/sun4v/sun4v/hv_pci.c @@ -371,6 +371,9 @@ hvpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); case PCIB_IVAR_BUS: *result = sc->hs_busnum; return (0); @@ -386,6 +389,8 @@ hvpci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) sc = device_get_softc(dev); switch (which) { + case PCIB_IVAR_DOMAIN: + return (EINVAL); case PCIB_IVAR_BUS: sc->hs_busnum = value; return (0); diff --git a/sys/sys/param.h b/sys/sys/param.h index 8c9643e..a52fa7d 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 700052 /* Master, propagated to newvers */ +#define __FreeBSD_version 700053 /* Master, propagated to newvers */ #ifndef LOCORE #include <sys/types.h> diff --git a/sys/sys/pciio.h b/sys/sys/pciio.h index d8d8156..d23f121 100644 --- a/sys/sys/pciio.h +++ b/sys/sys/pciio.h @@ -43,25 +43,27 @@ typedef enum { } pci_getconf_status; typedef enum { - PCI_GETCONF_NO_MATCH = 0x00, - PCI_GETCONF_MATCH_BUS = 0x01, - PCI_GETCONF_MATCH_DEV = 0x02, - PCI_GETCONF_MATCH_FUNC = 0x04, - PCI_GETCONF_MATCH_NAME = 0x08, - PCI_GETCONF_MATCH_UNIT = 0x10, - PCI_GETCONF_MATCH_VENDOR = 0x20, - PCI_GETCONF_MATCH_DEVICE = 0x40, - PCI_GETCONF_MATCH_CLASS = 0x80 + PCI_GETCONF_NO_MATCH = 0x0000, + PCI_GETCONF_MATCH_DOMAIN = 0x0001, + PCI_GETCONF_MATCH_BUS = 0x0002, + PCI_GETCONF_MATCH_DEV = 0x0004, + PCI_GETCONF_MATCH_FUNC = 0x0008, + PCI_GETCONF_MATCH_NAME = 0x0010, + PCI_GETCONF_MATCH_UNIT = 0x0020, + PCI_GETCONF_MATCH_VENDOR = 0x0040, + PCI_GETCONF_MATCH_DEVICE = 0x0080, + PCI_GETCONF_MATCH_CLASS = 0x0100 } pci_getconf_flags; struct pcisel { + u_int32_t pc_domain; /* domain number */ u_int8_t pc_bus; /* bus number */ u_int8_t pc_dev; /* device on this bus */ u_int8_t pc_func; /* function on this device */ }; struct pci_conf { - struct pcisel pc_sel; /* bus+slot+function */ + struct pcisel pc_sel; /* domain+bus+slot+function */ u_int8_t pc_hdr; /* PCI header type */ u_int16_t pc_subvendor; /* card vendor ID */ u_int16_t pc_subdevice; /* card device ID, assigned by @@ -78,7 +80,7 @@ struct pci_conf { }; struct pci_match_conf { - struct pcisel pc_sel; /* bus+slot+function */ + struct pcisel pc_sel; /* domain+bus+slot+function */ char pd_name[PCI_MAXNAMELEN + 1]; /* device name */ u_long pd_unit; /* Unit number */ u_int16_t pc_vendor; /* PCI Vendor ID */ @@ -105,7 +107,6 @@ struct pci_io { int pi_width; /* width (in bytes) of read or write */ u_int32_t pi_data; /* data to write or result of read */ }; - #define PCIOCGETCONF _IOWR('p', 1, struct pci_conf_io) #define PCIOCREAD _IOWR('p', 2, struct pci_io) diff --git a/tools/tools/pciroms/pciroms.c b/tools/tools/pciroms/pciroms.c index 8db9515..460c7ef 100644 --- a/tools/tools/pciroms/pciroms.c +++ b/tools/tools/pciroms/pciroms.c @@ -223,9 +223,10 @@ pci_enum_devs(int pci_fd, action_t action) switch (action) { case PRINT: - printf("Bus %02Xh Device %02Xh Function %02Xh: ", - p->pc_sel.pc_bus, p->pc_sel.pc_dev, - p->pc_sel.pc_func); + printf( +"Domain %04Xh Bus %02Xh Device %02Xh Function %02Xh: ", + p->pc_sel.pc_domain, p->pc_sel.pc_bus, + p->pc_sel.pc_dev, p->pc_sel.pc_func); printf((romsize ? "%dKB ROM aperture detected." : "No ROM present."), romsize/1024); printf("\r\n"); diff --git a/usr.sbin/pciconf/pciconf.8 b/usr.sbin/pciconf/pciconf.8 index ba5f61a..4195d28 100644 --- a/usr.sbin/pciconf/pciconf.8 +++ b/usr.sbin/pciconf/pciconf.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 2, 2007 +.Dd September 30, 2007 .Dt PCICONF 8 .Os .Sh NAME @@ -56,9 +56,12 @@ With the .Fl l option, it lists all devices found by the boot probe in the following format: .Bd -literal -foo0@pci0:4:0: class=0x010000 card=0x00000000 chip=0x000f1000 rev=0x01 hdr=0x00 -bar0@pci0:5:0: class=0x000100 card=0x00000000 chip=0x88c15333 rev=0x00 hdr=0x00 -none0@pci0:6:0: class=0x020000 card=0x00000000 chip=0x802910ec rev=0x00 hdr=0x00 +foo0@pci0:0:4:0: class=0x010000 card=0x00000000 chip=0x000f1000 rev=0x01 \ +hdr=0x00 +bar0@pci0:0:5:0: class=0x000100 card=0x00000000 chip=0x88c15333 rev=0x00 \ +hdr=0x00 +none0@pci0:0:6:0: class=0x020000 card=0x00000000 chip=0x802910ec rev=0x00 \ +hdr=0x00 .Ed .Pp The first column gives the @@ -139,7 +142,7 @@ except for require a .Ar selector of the form -.Li pci Ns Va bus Ns \&: Ns Va device +.Li pci Ns Va domain Ns \&: Ns Va bus Ns \&: Ns Va device (optionally followed by .Li \&: Ns Va function ) . A final colon may be appended and diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c index a42435c..07b6feb 100644 --- a/usr.sbin/pciconf/pciconf.c +++ b/usr.sbin/pciconf/pciconf.c @@ -203,13 +203,12 @@ list_devs(int verbose, int caps) return; } for (p = conf; p < &conf[pc.num_matches]; p++) { - - printf("%s%d@pci%d:%d:%d:\tclass=0x%06x card=0x%08x " + printf("%s%d@pci%d:%d:%d:%d:\tclass=0x%06x card=0x%08x " "chip=0x%08x rev=0x%02x hdr=0x%02x\n", (p->pd_name && *p->pd_name) ? p->pd_name : "none", (p->pd_name && *p->pd_name) ? (int)p->pd_unit : - none_count++, + none_count++, p->pc_sel.pc_domain, p->pc_sel.pc_bus, p->pc_sel.pc_dev, p->pc_sel.pc_func, (p->pc_class << 16) | (p->pc_subclass << 8) | p->pc_progif, @@ -497,6 +496,9 @@ getsel(const char *str) if (strncmp(ep, "pci", 3) == 0) { ep += 3; + sel.pc_domain = strtoul(ep, &ep, 0); + if (!ep || *ep++ != ':') + errx(1, "cannot parse selector %s", str); sel.pc_bus = strtoul(ep, &ep, 0); if (!ep || *ep++ != ':') errx(1, "cannot parse selector %s", str); |