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

Annotation of funnyos/kern/kern_devctl.c, Revision 1.1

1.1     ! nbrk        1: /*
        !             2:  * $id$
        !             3:  */
        !             4: #include <sys/types.h>
        !             5: #include <sys/device.h>
        !             6: #include <sys/devctl.h>
        !             7: #include <sys/mem.h>
        !             8:
        !             9: #include <libkern/printf.h>
        !            10: #include <libkern/string.h>
        !            11:
        !            12: /*
        !            13:  * devctl, Device control mechanism.
        !            14:  * devctl is used when driver or task want to talk to a specified attached device,
        !            15:  * Device driver (if it wishes to) implements devctl stub and registers it with devctl_register();
        !            16:  * Device driver also defines (for himself) a set of meanings of 32bit 'ctlcmd' field which will be
        !            17:  *  passed to his devctl stub among with 'ctldata' (which is a void *).
        !            18:  * In summary, picture look like this:
        !            19:  *   - device driver (foodev) implements and registers its devctl handler (foo_devctl()).
        !            20:  *   - another driver (bardev) or task wants to talk to foodev/0 and calls: devctl("foodev", 0, READ_DATA, buffer);
        !            21:  *   - program flow gets in foo_devctl(struct device *self, ctlcmd, ctldata);
        !            22:  *   - foo driver deciphers ctlcmd ("READ_DATA"), performs requested action and passes results back to 'bar' in ctldata ("buffer").
        !            23:  */
        !            24:
        !            25: struct devctl_vector {
        !            26:        struct device   *dcv_devp;
        !            27:        char                    *dcv_dvname;
        !            28:        uint8_t                 dcv_dvminor;
        !            29:        int                     (*dcv_ctlfunc)(struct device *self, uint32_t ctlcmd, void *ctldata);
        !            30:
        !            31:        struct devctl_vector *dcv_next;
        !            32: };
        !            33:
        !            34: /* system devctl table */
        !            35: struct devctl_vector *devctltable = NULL;
        !            36:
        !            37:
        !            38: void
        !            39: devctl_register(struct device *self, int (*ctlfunc)(struct device *self, uint32_t ctlcmd, void *ctldata))
        !            40: {
        !            41:        struct devctl_vector *dcvp, *prevdcvp;
        !            42:
        !            43:        /*
        !            44:         * Register given function as devctl stub for given device.
        !            45:         */
        !            46:
        !            47:        dcvp = devctltable;
        !            48:
        !            49:        if (dcvp == NULL) {
        !            50:                /*
        !            51:                 * First entry.
        !            52:                 */
        !            53:                dcvp = kmalloc(sizeof(struct devctl_vector));
        !            54:                if (dcvp == NULL) {
        !            55:                        panic("devctl_register: failed to allocate memory\n");
        !            56:                        /* NOTREACHED */
        !            57:                }
        !            58:
        !            59:                /* update list head */
        !            60:                devctltable = dcvp;
        !            61:        } else {
        !            62:                /*
        !            63:                 * Append to list.
        !            64:                 */
        !            65:                while(dcvp->dcv_next != NULL)
        !            66:                        dcvp = dcvp->dcv_next;
        !            67:
        !            68:                /* found last entry, allocate space for next (new) */
        !            69:                prevdcvp = dcvp;
        !            70:                dcvp->dcv_next = kmalloc(sizeof(struct devctl_vector));
        !            71:                if (dcvp->dcv_next == NULL)
        !            72:                        panic("devctl_register: failed to allocate memory\n");
        !            73:
        !            74:                /* ok, jump forward */
        !            75:                dcvp = dcvp->dcv_next;
        !            76:
        !            77:                prevdcvp->dcv_next = dcvp;
        !            78:        }
        !            79:
        !            80:        /* write entry; set dcv_next to NULL indicating end of list */
        !            81:        dcvp->dcv_devp = self;
        !            82:        dcvp->dcv_dvname = self->dv_name;
        !            83:        dcvp->dcv_dvminor = self->dv_minor;
        !            84:        dcvp->dcv_ctlfunc = ctlfunc;
        !            85:        dcvp->dcv_next = NULL;
        !            86: }
        !            87:
        !            88:
        !            89: int
        !            90: devctl(const char *dv_name, uint8_t dv_minor, uint32_t ctlcmd, void *ctldata)
        !            91: {
        !            92:        struct devctl_vector *dcvp;
        !            93:
        !            94:        dcvp = devctltable;
        !            95:
        !            96:        if (dcvp == NULL) {
        !            97:                /* devctl table is empty */
        !            98:                /* XXX panic here? */
        !            99:                panic("devctl: can't find devctl for %s/%d: devctltable is not configured yet\n", dv_name, dv_minor);
        !           100:                /* NOTREACHED */
        !           101:        }
        !           102:
        !           103:        /* look through the list */
        !           104:        while(dcvp != NULL) {
        !           105:
        !           106:                if (strncmp(dcvp->dcv_dvname, dv_name, DVNAMELEN - 1) == 0 && dcvp->dcv_dvminor == dv_minor)
        !           107:                        /* got it */
        !           108:                        return(dcvp->dcv_ctlfunc(dcvp->dcv_devp, ctlcmd, ctldata));
        !           109:
        !           110:                dcvp = dcvp->dcv_next;
        !           111:        }
        !           112:
        !           113:        /* requested devctl not found */
        !           114:        panic("devctl: can't find devctl for %s/%d: devctltable record not found\n", dv_name, dv_minor);
        !           115: }
        !           116:
        !           117:

CVSweb