Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140201760
D14325.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D14325.diff
View Options
Index: head/share/man/man9/pci.9
===================================================================
--- head/share/man/man9/pci.9
+++ head/share/man/man9/pci.9
@@ -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 @@
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 @@
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 @@
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
Index: head/sys/dev/pci/hostb_pci.c
===================================================================
--- head/sys/dev/pci/hostb_pci.c
+++ head/sys/dev/pci/hostb_pci.c
@@ -207,6 +207,14 @@
}
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 @@
}
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 @@
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 @@
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 }
};
Index: head/sys/dev/pci/pci.c
===================================================================
--- head/sys/dev/pci/pci.c
+++ head/sys/dev/pci/pci.c
@@ -183,8 +183,11 @@
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),
@@ -1377,7 +1380,7 @@
* 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)
@@ -1391,13 +1394,51 @@
}
/* 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);
}
@@ -1412,8 +1453,8 @@
{
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.
@@ -1455,6 +1496,33 @@
}
/*
+ * 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.
@@ -1486,6 +1554,41 @@
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);
Index: head/sys/dev/pci/pci_if.m
===================================================================
--- head/sys/dev/pci/pci_if.m
+++ head/sys/dev/pci/pci_if.m
@@ -141,6 +141,14 @@
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;
@@ -148,10 +156,26 @@
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;
};
Index: head/sys/dev/pci/pci_private.h
===================================================================
--- head/sys/dev/pci/pci_private.h
+++ head/sys/dev/pci/pci_private.h
@@ -90,10 +90,16 @@
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,
Index: head/sys/dev/pci/pcivar.h
===================================================================
--- head/sys/dev/pci/pcivar.h
+++ head/sys/dev/pci/pcivar.h
@@ -468,15 +468,36 @@
}
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
Index: head/sys/dev/pci/vga_pci.c
===================================================================
--- head/sys/dev/pci/vga_pci.c
+++ head/sys/dev/pci/vga_pci.c
@@ -497,6 +497,14 @@
}
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 @@
}
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 @@
}
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 @@
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),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Dec 22, 9:39 AM (10 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27131712
Default Alt Text
D14325.diff (13 KB)
Attached To
Mode
D14325: Add pci_find_next_cap, pci_find_next_extcap, and pci_find_next_htcap
Attached
Detach File
Event Timeline
Log In to Comment