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

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