diff options
author | Li-Ta Lo <ollie@lanl.gov> | 2004-03-23 21:28:05 +0000 |
---|---|---|
committer | Li-Ta Lo <ollie@lanl.gov> | 2004-03-23 21:28:05 +0000 |
commit | e52666931a3e34895b3f3b92641de9774ab722ec (patch) | |
tree | 890bb66a0a16ec7a57230283f000ee91eeb0b384 /src/devices/device.c | |
parent | 9f46132e9627d24f3ad76619cf3340006a4012fb (diff) |
Doxidization, reformat
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1469 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/devices/device.c')
-rw-r--r-- | src/devices/device.c | 173 |
1 files changed, 112 insertions, 61 deletions
diff --git a/src/devices/device.c b/src/devices/device.c index b54e770294..0186aa977a 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -22,24 +22,41 @@ #include <stdlib.h> #include <string.h> -/* Linked list of ALL devices */ +/** Linked list of ALL devices */ struct device *all_devices = &dev_root; -/* pointer to the last device */ +/** Pointer to the last device */ static struct device **last_dev_p = &dev_root.next; -#define DEVICE_MEM_HIGH 0xFEC00000UL /* Reserve 20M for the system */ +/** The upper limit of MEM resource of the devices. + * Reserve 20M for the system */ +#define DEVICE_MEM_HIGH 0xFEC00000UL +/** The lower limit of IO resource of the devices. + * Reserve 4k for ISA/Legacy devices */ #define DEVICE_IO_START 0x1000 -/** Allocate a new device structure +/** + * @brief Allocate a new device structure. + * + * Allocte a new device structure and attached it to the device tree as a child + * of the parent bus. + * + * @param parent parent bus the newly created device attached to. + * @param path path to the device to be created. + * + * @return pointer to the newly created device structure. + * + * @see device_path */ device_t alloc_dev(struct bus *parent, struct device_path *path) { device_t dev, child; int link; + /* Find the last child of our parent */ - for(child = parent->children; child && child->sibling; ) { + for (child = parent->children; child && child->sibling; ) { child = child->sibling; } + dev = malloc(sizeof(*dev)); if (dev == 0) { die("DEV: out of memory.\n"); @@ -47,14 +64,14 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) memset(dev, 0, sizeof(*dev)); memcpy(&dev->path, path, sizeof(*path)); - /* Append a new device to the global device chain. - * The chain is used to find devices once everything is set up. + /* Append a new device to the global device list. + * The list is used to find devices once everything is set up. */ *last_dev_p = dev; last_dev_p = &dev->next; /* Initialize the back pointers in the link fields */ - for(link = 0; link < MAX_LINKS; link++) { + for (link = 0; link < MAX_LINKS; link++) { dev->link[link].dev = dev; dev->link[link].link = link; } @@ -66,12 +83,15 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) } else { parent->children = dev; } + /* If we don't have any other information about a device enable it */ dev->enable = 1; + return dev; } -/** round a number to an alignment. +/** + * @brief round a number up to an alignment. * @param val the starting value * @param roundup Alignment as a power of two * @returns rounded up number @@ -104,7 +124,7 @@ static void read_resources(struct bus *bus) struct device *curdev; /* Walk through all of the devices and find which resources they need. */ - for(curdev = bus->children; curdev; curdev = curdev->sibling) { + for (curdev = bus->children; curdev; curdev = curdev->sibling) { unsigned links; int i; if (curdev->resources > 0) { @@ -112,20 +132,22 @@ static void read_resources(struct bus *bus) } if (!curdev->ops || !curdev->ops->read_resources) { printk_err("%s missing read_resources\n", - dev_path(curdev)); + dev_path(curdev)); continue; } if (!curdev->enable) { continue; } + curdev->ops->read_resources(curdev); + /* Read in subtractive resources behind the current device */ links = 0; - for(i = 0; i < curdev->resources; i++) { + for (i = 0; i < curdev->resources; i++) { struct resource *resource; resource = &curdev->resource[i]; if ((resource->flags & IORESOURCE_SUBTRACTIVE) && - (!(links & (1 << resource->index)))) + (!(links & (1 << resource->index)))) { links |= (1 << resource->index); read_resources(&curdev->link[resource->index]); @@ -142,8 +164,8 @@ struct pick_largest_state { int seen_last; }; -static void pick_largest_resource( - struct pick_largest_state *state, struct device *dev, struct resource *resource) +static void pick_largest_resource(struct pick_largest_state *state, + struct device *dev, struct resource *resource) { struct resource *last; last = state->last; @@ -152,32 +174,33 @@ static void pick_largest_resource( state->seen_last = 1; return; } - if (last && ( - (last->align < resource->align) || - ((last->align == resource->align) && - (last->size < resource->size)) || - ((last->align == resource->align) && - (last->size == resource->size) && - (!state->seen_last)))) { + if (last && + ((last->align < resource->align) || + ((last->align == resource->align) && + (last->size < resource->size)) || + ((last->align == resource->align) && + (last->size == resource->size) && + (!state->seen_last)))) { return; } - if (!state->result || - (state->result->align < resource->align) || - ((state->result->align == resource->align) && - (state->result->size < resource->size))) { + if (!state->result || + (state->result->align < resource->align) || + ((state->result->align == resource->align) && + (state->result->size < resource->size))) { state->result_dev = dev; state->result = resource; - } - + } } static void find_largest_resource(struct pick_largest_state *state, - struct bus *bus, unsigned long type_mask, unsigned long type) + struct bus *bus, unsigned long type_mask, + unsigned long type) { struct device *curdev; - for(curdev = bus->children; curdev; curdev = curdev->sibling) { + + for (curdev = bus->children; curdev; curdev = curdev->sibling) { int i; - for(i = 0; i < curdev->resources; i++) { + for (i = 0; i < curdev->resources; i++) { struct resource *resource = &curdev->resource[i]; /* If it isn't the right kind of resource ignore it */ if ((resource->flags & type_mask) != type) { @@ -187,7 +210,8 @@ static void find_largest_resource(struct pick_largest_state *state, if (resource->flags & IORESOURCE_SUBTRACTIVE) { struct bus *subbus; subbus = &curdev->link[resource->index]; - find_largest_resource(state, subbus, type_mask, type); + find_largest_resource(state, subbus, + type_mask, type); continue; } /* See if this is the largest resource */ @@ -196,8 +220,10 @@ static void find_largest_resource(struct pick_largest_state *state, } } -static struct device *largest_resource(struct bus *bus, struct resource **result_res, - unsigned long type_mask, unsigned long type) +static struct device *largest_resource(struct bus *bus, + struct resource **result_res, + unsigned long type_mask, + unsigned long type) { struct pick_largest_state state; @@ -254,12 +280,12 @@ void compute_allocate_resource( min_align = 0; base = bridge->base; - 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 @@ -278,8 +304,9 @@ void compute_allocate_resource( /* Remember I haven't found anything yet. */ resource = 0; - /* Walk through all the devices on the current bus and compute the addresses */ - while((dev = largest_resource(bus, &resource, type_mask, type))) { + /* Walk through all the devices on the current bus and compute the + * addresses */ + while ((dev = largest_resource(bus, &resource, type_mask, type))) { unsigned long size; /* Do NOT I repeat do not ignore resources which have zero size. * If they need to be ignored dev->read_resources should not even @@ -357,6 +384,8 @@ void compute_allocate_resource( static void allocate_vga_resource(void) { #warning "FIXME modify allocate_vga_resource so it is less pci centric!" +#warning "This function knows to much about PCI stuff, it should be just a ietrator/visitor." + /* FIXME handle the VGA pallette snooping */ struct device *dev, *vga; struct bus *bus; @@ -422,7 +451,7 @@ void enable_resources(struct device *dev) */ if (!dev->ops || !dev->ops->enable_resources) { printk_err("%s missing enable_resources\n", - dev_path(dev)); + dev_path(dev)); return; } if (!dev->enable) { @@ -431,58 +460,74 @@ void enable_resources(struct device *dev) dev->ops->enable_resources(dev); } -/** Enumerate the resources on the PCI by calling pci_init +/** + * @brief Determine the existence of dynamic devices and construct dynamic + * device tree. + * + * Start for the root device 'dev_root', scan the buses in the system, build + * the dynamic device tree according to the result of the probe. + * + * This function have no idea how to scan and probe the buses and devices at + * all. It depends on the bus/device specific scan_bus() method to do it. + * The scan_bus() function also have to create the device structure and attach + * it to the device tree. */ void dev_enumerate(void) { struct device *root; unsigned subordinate; - printk_info("Enumerating buses..."); + + printk_info("Enumerating buses...\n"); + root = &dev_root; subordinate = root->ops->scan_bus(root, 0); + printk_info("done\n"); } -/** Starting at the root, compute what resources are needed and allocate them. +/** + * @brief Configure devices on the devices tree. + * + * Starting at the root, compute what resources are needed and allocate them. * I/O starts at PCI_IO_START. Since the assignment is hierarchical we * set the values into the dev_root struct. */ void dev_configure(void) { struct device *root = &dev_root; + printk_info("Allocating resources..."); printk_debug("\n"); - root->ops->read_resources(root); - /* Make certain the io devices are allocated somewhere - * safe. - */ + /* Make certain the io devices are allocated somewhere safe. */ root->resource[0].base = DEVICE_IO_START; root->resource[0].flags |= IORESOURCE_ASSIGNED; root->resource[0].flags &= ~IORESOURCE_STORED; - /* Now reallocate the pci resources memory with the - * highest addresses I can manage. - */ + + /* Now reallocate the pci resources memory with the highest + * addresses I can manage.*/ root->resource[1].base = round_down(DEVICE_MEM_HIGH - root->resource[1].size, - 1UL << root->resource[1].align); + 1UL << root->resource[1].align); root->resource[1].flags |= IORESOURCE_ASSIGNED; root->resource[1].flags &= ~IORESOURCE_STORED; - /* Allocate the VGA I/O resource.. - */ + /* Allocate the VGA I/O resource.. */ allocate_vga_resource(); - // now just set things into registers ... we hope ... + /* now just set things into registers ... we hope ... */ root->ops->set_resources(root); printk_info("done.\n"); } -/** Starting at the root, walk the tree and enable all devices/bridges. - * What really happens is computed COMMAND bits get set in register 4 +/** + * @brief Enable devices on the device tree. + * + * Starting at the root, walk the tree and enable all devices/bridges by + * calling the device's enable_resources() method. */ void dev_enable(void) { @@ -490,22 +535,28 @@ void dev_enable(void) /* now enable everything. */ enable_resources(&dev_root); + printk_info("done.\n"); } -/** Starting at the root, walk the tree and call a driver to - * do device specific setup. +/** + * @brief Initialize all devices in the global device list. + * + * Starting at the first device on the global device link list, + * walk the list and call a driver to do device specific setup. */ void dev_initialize(void) { struct device *dev; printk_info("Initializing devices...\n"); + for (dev = all_devices; dev; dev = dev->next) { if (dev->enable && dev->ops && dev->ops->init) { printk_debug("%s init\n", dev_path(dev)); dev->ops->init(dev); } } + printk_info("Devices initialized\n"); } |