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

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