Annotation of funnyos/kern/kern_devconfig.c, Revision 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