mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 14:48:57 +00:00
MFC 292669:
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().
This commit is contained in:
parent
1fe4006656
commit
7746419926
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/stable/10/; revision=294340
@ -1022,6 +1022,8 @@ MLINKS+=pci.9 pci_alloc_msi.9 \
|
|||||||
pci.9 pci_get_vpd_readonly.9 \
|
pci.9 pci_get_vpd_readonly.9 \
|
||||||
pci.9 pci_msi_count.9 \
|
pci.9 pci_msi_count.9 \
|
||||||
pci.9 pci_msix_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_pending_msix.9 \
|
||||||
pci.9 pci_read_config.9 \
|
pci.9 pci_read_config.9 \
|
||||||
pci.9 pci_release_msi.9 \
|
pci.9 pci_release_msi.9 \
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 5, 2015
|
.Dd December 23, 2015
|
||||||
.Dt PCI 9
|
.Dt PCI 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -49,6 +49,8 @@
|
|||||||
.Nm pci_get_vpd_readonly ,
|
.Nm pci_get_vpd_readonly ,
|
||||||
.Nm pci_msi_count ,
|
.Nm pci_msi_count ,
|
||||||
.Nm pci_msix_count ,
|
.Nm pci_msix_count ,
|
||||||
|
.Nm pci_msix_pba_bar ,
|
||||||
|
.Nm pci_msix_table_bar ,
|
||||||
.Nm pci_pending_msix ,
|
.Nm pci_pending_msix ,
|
||||||
.Nm pci_read_config ,
|
.Nm pci_read_config ,
|
||||||
.Nm pci_release_msi ,
|
.Nm pci_release_msi ,
|
||||||
@ -105,6 +107,10 @@
|
|||||||
.Ft int
|
.Ft int
|
||||||
.Fn pci_msix_count "device_t dev"
|
.Fn pci_msix_count "device_t dev"
|
||||||
.Ft int
|
.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"
|
.Fn pci_pending_msix "device_t dev" "u_int index"
|
||||||
.Ft uint32_t
|
.Ft uint32_t
|
||||||
.Fn pci_read_config "device_t dev" "int reg" "int width"
|
.Fn pci_read_config "device_t dev" "int reg" "int width"
|
||||||
@ -618,6 +624,37 @@ then
|
|||||||
returns zero.
|
returns zero.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
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
|
.Fn pci_alloc_msix
|
||||||
function attempts to allocate
|
function attempts to allocate
|
||||||
.Fa *count
|
.Fa *count
|
||||||
@ -656,12 +693,21 @@ it returns an error.
|
|||||||
Unlike MSI,
|
Unlike MSI,
|
||||||
MSI-X does not require message counts that are powers of two.
|
MSI-X does not require message counts that are powers of two.
|
||||||
.Pp
|
.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
|
The
|
||||||
.Fn pci_pending_msix
|
.Fn pci_pending_msix
|
||||||
function examines the
|
function examines the
|
||||||
.Fa dev
|
.Fa dev
|
||||||
device's Pending Bit Array
|
device's PBA
|
||||||
.Pq PBA
|
|
||||||
to determine the pending status of the MSI-X message at table index
|
to determine the pending status of the MSI-X message at table index
|
||||||
.Fa index .
|
.Fa index .
|
||||||
If the indicated message is pending,
|
If the indicated message is pending,
|
||||||
@ -776,3 +822,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
|
but to the device number assigned by the combination of the PCI IDSEL
|
||||||
mechanism and the platform firmware.
|
mechanism and the platform firmware.
|
||||||
This should be taken note of when working with the kernel PCI code.
|
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.
|
||||||
|
@ -182,6 +182,8 @@ static device_method_t pci_methods[] = {
|
|||||||
DEVMETHOD(pci_release_msi, pci_release_msi_method),
|
DEVMETHOD(pci_release_msi, pci_release_msi_method),
|
||||||
DEVMETHOD(pci_msi_count, pci_msi_count_method),
|
DEVMETHOD(pci_msi_count, pci_msi_count_method),
|
||||||
DEVMETHOD(pci_msix_count, pci_msix_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_get_rid, pci_get_rid_method),
|
||||||
DEVMETHOD(pci_child_added, pci_child_added_method),
|
DEVMETHOD(pci_child_added, pci_child_added_method),
|
||||||
|
|
||||||
@ -1827,6 +1829,28 @@ pci_msix_count_method(device_t dev, device_t child)
|
|||||||
return (0);
|
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
|
* HyperTransport MSI mapping control
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +36,12 @@ CODE {
|
|||||||
{
|
{
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
null_msix_bar(device_t dev, device_t child)
|
||||||
|
{
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -180,6 +186,16 @@ METHOD int msix_count {
|
|||||||
device_t child;
|
device_t child;
|
||||||
} DEFAULT null_msi_count;
|
} 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 {
|
METHOD uint16_t get_rid {
|
||||||
device_t dev;
|
device_t dev;
|
||||||
device_t child;
|
device_t child;
|
||||||
|
@ -100,6 +100,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_release_msi_method(device_t dev, device_t child);
|
||||||
int pci_msi_count_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_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,
|
struct resource *pci_alloc_resource(device_t dev, device_t child,
|
||||||
int type, int *rid, u_long start, u_long end, u_long count,
|
int type, int *rid, u_long start, u_long end, u_long count,
|
||||||
u_int flags);
|
u_int flags);
|
||||||
|
@ -495,6 +495,18 @@ pci_msix_count(device_t dev)
|
|||||||
return (PCI_MSIX_COUNT(device_get_parent(dev), 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
|
static __inline uint16_t
|
||||||
pci_get_rid(device_t dev)
|
pci_get_rid(device_t dev)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user