Add a new get_id interface to pci and pcib. This will allow us to both
detect failures, and get different PCI IDs. For the former the interface returns an int to signal an error. The ID is returned at a uintptr_t * argument. For the latter there is a type argument that allows selecting the ID type. This only specifies a single type, however a MSI type will be added to handle the need to find the ID the hardware passes to the ARM GICv3 interrupt controller. A follow up commit will be made to remove pci_get_rid. Reviewed by: jhb, rstone Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D6239
This commit is contained in:
parent
4aa1608aee
commit
9a36a337ff
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299467
@ -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 \
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 23, 2015
|
||||
.Dd May 11, 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
|
||||
|
@ -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. */
|
||||
|
@ -27,6 +27,7 @@
|
||||
#
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
INTERFACE pci;
|
||||
|
||||
@ -208,9 +209,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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -175,10 +175,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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -268,6 +268,10 @@ struct pci_devinfo {
|
||||
|
||||
#ifdef _SYS_BUS_H_
|
||||
|
||||
enum pci_id_type {
|
||||
PCI_ID_RID,
|
||||
};
|
||||
|
||||
#include "pci_if.h"
|
||||
|
||||
enum pci_device_ivars {
|
||||
@ -542,10 +546,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
|
||||
|
Loading…
Reference in New Issue
Block a user