upstream u-boot with additional patches for our devices/boards: https://lists.denx.de/pipermail/u-boot/2017-March/282789.html (AXP crashes) ; Gbit ethernet patch for some LIME2 revisions ; with SPI flash support
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
u-boot/drivers/pci/pci.c

586 lines
14 KiB

22 years ago
/*
* (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Andreas Heppel <aheppel@sysgo.de>
*
* (C) Copyright 2002, 2003
22 years ago
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
22 years ago
*/
/*
* Old PCI routines
*
* Do not change this file. Instead, convert your board to use CONFIG_DM_PCI
* and change pci-uclass.c.
22 years ago
*/
#include <common.h>
#include <command.h>
#include <errno.h>
22 years ago
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
DECLARE_GLOBAL_DATA_PTR;
#define PCI_HOSE_OP(rw, size, type) \
int pci_hose_##rw##_config_##size(struct pci_controller *hose, \
pci_dev_t dev, \
int offset, type value) \
{ \
return hose->rw##_##size(hose, dev, offset, value); \
22 years ago
}
PCI_HOSE_OP(read, byte, u8 *)
PCI_HOSE_OP(read, word, u16 *)
PCI_HOSE_OP(read, dword, u32 *)
PCI_HOSE_OP(write, byte, u8)
PCI_HOSE_OP(write, word, u16)
PCI_HOSE_OP(write, dword, u32)
#define PCI_OP(rw, size, type, error_code) \
int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value) \
{ \
struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev)); \
\
if (!hose) \
{ \
error_code; \
return -1; \
} \
\
return pci_hose_##rw##_config_##size(hose, dev, offset, value); \
22 years ago
}
PCI_OP(read, byte, u8 *, *value = 0xff)
PCI_OP(read, word, u16 *, *value = 0xffff)
PCI_OP(read, dword, u32 *, *value = 0xffffffff)
PCI_OP(write, byte, u8, )
PCI_OP(write, word, u16, )
PCI_OP(write, dword, u32, )
#define PCI_READ_VIA_DWORD_OP(size, type, off_mask) \
int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
pci_dev_t dev, \
int offset, type val) \
{ \
u32 val32; \
\
if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) { \
*val = -1; \
return -1; \
} \
\
*val = (val32 >> ((offset & (int)off_mask) * 8)); \
\
return 0; \
22 years ago
}
#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask) \
int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
pci_dev_t dev, \
int offset, type val) \
{ \
u32 val32, mask, ldata, shift; \
\
if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
return -1; \
\
shift = ((offset & (int)off_mask) * 8); \
ldata = (((unsigned long)val) & val_mask) << shift; \
mask = val_mask << shift; \
val32 = (val32 & ~mask) | ldata; \
\
if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\
return -1; \
\
return 0; \
22 years ago
}
PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
/*
*
*/
static struct pci_controller* hose_head;
22 years ago
struct pci_controller *pci_get_hose_head(void)
{
if (gd->hose)
return gd->hose;
return hose_head;
}
22 years ago
void pci_register_hose(struct pci_controller* hose)
{
struct pci_controller **phose = &hose_head;
while(*phose)
phose = &(*phose)->next;
hose->next = NULL;
*phose = hose;
}
struct pci_controller *pci_bus_to_hose(int bus)
22 years ago
{
struct pci_controller *hose;
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
if (bus >= hose->first_busno && bus <= hose->last_busno)
22 years ago
return hose;
}
22 years ago
printf("pci_bus_to_hose() failed\n");
22 years ago
return NULL;
}
struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr)
{
struct pci_controller *hose;
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
if (hose->cfg_addr == cfg_addr)
return hose;
}
return NULL;
}
int pci_last_busno(void)
{
struct pci_controller *hose = pci_get_hose_head();
if (!hose)
return -1;
while (hose->next)
hose = hose->next;
return hose->last_busno;
}
22 years ago
pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
{
struct pci_controller * hose;
pci_dev_t bdf;
int bus;
22 years ago
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
bdf = pci_hose_find_devices(hose, bus, ids, &index);
if (bdf != -1)
return bdf;
}
}
return -1;
22 years ago
}
int pci_hose_config_device(struct pci_controller *hose,
pci_dev_t dev,
unsigned long io,
pci_addr_t mem,
22 years ago
unsigned long command)
{
u32 bar_response;
unsigned int old_command;
pci_addr_t bar_value;
pci_size_t bar_size;
22 years ago
unsigned char pin;
int bar, found_mem64;
debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io,
(u64)mem, command);
22 years ago
pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0);
22 years ago
for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) {
pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
pci_hose_read_config_dword(hose, dev, bar, &bar_response);
22 years ago
if (!bar_response)
continue;
found_mem64 = 0;
/* Check the BAR type and set our address mask */
if (bar_response & PCI_BASE_ADDRESS_SPACE) {
22 years ago
bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
/* round up region base address to a multiple of size */
22 years ago
io = ((io - 1) | (bar_size - 1)) + 1;
bar_value = io;
/* compute new region base address */
io = io + bar_size;
} else {
if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
PCI_BASE_ADDRESS_MEM_TYPE_64) {
u32 bar_response_upper;
u64 bar64;
pci_hose_write_config_dword(hose, dev, bar + 4,
0xffffffff);
pci_hose_read_config_dword(hose, dev, bar + 4,
&bar_response_upper);
bar64 = ((u64)bar_response_upper << 32) | bar_response;
22 years ago
bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
found_mem64 = 1;
} else {
bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
}
22 years ago
/* round up region base address to multiple of size */
22 years ago
mem = ((mem - 1) | (bar_size - 1)) + 1;
bar_value = mem;
/* compute new region base address */
mem = mem + bar_size;
22 years ago
}
/* Write it out and update our limit */
pci_hose_write_config_dword (hose, dev, bar, (u32)bar_value);
22 years ago
if (found_mem64) {
22 years ago
bar += 4;
#ifdef CONFIG_SYS_PCI_64BIT
pci_hose_write_config_dword(hose, dev, bar,
(u32)(bar_value >> 32));
#else
pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
#endif
22 years ago
}
}
/* Configure Cache Line Size Register */
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
22 years ago
/* Configure Latency Timer */
pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
22 years ago
/* Disable interrupt line, if device says it wants to use interrupts */
pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
if (pin != 0) {
pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE,
PCI_INTERRUPT_LINE_DISABLE);
22 years ago
}
pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command);
pci_hose_write_config_dword(hose, dev, PCI_COMMAND,
(old_command & 0xffff0000) | command);
22 years ago
return 0;
}
/*
*
*/
struct pci_config_table *pci_find_config(struct pci_controller *hose,
unsigned short class,
unsigned int vendor,
unsigned int device,
unsigned int bus,
unsigned int dev,
unsigned int func)
{
struct pci_config_table *table;
for (table = hose->config_table; table && table->vendor; table++) {
22 years ago
if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
(table->device == PCI_ANY_ID || table->device == device) &&
(table->class == PCI_ANY_ID || table->class == class) &&
(table->bus == PCI_ANY_ID || table->bus == bus) &&
(table->dev == PCI_ANY_ID || table->dev == dev) &&
(table->func == PCI_ANY_ID || table->func == func)) {
22 years ago
return table;
}
}
return NULL;
}
void pci_cfgfunc_config_device(struct pci_controller *hose,
pci_dev_t dev,
struct pci_config_table *entry)
{
pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1],
entry->priv[2]);
22 years ago
}
void pci_cfgfunc_do_nothing(struct pci_controller *hose,
pci_dev_t dev, struct pci_config_table *entry)
{
}
/*
* HJF: Changed this to return int. I think this is required
* to get the correct result when scanning bridges
*/
extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
22 years ago
#ifdef CONFIG_PCI_SCAN_SHOW
__weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
{
if (dev == PCI_BDF(hose->first_busno, 0, 0))
return 0;
return 1;
}
#endif /* CONFIG_PCI_SCAN_SHOW */
22 years ago
int pci_hose_scan_bus(struct pci_controller *hose, int bus)
{
unsigned int sub_bus, found_multi = 0;
22 years ago
unsigned short vendor, device, class;
unsigned char header_type;
#ifndef CONFIG_PCI_PNP
22 years ago
struct pci_config_table *cfg;
#endif
22 years ago
pci_dev_t dev;
pci: Use intelligent indentation for CONFIG_PCI_SCAN_SHOW When CONFIG_PCI_SCAN_SHOW is defined U-Boot prints out PCI devices as they are found during bootup, eg: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d This information is useful, but its difficult to determine the PCI bus topology. To things clearer, we can use indention to make it more obvious how the PCI bus is organized. For the example above, the updated output with this change is: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d In the examples above, an MPC8640 is connected to a PEX8518 PCIe switch (01:00 and 02:0x), which is connected to another PEX8518 PCIe switch (06:00 and 07:0x), which then connects to a MPC8572 processor (08:00). Also, the MPC8640's PEX8518 PCIe switch is connected to a PCI ethernet card (04:01) via a PEX8112 PCIe-to-PCI bridge (03:00). Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
#ifdef CONFIG_PCI_SCAN_SHOW
static int indent = 0;
#endif
22 years ago
sub_bus = bus;
for (dev = PCI_BDF(bus,0,0);
dev < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
PCI_MAX_PCI_FUNCTIONS - 1);
dev += PCI_BDF(0, 0, 1)) {
if (pci_skip_dev(hose, dev))
continue;
22 years ago
if (PCI_FUNC(dev) && !found_multi)
continue;
pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
pci: Clean up PCI info when CONFIG_PCI_SCAN_SHOW This change does the following: - Removes the printing of the PCI interrupt line value. This is normally set to 0 by U-Boot on bootup and is rarely used during everyday operation. - Prints out the PCI function number of a device. Previously a device with multiple functions would be printed identically 2 times, which is generally confusing. For example, on an Intel 2 port gigabit Ethernet card the following was displayed: ... 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 ... - Prints a text description of each device's PCI class instead of the raw PCI class code. The textual description makes it much easier to determine what devices are installed on a PCI bus. - Changes the general formatting of the PCI device output. Previous output: PCIE1: connected as Root Complex 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 03 00 10b5 8112 0604 00 02 01 10b5 8518 0604 00 02 02 10b5 8518 0604 00 08 00 1957 0040 0b20 00 07 00 10b5 8518 0604 00 09 00 10b5 8112 0604 00 07 01 10b5 8518 0604 00 07 02 10b5 8518 0604 00 06 00 10b5 8518 0604 00 02 03 10b5 8518 0604 00 01 00 10b5 8518 0604 00 PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d 00 1957 0040 0b20 00 PCIE2: Bus 0c - 0d Updated output: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
if (vendor == 0xffff || vendor == 0x0000)
continue;
22 years ago
pci: Clean up PCI info when CONFIG_PCI_SCAN_SHOW This change does the following: - Removes the printing of the PCI interrupt line value. This is normally set to 0 by U-Boot on bootup and is rarely used during everyday operation. - Prints out the PCI function number of a device. Previously a device with multiple functions would be printed identically 2 times, which is generally confusing. For example, on an Intel 2 port gigabit Ethernet card the following was displayed: ... 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 ... - Prints a text description of each device's PCI class instead of the raw PCI class code. The textual description makes it much easier to determine what devices are installed on a PCI bus. - Changes the general formatting of the PCI device output. Previous output: PCIE1: connected as Root Complex 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 03 00 10b5 8112 0604 00 02 01 10b5 8518 0604 00 02 02 10b5 8518 0604 00 08 00 1957 0040 0b20 00 07 00 10b5 8518 0604 00 09 00 10b5 8112 0604 00 07 01 10b5 8518 0604 00 07 02 10b5 8518 0604 00 06 00 10b5 8518 0604 00 02 03 10b5 8518 0604 00 01 00 10b5 8518 0604 00 PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d 00 1957 0040 0b20 00 PCIE2: Bus 0c - 0d Updated output: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
if (!PCI_FUNC(dev))
found_multi = header_type & 0x80;
22 years ago
debug("PCI Scan: Found Bus %d, Device %d, Function %d\n",
PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
22 years ago
pci: Clean up PCI info when CONFIG_PCI_SCAN_SHOW This change does the following: - Removes the printing of the PCI interrupt line value. This is normally set to 0 by U-Boot on bootup and is rarely used during everyday operation. - Prints out the PCI function number of a device. Previously a device with multiple functions would be printed identically 2 times, which is generally confusing. For example, on an Intel 2 port gigabit Ethernet card the following was displayed: ... 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 ... - Prints a text description of each device's PCI class instead of the raw PCI class code. The textual description makes it much easier to determine what devices are installed on a PCI bus. - Changes the general formatting of the PCI device output. Previous output: PCIE1: connected as Root Complex 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 03 00 10b5 8112 0604 00 02 01 10b5 8518 0604 00 02 02 10b5 8518 0604 00 08 00 1957 0040 0b20 00 07 00 10b5 8518 0604 00 09 00 10b5 8112 0604 00 07 01 10b5 8518 0604 00 07 02 10b5 8518 0604 00 06 00 10b5 8518 0604 00 02 03 10b5 8518 0604 00 01 00 10b5 8518 0604 00 PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d 00 1957 0040 0b20 00 PCIE2: Bus 0c - 0d Updated output: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
22 years ago
#ifdef CONFIG_PCI_FIXUP_DEV
board_pci_fixup_dev(hose, dev, vendor, device, class);
#endif
pci: Fix ordering of devices when CONFIG_PCI_SCAN_SHOW Move the printing of PCI device information to before the PCI device is configured. This prevents the case where recursive scanning results in the deepest devices being printed first. This change also makes PCI lockups during enumeration easier to diagnose since the device that is being configured is printed out prior to configuration. Previously, it was not possible to determine which device caused the PCI lockup. Original example: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Updated example: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
#ifdef CONFIG_PCI_SCAN_SHOW
pci: Use intelligent indentation for CONFIG_PCI_SCAN_SHOW When CONFIG_PCI_SCAN_SHOW is defined U-Boot prints out PCI devices as they are found during bootup, eg: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d This information is useful, but its difficult to determine the PCI bus topology. To things clearer, we can use indention to make it more obvious how the PCI bus is organized. For the example above, the updated output with this change is: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d In the examples above, an MPC8640 is connected to a PEX8518 PCIe switch (01:00 and 02:0x), which is connected to another PEX8518 PCIe switch (06:00 and 07:0x), which then connects to a MPC8572 processor (08:00). Also, the MPC8640's PEX8518 PCIe switch is connected to a PCI ethernet card (04:01) via a PEX8112 PCIe-to-PCI bridge (03:00). Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
indent++;
/* Print leading space, including bus indentation */
printf("%*c", indent + 1, ' ');
pci: Fix ordering of devices when CONFIG_PCI_SCAN_SHOW Move the printing of PCI device information to before the PCI device is configured. This prevents the case where recursive scanning results in the deepest devices being printed first. This change also makes PCI lockups during enumeration easier to diagnose since the device that is being configured is printed out prior to configuration. Previously, it was not possible to determine which device caused the PCI lockup. Original example: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Updated example: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
if (pci_print_dev(hose, dev)) {
pci: Use intelligent indentation for CONFIG_PCI_SCAN_SHOW When CONFIG_PCI_SCAN_SHOW is defined U-Boot prints out PCI devices as they are found during bootup, eg: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d This information is useful, but its difficult to determine the PCI bus topology. To things clearer, we can use indention to make it more obvious how the PCI bus is organized. For the example above, the updated output with this change is: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d In the examples above, an MPC8640 is connected to a PEX8518 PCIe switch (01:00 and 02:0x), which is connected to another PEX8518 PCIe switch (06:00 and 07:0x), which then connects to a MPC8572 processor (08:00). Also, the MPC8640's PEX8518 PCIe switch is connected to a PCI ethernet card (04:01) via a PEX8112 PCIe-to-PCI bridge (03:00). Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
printf("%02x:%02x.%-*x - %04x:%04x - %s\n",
PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev),
pci: Fix ordering of devices when CONFIG_PCI_SCAN_SHOW Move the printing of PCI device information to before the PCI device is configured. This prevents the case where recursive scanning results in the deepest devices being printed first. This change also makes PCI lockups during enumeration easier to diagnose since the device that is being configured is printed out prior to configuration. Previously, it was not possible to determine which device caused the PCI lockup. Original example: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Updated example: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
vendor, device, pci_class_str(class >> 8));
}
#endif
#ifdef CONFIG_PCI_PNP
sub_bus = max((unsigned int)pciauto_config_device(hose, dev),
sub_bus);
#else
pci: Clean up PCI info when CONFIG_PCI_SCAN_SHOW This change does the following: - Removes the printing of the PCI interrupt line value. This is normally set to 0 by U-Boot on bootup and is rarely used during everyday operation. - Prints out the PCI function number of a device. Previously a device with multiple functions would be printed identically 2 times, which is generally confusing. For example, on an Intel 2 port gigabit Ethernet card the following was displayed: ... 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 ... - Prints a text description of each device's PCI class instead of the raw PCI class code. The textual description makes it much easier to determine what devices are installed on a PCI bus. - Changes the general formatting of the PCI device output. Previous output: PCIE1: connected as Root Complex 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 03 00 10b5 8112 0604 00 02 01 10b5 8518 0604 00 02 02 10b5 8518 0604 00 08 00 1957 0040 0b20 00 07 00 10b5 8518 0604 00 09 00 10b5 8112 0604 00 07 01 10b5 8518 0604 00 07 02 10b5 8518 0604 00 06 00 10b5 8518 0604 00 02 03 10b5 8518 0604 00 01 00 10b5 8518 0604 00 PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d 00 1957 0040 0b20 00 PCIE2: Bus 0c - 0d Updated output: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
cfg = pci_find_config(hose, class, vendor, device,
PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
if (cfg) {
cfg->config_device(hose, dev, cfg);
sub_bus = max(sub_bus,
(unsigned int)hose->current_busno);
pci: Clean up PCI info when CONFIG_PCI_SCAN_SHOW This change does the following: - Removes the printing of the PCI interrupt line value. This is normally set to 0 by U-Boot on bootup and is rarely used during everyday operation. - Prints out the PCI function number of a device. Previously a device with multiple functions would be printed identically 2 times, which is generally confusing. For example, on an Intel 2 port gigabit Ethernet card the following was displayed: ... 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 ... - Prints a text description of each device's PCI class instead of the raw PCI class code. The textual description makes it much easier to determine what devices are installed on a PCI bus. - Changes the general formatting of the PCI device output. Previous output: PCIE1: connected as Root Complex 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 03 00 10b5 8112 0604 00 02 01 10b5 8518 0604 00 02 02 10b5 8518 0604 00 08 00 1957 0040 0b20 00 07 00 10b5 8518 0604 00 09 00 10b5 8112 0604 00 07 01 10b5 8518 0604 00 07 02 10b5 8518 0604 00 06 00 10b5 8518 0604 00 02 03 10b5 8518 0604 00 01 00 10b5 8518 0604 00 PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d 00 1957 0040 0b20 00 PCIE2: Bus 0c - 0d Updated output: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
}
#endif
pci: Fix ordering of devices when CONFIG_PCI_SCAN_SHOW Move the printing of PCI device information to before the PCI device is configured. This prevents the case where recursive scanning results in the deepest devices being printed first. This change also makes PCI lockups during enumeration easier to diagnose since the device that is being configured is printed out prior to configuration. Previously, it was not possible to determine which device caused the PCI lockup. Original example: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Updated example: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
pci: Use intelligent indentation for CONFIG_PCI_SCAN_SHOW When CONFIG_PCI_SCAN_SHOW is defined U-Boot prints out PCI devices as they are found during bootup, eg: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d This information is useful, but its difficult to determine the PCI bus topology. To things clearer, we can use indention to make it more obvious how the PCI bus is organized. For the example above, the updated output with this change is: PCIE1: connected as Root Complex 01:00.0 - 10b5:8518 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 03:00.0 - 10b5:8112 - Bridge device 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 02:02.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 07:00.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:01.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:02.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d In the examples above, an MPC8640 is connected to a PEX8518 PCIe switch (01:00 and 02:0x), which is connected to another PEX8518 PCIe switch (06:00 and 07:0x), which then connects to a MPC8572 processor (08:00). Also, the MPC8640's PEX8518 PCIe switch is connected to a PCI ethernet card (04:01) via a PEX8112 PCIe-to-PCI bridge (03:00). Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
#ifdef CONFIG_PCI_SCAN_SHOW
indent--;
#endif
pci: Clean up PCI info when CONFIG_PCI_SCAN_SHOW This change does the following: - Removes the printing of the PCI interrupt line value. This is normally set to 0 by U-Boot on bootup and is rarely used during everyday operation. - Prints out the PCI function number of a device. Previously a device with multiple functions would be printed identically 2 times, which is generally confusing. For example, on an Intel 2 port gigabit Ethernet card the following was displayed: ... 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 ... - Prints a text description of each device's PCI class instead of the raw PCI class code. The textual description makes it much easier to determine what devices are installed on a PCI bus. - Changes the general formatting of the PCI device output. Previous output: PCIE1: connected as Root Complex 04 01 8086 1010 0200 00 04 01 8086 1010 0200 00 03 00 10b5 8112 0604 00 02 01 10b5 8518 0604 00 02 02 10b5 8518 0604 00 08 00 1957 0040 0b20 00 07 00 10b5 8518 0604 00 09 00 10b5 8112 0604 00 07 01 10b5 8518 0604 00 07 02 10b5 8518 0604 00 06 00 10b5 8518 0604 00 02 03 10b5 8518 0604 00 01 00 10b5 8518 0604 00 PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d 00 1957 0040 0b20 00 PCIE2: Bus 0c - 0d Updated output: PCIE1: connected as Root Complex 04:01.0 - 8086:1010 - Network controller 04:01.1 - 8086:1010 - Network controller 03:00.0 - 10b5:8112 - Bridge device 02:01.0 - 10b5:8518 - Bridge device 02:02.0 - 10b5:8518 - Bridge device 08:00.0 - 1957:0040 - Processor 07:00.0 - 10b5:8518 - Bridge device 09:00.0 - 10b5:8112 - Bridge device 07:01.0 - 10b5:8518 - Bridge device 07:02.0 - 10b5:8518 - Bridge device 06:00.0 - 10b5:8518 - Bridge device 02:03.0 - 10b5:8518 - Bridge device 01:00.0 - 10b5:8518 - Bridge device PCIE1: Bus 00 - 0b PCIE2: connected as Root Complex 0d:00.0 - 1957:0040 - Processor PCIE2: Bus 0c - 0d Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
14 years ago
if (hose->fixup_irq)
hose->fixup_irq(hose, dev);
22 years ago
}
return sub_bus;
}
int pci_hose_scan(struct pci_controller *hose)
{
#if defined(CONFIG_PCI_BOOTDELAY)
char *s;
int i;
if (!gd->pcidelay_done) {
/* wait "pcidelay" ms (if defined)... */
s = getenv("pcidelay");
if (s) {
int val = simple_strtoul(s, NULL, 10);
for (i = 0; i < val; i++)
udelay(1000);
}
gd->pcidelay_done = 1;
}
#endif /* CONFIG_PCI_BOOTDELAY */
#ifdef CONFIG_PCI_SCAN_SHOW
puts("PCI:\n");
#endif
/*
* Start scan at current_busno.
* PCIe will start scan at first_busno+1.
*/
/* For legacy support, ensure current >= first */
if (hose->first_busno > hose->current_busno)
hose->current_busno = hose->first_busno;
22 years ago
#ifdef CONFIG_PCI_PNP
pciauto_config_init(hose);
#endif
return pci_hose_scan_bus(hose, hose->current_busno);
22 years ago
}
void pci_init(void)
{
hose_head = NULL;
/* allow env to disable pci init/enum */
if (getenv("pcidisable") != NULL)
return;
/* now call board specific pci_init()... */
pci_init_board();
}
/* Returns the address of the requested capability structure within the
* device's PCI configuration space or 0 in case the device does not
* support it.
* */
int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev,
int cap)
{
int pos;
u8 hdr_type;
pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type);
pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F);
if (pos)
pos = pci_find_cap(hose, dev, pos, cap);
return pos;
}
/* Find the header pointer to the Capabilities*/
int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
u8 hdr_type)
{
u16 status;
pci_hose_read_config_word(hose, dev, PCI_STATUS, &status);
if (!(status & PCI_STATUS_CAP_LIST))
return 0;
switch (hdr_type) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
return PCI_CAPABILITY_LIST;
case PCI_HEADER_TYPE_CARDBUS:
return PCI_CB_CAPABILITY_LIST;
default:
return 0;
}
}
int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap)
{
int ttl = PCI_FIND_CAP_TTL;
u8 id;
u8 next_pos;
while (ttl--) {
pci_hose_read_config_byte(hose, dev, pos, &next_pos);
if (next_pos < CAP_START_POS)
break;
next_pos &= ~3;
pos = (int) next_pos;
pci_hose_read_config_byte(hose, dev,
pos + PCI_CAP_LIST_ID, &id);
if (id == 0xff)
break;
if (id == cap)
return pos;
pos += PCI_CAP_LIST_NEXT;
}
return 0;
}
/**
* pci_find_next_ext_capability - Find an extended capability
*
* Returns the address of the next matching extended capability structure
* within the device's PCI configuration space or 0 if the device does
* not support it. Some capabilities can occur several times, e.g., the
* vendor-specific capability, and this provides a way to find them all.
*/
int pci_find_next_ext_capability(struct pci_controller *hose, pci_dev_t dev,
int start, int cap)
{
u32 header;
int ttl, pos = PCI_CFG_SPACE_SIZE;
/* minimum 8 bytes per capability */
ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
if (start)
pos = start;
pci_hose_read_config_dword(hose, dev, pos, &header);
if (header == 0xffffffff || header == 0)
return 0;
while (ttl-- > 0) {
if (PCI_EXT_CAP_ID(header) == cap && pos != start)
return pos;
pos = PCI_EXT_CAP_NEXT(header);
if (pos < PCI_CFG_SPACE_SIZE)
break;
pci_hose_read_config_dword(hose, dev, pos, &header);
if (header == 0xffffffff || header == 0)
break;
}
return 0;
}
/**
* pci_hose_find_ext_capability - Find an extended capability
*
* Returns the address of the requested extended capability structure
* within the device's PCI configuration space or 0 if the device does
* not support it.
*/
int pci_hose_find_ext_capability(struct pci_controller *hose, pci_dev_t dev,
int cap)
{
return pci_find_next_ext_capability(hose, dev, 0, cap);
}