[BACK]Return to kern_devconfig.c CVS log [TXT][DIR] Up to [local] / funnyos / kern

Annotation of funnyos/kern/kern_devconfig.c, Revision 1.3

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

CVSweb