Annotation of funnyos/kern/kern_devconfig.c, Revision 1.6
1.1 init 1: /*
1.6 ! init 2: * $Id: kern_devconfig.c,v 1.5 2007/10/23 12:32:01 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:
1.4 init 11: /* #define DEVCONFIG_DEBUG */
1.1 init 12:
13: #ifdef DEVCONFIG_DEBUG
14: #define DPRINTF(x...) do { printf(x); } while (0)
15: #else
16: #define DPRINTF(x...) { }
17: #endif
18:
19:
20: /* system root device */
21: extern struct device *rootdev;
22:
23: /* config stuff */
24: extern struct attachinfo config_attachinfo[];
25: extern struct driverinfo config_driverinfo[];
26:
27:
28: void
29: devconfig_recurse(void)
30: {
31: /*
32: * Recursive attach all device tree.
33: * Steps involved:
34: * - find root device in device list and attach it
35: * - for every root's child do:
36: * - attach this child
37: * - for every child's child do:
38: * - attach that child
39: * - ...and so on.
40: */
41: devconfig_attach_root();
42: }
43:
44:
45: void
46: devconfig_attach_root(void)
47: {
48: /*
49: * Attach root and call devconfig_attach on itself (proceeding with its children).
50: */
51: int retval;
52: struct driver *drp;
53: struct driverinfo *dip;
54:
55: DPRINTF("devconfig_attach_root: entering\n");
56:
57: /* allocate memory for root device */
58: rootdev = kmalloc(sizeof(struct device));
59: if (rootdev == NULL)
60: panic("failed to allocate space for rootdev\n");
61: /* NOTREACHED */
62:
63: /* find root's driverinfo */
64: dip = devconfig_finddriverinfo("root");
65:
66: drp = dip->di_driverp;
67:
68: /* allocate space for root's devdata */
69: rootdev->dv_devdata = kmalloc(drp->dr_ddsize);
70: if(rootdev->dv_devdata == NULL)
71: panic("failed to allocate space for rootdev devdata\n");
72: /* NOTREACHED */
73:
74: /* increment number of this driver's instances */
75: dip->di_ninstances++;
76: rootdev->dv_minor = dip->di_ninstances;
77:
78: rootdev->dv_name = dip->di_dname;
79:
80: /* link dv_parent into root itself */
81: rootdev->dv_parent = rootdev;
82:
83: printf("%s/%d at %s/%d loc 0x%x flags 0x%x: ", rootdev->dv_name, rootdev->dv_minor,
84: rootdev->dv_parent->dv_name, rootdev->dv_parent->dv_minor, 0, 0);
85:
86: /* attach root; should never fail */
87: retval = drp->dr_attach(rootdev, 0, 0);
88:
1.6 ! init 89: if (retval != 0)
1.1 init 90: panic("failed to attach rootdev\n");
91: /* NOTREACHED */
92:
93: /* rootdev has been attached, so activate it */
94: rootdev->dv_active = 1;
95:
96: /* attach all other devices */
97: devconfig_attach_childs(rootdev);
98:
99: }
100:
101: int
102: devconfig_attach_childs(struct device *pdevp)
103: {
104: /*
105: * Attach device childs, if any.
106: * XXX Allocate space for struct device and its xxx_dd
107: */
108: int retval;
109: struct device *cdevp;
110: struct driver *drp;
111: struct driverinfo *dip;
112: struct attachinfo *aip = config_attachinfo;
113:
114: DPRINTF("devconfig_attach_childs: entering for %s/%d\n", pdevp->dv_name, pdevp->dv_minor);
115:
116: /* look for potential children in config_attachinfo table */
117: while(aip->ai_cname != NULL) {
118: if (strncmp(aip->ai_pname, pdevp->dv_name, DVNAMELEN - 1) == 0 && aip->ai_pminor == pdevp->dv_minor) {
119: /*
120: * It is our child.
121: */
122:
123: /* find child's driverinfo */
124: dip = devconfig_finddriverinfo(aip->ai_cname);
125:
126: /* allocate space for child's device */
127: cdevp = kmalloc(sizeof(struct device));
128: if (cdevp == NULL)
129: panic("failed to allocate space for %s device\n", aip->ai_cname);
130: /* NOTREACHED */
131:
132: /* link with parent */
133: cdevp->dv_parent = pdevp;
134:
135: drp = dip->di_driverp;
136:
137: /* allocate space for device's devdata */
138: cdevp->dv_devdata = kmalloc(drp->dr_ddsize);
139: if (cdevp->dv_devdata == NULL)
140: panic("failed to allocate space for %s devdata\n");
141: /* NOTREACHED */
142:
143: /* increment number of driver's instances */
144: dip->di_ninstances++;
145:
146: cdevp->dv_name = dip->di_dname;
147: cdevp->dv_minor = dip->di_ninstances;
148:
149: /* XXX what about locator (aip->ai_locator)? */
150:
151: printf("%s/%d at %s/%d loc 0x%x flags 0x%x: ", cdevp->dv_name, cdevp->dv_minor,
152: pdevp->dv_name, pdevp->dv_minor, aip->ai_locator, aip->ai_flags);
153:
154: /* try to attach this device */
155: retval = drp->dr_attach(cdevp, aip->ai_locator, aip->ai_flags);
1.6 ! init 156: if (retval != 0) {
1.1 init 157: /*
158: * Attachment failed.
159: */
160:
161: /* XXX what should we do? */
162: printf("disabling %s/%d\n", cdevp->dv_name, cdevp->dv_minor);
163:
164: /* TODO kfree devdata and device */
165:
1.2 init 166: /* XXX next aip */
167: aip++;
168:
1.1 init 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 */
1.2 init 183: devconfig_attach_childs(cdevp);
1.1 init 184:
185: }
186:
187: /* next attachinfo in table */
188: aip++;
189: }
190:
191: }
192:
193:
194: struct driverinfo
195: *devconfig_finddriverinfo(const char *dname)
196: {
197: /*
198: * Return associated with dname driver (from config_driverinfo[])
199: * Will cause SYSTEM PANIC if can't find associated driver.
200: */
201: struct driverinfo *dip = config_driverinfo;
202:
203: while(dip->di_dname != NULL) {
204: if (strncmp(dname, dip->di_dname, DVNAMELEN - 1) == 0)
205: return(dip);
206:
207: dip++;
208: }
209:
210: panic("failed to find driverinfo entry for %s\n", dname);
211: /* NOTREACHED */
212:
213: return(NULL);
214: }
215:
216:
CVSweb