Annotation of funnyos/kern/kern_devconfig.c, Revision 1.7
1.1 init 1: /*
1.7 ! init 2: * $Id: kern_devconfig.c,v 1.6 2007/11/01 13:19:27 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.
1.7 ! init 106: * Allocate space for struct device and its xxx_dd
1.1 init 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: printf("%s/%d at %s/%d loc 0x%x flags 0x%x: ", cdevp->dv_name, cdevp->dv_minor,
150: pdevp->dv_name, pdevp->dv_minor, aip->ai_locator, aip->ai_flags);
151:
152: /* try to attach this device */
153: retval = drp->dr_attach(cdevp, aip->ai_locator, aip->ai_flags);
1.6 init 154: if (retval != 0) {
1.1 init 155: /*
156: * Attachment failed.
157: */
158:
159: /* XXX what should we do? */
160: printf("disabling %s/%d\n", cdevp->dv_name, cdevp->dv_minor);
161:
162: /* TODO kfree devdata and device */
163:
1.7 ! init 164: /* next aip */
1.2 init 165: aip++;
166:
1.1 init 167: continue;
168: /* NOTREACHED */
169: }
170:
171: /*
172: * Attachment completed.
173: */
174:
175: /* activate device */
176: cdevp->dv_active = 1;
177:
178: /* recursive attach this child's children */
1.2 init 179: devconfig_attach_childs(cdevp);
1.1 init 180:
181: }
182:
183: /* next attachinfo in table */
184: aip++;
185: }
186:
187: }
188:
189:
190: struct driverinfo
191: *devconfig_finddriverinfo(const char *dname)
192: {
193: /*
194: * Return associated with dname driver (from config_driverinfo[])
195: * Will cause SYSTEM PANIC if can't find associated driver.
196: */
197: struct driverinfo *dip = config_driverinfo;
198:
199: while(dip->di_dname != NULL) {
200: if (strncmp(dname, dip->di_dname, DVNAMELEN - 1) == 0)
201: return(dip);
202:
203: dip++;
204: }
205:
206: panic("failed to find driverinfo entry for %s\n", dname);
207: /* NOTREACHED */
208:
209: return(NULL);
210: }
211:
212:
CVSweb