summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-06-24 17:26:42 +0000
committerjhb <jhb@FreeBSD.org>2016-06-24 17:26:42 +0000
commit73d915a1ae17a1f5e5259b8555ff53f9c3ba1ad2 (patch)
tree42c9c5655c7b53d96282330ff2dff3f5bb7e6de4
parentb5c3fb9427806b740f7df3e43a1513e1f5fa840b (diff)
downloadFreeBSD-src-73d915a1ae17a1f5e5259b8555ff53f9c3ba1ad2.zip
FreeBSD-src-73d915a1ae17a1f5e5259b8555ff53f9c3ba1ad2.tar.gz
Add pci_get_max_payload() to fetch the PCI-express maximum payload size.
Approved by: re (gjb) MFC after: 2 weeks Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D6951
-rw-r--r--share/man/man9/pci.915
-rw-r--r--sys/dev/pci/pci.c16
-rw-r--r--sys/dev/pci/pcivar.h1
3 files changed, 31 insertions, 1 deletions
diff --git a/share/man/man9/pci.9 b/share/man/man9/pci.9
index 52df250..a53f971 100644
--- a/share/man/man9/pci.9
+++ b/share/man/man9/pci.9
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 16, 2016
+.Dd June 24, 2016
.Dt PCI 9
.Os
.Sh NAME
@@ -44,6 +44,7 @@
.Nm pci_find_htcap ,
.Nm pci_find_pcie_root_port ,
.Nm pci_get_id ,
+.Nm pci_get_max_payload ,
.Nm pci_get_max_read_req ,
.Nm pci_get_powerstate ,
.Nm pci_get_vpd_ident ,
@@ -100,6 +101,8 @@
.Ft int
.Fn pci_get_id "device_t dev" "enum pci_id_type type" "uintptr_t *id"
.Ft int
+.Fn pci_get_max_payload "device_t dev"
+.Ft int
.Fn pci_get_max_read_req "device_t dev"
.Ft int
.Fn pci_get_powerstate "device_t dev"
@@ -461,6 +464,16 @@ or
.Xr bus_activate_resource 9 .
.Pp
The
+.Fn pci_get_max_payload
+function returns the current maximum TLP payload size in bytes for a
+PCI-express device.
+If the
+.Fa dev
+device is not a PCI-express device,
+.Fn pci_get_max_payload
+returns zero.
+.Pp
+The
.Fn pci_get_max_read_req
function returns the current maximum read request size in bytes for a
PCI-express device.
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 06877b9..784dd00 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1993,6 +1993,22 @@ pci_ht_map_msi(device_t dev, uint64_t addr)
}
int
+pci_get_max_payload(device_t dev)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(dev);
+ int cap;
+ uint16_t val;
+
+ cap = dinfo->cfg.pcie.pcie_location;
+ if (cap == 0)
+ return (0);
+ val = pci_read_config(dev, cap + PCIER_DEVICE_CTL, 2);
+ val &= PCIEM_CTL_MAX_PAYLOAD;
+ val >>= 5;
+ return (1 << (val + 7));
+}
+
+int
pci_get_max_read_req(device_t dev)
{
struct pci_devinfo *dinfo = device_get_ivars(dev);
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 7eaf5a6..3180b4e 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -585,6 +585,7 @@ int pci_msix_device_blacklisted(device_t dev);
void pci_ht_map_msi(device_t dev, uint64_t addr);
device_t pci_find_pcie_root_port(device_t dev);
+int pci_get_max_payload(device_t dev);
int pci_get_max_read_req(device_t dev);
void pci_restore_state(device_t dev);
void pci_save_state(device_t dev);
OpenPOWER on IntegriCloud