Annotation of funnyos/kern/kern_devconfig.c, Revision 1.1.1.1
1.1 init 1: /*
2: * $Id: kern_devconfig.c,v 1.1.1.1 2007/10/12 08:40:36 init Exp $
3: */
4: #include <sys/types.h>
5: #include <sys/device.h>
6: #include <sys/kern_devconfig.h>
7: #include <sys/mem.h>
8: #include <libkern/string.h>
9: #include <libkern/printf.h>
10:
11: #define DEVCONFIG_DEBUG
12:
13: #ifdef DEVCONFIG_DEBUG
14: #define DPRINTF(x...) do { printf(x); } while (0)
15: #else
16: #define DPRINTF(x...) { }
17: #endif
18:
19: //extern struct device devlist[];
20: //extern uint8_t ndevices;
21:
22: /* system root device */
23: extern struct device *rootdev;
24:
25: /* config stuff */
26: extern struct attachinfo config_attachinfo[];
27: extern struct driverinfo config_driverinfo[];
28:
29:
30: void
31: devconfig_recurse(void)
32: {
33: /*
34: * Recursive attach all device tree.
35: * Steps involved:
36: * - find root device in device list and attach it
37: * - for every root's child do:
38: * - attach this child
39: * - for every child's child do:
40: * - attach that child
41: * - ...and so on.
42: */
43: devconfig_attach_root();
44: // devconfig_attach(&rootdev);
45: }
46:
47:
48: void
49: devconfig_attach_root(void)
50: {
51: /*
52: * Attach root and call devconfig_attach on itself (proceeding with its children).
53: */
54: int retval;
55: struct driver *drp;
56: struct driverinfo *dip;
57:
58: DPRINTF("devconfig_attach_root: entering\n");
59:
60: /* allocate memory for root device */
61: rootdev = kmalloc(sizeof(struct device));
62: if (rootdev == NULL)
63: panic("failed to allocate space for rootdev\n");
64: /* NOTREACHED */
65:
66: /* find root's driverinfo */
67: dip = devconfig_finddriverinfo("root");
68:
69: drp = dip->di_driverp;
70:
71: /* allocate space for root's devdata */
72: rootdev->dv_devdata = kmalloc(drp->dr_ddsize);
73: if(rootdev->dv_devdata == NULL)
74: panic("failed to allocate space for rootdev devdata\n");
75: /* NOTREACHED */
76:
77: /* increment number of this driver's instances */
78: dip->di_ninstances++;
79: rootdev->dv_minor = dip->di_ninstances;
80:
81: rootdev->dv_name = dip->di_dname;
82:
83: /* link dv_parent into root itself */
84: rootdev->dv_parent = rootdev;
85:
86: printf("%s/%d at %s/%d loc 0x%x flags 0x%x: ", rootdev->dv_name, rootdev->dv_minor,
87: rootdev->dv_parent->dv_name, rootdev->dv_parent->dv_minor, 0, 0);
88:
89: /* attach root; should never fail */
90: retval = drp->dr_attach(rootdev, 0, 0);
91:
92: if (retval == -1)
93: panic("failed to attach rootdev\n");
94: /* NOTREACHED */
95:
96: /* rootdev has been attached, so activate it */
97: rootdev->dv_active = 1;
98:
99: /* attach all other devices */
100: devconfig_attach_childs(rootdev);
101:
102: }
103:
104: int
105: devconfig_attach_childs(struct device *pdevp)
106: {
107: /*
108: * Attach device childs, if any.
109: * XXX Allocate space for struct device and its xxx_dd
110: */
111: int retval;
112: struct device *cdevp;
113: struct driver *drp;
114: struct driverinfo *dip;
115: struct attachinfo *aip = config_attachinfo;
116:
117: DPRINTF("devconfig_attach_childs: entering for %s/%d\n", pdevp->dv_name, pdevp->dv_minor);
118:
119: /* look for potential children in config_attachinfo table */
120: while(aip->ai_cname != NULL) {
121: if (strncmp(aip->ai_pname, pdevp->dv_name, DVNAMELEN - 1) == 0 && aip->ai_pminor == pdevp->dv_minor) {
122: /*
123: * It is our child.
124: */
125:
126: /* find child's driverinfo */
127: dip = devconfig_finddriverinfo(aip->ai_cname);
128:
129: /* allocate space for child's device */
130: cdevp = kmalloc(sizeof(struct device));
131: if (cdevp == NULL)
132: panic("failed to allocate space for %s device\n", aip->ai_cname);
133: /* NOTREACHED */
134:
135: /* link with parent */
136: cdevp->dv_parent = pdevp;
137:
138: drp = dip->di_driverp;
139:
140: /* allocate space for device's devdata */
141: cdevp->dv_devdata = kmalloc(drp->dr_ddsize);
142: if (cdevp->dv_devdata == NULL)
143: panic("failed to allocate space for %s devdata\n");
144: /* NOTREACHED */
145:
146: /* increment number of driver's instances */
147: dip->di_ninstances++;
148:
149: cdevp->dv_name = dip->di_dname;
150: cdevp->dv_minor = dip->di_ninstances;
151:
152: /* XXX what about locator (aip->ai_locator)? */
153:
154: printf("%s/%d at %s/%d loc 0x%x flags 0x%x: ", cdevp->dv_name, cdevp->dv_minor,
155: pdevp->dv_name, pdevp->dv_minor, aip->ai_locator, aip->ai_flags);
156:
157: /* try to attach this device */
158: retval = drp->dr_attach(cdevp, aip->ai_locator, aip->ai_flags);
159: if (retval == -1) {
160: /*
161: * Attachment failed.
162: */
163:
164: /* XXX what should we do? */
165: printf("disabling %s/%d\n", cdevp->dv_name, cdevp->dv_minor);
166:
167: /* TODO kfree devdata and device */
168:
169: continue;
170: /* NOTREACHED */
171: }
172:
173: /*
174: * Attachment completed.
175: */
176:
177: /* activate device */
178: cdevp->dv_active = 1;
179:
180: /* XXX think about recursion */
181:
182: /* recursive attach this child's children */
183: //devconfig_attach_childs(cdevp);
184:
185: }
186:
187: /* next attachinfo in table */
188: aip++;
189: }
190:
191: }
192:
193: #if 0
194: void
195: devconfig_iterate(void)
196: {
197: struct device *devp = devlist;
198:
199: printf("Entered devconfig phase\n");
200:
201: while(devp->dv_attach != NULL) {
202: /*
203: * Iterative attach all devices in list.
204: */
205: if (! devp->dv_active && (devp->dv_parent->dv_active || devp->dv_parent == devp)) {
206:
207: printf("%s/%d at %s/%d loc 0x%x: ", devp->dv_name, devp->dv_minor, devp->dv_parent->dv_name,
208: devp->dv_parent->dv_minor, devp->dv_locator);
209:
210: /* call attach_subr and activate device if it returns 0 */
211: if (devp->dv_attach(devp) == 0) {
212: /* driver returns okay; mark device as active */
213: devp->dv_active = 1;
214: }
215: else {
216: /* attachment failed */
217: printf("disabling %s/%d\n", devp->dv_name, devp->dv_minor);
218: }
219: }
220:
221: devp++;
222: }
223:
224: printf("Exited devconfig phase\n");
225: }
226:
227:
228: int
229: devconfig_target(struct device *devp)
230: {
231: /*
232: * Recursive attach (subtree) nodes upto already active parent or (root).
233: */
234:
235: if (devp == NULL)
236: return(-1);
237:
238: /* attach parent if it's not (root) or not activated yet */
239: if (devp->dv_parent != devp && ! devp->dv_parent->dv_active) {
240:
241: if (devconfig_target(devp->dv_parent) == -1)
242: return(-1);
243: }
244:
245: printf("%s/%d at %s/%d\n", devp->dv_name, devp->dv_minor,
246: devp->dv_parent->dv_name, devp->dv_parent->dv_minor);
247: if (devp->dv_attach(devp) == 0) {
248: /* attached */
249: devp->dv_active = 1;
250:
251: return(0);
252: }
253: else {
254: /* failed */
255: printf("disabling %s/%d\n", devp->dv_name, devp->dv_minor);
256:
257: /* XXX maybe it is easier to panic here? */
258: /* panic(XXX) */
259:
260: return(-1);
261: }
262: }
263:
264:
265: struct device
266: *devconfig_findbyname(const char *dv_name, const uint8_t dv_minor)
267: {
268: /*
269: * Return pointer to device dv_name/dv_minor.
270: */
271: struct device *devp = devlist;
272:
273: while(devp->dv_name) {
274: if (strncmp(devp->dv_name, dv_name, DVNAMELEN - 1) == 0 && devp->dv_minor == dv_minor)
275: return (devp);
276: }
277:
278: /* nothing has been found */
279: return(NULL);
280: }
281: #endif /* not 0 */
282:
283: struct driverinfo
284: *devconfig_finddriverinfo(const char *dname)
285: {
286: /*
287: * Return associated with dname driver (from config_driverinfo[])
288: * Will cause SYSTEM PANIC if can't find associated driver.
289: */
290: struct driverinfo *dip = config_driverinfo;
291:
292: while(dip->di_dname != NULL) {
293: if (strncmp(dname, dip->di_dname, DVNAMELEN - 1) == 0)
294: return(dip);
295:
296: dip++;
297: }
298:
299: panic("failed to find driverinfo entry for %s\n", dname);
300: /* NOTREACHED */
301:
302: return(NULL);
303: }
304:
305:
CVSweb