PCI scan by BAR number

Added BAR (Base Address Registers) as a parameter for PCI scan.
Some devices (as UART in Quark) use two set of BARs for different
purposes. A driver may require only one of them.

BARs are numbered from 0 to PCI_MAX_BARS.
PCI_BAR_ANY means ignore the BAR number. Constants are defined
in drivers/pci.h

If device class is not specified as a scanning parameter, and
set to 0, ignore it.

Change-Id: I6b7116c5c6cf9c470ab22bec9eb74842f15b5d99
Signed-off-by: Dmitriy Korovkin <dmitriy.korovkin@windriver.com>
This commit is contained in:
Dmitriy Korovkin 2015-05-25 17:26:33 -04:00 committed by Anas Nashif
commit 627155afeb
2 changed files with 17 additions and 5 deletions

View file

@ -146,7 +146,6 @@ restarting from 0.
#define BAR_IO_MASK(x) ((x) & ~0x3)
#define BAR_MEM_MASK(x) ((x) & ~0xf)
#define MAX_BARS 6
struct bus_dev {
uint16_t set:1;
@ -310,8 +309,12 @@ static inline int pci_dev_scan(union pci_addr_reg pci_ctrl_addr,
pci_ctrl_addr.field.device;
}
/* Skip a device if its class is not specified by the caller */
if (pci_dev_header.field.class != lookup.info.class) {
/*
* Skip a device if its class is specified by the
* caller and does not match
*/
if (lookup.info.class &&
pci_dev_header.field.class != lookup.info.class) {
continue;
}
@ -325,13 +328,16 @@ static inline int pci_dev_scan(union pci_addr_reg pci_ctrl_addr,
if ((pci_dev_header.field.hdr_type & 0x7f) == 1) {
max_bars = 2;
} else {
max_bars = MAX_BARS;
max_bars = PCI_MAX_BARS;
}
for (; lookup.bar < max_bars; lookup.bar++) {
/* Ignore BARs with errors and 64 bit BARs */
if (pci_bar_params_get(pci_ctrl_addr, dev_info) != 0) {
continue;
} else if (lookup.info.bar != PCI_BAR_ANY &&
lookup.bar != lookup.info.bar) {
continue;
} else {
dev_info->vendor_id =
pci_dev_header.field.vendor_id;
@ -361,6 +367,7 @@ void pci_bus_scan_init(void)
lookup.info.class = 0;
lookup.info.vendor_id = 0;
lookup.info.device_id = 0;
lookup.info.bar = PCI_BAR_ANY;
lookup.bus = 0;
lookup.dev = 0;
lookup.func = 0;
@ -387,10 +394,12 @@ int pci_bus_scan(struct pci_dev_info *dev_info)
if (!lookup.info.class &&
!lookup.info.vendor_id &&
!lookup.info.device_id) {
!lookup.info.device_id &&
lookup.info.bar == PCI_BAR_ANY) {
lookup.info.class = dev_info->class;
lookup.info.vendor_id = dev_info->vendor_id;
lookup.info.device_id = dev_info->device_id;
lookup.info.bar = dev_info->bar;
if (class_bd[lookup.info.class].set) {
lookup.bus = class_bd[lookup.info.class].bus;

View file

@ -43,6 +43,9 @@ Module declares routines of PCI bus initialization and query
#define BAR_SPACE_MEM 0
#define BAR_SPACE_IO 1
#define PCI_MAX_BARS 6
#define PCI_BAR_ANY PCI_MAX_BARS
/* PCI device information */
struct pci_dev_info {