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_IO_MASK(x) ((x) & ~0x3)
#define BAR_MEM_MASK(x) ((x) & ~0xf) #define BAR_MEM_MASK(x) ((x) & ~0xf)
#define MAX_BARS 6
struct bus_dev { struct bus_dev {
uint16_t set:1; 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; 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; 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) { if ((pci_dev_header.field.hdr_type & 0x7f) == 1) {
max_bars = 2; max_bars = 2;
} else { } else {
max_bars = MAX_BARS; max_bars = PCI_MAX_BARS;
} }
for (; lookup.bar < max_bars; lookup.bar++) { for (; lookup.bar < max_bars; lookup.bar++) {
/* Ignore BARs with errors and 64 bit BARs */ /* Ignore BARs with errors and 64 bit BARs */
if (pci_bar_params_get(pci_ctrl_addr, dev_info) != 0) { if (pci_bar_params_get(pci_ctrl_addr, dev_info) != 0) {
continue; continue;
} else if (lookup.info.bar != PCI_BAR_ANY &&
lookup.bar != lookup.info.bar) {
continue;
} else { } else {
dev_info->vendor_id = dev_info->vendor_id =
pci_dev_header.field.vendor_id; pci_dev_header.field.vendor_id;
@ -361,6 +367,7 @@ void pci_bus_scan_init(void)
lookup.info.class = 0; lookup.info.class = 0;
lookup.info.vendor_id = 0; lookup.info.vendor_id = 0;
lookup.info.device_id = 0; lookup.info.device_id = 0;
lookup.info.bar = PCI_BAR_ANY;
lookup.bus = 0; lookup.bus = 0;
lookup.dev = 0; lookup.dev = 0;
lookup.func = 0; lookup.func = 0;
@ -387,10 +394,12 @@ int pci_bus_scan(struct pci_dev_info *dev_info)
if (!lookup.info.class && if (!lookup.info.class &&
!lookup.info.vendor_id && !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.class = dev_info->class;
lookup.info.vendor_id = dev_info->vendor_id; lookup.info.vendor_id = dev_info->vendor_id;
lookup.info.device_id = dev_info->device_id; lookup.info.device_id = dev_info->device_id;
lookup.info.bar = dev_info->bar;
if (class_bd[lookup.info.class].set) { if (class_bd[lookup.info.class].set) {
lookup.bus = class_bd[lookup.info.class].bus; 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_MEM 0
#define BAR_SPACE_IO 1 #define BAR_SPACE_IO 1
#define PCI_MAX_BARS 6
#define PCI_BAR_ANY PCI_MAX_BARS
/* PCI device information */ /* PCI device information */
struct pci_dev_info { struct pci_dev_info {