Add accessor methods to fetch the BAR holding the MSI-X table and PBA.
While here, explicitly note the requirement that the BAR(s) must be allocated prior to calling pci_alloc_msix(). Reviewed by: andrew, emaste MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D4688
This commit is contained in:
parent
9e8d8b4b0c
commit
ce204e1bd8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=292669
@ -1287,6 +1287,8 @@ MLINKS+=pci.9 pci_alloc_msi.9 \
|
||||
pci.9 pci_iov_detach.9 \
|
||||
pci.9 pci_msi_count.9 \
|
||||
pci.9 pci_msix_count.9 \
|
||||
pci.9 pci_msix_pba_bar.9 \
|
||||
pci.9 pci_msix_table_bar.9 \
|
||||
pci.9 pci_pending_msix.9 \
|
||||
pci.9 pci_read_config.9 \
|
||||
pci.9 pci_release_msi.9 \
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 5, 2015
|
||||
.Dd December 23, 2015
|
||||
.Dt PCI 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -51,6 +51,8 @@
|
||||
.Nm pci_iov_detach ,
|
||||
.Nm pci_msi_count ,
|
||||
.Nm pci_msix_count ,
|
||||
.Nm pci_msix_pba_bar ,
|
||||
.Nm pci_msix_table_bar ,
|
||||
.Nm pci_pending_msix ,
|
||||
.Nm pci_read_config ,
|
||||
.Nm pci_release_msi ,
|
||||
@ -107,6 +109,10 @@
|
||||
.Ft int
|
||||
.Fn pci_msix_count "device_t dev"
|
||||
.Ft int
|
||||
.Fn pci_msix_pba_bar "device_t dev"
|
||||
.Ft int
|
||||
.Fn pci_msix_table_bar "device_t dev"
|
||||
.Ft int
|
||||
.Fn pci_pending_msix "device_t dev" "u_int index"
|
||||
.Ft uint32_t
|
||||
.Fn pci_read_config "device_t dev" "int reg" "int width"
|
||||
@ -694,6 +700,37 @@ then
|
||||
returns zero.
|
||||
.Pp
|
||||
The
|
||||
.Fn pci_msix_pba_bar
|
||||
function returns the offset in configuration space of the Base Address Register
|
||||
.Pq BAR
|
||||
containing the MSI-X Pending Bit Array (PBA) for device
|
||||
.Fa dev .
|
||||
The returned value can be used as the resource ID with
|
||||
.Xr bus_alloc_resource 9
|
||||
and
|
||||
.Xr bus_release_resource 9
|
||||
to allocate the BAR.
|
||||
If the device does not support MSI-X,
|
||||
then
|
||||
.Fn pci_msix_pba_bar
|
||||
returns -1.
|
||||
.Pp
|
||||
The
|
||||
.Fn pci_msix_table_bar
|
||||
function returns the offset in configuration space of the BAR
|
||||
containing the MSI-X vector table for device
|
||||
.Fa dev .
|
||||
The returned value can be used as the resource ID with
|
||||
.Xr bus_alloc_resource 9
|
||||
and
|
||||
.Xr bus_release_resource 9
|
||||
to allocate the BAR.
|
||||
If the device does not support MSI-X,
|
||||
then
|
||||
.Fn pci_msix_table_bar
|
||||
returns -1.
|
||||
.Pp
|
||||
The
|
||||
.Fn pci_alloc_msix
|
||||
function attempts to allocate
|
||||
.Fa *count
|
||||
@ -732,12 +769,21 @@ it returns an error.
|
||||
Unlike MSI,
|
||||
MSI-X does not require message counts that are powers of two.
|
||||
.Pp
|
||||
The BARs containing the MSI-X vector table and PBA must be
|
||||
allocated via
|
||||
.Xr bus_alloc_resource 9
|
||||
before calling
|
||||
.Fn pci_alloc_msix
|
||||
and must not be released until after calling
|
||||
.Fn pci_release_msi .
|
||||
Note that the vector table and PBA may be stored in the same BAR or in
|
||||
different BARs.
|
||||
.Pp
|
||||
The
|
||||
.Fn pci_pending_msix
|
||||
function examines the
|
||||
.Fa dev
|
||||
device's Pending Bit Array
|
||||
.Pq PBA
|
||||
device's PBA
|
||||
to determine the pending status of the MSI-X message at table index
|
||||
.Fa index .
|
||||
If the indicated message is pending,
|
||||
@ -853,3 +899,6 @@ These do not refer to the geographic location of PCI devices,
|
||||
but to the device number assigned by the combination of the PCI IDSEL
|
||||
mechanism and the platform firmware.
|
||||
This should be taken note of when working with the kernel PCI code.
|
||||
.Pp
|
||||
The PCI bus driver should allocate the MSI-X vector table and PBA internally
|
||||
as necessary rather than requiring the caller to do so.
|
||||
|
@ -187,6 +187,8 @@ static device_method_t pci_methods[] = {
|
||||
DEVMETHOD(pci_release_msi, pci_release_msi_method),
|
||||
DEVMETHOD(pci_msi_count, pci_msi_count_method),
|
||||
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_child_added, pci_child_added_method),
|
||||
#ifdef PCI_IOV
|
||||
@ -1851,6 +1853,28 @@ pci_msix_count_method(device_t dev, device_t child)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pci_msix_pba_bar_method(device_t dev, device_t child)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(child);
|
||||
struct pcicfg_msix *msix = &dinfo->cfg.msix;
|
||||
|
||||
if (pci_do_msix && msix->msix_location != 0)
|
||||
return (msix->msix_pba_bar);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
pci_msix_table_bar_method(device_t dev, device_t child)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(child);
|
||||
struct pcicfg_msix *msix = &dinfo->cfg.msix;
|
||||
|
||||
if (pci_do_msix && msix->msix_location != 0)
|
||||
return (msix->msix_table_bar);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* HyperTransport MSI mapping control
|
||||
*/
|
||||
|
@ -36,7 +36,13 @@ CODE {
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
null_msix_bar(device_t dev, device_t child)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static device_t
|
||||
null_create_iov_child(device_t bus, device_t pf, uint16_t rid,
|
||||
uint16_t vid, uint16_t did)
|
||||
@ -192,6 +198,16 @@ METHOD int msix_count {
|
||||
device_t child;
|
||||
} DEFAULT null_msi_count;
|
||||
|
||||
METHOD int msix_pba_bar {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
} DEFAULT null_msix_bar;
|
||||
|
||||
METHOD int msix_table_bar {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
} DEFAULT null_msix_bar;
|
||||
|
||||
METHOD uint16_t get_rid {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
|
@ -102,6 +102,8 @@ int pci_remap_msix_method(device_t dev, device_t child,
|
||||
int pci_release_msi_method(device_t dev, device_t child);
|
||||
int pci_msi_count_method(device_t dev, device_t child);
|
||||
int pci_msix_count_method(device_t dev, device_t child);
|
||||
int pci_msix_pba_bar_method(device_t dev, device_t child);
|
||||
int pci_msix_table_bar_method(device_t dev, device_t child);
|
||||
struct resource *pci_alloc_resource(device_t dev, device_t child,
|
||||
int type, int *rid, u_long start, u_long end, u_long count,
|
||||
u_int flags);
|
||||
|
@ -516,6 +516,18 @@ pci_msix_count(device_t dev)
|
||||
return (PCI_MSIX_COUNT(device_get_parent(dev), dev));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
pci_msix_pba_bar(device_t dev)
|
||||
{
|
||||
return (PCI_MSIX_PBA_BAR(device_get_parent(dev), dev));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
pci_msix_table_bar(device_t dev)
|
||||
{
|
||||
return (PCI_MSIX_TABLE_BAR(device_get_parent(dev), dev));
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
pci_get_rid(device_t dev)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user