svn commit: r331111 - in stable/11: share/man/man9 sys/dev/pci
Bryan Venteicher
bryanv at FreeBSD.org
Sat Mar 17 20:20:31 UTC 2018
Author: bryanv
Date: Sat Mar 17 20:20:29 2018
New Revision: 331111
URL: https://svnweb.freebsd.org/changeset/base/331111
Log:
MFC r329598:
Add PCI methods to iterate over the PCI capabilities
VirtIO V1 provides configuration in multiple VENDOR capabilities so this
allows all of the configuration to be discovered.
Reviewed by: jhb
Differential Revision: https://reviews.freebsd.org/D14325
Modified:
stable/11/share/man/man9/pci.9
stable/11/sys/dev/pci/hostb_pci.c
stable/11/sys/dev/pci/pci.c
stable/11/sys/dev/pci/pci_if.m
stable/11/sys/dev/pci/pci_private.h
stable/11/sys/dev/pci/pcivar.h
stable/11/sys/dev/pci/vga_pci.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/share/man/man9/pci.9
==============================================================================
--- stable/11/share/man/man9/pci.9 Sat Mar 17 20:17:35 2018 (r331110)
+++ stable/11/share/man/man9/pci.9 Sat Mar 17 20:20:29 2018 (r331111)
@@ -42,6 +42,9 @@
.Nm pci_find_device ,
.Nm pci_find_extcap ,
.Nm pci_find_htcap ,
+.Nm pci_find_next_cap ,
+.Nm pci_find_next_extcap ,
+.Nm pci_find_next_htcap ,
.Nm pci_find_pcie_root_port ,
.Nm pci_get_id ,
.Nm pci_get_max_payload ,
@@ -100,6 +103,12 @@
.Fn pci_find_extcap "device_t dev" "int capability" "int *capreg"
.Ft int
.Fn pci_find_htcap "device_t dev" "int capability" "int *capreg"
+.Ft int
+.Fn pci_find_next_cap "device_t dev" "int capability" "int start" "int *capreg"
+.Ft int
+.Fn pci_find_next_extcap "device_t dev" "int capability" "int start" "int *capreg"
+.Ft int
+.Fn pci_find_next_htcap "device_t dev" "int capability" "int start" "int *capreg"
.Ft device_t
.Fn pci_find_pcie_root_port "device_t dev"
.Ft int
@@ -330,6 +339,22 @@ returns zero.
If the capability is not found or the device does not support capabilities,
.Fn pci_find_cap
returns an error.
+The
+.Fn pci_find_next_cap
+function is used to locate the next instance of a PCI capability
+register set for the device
+.Fa dev .
+The
+.Fa start
+should be the
+.Fa *capreg
+returned by a prior
+.Fn pci_find_cap
+or
+.Fn pci_find_next_cap .
+When no more instances are located
+.Fn pci_find_next_cap
+returns an error.
.Pp
The
.Fn pci_find_extcap
@@ -352,6 +377,22 @@ If the extended capability is not found or the device
PCI-express device,
.Fn pci_find_extcap
returns an error.
+The
+.Fn pci_find_next_extcap
+function is used to locate the next instance of a PCI-express
+extended capability register set for the device
+.Fa dev .
+The
+.Fa start
+should be the
+.Fa *capreg
+returned by a prior
+.Fn pci_find_extcap
+or
+.Fn pci_find_next_extcap .
+When no more instances are located
+.Fn pci_find_next_extcap
+returns an error.
.Pp
The
.Fn pci_find_htcap
@@ -372,6 +413,22 @@ and
returns zero.
If the capability is not found or the device is not a HyperTransport device,
.Fn pci_find_htcap
+returns an error.
+The
+.Fn pci_find_next_htcap
+function is used to locate the next instance of a HyperTransport capability
+register set for the device
+.Fa dev .
+The
+.Fa start
+should be the
+.Fa *capreg
+returned by a prior
+.Fn pci_find_htcap
+or
+.Fn pci_find_next_htcap .
+When no more instances are located
+.Fn pci_find_next_htcap
returns an error.
.Pp
The
Modified: stable/11/sys/dev/pci/hostb_pci.c
==============================================================================
--- stable/11/sys/dev/pci/hostb_pci.c Sat Mar 17 20:17:35 2018 (r331110)
+++ stable/11/sys/dev/pci/hostb_pci.c Sat Mar 17 20:20:29 2018 (r331111)
@@ -207,6 +207,14 @@ pci_hostb_find_cap(device_t dev, device_t child, int c
}
static int
+pci_hostb_find_next_cap(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+
+ return (pci_find_next_cap(dev, capability, start, capreg));
+}
+
+static int
pci_hostb_find_extcap(device_t dev, device_t child, int capability,
int *capreg)
{
@@ -215,6 +223,14 @@ pci_hostb_find_extcap(device_t dev, device_t child, in
}
static int
+pci_hostb_find_next_extcap(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+
+ return (pci_find_next_extcap(dev, capability, start, capreg));
+}
+
+static int
pci_hostb_find_htcap(device_t dev, device_t child, int capability,
int *capreg)
{
@@ -222,6 +238,14 @@ pci_hostb_find_htcap(device_t dev, device_t child, int
return (pci_find_htcap(dev, capability, capreg));
}
+static int
+pci_hostb_find_next_htcap(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+
+ return (pci_find_next_htcap(dev, capability, start, capreg));
+}
+
static device_method_t pci_hostb_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pci_hostb_probe),
@@ -252,8 +276,11 @@ static device_method_t pci_hostb_methods[] = {
DEVMETHOD(pci_set_powerstate, pci_hostb_set_powerstate),
DEVMETHOD(pci_assign_interrupt, pci_hostb_assign_interrupt),
DEVMETHOD(pci_find_cap, pci_hostb_find_cap),
+ DEVMETHOD(pci_find_next_cap, pci_hostb_find_next_cap),
DEVMETHOD(pci_find_extcap, pci_hostb_find_extcap),
+ DEVMETHOD(pci_find_next_extcap, pci_hostb_find_next_extcap),
DEVMETHOD(pci_find_htcap, pci_hostb_find_htcap),
+ DEVMETHOD(pci_find_next_htcap, pci_hostb_find_next_htcap),
{ 0, 0 }
};
Modified: stable/11/sys/dev/pci/pci.c
==============================================================================
--- stable/11/sys/dev/pci/pci.c Sat Mar 17 20:17:35 2018 (r331110)
+++ stable/11/sys/dev/pci/pci.c Sat Mar 17 20:20:29 2018 (r331111)
@@ -180,8 +180,11 @@ static device_method_t pci_methods[] = {
DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method),
DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method),
DEVMETHOD(pci_find_cap, pci_find_cap_method),
+ DEVMETHOD(pci_find_next_cap, pci_find_next_cap_method),
DEVMETHOD(pci_find_extcap, pci_find_extcap_method),
+ DEVMETHOD(pci_find_next_extcap, pci_find_next_extcap_method),
DEVMETHOD(pci_find_htcap, pci_find_htcap_method),
+ DEVMETHOD(pci_find_next_htcap, pci_find_next_htcap_method),
DEVMETHOD(pci_alloc_msi, pci_alloc_msi_method),
DEVMETHOD(pci_alloc_msix, pci_alloc_msix_method),
DEVMETHOD(pci_enable_msi, pci_enable_msi_method),
@@ -1374,7 +1377,7 @@ pci_find_htcap_method(device_t dev, device_t child, in
* Traverse the capabilities list checking each HT capability
* to see if it matches the requested HT capability.
*/
- while (ptr != 0) {
+ for (;;) {
val = pci_read_config(child, ptr + PCIR_HT_COMMAND, 2);
if (capability == PCIM_HTCAP_SLAVE ||
capability == PCIM_HTCAP_HOST)
@@ -1388,13 +1391,51 @@ pci_find_htcap_method(device_t dev, device_t child, in
}
/* Skip to the next HT capability. */
- while (ptr != 0) {
- ptr = pci_read_config(child, ptr + PCICAP_NEXTPTR, 1);
- if (pci_read_config(child, ptr + PCICAP_ID, 1) ==
- PCIY_HT)
- break;
+ if (pci_find_next_cap(child, PCIY_HT, ptr, &ptr) != 0)
+ break;
+ }
+
+ return (ENOENT);
+}
+
+/*
+ * Find the next requested HyperTransport capability after start and return
+ * the offset in configuration space via the pointer provided. The function
+ * returns 0 on success and an error code otherwise.
+ */
+int
+pci_find_next_htcap_method(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+ int ptr;
+ uint16_t val;
+
+ KASSERT(pci_read_config(child, start + PCICAP_ID, 1) == PCIY_HT,
+ ("start capability is not HyperTransport capability"));
+ ptr = start;
+
+ /*
+ * Traverse the capabilities list checking each HT capability
+ * to see if it matches the requested HT capability.
+ */
+ for (;;) {
+ /* Skip to the next HT capability. */
+ if (pci_find_next_cap(child, PCIY_HT, ptr, &ptr) != 0)
+ break;
+
+ val = pci_read_config(child, ptr + PCIR_HT_COMMAND, 2);
+ if (capability == PCIM_HTCAP_SLAVE ||
+ capability == PCIM_HTCAP_HOST)
+ val &= 0xe000;
+ else
+ val &= PCIM_HTCMD_CAP_MASK;
+ if (val == capability) {
+ if (capreg != NULL)
+ *capreg = ptr;
+ return (0);
}
}
+
return (ENOENT);
}
@@ -1409,8 +1450,8 @@ pci_find_cap_method(device_t dev, device_t child, int
{
struct pci_devinfo *dinfo = device_get_ivars(child);
pcicfgregs *cfg = &dinfo->cfg;
- u_int32_t status;
- u_int8_t ptr;
+ uint32_t status;
+ uint8_t ptr;
/*
* Check the CAP_LIST bit of the PCI status register first.
@@ -1452,6 +1493,33 @@ pci_find_cap_method(device_t dev, device_t child, int
}
/*
+ * Find the next requested capability after start and return the offset in
+ * configuration space via the pointer provided. The function returns
+ * 0 on success and an error code otherwise.
+ */
+int
+pci_find_next_cap_method(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+ uint8_t ptr;
+
+ KASSERT(pci_read_config(child, start + PCICAP_ID, 1) == capability,
+ ("start capability is not expected capability"));
+
+ ptr = pci_read_config(child, start + PCICAP_NEXTPTR, 1);
+ while (ptr != 0) {
+ if (pci_read_config(child, ptr + PCICAP_ID, 1) == capability) {
+ if (capreg != NULL)
+ *capreg = ptr;
+ return (0);
+ }
+ ptr = pci_read_config(child, ptr + PCICAP_NEXTPTR, 1);
+ }
+
+ return (ENOENT);
+}
+
+/*
* Find the requested extended capability and return the offset in
* configuration space via the pointer provided. The function returns
* 0 on success and an error code otherwise.
@@ -1483,6 +1551,41 @@ pci_find_extcap_method(device_t dev, device_t child, i
if (ptr == 0)
break;
ecap = pci_read_config(child, ptr, 4);
+ }
+
+ return (ENOENT);
+}
+
+/*
+ * Find the next requested extended capability after start and return the
+ * offset in configuration space via the pointer provided. The function
+ * returns 0 on success and an error code otherwise.
+ */
+int
+pci_find_next_extcap_method(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ uint32_t ecap;
+ uint16_t ptr;
+
+ /* Only supported for PCI-express devices. */
+ if (cfg->pcie.pcie_location == 0)
+ return (ENXIO);
+
+ ecap = pci_read_config(child, start, 4);
+ KASSERT(PCI_EXTCAP_ID(ecap) == capability,
+ ("start extended capability is not expected capability"));
+ ptr = PCI_EXTCAP_NEXTPTR(ecap);
+ while (ptr != 0) {
+ ecap = pci_read_config(child, ptr, 4);
+ if (PCI_EXTCAP_ID(ecap) == capability) {
+ if (capreg != NULL)
+ *capreg = ptr;
+ return (0);
+ }
+ ptr = PCI_EXTCAP_NEXTPTR(ecap);
}
return (ENOENT);
Modified: stable/11/sys/dev/pci/pci_if.m
==============================================================================
--- stable/11/sys/dev/pci/pci_if.m Sat Mar 17 20:17:35 2018 (r331110)
+++ stable/11/sys/dev/pci/pci_if.m Sat Mar 17 20:20:29 2018 (r331111)
@@ -144,6 +144,14 @@ METHOD int find_cap {
int *capreg;
};
+METHOD int find_next_cap {
+ device_t dev;
+ device_t child;
+ int capability;
+ int start;
+ int *capreg;
+};
+
METHOD int find_extcap {
device_t dev;
device_t child;
@@ -151,10 +159,26 @@ METHOD int find_extcap {
int *capreg;
};
+METHOD int find_next_extcap {
+ device_t dev;
+ device_t child;
+ int capability;
+ int start;
+ int *capreg;
+};
+
METHOD int find_htcap {
device_t dev;
device_t child;
int capability;
+ int *capreg;
+};
+
+METHOD int find_next_htcap {
+ device_t dev;
+ device_t child;
+ int capability;
+ int start;
int *capreg;
};
Modified: stable/11/sys/dev/pci/pci_private.h
==============================================================================
--- stable/11/sys/dev/pci/pci_private.h Sat Mar 17 20:17:35 2018 (r331110)
+++ stable/11/sys/dev/pci/pci_private.h Sat Mar 17 20:20:29 2018 (r331111)
@@ -90,10 +90,16 @@ int pci_enable_io_method(device_t dev, device_t child
int pci_disable_io_method(device_t dev, device_t child, int space);
int pci_find_cap_method(device_t dev, device_t child,
int capability, int *capreg);
+int pci_find_next_cap_method(device_t dev, device_t child,
+ int capability, int start, int *capreg);
int pci_find_extcap_method(device_t dev, device_t child,
int capability, int *capreg);
+int pci_find_next_extcap_method(device_t dev, device_t child,
+ int capability, int start, int *capreg);
int pci_find_htcap_method(device_t dev, device_t child,
int capability, int *capreg);
+int pci_find_next_htcap_method(device_t dev, device_t child,
+ int capability, int start, int *capreg);
int pci_alloc_msi_method(device_t dev, device_t child, int *count);
int pci_alloc_msix_method(device_t dev, device_t child, int *count);
void pci_enable_msi_method(device_t dev, device_t child,
Modified: stable/11/sys/dev/pci/pcivar.h
==============================================================================
--- stable/11/sys/dev/pci/pcivar.h Sat Mar 17 20:17:35 2018 (r331110)
+++ stable/11/sys/dev/pci/pcivar.h Sat Mar 17 20:20:29 2018 (r331111)
@@ -468,15 +468,36 @@ pci_find_cap(device_t dev, int capability, int *capreg
}
static __inline int
+pci_find_next_cap(device_t dev, int capability, int start, int *capreg)
+{
+ return (PCI_FIND_NEXT_CAP(device_get_parent(dev), dev, capability, start,
+ capreg));
+}
+
+static __inline int
pci_find_extcap(device_t dev, int capability, int *capreg)
{
return (PCI_FIND_EXTCAP(device_get_parent(dev), dev, capability, capreg));
}
static __inline int
+pci_find_next_extcap(device_t dev, int capability, int start, int *capreg)
+{
+ return (PCI_FIND_NEXT_EXTCAP(device_get_parent(dev), dev, capability,
+ start, capreg));
+}
+
+static __inline int
pci_find_htcap(device_t dev, int capability, int *capreg)
{
return (PCI_FIND_HTCAP(device_get_parent(dev), dev, capability, capreg));
+}
+
+static __inline int
+pci_find_next_htcap(device_t dev, int capability, int start, int *capreg)
+{
+ return (PCI_FIND_NEXT_HTCAP(device_get_parent(dev), dev, capability,
+ start, capreg));
}
static __inline int
Modified: stable/11/sys/dev/pci/vga_pci.c
==============================================================================
--- stable/11/sys/dev/pci/vga_pci.c Sat Mar 17 20:17:35 2018 (r331110)
+++ stable/11/sys/dev/pci/vga_pci.c Sat Mar 17 20:20:29 2018 (r331111)
@@ -497,6 +497,14 @@ vga_pci_find_cap(device_t dev, device_t child, int cap
}
static int
+vga_pci_find_next_cap(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+
+ return (pci_find_next_cap(dev, capability, start, capreg));
+}
+
+static int
vga_pci_find_extcap(device_t dev, device_t child, int capability,
int *capreg)
{
@@ -505,6 +513,14 @@ vga_pci_find_extcap(device_t dev, device_t child, int
}
static int
+vga_pci_find_next_extcap(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+
+ return (pci_find_next_extcap(dev, capability, start, capreg));
+}
+
+static int
vga_pci_find_htcap(device_t dev, device_t child, int capability,
int *capreg)
{
@@ -513,6 +529,14 @@ vga_pci_find_htcap(device_t dev, device_t child, int c
}
static int
+vga_pci_find_next_htcap(device_t dev, device_t child, int capability,
+ int start, int *capreg)
+{
+
+ return (pci_find_next_htcap(dev, capability, start, capreg));
+}
+
+static int
vga_pci_alloc_msi(device_t dev, device_t child, int *count)
{
struct vga_pci_softc *sc;
@@ -622,8 +646,11 @@ static device_method_t vga_pci_methods[] = {
DEVMETHOD(pci_set_powerstate, vga_pci_set_powerstate),
DEVMETHOD(pci_assign_interrupt, vga_pci_assign_interrupt),
DEVMETHOD(pci_find_cap, vga_pci_find_cap),
+ DEVMETHOD(pci_find_next_cap, vga_pci_find_next_cap),
DEVMETHOD(pci_find_extcap, vga_pci_find_extcap),
+ DEVMETHOD(pci_find_next_extcap, vga_pci_find_next_extcap),
DEVMETHOD(pci_find_htcap, vga_pci_find_htcap),
+ DEVMETHOD(pci_find_next_htcap, vga_pci_find_next_htcap),
DEVMETHOD(pci_alloc_msi, vga_pci_alloc_msi),
DEVMETHOD(pci_alloc_msix, vga_pci_alloc_msix),
DEVMETHOD(pci_remap_msix, vga_pci_remap_msix),
More information about the svn-src-stable
mailing list