summaryrefslogtreecommitdiff
path: root/src/devices
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/chip.c30
-rw-r--r--src/devices/device.c32
-rw-r--r--src/devices/device_util.c15
-rw-r--r--src/devices/hypertransport.c16
-rw-r--r--src/devices/pci_device.c51
-rw-r--r--src/devices/root_device.c2
6 files changed, 92 insertions, 54 deletions
diff --git a/src/devices/chip.c b/src/devices/chip.c
index b7eace38f0..c9e1ac5643 100644
--- a/src/devices/chip.c
+++ b/src/devices/chip.c
@@ -46,16 +46,33 @@ void chip_enumerate(struct chip *chip)
int identical_paths;
identical_paths =
(i > 0) &&
- (path_eq(&chip->path[i - 1].path, &chip->path[i].path)) &&
- (chip->path[i - 1].channel == chip->path[i].channel);
+ (path_eq(&chip->path[i - 1].path, &chip->path[i].path));
if (!identical_paths) {
+ struct bus *parent;
+ int bus;
link = 0;
dev = 0;
+ parent = chip->bus;
switch(chip->path[i].path.type) {
case DEVICE_PATH_NONE:
break;
+ case DEVICE_PATH_PCI:
+ bus = chip->path[i].path.u.pci.bus;
+ if (bus != 0) {
+ device_t dev;
+ int i = 1;
+ dev = chip->dev;
+ while(dev && (i != bus)) {
+ dev = dev->next;
+ i++;
+ }
+ if ((i == bus) && dev) {
+ parent = &dev->link[0];
+ }
+ }
+ /* Fall through */
default:
- dev = alloc_dev(chip->bus, &chip->path[i].path);
+ dev = alloc_dev(parent, &chip->path[i].path);
break;
}
}
@@ -63,12 +80,13 @@ void chip_enumerate(struct chip *chip)
link += 1;
}
if (dev) {
- printk_spew("path %s %s\n", dev_path(dev), identical_paths?"identical":"");
+ printk_spew("path (%p) %s %s", dev, dev_path(dev), identical_paths?"identical":"");
+ printk_spew(" parent: (%p) %s\n",dev->bus->dev, dev_path(dev->bus->dev));
+ dev->chip = chip;
dev->enable = chip->path[i].enable;
dev->links = link + 1;
for(child = chip->children; child; child = child->next) {
- if (!child->bus &&
- child->path[0].channel == i) {
+ if (!child->bus && child->link == i) {
child->bus = &dev->link[link];
}
}
diff --git a/src/devices/device.c b/src/devices/device.c
index 289c0766ea..c6dd5fc4ad 100644
--- a/src/devices/device.c
+++ b/src/devices/device.c
@@ -115,6 +115,9 @@ static void read_resources(struct bus *bus)
dev_path(curdev));
continue;
}
+ if (!curdev->enable) {
+ continue;
+ }
curdev->ops->read_resources(curdev);
/* Read in subtractive resources behind the current device */
links = 0;
@@ -251,16 +254,12 @@ void compute_allocate_resource(
min_align = 0;
base = bridge->base;
- printk_spew("%s: bus %p, bridge %p, type_mask 0x%x, type 0x%x\n",
- __FUNCTION__,
- bus, bridge, type_mask, type);
- printk_spew("vendor 0x%x device 0x%x class 0x%x \n",
- bus->dev->vendor, bus->dev->device, bus->dev->class);
- printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n",
- dev_path(bus->dev),
- (bridge->flags & IORESOURCE_IO)? "io":
- (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
- base, bridge->size, bridge->align, bridge->gran);
+ printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n",
+ dev_path(bus->dev),
+ (bridge->flags & IORESOURCE_IO)? "io":
+ (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
+ base, bridge->size, bridge->align, bridge->gran);
+
/* We want different minimum alignments for different kinds of
* resources. These minimums are not device type specific
@@ -406,6 +405,9 @@ void assign_resources(struct bus *bus)
dev_path(curdev));
continue;
}
+ if (!curdev->enable) {
+ continue;
+ }
curdev->ops->set_resources(curdev);
}
printk_debug("ASSIGNED RESOURCES, bus %d\n", bus->secondary);
@@ -422,6 +424,9 @@ void enable_resources(struct device *dev)
dev_path(dev));
return;
}
+ if (!dev->enable) {
+ return;
+ }
dev->ops->enable_resources(dev);
}
@@ -444,13 +449,12 @@ void dev_enumerate(void)
void dev_configure(void)
{
struct device *root = &dev_root;
- printk_info("%s: Allocating resources...", __FUNCTION__);
+ printk_info("Allocating resources...");
printk_debug("\n");
root->ops->read_resources(root);
- printk_spew("%s: done reading resources...\n", __FUNCTION__);
/* Make certain the io devices are allocated somewhere
* safe.
*/
@@ -465,10 +469,8 @@ void dev_configure(void)
root->resource[1].flags |= IORESOURCE_SET;
// now just set things into registers ... we hope ...
root->ops->set_resources(root);
- printk_spew("%s: done setting resources...\n", __FUNCTION__);
allocate_vga_resource();
- printk_spew("%s: done vga resources...\n", __FUNCTION__);
printk_info("done.\n");
}
@@ -494,7 +496,7 @@ void dev_initialize(void)
printk_info("Initializing devices...\n");
for (dev = all_devices; dev; dev = dev->next) {
- if (dev->ops && dev->ops->init) {
+ if (dev->enable && dev->ops && dev->ops->init) {
printk_debug("%s init\n", dev_path(dev));
dev->ops->init(dev);
}
diff --git a/src/devices/device_util.c b/src/devices/device_util.c
index 384a3be8e0..6652c86ea0 100644
--- a/src/devices/device_util.c
+++ b/src/devices/device_util.c
@@ -30,15 +30,17 @@ device_t alloc_find_dev(struct bus *parent, struct device_path *path)
*/
struct device *dev_find_slot(unsigned int bus, unsigned int devfn)
{
- struct device *dev;
+ struct device *dev, *result;
+ result = 0;
for (dev = all_devices; dev; dev = dev->next) {
if ((dev->bus->secondary == bus) &&
(dev->path.u.pci.devfn == devfn)) {
+ result = dev;
break;
}
}
- return dev;
+ return result;
}
/** Find a device of a given vendor and type
@@ -88,6 +90,9 @@ const char *dev_path(device_t dev)
}
else {
switch(dev->path.type) {
+ case DEVICE_PATH_ROOT:
+ memcpy(buffer, "Root Device", 12);
+ break;
case DEVICE_PATH_PCI:
sprintf(buffer, "PCI: %02x:%02x.%01x",
dev->bus->secondary,
@@ -116,8 +121,12 @@ int path_eq(struct device_path *path1, struct device_path *path2)
switch(path1->type) {
case DEVICE_PATH_NONE:
break;
+ case DEVICE_PATH_ROOT:
+ equal = 1;
+ break;
case DEVICE_PATH_PCI:
- equal = path1->u.pci.devfn == path2->u.pci.devfn;
+ equal = (path1->u.pci.bus == path2->u.pci.bus) &&
+ (path1->u.pci.devfn == path2->u.pci.devfn);
break;
case DEVICE_PATH_PNP:
equal = (path1->u.pnp.port == path2->u.pnp.port) &&
diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c
index 0c1dc3959a..326f343662 100644
--- a/src/devices/hypertransport.c
+++ b/src/devices/hypertransport.c
@@ -4,6 +4,7 @@
#include <device/path.h>
#include <device/pci.h>
#include <device/hypertransport.h>
+#include <device/chip.h>
#include <part/hard_reset.h>
#include <part/fallback_boot.h>
@@ -243,11 +244,19 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
/* Add this device to the pci bus chain */
*chain_last = dev;
/* Run the magice enable/disable sequence for the device */
- if (dev->ops && dev->ops->enable) {
- dev->ops->enable(dev);
+ if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
+ dev->chip->control->enable_dev(dev);
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
+
+ /* If the chain is fully enumerated quit */
+ if (id == 0xffffffff || id == 0x00000000 ||
+ id == 0x0000ffff || id == 0xffff0000) {
+ printk_err("Missing static device: %s\n",
+ dev_path(dev));
+ break;
+ }
}
/* Update the device chain tail */
for(func = dev; func; func = func->sibling) {
@@ -268,7 +277,8 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
/* Find the hypertransport link capability */
pos = ht_lookup_slave_capability(dev);
if (pos == 0) {
- printk_err("Hypertransport link capability not found");
+ printk_err("%s Hypertransport link capability not found",
+ dev_path(dev));
break;
}
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index 806734c18b..031d855fbf 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -18,6 +18,7 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
+#include <device/chip.h>
#include <part/hard_reset.h>
#include <part/fallback_boot.h>
@@ -175,7 +176,6 @@ static void pci_bridge_read_bases(struct device *dev)
/* FIXME handle bridges without some of the optional resources */
- printk_spew("%s: path %s\n", __FUNCTION__, dev_path(dev));
/* Initialize the io space constraints on the current bus */
dev->resource[reg].base = 0;
dev->resource[reg].size = 0;
@@ -215,7 +215,6 @@ static void pci_bridge_read_bases(struct device *dev)
reg++;
dev->resources = reg;
- printk_spew("DONE %s: path %s\n", __FUNCTION__, dev_path(dev));
}
@@ -455,11 +454,13 @@ static void set_pci_ops(struct device *dev)
break;
default:
bad:
- printk_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);
+ if (dev->enable) {
+ printk_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;
}
@@ -556,17 +557,16 @@ unsigned int pci_scan_bus(struct bus *bus,
}
else {
/* Run the magic enable/disable sequence for the device */
- if (dev->ops && dev->ops->enable) {
- dev->ops->enable(dev);
+ if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
+ dev->chip->control->enable_dev(dev);
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
}
-
/* 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);
-
+
/* Store the interesting information in the device structure */
dev->vendor = id & 0xffff;
dev->device = (id >> 16) & 0xffff;
@@ -576,20 +576,19 @@ unsigned int pci_scan_bus(struct bus *bus,
/* 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.
+ * methods to use. Unless we already have some pci ops.
*/
- if (!dev->ops) {
- set_pci_ops(dev);
- /* Error if we don't have some pci operations for it */
- if (!dev->ops) {
- printk_err("%s No device operations\n",
- dev_path(dev));
- continue;
- }
- /* Now run the magic enable/disable sequence for the device */
- if (dev->ops && dev->ops->enable) {
- dev->ops->enable(dev);
- }
+ set_pci_ops(dev);
+ /* Error if we don't have some pci operations for it */
+ if (dev->enable && !dev->ops) {
+ printk_err("%s No device operations\n",
+ dev_path(dev));
+ continue;
+ }
+
+ /* Now run the magic enable/disable sequence for the device */
+ if (dev->ops && dev->ops->enable) {
+ dev->ops->enable(dev);
}
printk_debug("%s [%04x/%04x] %s\n",
@@ -632,8 +631,7 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
struct bus *bus;
uint32_t buses;
uint16_t cr;
-
- printk_spew("%s: dev %p, max %d\n", __FUNCTION__, dev, max);
+
bus = &dev->link[0];
dev->links = 1;
@@ -707,7 +705,6 @@ static void pci_level_irq(unsigned char intNum)
}
}
-
/*
This function assigns IRQs for all functions contained within
the indicated device address. If the device does not exist or does
diff --git a/src/devices/root_device.c b/src/devices/root_device.c
index ae02277363..4a076a1bb3 100644
--- a/src/devices/root_device.c
+++ b/src/devices/root_device.c
@@ -123,6 +123,8 @@ struct device_operations default_dev_ops_root = {
struct device dev_root = {
.ops = &default_dev_ops_root,
.bus = &dev_root.link[0],
+ .path = { .type = DEVICE_PATH_ROOT },
+ .enable = 1,
.links = 1,
.link = {
[0] = {