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

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

1.1       init        1: /*
1.9     ! nbrk        2:  * $Id: kern_devconfig.c,v 1.8 2007/11/02 13:17:39 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>
1.8       init        8: #include <sys/kern_irq.h>
1.1       init        9: #include <libkern/string.h>
                     10: #include <libkern/printf.h>
                     11:
1.4       init       12: /* #define DEVCONFIG_DEBUG */
1.1       init       13:
                     14: #ifdef DEVCONFIG_DEBUG
                     15: #define DPRINTF(x...)  do { printf(x); } while (0)
                     16: #else
                     17: #define DPRINTF(x...)  { }
                     18: #endif
                     19:
                     20:
                     21: /* system root device */
                     22: extern struct device   *rootdev;
                     23:
                     24: /* config stuff */
                     25: extern struct attachinfo       config_attachinfo[];
                     26: extern struct driverinfo       config_driverinfo[];
                     27:
                     28:
                     29: void
                     30: devconfig_recurse(void)
                     31: {
                     32:        /*
                     33:         * Recursive attach all device tree.
                     34:         * Steps involved:
                     35:         *  - find root device in device list and attach it
                     36:         *  - for every root's child do:
                     37:         *  -  attach this child
                     38:         *  -   for every child's child do:
                     39:         *  -    attach that child
                     40:         *  -     ...and so on.
                     41:         */
                     42:        devconfig_attach_root();
                     43: }
                     44:
                     45:
                     46: void
                     47: devconfig_attach_root(void)
                     48: {
                     49:        /*
                     50:         * Attach root and call devconfig_attach on itself (proceeding with its children).
                     51:         */
                     52:        int     retval;
                     53:        struct driver *drp;
                     54:        struct driverinfo *dip;
                     55:
                     56:        DPRINTF("devconfig_attach_root: entering\n");
                     57:
                     58:        /* allocate memory for root device */
                     59:        rootdev = kmalloc(sizeof(struct device));
                     60:        if (rootdev == NULL)
                     61:                panic("failed to allocate space for rootdev\n");
                     62:                /* NOTREACHED */
                     63:
                     64:        /* find root's driverinfo */
                     65:        dip = devconfig_finddriverinfo("root");
                     66:
                     67:        drp = dip->di_driverp;
                     68:
                     69:        /* allocate space for root's devdata */
                     70:        rootdev->dv_devdata = kmalloc(drp->dr_ddsize);
                     71:        if(rootdev->dv_devdata == NULL)
                     72:                panic("failed to allocate space for rootdev devdata\n");
                     73:                /* NOTREACHED */
                     74:
                     75:        /* increment number of this driver's instances */
                     76:        dip->di_ninstances++;
                     77:        rootdev->dv_minor = dip->di_ninstances;
                     78:
                     79:        rootdev->dv_name = dip->di_dname;
                     80:
                     81:        /* link dv_parent into root itself */
                     82:        rootdev->dv_parent = rootdev;
                     83:
                     84:        printf("%s/%d at %s/%d loc 0x%x flags 0x%x: ", rootdev->dv_name, rootdev->dv_minor,
                     85:                                        rootdev->dv_parent->dv_name, rootdev->dv_parent->dv_minor, 0, 0);
                     86:
                     87:        /* attach root; should never fail */
                     88:        retval = drp->dr_attach(rootdev, 0, 0);
                     89:
1.6       init       90:        if (retval != 0)
1.1       init       91:                panic("failed to attach rootdev\n");
                     92:                /* NOTREACHED */
                     93:
                     94:        /* rootdev has been attached, so activate it */
                     95:        rootdev->dv_active = 1;
                     96:
                     97:        /* attach all other devices */
                     98:        devconfig_attach_childs(rootdev);
                     99:
                    100: }
                    101:
                    102: int
                    103: devconfig_attach_childs(struct device *pdevp)
                    104: {
                    105:        /*
                    106:         * Attach device childs, if any.
1.7       init      107:         * Allocate space for struct device and its xxx_dd
1.1       init      108:         */
                    109:        int retval;
                    110:        struct device *cdevp;
                    111:        struct driver *drp;
                    112:        struct driverinfo *dip;
                    113:        struct attachinfo *aip = config_attachinfo;
                    114:
                    115:        DPRINTF("devconfig_attach_childs: entering for %s/%d\n", pdevp->dv_name, pdevp->dv_minor);
                    116:
                    117:        /* look for potential children in config_attachinfo table */
                    118:        while(aip->ai_cname != NULL) {
                    119:                if (strncmp(aip->ai_pname, pdevp->dv_name, DVNAMELEN - 1) == 0 && aip->ai_pminor == pdevp->dv_minor) {
                    120:                        /*
                    121:                         * It is our child.
                    122:                         */
                    123:
                    124:                        /* find child's driverinfo */
                    125:                        dip = devconfig_finddriverinfo(aip->ai_cname);
                    126:
                    127:                        /* allocate space for child's device */
                    128:                        cdevp = kmalloc(sizeof(struct device));
                    129:                        if (cdevp == NULL)
                    130:                                panic("failed to allocate space for %s device\n", aip->ai_cname);
                    131:                                /* NOTREACHED */
                    132:
                    133:                        /* link with parent */
                    134:                        cdevp->dv_parent = pdevp;
                    135:
                    136:                        drp = dip->di_driverp;
                    137:
                    138:                        /* allocate space for device's devdata */
                    139:                        cdevp->dv_devdata = kmalloc(drp->dr_ddsize);
                    140:                        if (cdevp->dv_devdata == NULL)
1.9     ! nbrk      141:                                panic("failed to allocate space for %s devdata\n", aip->ai_cname);
1.1       init      142:                                /* NOTREACHED */
                    143:
                    144:                        /* increment number of driver's instances */
                    145:                        dip->di_ninstances++;
                    146:
                    147:                        cdevp->dv_name = dip->di_dname;
                    148:                        cdevp->dv_minor = dip->di_ninstances;
                    149:
                    150:                        printf("%s/%d at %s/%d loc 0x%x flags 0x%x: ", cdevp->dv_name, cdevp->dv_minor,
                    151:                                                                        pdevp->dv_name, pdevp->dv_minor, aip->ai_locator, aip->ai_flags);
                    152:
                    153:                        /* try to attach this device */
                    154:                        retval = drp->dr_attach(cdevp, aip->ai_locator, aip->ai_flags);
1.6       init      155:                        if (retval != 0) {
1.1       init      156:                                /*
                    157:                                 * Attachment failed.
                    158:                                 */
                    159:
                    160:                                /* XXX what should we do? */
                    161:                                printf("disabling %s/%d\n", cdevp->dv_name, cdevp->dv_minor);
                    162:
                    163:                                /* TODO kfree devdata and device */
                    164:
1.7       init      165:                                /* next aip */
1.2       init      166:                                aip++;
                    167:
1.1       init      168:                                continue;
                    169:                                /* NOTREACHED */
                    170:                        }
                    171:
                    172:                        /*
                    173:                         * Attachment completed.
                    174:                         */
                    175:
                    176:                        /* activate device */
                    177:                        cdevp->dv_active = 1;
1.8       init      178:
                    179:                        /* if device has interrupt handler, establish it */
                    180:                        if (drp->dr_interrupt != NULL && aip->ai_intrno != 0) {
                    181:                                DPRINTF("devconfig_attach_childs: establishing interrupt %d for %s/%d\n",
                    182:                                                        aip->ai_intrno, cdevp->dv_name, cdevp->dv_minor);
                    183:                                intr_establish(aip->ai_intrno, cdevp, drp->dr_interrupt);
                    184:                        }
1.1       init      185:
                    186:                        /* recursive attach this child's children */
1.2       init      187:                        devconfig_attach_childs(cdevp);
1.1       init      188:
                    189:                }
                    190:
                    191:                /* next attachinfo in table */
                    192:                aip++;
                    193:        }
                    194:
                    195: }
                    196:
                    197:
                    198: struct driverinfo
                    199: *devconfig_finddriverinfo(const char *dname)
                    200: {
                    201:        /*
                    202:         * Return associated with dname driver (from config_driverinfo[])
                    203:         * Will cause SYSTEM PANIC if can't find associated driver.
                    204:         */
                    205:        struct driverinfo *dip = config_driverinfo;
                    206:
                    207:        while(dip->di_dname != NULL) {
                    208:                if (strncmp(dname, dip->di_dname, DVNAMELEN - 1) == 0)
                    209:                        return(dip);
                    210:
                    211:                dip++;
                    212:        }
                    213:
                    214:        panic("failed to find driverinfo entry for %s\n", dname);
                    215:        /* NOTREACHED */
                    216:
                    217:        return(NULL);
                    218: }
                    219:
                    220:

CVSweb