Annotation of funnyos/kern/kern_devconfig.c, Revision 1.2
1.1 init 1: /*
1.2 ! init 2: * $Id: kern_devconfig.c,v 1.1.1.1 2007/10/16 08:41:04 init Exp $
1.1 init 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:
1.2 ! init 169: /* XXX next aip */
! 170: aip++;
! 171:
1.1 init 172: continue;
173: /* NOTREACHED */
174: }
175:
176: /*
177: * Attachment completed.
178: */
179:
180: /* activate device */
181: cdevp->dv_active = 1;
182:
183: /* XXX think about recursion */
184:
185: /* recursive attach this child's children */
1.2 ! init 186: devconfig_attach_childs(cdevp);
1.1 init 187:
188: }
1.2 ! init 189: printf("next aip\n");
1.1 init 190:
191: /* next attachinfo in table */
192: aip++;
193: }
194:
195: }
196:
197: #if 0
198: void
199: devconfig_iterate(void)
200: {
201: struct device *devp = devlist;
202:
203: printf("Entered devconfig phase\n");
204:
205: while(devp->dv_attach != NULL) {
206: /*
207: * Iterative attach all devices in list.
208: */
209: if (! devp->dv_active && (devp->dv_parent->dv_active || devp->dv_parent == devp)) {
210:
211: printf("%s/%d at %s/%d loc 0x%x: ", devp->dv_name, devp->dv_minor, devp->dv_parent->dv_name,
212: devp->dv_parent->dv_minor, devp->dv_locator);
213:
214: /* call attach_subr and activate device if it returns 0 */
215: if (devp->dv_attach(devp) == 0) {
216: /* driver returns okay; mark device as active */
217: devp->dv_active = 1;
218: }
219: else {
220: /* attachment failed */
221: printf("disabling %s/%d\n", devp->dv_name, devp->dv_minor);
222: }
223: }
224:
225: devp++;
226: }
227:
228: printf("Exited devconfig phase\n");
229: }
230:
231:
232: int
233: devconfig_target(struct device *devp)
234: {
235: /*
236: * Recursive attach (subtree) nodes upto already active parent or (root).
237: */
238:
239: if (devp == NULL)
240: return(-1);
241:
242: /* attach parent if it's not (root) or not activated yet */
243: if (devp->dv_parent != devp && ! devp->dv_parent->dv_active) {
244:
245: if (devconfig_target(devp->dv_parent) == -1)
246: return(-1);
247: }
248:
249: printf("%s/%d at %s/%d\n", devp->dv_name, devp->dv_minor,
250: devp->dv_parent->dv_name, devp->dv_parent->dv_minor);
251: if (devp->dv_attach(devp) == 0) {
252: /* attached */
253: devp->dv_active = 1;
254:
255: return(0);
256: }
257: else {
258: /* failed */
259: printf("disabling %s/%d\n", devp->dv_name, devp->dv_minor);
260:
261: /* XXX maybe it is easier to panic here? */
262: /* panic(XXX) */
263:
264: return(-1);
265: }
266: }
267:
268:
269: struct device
270: *devconfig_findbyname(const char *dv_name, const uint8_t dv_minor)
271: {
272: /*
273: * Return pointer to device dv_name/dv_minor.
274: */
275: struct device *devp = devlist;
276:
277: while(devp->dv_name) {
278: if (strncmp(devp->dv_name, dv_name, DVNAMELEN - 1) == 0 && devp->dv_minor == dv_minor)
279: return (devp);
280: }
281:
282: /* nothing has been found */
283: return(NULL);
284: }
285: #endif /* not 0 */
286:
287: struct driverinfo
288: *devconfig_finddriverinfo(const char *dname)
289: {
290: /*
291: * Return associated with dname driver (from config_driverinfo[])
292: * Will cause SYSTEM PANIC if can't find associated driver.
293: */
294: struct driverinfo *dip = config_driverinfo;
295:
296: while(dip->di_dname != NULL) {
297: if (strncmp(dname, dip->di_dname, DVNAMELEN - 1) == 0)
298: return(dip);
299:
300: dip++;
301: }
302:
303: panic("failed to find driverinfo entry for %s\n", dname);
304: /* NOTREACHED */
305:
306: return(NULL);
307: }
308:
309:
CVSweb