Various cosmetic and coding style fixes in src/devices.
Also: - Improve a few code comments, fix typos, etc. - Change a few more variable types to u8/u16/u32 etc. - Make some very long lines fit into 80chars/line. - Drop a huge duplicated comment, use "@see" to refer to the other one. - Reduce nesting level a bit by restructuring some code chunks. - s/Config.lb/devicetree.cb/ in a few places. Abuild-tested. Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6019 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
@@ -56,6 +56,7 @@
|
||||
u8 pci_moving_config8(struct device *dev, unsigned int reg)
|
||||
{
|
||||
u8 value, ones, zeroes;
|
||||
|
||||
value = pci_read_config8(dev, reg);
|
||||
|
||||
pci_write_config8(dev, reg, 0xff);
|
||||
@@ -69,9 +70,10 @@ u8 pci_moving_config8(struct device *dev, unsigned int reg)
|
||||
return ones ^ zeroes;
|
||||
}
|
||||
|
||||
u16 pci_moving_config16(struct device * dev, unsigned int reg)
|
||||
u16 pci_moving_config16(struct device *dev, unsigned int reg)
|
||||
{
|
||||
u16 value, ones, zeroes;
|
||||
|
||||
value = pci_read_config16(dev, reg);
|
||||
|
||||
pci_write_config16(dev, reg, 0xffff);
|
||||
@@ -85,9 +87,10 @@ u16 pci_moving_config16(struct device * dev, unsigned int reg)
|
||||
return ones ^ zeroes;
|
||||
}
|
||||
|
||||
u32 pci_moving_config32(struct device * dev, unsigned int reg)
|
||||
u32 pci_moving_config32(struct device *dev, unsigned int reg)
|
||||
{
|
||||
u32 value, ones, zeroes;
|
||||
|
||||
value = pci_read_config32(dev, reg);
|
||||
|
||||
pci_write_config32(dev, reg, 0xffffffff);
|
||||
@@ -114,13 +117,13 @@ unsigned pci_find_next_capability(struct device *dev, unsigned cap,
|
||||
unsigned last)
|
||||
{
|
||||
unsigned pos = 0;
|
||||
unsigned status;
|
||||
u16 status;
|
||||
unsigned reps = 48;
|
||||
|
||||
status = pci_read_config16(dev, PCI_STATUS);
|
||||
if (!(status & PCI_STATUS_CAP_LIST)) {
|
||||
if (!(status & PCI_STATUS_CAP_LIST))
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (dev->hdr_type & 0x7f) {
|
||||
case PCI_HEADER_TYPE_NORMAL:
|
||||
case PCI_HEADER_TYPE_BRIDGE:
|
||||
@@ -132,22 +135,24 @@ unsigned pci_find_next_capability(struct device *dev, unsigned cap,
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos = pci_read_config8(dev, pos);
|
||||
while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */
|
||||
while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */
|
||||
int this_cap;
|
||||
|
||||
pos &= ~3;
|
||||
this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
|
||||
printk(BIOS_SPEW, "Capability: type 0x%02x @ 0x%02x\n", this_cap,
|
||||
pos);
|
||||
if (this_cap == 0xff) {
|
||||
printk(BIOS_SPEW, "Capability: type 0x%02x @ 0x%02x\n",
|
||||
this_cap, pos);
|
||||
if (this_cap == 0xff)
|
||||
break;
|
||||
}
|
||||
if (!last && (this_cap == cap)) {
|
||||
|
||||
if (!last && (this_cap == cap))
|
||||
return pos;
|
||||
}
|
||||
if (last == pos) {
|
||||
|
||||
if (last == pos)
|
||||
last = 0;
|
||||
}
|
||||
|
||||
pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
|
||||
}
|
||||
return 0;
|
||||
@@ -199,6 +204,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
|
||||
moving |=
|
||||
((resource_t) pci_moving_config32(dev, index + 4)) << 32;
|
||||
}
|
||||
|
||||
/* Find the resource constraints.
|
||||
* Start by finding the bits that move. From there:
|
||||
* - Size is the least significant bit of the bits that move.
|
||||
@@ -217,20 +223,25 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
|
||||
resource->limit = limit = moving | (resource->size - 1);
|
||||
}
|
||||
|
||||
/* Some broken hardware has read-only registers that do not
|
||||
/*
|
||||
* Some broken hardware has read-only registers that do not
|
||||
* really size correctly.
|
||||
* Example: the Acer M7229 has BARs 1-4 normally read-only.
|
||||
*
|
||||
* Example: the Acer M7229 has BARs 1-4 normally read-only,
|
||||
* so BAR1 at offset 0x10 reads 0x1f1. If you size that register
|
||||
* by writing 0xffffffff to it, it will read back as 0x1f1 -- a
|
||||
* violation of the spec.
|
||||
* We catch this case and ignore it by observing which bits move,
|
||||
* This also catches the common case unimplemented registers
|
||||
* by writing 0xffffffff to it, it will read back as 0x1f1 -- which
|
||||
* is a violation of the spec.
|
||||
*
|
||||
* We catch this case and ignore it by observing which bits move.
|
||||
*
|
||||
* This also catches the common case of unimplemented registers
|
||||
* that always read back as 0.
|
||||
*/
|
||||
if (moving == 0) {
|
||||
if (value != 0) {
|
||||
printk(BIOS_DEBUG, "%s register %02lx(%08lx), read-only ignoring it\n",
|
||||
dev_path(dev), index, value);
|
||||
printk(BIOS_DEBUG, "%s register %02lx(%08lx), "
|
||||
"read-only ignoring it\n",
|
||||
dev_path(dev), index, value);
|
||||
}
|
||||
resource->flags = 0;
|
||||
} else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
|
||||
@@ -243,9 +254,8 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
|
||||
/* A Memory mapped base address. */
|
||||
attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
|
||||
resource->flags |= IORESOURCE_MEM;
|
||||
if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) {
|
||||
if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH)
|
||||
resource->flags |= IORESOURCE_PREFETCH;
|
||||
}
|
||||
attr &= PCI_BASE_ADDRESS_MEM_LIMIT_MASK;
|
||||
if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
|
||||
/* 32bit limit. */
|
||||
@@ -265,10 +275,10 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
|
||||
resource->flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't let the limit exceed which bits can move. */
|
||||
if (resource->limit > limit) {
|
||||
if (resource->limit > limit)
|
||||
resource->limit = limit;
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
@@ -315,8 +325,9 @@ static void pci_get_rom_resource(struct device *dev, unsigned long index)
|
||||
resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY;
|
||||
} else {
|
||||
if (value != 0) {
|
||||
printk(BIOS_DEBUG, "%s register %02lx(%08lx), read-only ignoring it\n",
|
||||
dev_path(dev), index, value);
|
||||
printk(BIOS_DEBUG, "%s register %02lx(%08lx), "
|
||||
"read-only ignoring it\n",
|
||||
dev_path(dev), index, value);
|
||||
}
|
||||
resource->flags = 0;
|
||||
}
|
||||
@@ -346,27 +357,29 @@ static void pci_read_bases(struct device *dev, unsigned int howmany)
|
||||
static void pci_record_bridge_resource(struct device *dev, resource_t moving,
|
||||
unsigned index, unsigned long type)
|
||||
{
|
||||
/* Initialize the constraints on the current bus. */
|
||||
struct resource *resource;
|
||||
unsigned long gran;
|
||||
resource_t step;
|
||||
|
||||
resource = NULL;
|
||||
if (moving) {
|
||||
unsigned long gran;
|
||||
resource_t step;
|
||||
resource = new_resource(dev, index);
|
||||
resource->size = 0;
|
||||
gran = 0;
|
||||
step = 1;
|
||||
while ((moving & step) == 0) {
|
||||
gran += 1;
|
||||
step <<= 1;
|
||||
}
|
||||
resource->gran = gran;
|
||||
resource->align = gran;
|
||||
resource->limit = moving | (step - 1);
|
||||
resource->flags = type | IORESOURCE_PCI_BRIDGE |
|
||||
IORESOURCE_BRIDGE;
|
||||
|
||||
if (!moving)
|
||||
return;
|
||||
|
||||
/* Initialize the constraints on the current bus. */
|
||||
resource = new_resource(dev, index);
|
||||
resource->size = 0;
|
||||
gran = 0;
|
||||
step = 1;
|
||||
while ((moving & step) == 0) {
|
||||
gran += 1;
|
||||
step <<= 1;
|
||||
}
|
||||
return;
|
||||
resource->gran = gran;
|
||||
resource->align = gran;
|
||||
resource->limit = moving | (step - 1);
|
||||
resource->flags = type | IORESOURCE_PCI_BRIDGE |
|
||||
IORESOURCE_BRIDGE;
|
||||
}
|
||||
|
||||
static void pci_bridge_read_bases(struct device *dev)
|
||||
@@ -452,26 +465,23 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
||||
|
||||
/* Make certain the resource has actually been assigned a value. */
|
||||
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
|
||||
printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx not assigned\n",
|
||||
dev_path(dev), resource->index,
|
||||
resource_type(resource), resource->size);
|
||||
printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx not "
|
||||
"assigned\n", dev_path(dev), resource->index,
|
||||
resource_type(resource), resource->size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this resource is fixed don't worry about it. */
|
||||
if (resource->flags & IORESOURCE_FIXED) {
|
||||
if (resource->flags & IORESOURCE_FIXED)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If I have already stored this resource don't worry about it. */
|
||||
if (resource->flags & IORESOURCE_STORED) {
|
||||
if (resource->flags & IORESOURCE_STORED)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the resource is subtractive don't worry about it. */
|
||||
if (resource->flags & IORESOURCE_SUBTRACTIVE) {
|
||||
if (resource->flags & IORESOURCE_SUBTRACTIVE)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only handle PCI memory and I/O resources for now. */
|
||||
if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
|
||||
@@ -479,16 +489,14 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
||||
|
||||
/* Enable the resources in the command register. */
|
||||
if (resource->size) {
|
||||
if (resource->flags & IORESOURCE_MEM) {
|
||||
if (resource->flags & IORESOURCE_MEM)
|
||||
dev->command |= PCI_COMMAND_MEMORY;
|
||||
}
|
||||
if (resource->flags & IORESOURCE_IO) {
|
||||
if (resource->flags & IORESOURCE_IO)
|
||||
dev->command |= PCI_COMMAND_IO;
|
||||
}
|
||||
if (resource->flags & IORESOURCE_PCI_BRIDGE) {
|
||||
if (resource->flags & IORESOURCE_PCI_BRIDGE)
|
||||
dev->command |= PCI_COMMAND_MASTER;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the base address. */
|
||||
base = resource->base;
|
||||
|
||||
@@ -498,8 +506,9 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
||||
/* Now store the resource. */
|
||||
resource->flags |= IORESOURCE_STORED;
|
||||
|
||||
/* PCI Bridges have no enable bit. They are disabled if the base of
|
||||
* the range is greater than the limit. If the size is zero, disable
|
||||
/*
|
||||
* PCI bridges have no enable bit. They are disabled if the base of
|
||||
* the range is greater than the limit. If the size is zero, disable
|
||||
* by setting the base = limit and end = limit - 2^gran.
|
||||
*/
|
||||
if (resource->size == 0 && (resource->flags & IORESOURCE_PCI_BRIDGE)) {
|
||||
@@ -510,18 +519,18 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
||||
|
||||
if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
|
||||
unsigned long base_lo, base_hi;
|
||||
/* Some chipsets allow us to set/clear the I/O bit
|
||||
* (e.g. VIA 82c686a). So set it to be safe.
|
||||
|
||||
/*
|
||||
* Some chipsets allow us to set/clear the I/O bit
|
||||
* (e.g. VIA 82C686A). So set it to be safe.
|
||||
*/
|
||||
base_lo = base & 0xffffffff;
|
||||
base_hi = (base >> 32) & 0xffffffff;
|
||||
if (resource->flags & IORESOURCE_IO) {
|
||||
if (resource->flags & IORESOURCE_IO)
|
||||
base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
|
||||
}
|
||||
pci_write_config32(dev, resource->index, base_lo);
|
||||
if (resource->flags & IORESOURCE_PCI64) {
|
||||
if (resource->flags & IORESOURCE_PCI64)
|
||||
pci_write_config32(dev, resource->index + 4, base_hi);
|
||||
}
|
||||
} else if (resource->index == PCI_IO_BASE) {
|
||||
/* Set the I/O ranges. */
|
||||
pci_write_config8(dev, PCI_IO_BASE, base >> 8);
|
||||
@@ -542,10 +551,10 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
||||
/* Don't let me think I stored the resource. */
|
||||
resource->flags &= ~IORESOURCE_STORED;
|
||||
printk(BIOS_ERR, "ERROR: invalid resource->index %lx\n",
|
||||
resource->index);
|
||||
resource->index);
|
||||
}
|
||||
|
||||
report_resource_stored(dev, resource, "");
|
||||
return;
|
||||
}
|
||||
|
||||
void pci_dev_set_resources(struct device *dev)
|
||||
@@ -554,28 +563,26 @@ void pci_dev_set_resources(struct device *dev)
|
||||
struct bus *bus;
|
||||
u8 line;
|
||||
|
||||
for (res = dev->resource_list; res; res = res->next) {
|
||||
for (res = dev->resource_list; res; res = res->next)
|
||||
pci_set_resource(dev, res);
|
||||
}
|
||||
|
||||
for (bus = dev->link_list; bus; bus = bus->next) {
|
||||
if (bus->children) {
|
||||
if (bus->children)
|
||||
assign_resources(bus);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set a default latency timer. */
|
||||
pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
|
||||
|
||||
/* Set a default secondary latency timer. */
|
||||
if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
|
||||
if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE)
|
||||
pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
|
||||
}
|
||||
|
||||
/* Zero the IRQ settings. */
|
||||
line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
|
||||
if (line) {
|
||||
if (line)
|
||||
pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
|
||||
}
|
||||
|
||||
/* Set the cache line size, so far 64 bytes is good for everyone. */
|
||||
pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
|
||||
}
|
||||
@@ -585,22 +592,23 @@ void pci_dev_enable_resources(struct device *dev)
|
||||
const struct pci_operations *ops;
|
||||
u16 command;
|
||||
|
||||
/* Set the subsystem vendor and device id for mainboard devices. */
|
||||
/* Set the subsystem vendor and device ID for mainboard devices. */
|
||||
ops = ops_pci(dev);
|
||||
if (dev->on_mainboard && ops && ops->set_subsystem) {
|
||||
printk(BIOS_DEBUG, "%s subsystem <- %02x/%02x\n",
|
||||
dev_path(dev),
|
||||
CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
|
||||
CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
|
||||
printk(BIOS_DEBUG, "%s subsystem <- %02x/%02x\n", dev_path(dev),
|
||||
CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
|
||||
CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
|
||||
ops->set_subsystem(dev,
|
||||
CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
|
||||
CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
|
||||
}
|
||||
command = pci_read_config16(dev, PCI_COMMAND);
|
||||
command |= dev->command;
|
||||
|
||||
/* v3 has
|
||||
* command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); // Error check.
|
||||
*/
|
||||
|
||||
printk(BIOS_DEBUG, "%s cmd <- %02x\n", dev_path(dev), command);
|
||||
pci_write_config16(dev, PCI_COMMAND, command);
|
||||
}
|
||||
@@ -609,14 +617,15 @@ void pci_bus_enable_resources(struct device *dev)
|
||||
{
|
||||
u16 ctrl;
|
||||
|
||||
/* Enable I/O in command register if there is VGA card
|
||||
/*
|
||||
* Enable I/O in command register if there is VGA card
|
||||
* connected with (even it does not claim I/O resource).
|
||||
*/
|
||||
if (dev->link_list->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
|
||||
dev->command |= PCI_COMMAND_IO;
|
||||
ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
|
||||
ctrl |= dev->link_list->bridge_ctrl;
|
||||
ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* Error check. */
|
||||
ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* Error check. */
|
||||
printk(BIOS_DEBUG, "%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
|
||||
pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
|
||||
|
||||
@@ -625,11 +634,13 @@ void pci_bus_enable_resources(struct device *dev)
|
||||
|
||||
void pci_bus_reset(struct bus *bus)
|
||||
{
|
||||
unsigned ctl;
|
||||
u16 ctl;
|
||||
|
||||
ctl = pci_read_config16(bus->dev, PCI_BRIDGE_CONTROL);
|
||||
ctl |= PCI_BRIDGE_CTL_BUS_RESET;
|
||||
pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
|
||||
mdelay(10);
|
||||
|
||||
ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
|
||||
pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
|
||||
delay(1);
|
||||
@@ -641,7 +652,7 @@ void pci_dev_set_subsystem(struct device *dev, unsigned vendor, unsigned device)
|
||||
((device & 0xffff) << 16) | (vendor & 0xffff));
|
||||
}
|
||||
|
||||
/** default handler: only runs the relevant pci bios. */
|
||||
/** Default handler: only runs the relevant PCI BIOS. */
|
||||
void pci_dev_init(struct device *dev)
|
||||
{
|
||||
#if CONFIG_PCI_ROM_RUN == 1 || CONFIG_VGA_ROM_RUN == 1
|
||||
@@ -666,7 +677,7 @@ void pci_dev_init(struct device *dev)
|
||||
run_bios(dev, (unsigned long)ram);
|
||||
|
||||
#if CONFIG_CONSOLE_VGA == 1
|
||||
if ((dev->class>>8) == PCI_CLASS_DISPLAY_VGA)
|
||||
if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
|
||||
vga_console_init();
|
||||
#endif /* CONFIG_CONSOLE_VGA */
|
||||
#endif /* CONFIG_PCI_ROM_RUN || CONFIG_VGA_ROM_RUN */
|
||||
@@ -678,13 +689,13 @@ static struct pci_operations pci_dev_ops_pci = {
|
||||
};
|
||||
|
||||
struct device_operations default_pci_ops_dev = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = pci_dev_init,
|
||||
.scan_bus = 0,
|
||||
.enable = 0,
|
||||
.ops_pci = &pci_dev_ops_pci,
|
||||
.init = pci_dev_init,
|
||||
.scan_bus = 0,
|
||||
.enable = 0,
|
||||
.ops_pci = &pci_dev_ops_pci,
|
||||
};
|
||||
|
||||
/** Default device operations for PCI bridges */
|
||||
@@ -693,14 +704,14 @@ static struct pci_operations pci_bus_ops_pci = {
|
||||
};
|
||||
|
||||
struct device_operations default_pci_ops_bus = {
|
||||
.read_resources = pci_bus_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.read_resources = pci_bus_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_bus_enable_resources,
|
||||
.init = 0,
|
||||
.scan_bus = pci_scan_bridge,
|
||||
.enable = 0,
|
||||
.reset_bus = pci_bus_reset,
|
||||
.ops_pci = &pci_bus_ops_pci,
|
||||
.init = 0,
|
||||
.scan_bus = pci_scan_bridge,
|
||||
.enable = 0,
|
||||
.reset_bus = pci_bus_reset,
|
||||
.ops_pci = &pci_bus_ops_pci,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -711,15 +722,15 @@ struct device_operations default_pci_ops_bus = {
|
||||
* blocks to figure out the type of downstream bridge. PCI-X, PCI-E, and
|
||||
* Hypertransport all seem to have appropriate capabilities.
|
||||
*
|
||||
* When only a PCI-Express capability is found the type
|
||||
* is examined to see which type of bridge we have.
|
||||
* When only a PCI-Express capability is found the type is examined to see
|
||||
* which type of bridge we have.
|
||||
*
|
||||
* @param dev Pointer to the device structure of the bridge.
|
||||
* @return Appropriate bridge operations.
|
||||
*/
|
||||
static struct device_operations *get_pci_bridge_ops(device_t dev)
|
||||
{
|
||||
unsigned pos;
|
||||
unsigned int pos;
|
||||
|
||||
#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
|
||||
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
||||
@@ -729,17 +740,17 @@ static struct device_operations *get_pci_bridge_ops(device_t dev)
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_AGP_PLUGIN_SUPPORT == 1
|
||||
/* How do I detect an PCI to AGP bridge? */
|
||||
/* How do I detect a PCI to AGP bridge? */
|
||||
#endif
|
||||
#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
|
||||
pos = 0;
|
||||
while ((pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos))) {
|
||||
unsigned flags;
|
||||
u16 flags;
|
||||
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
||||
if ((flags >> 13) == 1) {
|
||||
/* Host or Secondary Interface */
|
||||
printk(BIOS_DEBUG, "%s subordinate bus Hypertransport\n",
|
||||
dev_path(dev));
|
||||
printk(BIOS_DEBUG, "%s subordinate bus HT\n",
|
||||
dev_path(dev));
|
||||
return &default_ht_ops_bus;
|
||||
}
|
||||
}
|
||||
@@ -747,17 +758,18 @@ static struct device_operations *get_pci_bridge_ops(device_t dev)
|
||||
#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
|
||||
pos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
|
||||
if (pos) {
|
||||
unsigned flags;
|
||||
u16 flags;
|
||||
flags = pci_read_config16(dev, pos + PCI_EXP_FLAGS);
|
||||
switch ((flags & PCI_EXP_FLAGS_TYPE) >> 4) {
|
||||
case PCI_EXP_TYPE_ROOT_PORT:
|
||||
case PCI_EXP_TYPE_UPSTREAM:
|
||||
case PCI_EXP_TYPE_DOWNSTREAM:
|
||||
printk(BIOS_DEBUG, "%s subordinate bus PCI Express\n",
|
||||
dev_path(dev));
|
||||
dev_path(dev));
|
||||
return &default_pciexp_ops_bus;
|
||||
case PCI_EXP_TYPE_PCI_BRIDGE:
|
||||
printk(BIOS_DEBUG, "%s subordinate PCI\n", dev_path(dev));
|
||||
printk(BIOS_DEBUG, "%s subordinate PCI\n",
|
||||
dev_path(dev));
|
||||
return &default_pci_ops_bus;
|
||||
default:
|
||||
break;
|
||||
@@ -779,11 +791,12 @@ static struct device_operations *get_pci_bridge_ops(device_t dev)
|
||||
static void set_pci_ops(struct device *dev)
|
||||
{
|
||||
struct pci_driver *driver;
|
||||
if (dev->ops) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look through the list of setup drivers and find one for
|
||||
if (dev->ops)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Look through the list of setup drivers and find one for
|
||||
* this PCI device.
|
||||
*/
|
||||
for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
|
||||
@@ -791,16 +804,15 @@ static void set_pci_ops(struct device *dev)
|
||||
(driver->device == dev->device)) {
|
||||
dev->ops = (struct device_operations *)driver->ops;
|
||||
printk(BIOS_SPEW, "%s [%04x/%04x] %sops\n",
|
||||
dev_path(dev),
|
||||
driver->vendor, driver->device,
|
||||
(driver->ops->scan_bus ? "bus " : ""));
|
||||
dev_path(dev), driver->vendor, driver->device,
|
||||
(driver->ops->scan_bus ? "bus " : ""));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If I don't have a specific driver use the default operations */
|
||||
switch (dev->hdr_type & 0x7f) { /* header type */
|
||||
case PCI_HEADER_TYPE_NORMAL: /* standard header */
|
||||
/* If I don't have a specific driver use the default operations. */
|
||||
switch (dev->hdr_type & 0x7f) { /* Header type */
|
||||
case PCI_HEADER_TYPE_NORMAL:
|
||||
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
|
||||
goto bad;
|
||||
dev->ops = &default_pci_ops_dev;
|
||||
@@ -815,17 +827,15 @@ static void set_pci_ops(struct device *dev)
|
||||
dev->ops = &default_cardbus_ops_bus;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
bad:
|
||||
default:
|
||||
bad:
|
||||
if (dev->enabled) {
|
||||
printk(BIOS_ERR, "%s [%04x/%04x/%06x] has unknown header "
|
||||
"type %02x, ignoring.\n",
|
||||
dev_path(dev),
|
||||
dev->vendor, dev->device,
|
||||
dev->class >> 8, dev->hdr_type);
|
||||
printk(BIOS_ERR, "%s [%04x/%04x/%06x] has unknown "
|
||||
"header type %02x, ignoring.\n", dev_path(dev),
|
||||
dev->vendor, dev->device,
|
||||
dev->class >> 8, dev->hdr_type);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -843,11 +853,12 @@ static void set_pci_ops(struct device *dev)
|
||||
static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = 0;
|
||||
for (; *list; list = &(*list)->sibling) {
|
||||
if ((*list)->path.type != DEVICE_PATH_PCI) {
|
||||
printk(BIOS_ERR, "child %s not a pci device\n",
|
||||
dev_path(*list));
|
||||
printk(BIOS_ERR, "child %s not a PCI device\n",
|
||||
dev_path(*list));
|
||||
continue;
|
||||
}
|
||||
if ((*list)->path.pci.devfn == devfn) {
|
||||
@@ -859,23 +870,24 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Just like alloc_dev() add the device to the list of devices on the
|
||||
/*
|
||||
* Just like alloc_dev() add the device to the list of devices on the
|
||||
* bus. When the list of devices was formed we removed all of the
|
||||
* parents children, and now we are interleaving static and dynamic
|
||||
* devices in order on the bus.
|
||||
*/
|
||||
if (dev) {
|
||||
struct device *child;
|
||||
|
||||
/* Find the last child of our parent. */
|
||||
for (child = dev->bus->children; child && child->sibling;) {
|
||||
for (child = dev->bus->children; child && child->sibling;)
|
||||
child = child->sibling;
|
||||
}
|
||||
|
||||
/* Place the device on the list of children of its parent. */
|
||||
if (child) {
|
||||
if (child)
|
||||
child->sibling = dev;
|
||||
} else {
|
||||
else
|
||||
dev->bus->children = dev;
|
||||
}
|
||||
}
|
||||
|
||||
return dev;
|
||||
@@ -900,25 +912,29 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
||||
/* Detect if a device is present. */
|
||||
if (!dev) {
|
||||
struct device dummy;
|
||||
|
||||
dummy.bus = bus;
|
||||
dummy.path.type = DEVICE_PATH_PCI;
|
||||
dummy.path.pci.devfn = devfn;
|
||||
|
||||
id = pci_read_config32(&dummy, PCI_VENDOR_ID);
|
||||
/* Have we found something?
|
||||
* Some broken boards return 0 if a slot is empty, but
|
||||
* the expected answer is 0xffffffff
|
||||
/*
|
||||
* Have we found something? Some broken boards return 0 if a
|
||||
* slot is empty, but the expected answer is 0xffffffff.
|
||||
*/
|
||||
if (id == 0xffffffff) {
|
||||
if (id == 0xffffffff)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((id == 0x00000000) || (id == 0x0000ffff) ||
|
||||
(id == 0xffff0000)) {
|
||||
printk(BIOS_SPEW, "%s, bad id 0x%x\n", dev_path(&dummy), id);
|
||||
printk(BIOS_SPEW, "%s, bad id 0x%x\n",
|
||||
dev_path(&dummy), id);
|
||||
return NULL;
|
||||
}
|
||||
dev = alloc_dev(bus, &dummy.path);
|
||||
} else {
|
||||
/* Enable/disable the device. Once we have found the device-
|
||||
/*
|
||||
* Enable/disable the device. Once we have found the device-
|
||||
* specific operations this operations we will disable the
|
||||
* device with those as well.
|
||||
*
|
||||
@@ -929,13 +945,14 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
||||
* it may be absent and enable_dev() must cope.
|
||||
*/
|
||||
/* Run the magic enable sequence for the device. */
|
||||
if (dev->chip_ops && dev->chip_ops->enable_dev) {
|
||||
if (dev->chip_ops && dev->chip_ops->enable_dev)
|
||||
dev->chip_ops->enable_dev(dev);
|
||||
}
|
||||
|
||||
/* Now read the vendor and device ID. */
|
||||
id = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
|
||||
/* If the device does not have a PCI ID disable it. Possibly
|
||||
/*
|
||||
* If the device does not have a PCI ID disable it. Possibly
|
||||
* this is because we have already disabled the device. But
|
||||
* this also handles optional devices that may not always
|
||||
* show up.
|
||||
@@ -944,13 +961,14 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
||||
if ((id == 0xffffffff) || (id == 0x00000000) ||
|
||||
(id == 0x0000ffff) || (id == 0xffff0000)) {
|
||||
if (dev->enabled) {
|
||||
printk(BIOS_INFO, "PCI: Static device %s not found, disabling it.\n",
|
||||
dev_path(dev));
|
||||
printk(BIOS_INFO, "PCI: Static device %s not "
|
||||
"found, disabling it.\n", dev_path(dev));
|
||||
dev->enabled = 0;
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the rest of the PCI configuration information. */
|
||||
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
|
||||
class = pci_read_config32(dev, PCI_CLASS_REVISION);
|
||||
@@ -964,26 +982,24 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
||||
dev->class = class >> 8;
|
||||
|
||||
/* Architectural/System devices always need to be bus masters. */
|
||||
if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
|
||||
if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM)
|
||||
dev->command |= PCI_COMMAND_MASTER;
|
||||
}
|
||||
/* Look at the vendor and device ID, or at least the header type and
|
||||
|
||||
/*
|
||||
* Look at the vendor and device ID, or at least the header type and
|
||||
* class and figure out which set of configuration methods to use.
|
||||
* Unless we already have some PCI ops.
|
||||
*/
|
||||
set_pci_ops(dev);
|
||||
|
||||
/* Now run the magic enable/disable sequence for the device. */
|
||||
if (dev->ops && dev->ops->enable) {
|
||||
if (dev->ops && dev->ops->enable)
|
||||
dev->ops->enable(dev);
|
||||
}
|
||||
|
||||
/* Display the device. */
|
||||
printk(BIOS_DEBUG, "%s [%04x/%04x] %s%s\n",
|
||||
dev_path(dev),
|
||||
dev->vendor, dev->device,
|
||||
dev->enabled ? "enabled" : "disabled",
|
||||
dev->ops ? "" : " No operations");
|
||||
printk(BIOS_DEBUG, "%s [%04x/%04x] %s%s\n", dev_path(dev),
|
||||
dev->vendor, dev->device, dev->enabled ? "enabled" : "disabled",
|
||||
dev->ops ? "" : " No operations");
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -1003,9 +1019,8 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
||||
* @param max Current bus number.
|
||||
* @return The maximum bus number found, after scanning all subordinate busses.
|
||||
*/
|
||||
unsigned int pci_scan_bus(struct bus *bus,
|
||||
unsigned min_devfn, unsigned max_devfn,
|
||||
unsigned int max)
|
||||
unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn,
|
||||
unsigned max_devfn, unsigned int max)
|
||||
{
|
||||
unsigned int devfn;
|
||||
struct device *old_devices;
|
||||
@@ -1013,16 +1028,17 @@ unsigned int pci_scan_bus(struct bus *bus,
|
||||
|
||||
#if CONFIG_PCI_BUS_SEGN_BITS
|
||||
printk(BIOS_DEBUG, "PCI: pci_scan_bus for bus %04x:%02x\n",
|
||||
bus->secondary >> 8, bus->secondary & 0xff);
|
||||
bus->secondary >> 8, bus->secondary & 0xff);
|
||||
#else
|
||||
printk(BIOS_DEBUG, "PCI: pci_scan_bus for bus %02x\n", bus->secondary);
|
||||
#endif
|
||||
|
||||
// Maximum sane devfn is 0xFF
|
||||
/* Maximum sane devfn is 0xFF. */
|
||||
if (max_devfn > 0xff) {
|
||||
printk(BIOS_ERR, "PCI: pci_scan_bus limits devfn %x - devfn %x\n",
|
||||
min_devfn, max_devfn );
|
||||
printk(BIOS_ERR, "PCI: pci_scan_bus upper limit too big. Using 0xff.\n");
|
||||
printk(BIOS_ERR, "PCI: pci_scan_bus limits devfn %x - "
|
||||
"devfn %x\n", min_devfn, max_devfn);
|
||||
printk(BIOS_ERR, "PCI: pci_scan_bus upper limit too big. "
|
||||
"Using 0xff.\n");
|
||||
max_devfn=0xff;
|
||||
}
|
||||
|
||||
@@ -1030,50 +1046,55 @@ unsigned int pci_scan_bus(struct bus *bus,
|
||||
bus->children = NULL;
|
||||
|
||||
post_code(0x24);
|
||||
/* Probe all devices/functions on this bus with some optimization for
|
||||
|
||||
/*
|
||||
* Probe all devices/functions on this bus with some optimization for
|
||||
* non-existence and single function devices.
|
||||
*/
|
||||
for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
|
||||
struct device *dev;
|
||||
|
||||
/* First thing setup the device structure */
|
||||
/* First thing setup the device structure. */
|
||||
dev = pci_scan_get_dev(&old_devices, devfn);
|
||||
|
||||
/* See if a device is present and setup the device structure. */
|
||||
dev = pci_probe_dev(dev, bus, devfn);
|
||||
|
||||
/* If this is not a multi function device, or the device is
|
||||
/*
|
||||
* If this is not a multi function device, or the device is
|
||||
* not present don't waste time probing another function.
|
||||
* Skip to next device.
|
||||
*/
|
||||
if ((PCI_FUNC(devfn) == 0x00) &&
|
||||
(!dev
|
||||
if ((PCI_FUNC(devfn) == 0x00) && (!dev
|
||||
|| (dev->enabled && ((dev->hdr_type & 0x80) != 0x80)))) {
|
||||
devfn += 0x07;
|
||||
}
|
||||
}
|
||||
|
||||
post_code(0x25);
|
||||
|
||||
/* Warn if any leftover static devices are are found.
|
||||
* There's probably a problem in the Config.lb.
|
||||
/*
|
||||
* Warn if any leftover static devices are are found.
|
||||
* There's probably a problem in devicetree.cb.
|
||||
*/
|
||||
if (old_devices) {
|
||||
device_t left;
|
||||
printk(BIOS_WARNING, "PCI: Left over static devices:\n");
|
||||
for (left = old_devices; left; left = left->sibling) {
|
||||
for (left = old_devices; left; left = left->sibling)
|
||||
printk(BIOS_WARNING, "%s\n", dev_path(left));
|
||||
}
|
||||
printk(BIOS_WARNING, "PCI: Check your mainboard Config.lb.\n");
|
||||
|
||||
printk(BIOS_WARNING, "PCI: Check your devicetree.cb.\n");
|
||||
}
|
||||
|
||||
/* For all children that implement scan_bus() (i.e. bridges)
|
||||
/*
|
||||
* For all children that implement scan_bus() (i.e. bridges)
|
||||
* scan the bus behind that child.
|
||||
*/
|
||||
for (child = bus->children; child; child = child->sibling) {
|
||||
for (child = bus->children; child; child = child->sibling)
|
||||
max = scan_bus(child, max);
|
||||
}
|
||||
|
||||
/* We've scanned the bus and so we know all about what's on the other
|
||||
/*
|
||||
* We've scanned the bus and so we know all about what's on the other
|
||||
* side of any bridges that may be on this bus plus any devices.
|
||||
* Return how far we've got finding sub-buses.
|
||||
*/
|
||||
@@ -1119,7 +1140,8 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
|
||||
|
||||
bus = dev->link_list;
|
||||
|
||||
/* Set up the primary, secondary and subordinate bus numbers. We have
|
||||
/*
|
||||
* Set up the primary, secondary and subordinate bus numbers. We have
|
||||
* no idea how many buses are behind this bridge yet, so we set the
|
||||
* subordinate bus number to 0xff for the moment.
|
||||
*/
|
||||
@@ -1131,12 +1153,14 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
|
||||
pci_write_config16(dev, PCI_COMMAND, 0x0000);
|
||||
pci_write_config16(dev, PCI_STATUS, 0xffff);
|
||||
|
||||
/* Read the existing primary/secondary/subordinate bus
|
||||
/*
|
||||
* Read the existing primary/secondary/subordinate bus
|
||||
* number configuration.
|
||||
*/
|
||||
buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
|
||||
|
||||
/* Configure the bus numbers for this bridge: the configuration
|
||||
/*
|
||||
* Configure the bus numbers for this bridge: the configuration
|
||||
* transactions will not be propagated by the bridge if it is not
|
||||
* correctly configured.
|
||||
*/
|
||||
@@ -1146,12 +1170,11 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
|
||||
((unsigned int)(bus->subordinate) << 16));
|
||||
pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
|
||||
|
||||
/* Now we can scan all subordinate buses
|
||||
* i.e. the bus behind the bridge.
|
||||
*/
|
||||
/* Now we can scan all subordinate buses (those behind the bridge). */
|
||||
max = do_scan_bus(bus, 0x00, 0xff, max);
|
||||
|
||||
/* We know the number of buses behind this bridge. Set the subordinate
|
||||
/*
|
||||
* We know the number of buses behind this bridge. Set the subordinate
|
||||
* bus number to its real value.
|
||||
*/
|
||||
bus->subordinate = max;
|
||||
@@ -1200,7 +1223,7 @@ unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
|
||||
* Assign IRQ numbers.
|
||||
*
|
||||
* This function assigns IRQs for all functions contained within the indicated
|
||||
* device address. If the device does not exist or does not require interrupts
|
||||
* device address. If the device does not exist or does not require interrupts
|
||||
* then this function has no effect.
|
||||
*
|
||||
* This function should be called for each PCI slot in your system.
|
||||
@@ -1212,14 +1235,13 @@ unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
|
||||
* routing inside your southbridge and on your board.
|
||||
*/
|
||||
void pci_assign_irqs(unsigned bus, unsigned slot,
|
||||
const unsigned char pIntAtoD[4])
|
||||
const unsigned char pIntAtoD[4])
|
||||
{
|
||||
unsigned int funct;
|
||||
device_t pdev;
|
||||
u8 line;
|
||||
u8 irq;
|
||||
u8 line, irq;
|
||||
|
||||
/* Each slot may contain up to eight functions */
|
||||
/* Each slot may contain up to eight functions. */
|
||||
for (funct = 0; funct < 8; funct++) {
|
||||
pdev = dev_find_slot(bus, (slot << 3) + funct);
|
||||
|
||||
@@ -1228,26 +1250,26 @@ void pci_assign_irqs(unsigned bus, unsigned slot,
|
||||
|
||||
line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
|
||||
|
||||
// PCI spec says all values except 1..4 are reserved.
|
||||
/* PCI spec says all values except 1..4 are reserved. */
|
||||
if ((line < 1) || (line > 4))
|
||||
continue;
|
||||
|
||||
irq = pIntAtoD[line - 1];
|
||||
|
||||
printk(BIOS_DEBUG, "Assigning IRQ %d to %d:%x.%d\n",
|
||||
irq, bus, slot, funct);
|
||||
irq, bus, slot, funct);
|
||||
|
||||
pci_write_config8(pdev, PCI_INTERRUPT_LINE,
|
||||
pIntAtoD[line - 1]);
|
||||
pIntAtoD[line - 1]);
|
||||
|
||||
#ifdef PARANOID_IRQ_ASSIGNMENTS
|
||||
irq = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
|
||||
printk(BIOS_DEBUG, " Readback = %d\n", irq);
|
||||
#endif
|
||||
|
||||
// Change to level triggered
|
||||
i8259_configure_irq_trigger(pIntAtoD[line - 1], IRQ_LEVEL_TRIGGERED);
|
||||
/* Change to level triggered. */
|
||||
i8259_configure_irq_trigger(pIntAtoD[line - 1],
|
||||
IRQ_LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user