summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2016-05-16 09:15:50 +0000
committerAndrew Turner <andrew@FreeBSD.org>2016-05-16 09:15:50 +0000
commitd7be980dbe6961abce6b3e12de0391cbad295f95 (patch)
treeffb68344d6a4eba6f36168fd0dca004f1d829d52
parent3fc155dc64bd967aebcde25b51c4210d870718b9 (diff)
Notes
-rw-r--r--share/man/man9/Makefile1
-rw-r--r--share/man/man9/pci.917
-rw-r--r--sys/dev/pci/pci.c12
-rw-r--r--sys/dev/pci/pci_if.m9
-rw-r--r--sys/dev/pci/pci_pci.c19
-rw-r--r--sys/dev/pci/pcib_if.m10
-rw-r--r--sys/dev/pci/pcib_private.h3
-rw-r--r--sys/dev/pci/pcib_support.c10
-rw-r--r--sys/dev/pci/pcivar.h18
9 files changed, 79 insertions, 20 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 21e8af4cf9e7..27316080813c 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1290,6 +1290,7 @@ MLINKS+=pci.9 pci_alloc_msi.9 \
pci.9 pci_find_extcap.9 \
pci.9 pci_find_htcap.9 \
pci.9 pci_find_pcie_root_port.9 \
+ pci.9 pci_get_id.9 \
pci.9 pci_get_max_read_req.9 \
pci.9 pci_get_powerstate.9 \
pci.9 pci_get_vpd_ident.9 \
diff --git a/share/man/man9/pci.9 b/share/man/man9/pci.9
index 0e1024cf1850..4b9003ac9c62 100644
--- a/share/man/man9/pci.9
+++ b/share/man/man9/pci.9
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 23, 2015
+.Dd May 16, 2016
.Dt PCI 9
.Os
.Sh NAME
@@ -43,6 +43,7 @@
.Nm pci_find_extcap ,
.Nm pci_find_htcap ,
.Nm pci_find_pcie_root_port ,
+.Nm pci_get_id ,
.Nm pci_get_max_read_req ,
.Nm pci_get_powerstate ,
.Nm pci_get_vpd_ident ,
@@ -97,6 +98,8 @@
.Ft device_t
.Fn pci_find_pcie_root_port "device_t dev"
.Ft int
+.Fn pci_get_id "device_t dev" "enum pci_id_type type" "uintptr_t *id"
+.Ft int
.Fn pci_get_max_read_req "device_t dev"
.Ft int
.Fn pci_get_powerstate "device_t dev"
@@ -357,6 +360,18 @@ returns
.Dv NULL .
.Pp
The
+.Fn pci_get_id
+function is used to read an identifier from a device.
+The
+.Fa type
+flag is used to specify which identifier to read.
+The following flags are supported:
+.Bl -hang -width ".Dv PCI_ID_RID"
+.It Dv PCI_ID_RID
+Read the routing identifier for the device.
+.El
+.Pp
+The
.Fn pci_get_vpd_ident
function is used to fetch a device's Vital Product Data
.Pq VPD
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 3c998b4f6681..06877b9bb5b7 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -122,7 +122,8 @@ static void pci_resume_msix(device_t dev);
static int pci_remap_intr_method(device_t bus, device_t dev,
u_int irq);
-static uint16_t pci_get_rid_method(device_t dev, device_t child);
+static int pci_get_id_method(device_t dev, device_t child,
+ enum pci_id_type type, uintptr_t *rid);
static struct pci_devinfo * pci_fill_devinfo(device_t pcib, device_t bus, int d,
int b, int s, int f, uint16_t vid, uint16_t did);
@@ -190,7 +191,7 @@ static device_method_t pci_methods[] = {
DEVMETHOD(pci_msix_count, pci_msix_count_method),
DEVMETHOD(pci_msix_pba_bar, pci_msix_pba_bar_method),
DEVMETHOD(pci_msix_table_bar, pci_msix_table_bar_method),
- DEVMETHOD(pci_get_rid, pci_get_rid_method),
+ DEVMETHOD(pci_get_id, pci_get_id_method),
DEVMETHOD(pci_alloc_devinfo, pci_alloc_devinfo_method),
DEVMETHOD(pci_child_added, pci_child_added_method),
#ifdef PCI_IOV
@@ -5823,11 +5824,12 @@ pci_restore_state(device_t dev)
pci_cfg_restore(dev, dinfo);
}
-static uint16_t
-pci_get_rid_method(device_t dev, device_t child)
+static int
+pci_get_id_method(device_t dev, device_t child, enum pci_id_type type,
+ uintptr_t *id)
{
- return (PCIB_GET_RID(device_get_parent(dev), child));
+ return (PCIB_GET_ID(device_get_parent(dev), child, type, id));
}
/* Find the upstream port of a given PCI device in a root complex. */
diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m
index da8030584538..25dbce4d7255 100644
--- a/sys/dev/pci/pci_if.m
+++ b/sys/dev/pci/pci_if.m
@@ -27,6 +27,7 @@
#
#include <sys/bus.h>
+#include <dev/pci/pcivar.h>
INTERFACE pci;
@@ -54,6 +55,10 @@ CODE {
HEADER {
struct nvlist;
+
+ enum pci_id_type {
+ PCI_ID_RID,
+ };
}
@@ -208,9 +213,11 @@ METHOD int msix_table_bar {
device_t child;
} DEFAULT null_msix_bar;
-METHOD uint16_t get_rid {
+METHOD int get_id {
device_t dev;
device_t child;
+ enum pci_id_type type;
+ uintptr_t *id;
};
METHOD struct pci_devinfo * alloc_devinfo {
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index e3539f5a9a84..87475f662736 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -59,7 +59,8 @@ static int pcib_suspend(device_t dev);
static int pcib_resume(device_t dev);
static int pcib_power_for_sleep(device_t pcib, device_t dev,
int *pstate);
-static uint16_t pcib_ari_get_rid(device_t pcib, device_t dev);
+static int pcib_ari_get_id(device_t pcib, device_t dev,
+ enum pci_id_type type, uintptr_t *id);
static uint32_t pcib_read_config(device_t dev, u_int b, u_int s,
u_int f, u_int reg, int width);
static void pcib_write_config(device_t dev, u_int b, u_int s,
@@ -114,7 +115,7 @@ static device_method_t pcib_methods[] = {
DEVMETHOD(pcib_release_msix, pcib_release_msix),
DEVMETHOD(pcib_map_msi, pcib_map_msi),
DEVMETHOD(pcib_power_for_sleep, pcib_power_for_sleep),
- DEVMETHOD(pcib_get_rid, pcib_ari_get_rid),
+ DEVMETHOD(pcib_get_id, pcib_ari_get_id),
DEVMETHOD(pcib_try_enable_ari, pcib_try_enable_ari),
DEVMETHOD(pcib_ari_enabled, pcib_ari_enabled),
DEVMETHOD(pcib_decode_rid, pcib_ari_decode_rid),
@@ -2574,26 +2575,32 @@ pcib_ari_enabled(device_t pcib)
return ((sc->flags & PCIB_ENABLE_ARI) != 0);
}
-static uint16_t
-pcib_ari_get_rid(device_t pcib, device_t dev)
+static int
+pcib_ari_get_id(device_t pcib, device_t dev, enum pci_id_type type,
+ uintptr_t *id)
{
struct pcib_softc *sc;
uint8_t bus, slot, func;
+ if (type != PCI_ID_RID)
+ return (ENXIO);
+
sc = device_get_softc(pcib);
if (sc->flags & PCIB_ENABLE_ARI) {
bus = pci_get_bus(dev);
func = pci_get_function(dev);
- return (PCI_ARI_RID(bus, func));
+ *id = (PCI_ARI_RID(bus, func));
} else {
bus = pci_get_bus(dev);
slot = pci_get_slot(dev);
func = pci_get_function(dev);
- return (PCI_RID(bus, slot, func));
+ *id = (PCI_RID(bus, slot, func));
}
+
+ return (0);
}
/*
diff --git a/sys/dev/pci/pcib_if.m b/sys/dev/pci/pcib_if.m
index 6fdc0f42518e..530744a2f14f 100644
--- a/sys/dev/pci/pcib_if.m
+++ b/sys/dev/pci/pcib_if.m
@@ -48,6 +48,10 @@ CODE {
}
};
+HEADER {
+ #include "pci_if.h"
+};
+
#
# Return the number of slots on the attached PCI bus.
#
@@ -175,10 +179,12 @@ METHOD int power_for_sleep {
#
# Return the PCI Routing Identifier (RID) for the device.
#
-METHOD uint16_t get_rid {
+METHOD int get_id {
device_t pcib;
device_t dev;
-} DEFAULT pcib_get_rid;
+ enum pci_id_type type;
+ uintptr_t *id;
+} DEFAULT pcib_get_id;
#
# Enable Alternative RID Interpretation if both the downstream port (pcib)
diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h
index c209162b34ed..7d43e60a3547 100644
--- a/sys/dev/pci/pcib_private.h
+++ b/sys/dev/pci/pcib_private.h
@@ -190,7 +190,8 @@ int pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs);
int pcib_alloc_msix(device_t pcib, device_t dev, int *irq);
int pcib_release_msix(device_t pcib, device_t dev, int irq);
int pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data);
-uint16_t pcib_get_rid(device_t pcib, device_t dev);
+int pcib_get_id(device_t pcib, device_t dev, enum pci_id_type type,
+ uintptr_t *id);
void pcib_decode_rid(device_t pcib, uint16_t rid, int *bus,
int *slot, int *func);
diff --git a/sys/dev/pci/pcib_support.c b/sys/dev/pci/pcib_support.c
index ef88a601ac64..fdd3a45e2572 100644
--- a/sys/dev/pci/pcib_support.c
+++ b/sys/dev/pci/pcib_support.c
@@ -54,16 +54,20 @@ pcib_maxfuncs(device_t dev)
return (PCI_FUNCMAX);
}
-uint16_t
-pcib_get_rid(device_t pcib, device_t dev)
+int
+pcib_get_id(device_t pcib, device_t dev, enum pci_id_type type, uintptr_t *id)
{
uint8_t bus, slot, func;
+ if (type != PCI_ID_RID)
+ return (ENXIO);
+
bus = pci_get_bus(dev);
slot = pci_get_slot(dev);
func = pci_get_function(dev);
- return (PCI_RID(bus, slot, func));
+ *id = (PCI_RID(bus, slot, func));
+ return (0);
}
void
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 8d9ea7ec02fb..7eaf5a629510 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -542,10 +542,26 @@ pci_msix_table_bar(device_t dev)
return (PCI_MSIX_TABLE_BAR(device_get_parent(dev), dev));
}
+static __inline int
+pci_get_id(device_t dev, enum pci_id_type type, uintptr_t *id)
+{
+ return (PCI_GET_ID(device_get_parent(dev), dev, type, id));
+}
+
+/*
+ * This is the deprecated interface, there is no way to tell the difference
+ * between a failure and a valid value that happens to be the same as the
+ * failure value.
+ */
static __inline uint16_t
pci_get_rid(device_t dev)
{
- return (PCI_GET_RID(device_get_parent(dev), dev));
+ uintptr_t rid;
+
+ if (pci_get_id(dev, PCI_ID_RID, &rid) != 0)
+ return (0);
+
+ return (rid);
}
static __inline void