1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* chips are arbitrary chips (superio, southbridge, etc.)
* They have private structures that define chip resources and default
* settings. They have four externally visible functions for control.
* They have a generic component which applies to all chips for
* path, etc.
*/
#include <console/console.h>
#include <device/chip.h>
#include <device/pci.h>
void
chip_configure(struct chip *root, enum chip_pass pass)
{
struct chip *c;
for (c = root; c; c = c->next) {
if (c->control && c->control->enable)
c->control->enable(c, pass);
}
for (c = root; c; c = c->next) {
if (c->children)
chip_configure(c->children, pass);
}
}
/** Convert a static struct chip structure to a set of dynamic device structures.
* @param chip Static chip structure to start with.
*/
void chip_enumerate(struct chip *chip)
{
struct chip *child;
device_t dev;
int link;
int i;
dev = 0;
link = 0;
#if 1
if (chip->control && chip->control->name) {
printk_debug("Enumerating: %s\n", chip->control->name);
}
#endif
for(i = 0; i < MAX_CHIP_PATHS; i++) {
int identical_paths;
identical_paths =
(i > 0) &&
(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(parent, &chip->path[i].path);
break;
}
}
else {
link += 1;
}
if (dev) {
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->link == i) {
child->bus = &dev->link[link];
}
}
}
if (dev && !chip->dev) {
chip->dev = dev;
}
}
for(child = chip->children; child; child = child->next) {
if (!child->bus) {
child->bus = &chip->dev->link[0];
}
}
}
static void enumerate_static_device_chain(struct chip *root)
{
struct chip *chip;
for(chip = root; chip; chip = chip->next) {
void (*enumerate)(struct chip *chip);
enumerate = chip_enumerate;
if (chip->control && chip->control->enumerate) {
enumerate = chip->control->enumerate;
}
enumerate(chip);
}
for(chip = root; chip; chip = chip->next) {
if (chip->children) {
enumerate_static_device_chain(chip->children);
}
}
}
void enumerate_static_devices(void)
{
enumerate_static_device_chain(&static_root);
}
|