Changeset a455321 in mainline for uspace/drv/char/i8042/i8042.c


Ignore:
Timestamp:
2012-01-04T00:13:53Z (14 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
22e4e9b
Parents:
ecc6323
Message:

i8042, ps2mouse: Use separate chardev interface instead of the one provided by DDF.

Requested on ML.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/i8042/i8042.c

    recc6323 ra455321  
    5555static int i8042_write_kbd(ddf_fun_t *, char *, size_t);
    5656static int i8042_read_kbd(ddf_fun_t *, char *, size_t);
    57 static int i8042_write_aux(ddf_fun_t *, char *, size_t);
    58 static int i8042_read_aux(ddf_fun_t *, char *, size_t);
    5957
    6058/** Primary port interface structure. */
     
    6462};
    6563
    66 /** Auxiliary port interface structure. */
    67 static char_dev_ops_t aux_iface = {
    68     .read = i8042_read_aux,
    69     .write = i8042_write_aux,
    70 };
     64void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    7165
    7266/** Primary port function operations. */
    7367static ddf_dev_ops_t kbd_ops = {
    74         .interfaces[CHAR_DEV_IFACE] = &kbd_iface
     68        .interfaces[CHAR_DEV_IFACE] = &kbd_iface,
     69        .default_handler = default_handler,
    7570};
    7671
    7772/** Auxiliary port function operations. */
    78 static ddf_dev_ops_t aux_ops = {
    79         .interfaces[CHAR_DEV_IFACE] = &aux_iface
     73static ddf_dev_ops_t ops = {
     74        .default_handler = default_handler,
    8075};
    8176
     
    181176        }
    182177
    183         dev->mouse_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    184         if (!dev->mouse_fun) {
     178        dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
     179        if (!dev->aux_fun) {
    185180                ddf_fun_destroy(dev->kbd_fun);
    186181                return ENOMEM;
    187182        }
    188183
    189         ret = ddf_fun_add_match_id(dev->mouse_fun, "char/ps2mouse", 90);
     184        ret = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
    190185        if (ret != EOK) {
    191186                ddf_fun_destroy(dev->kbd_fun);
    192                 ddf_fun_destroy(dev->mouse_fun);
     187                ddf_fun_destroy(dev->aux_fun);
    193188                return ret;
    194189        }
    195190
    196191        dev->kbd_fun->ops = &kbd_ops;
    197         dev->mouse_fun->ops = &aux_ops;
     192        dev->aux_fun->ops = &ops;
    198193        dev->kbd_fun->driver_data = dev;
    199         dev->mouse_fun->driver_data = dev;
     194        dev->aux_fun->driver_data = dev;
    200195
    201196        buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
     
    210205                ddf_fun_destroy(dev->kbd_fun); \
    211206        } \
    212         if (dev->mouse_fun) { \
    213                 dev->mouse_fun->driver_data = NULL; \
    214                 ddf_fun_destroy(dev->mouse_fun); \
     207        if (dev->aux_fun) { \
     208                dev->aux_fun->driver_data = NULL; \
     209                ddf_fun_destroy(dev->aux_fun); \
    215210        } \
    216211} else (void)0
     
    220215            "Failed to bind keyboard function: %s.", str_error(ret));
    221216
    222         ret = ddf_fun_bind(dev->mouse_fun);
     217        ret = ddf_fun_bind(dev->aux_fun);
    223218        CHECK_RET_DESTROY(ret,
    224219            "Failed to bind mouse function: %s.", str_error(ret));
     
    242237                ddf_fun_destroy(dev->kbd_fun); \
    243238        } \
    244         if (dev->mouse_fun) { \
    245                 ddf_fun_unbind(dev->mouse_fun); \
    246                 dev->mouse_fun->driver_data = NULL; \
    247                 ddf_fun_destroy(dev->mouse_fun); \
     239        if (dev->aux_fun) { \
     240                ddf_fun_unbind(dev->aux_fun); \
     241                dev->aux_fun->driver_data = NULL; \
     242                ddf_fun_destroy(dev->aux_fun); \
    248243        } \
    249244} else (void)0
     
    328323}
    329324
    330 /** Write data to i8042 auxiliary port.
     325// TODO use shared instead of own copy
     326enum {
     327        IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
     328        IPC_CHAR_WRITE,
     329};
     330
     331/** Write data to i8042 port.
    331332 * @param fun DDF function.
    332333 * @param buffer Data source.
     
    334335 * @return Bytes written.
    335336 */
    336 static int i8042_write_aux(ddf_fun_t *fun, char *buffer, size_t size)
     337static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size)
    337338{
    338339        assert(fun);
     
    342343        for (size_t i = 0; i < size; ++i) {
    343344                wait_ready(controller);
    344                 pio_write_8(&controller->regs->status, i8042_CMD_WRITE_AUX);
     345                if (controller->aux_fun == fun)
     346                        pio_write_8(
     347                            &controller->regs->status, i8042_CMD_WRITE_AUX);
    345348                pio_write_8(&controller->regs->data, buffer[i]);
    346349        }
     
    349352}
    350353
    351 /** Read data from i8042 auxiliary port.
     354/** Read data from i8042 port.
    352355 * @param fun DDF function.
    353356 * @param buffer Data place.
     
    355358 * @return Bytes read.
    356359 */
    357 static int i8042_read_aux(ddf_fun_t *fun, char *buffer, size_t size)
     360static int i8042_read(ddf_fun_t *fun, char *data, size_t size)
    358361{
    359362        assert(fun);
    360363        assert(fun->driver_data);
    361         bzero(buffer, size);
    362364
    363365        i8042_t *controller = fun->driver_data;
     366        buffer_t *buffer = (fun == controller->aux_fun) ?
     367            &controller->aux_buffer : &controller->kbd_buffer;
    364368        for (size_t i = 0; i < size; ++i) {
    365                 *buffer++ = buffer_read(&controller->aux_buffer);
     369                *data++ = buffer_read(buffer);
    366370        }
    367371        return size;
     372}
     373
     374void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
     375{
     376        const sysarg_t method = IPC_GET_IMETHOD(*call);
     377        const size_t size = IPC_GET_ARG1(*call);
     378        switch (method) {
     379        case IPC_CHAR_READ:
     380                if (size <= 4 * sizeof(sysarg_t)) {
     381                        sysarg_t message[4] = { 0 };
     382                        i8042_read(fun, (char*)message, size);
     383                        async_answer_4(id, size, message[0], message[1],
     384                            message[2], message[3]);
     385                } else {
     386                        async_answer_0(id, ELIMIT);
     387                }
     388                break;
     389
     390        case IPC_CHAR_WRITE:
     391                if (size <= 3 * sizeof(sysarg_t)) {
     392                        const sysarg_t message[3] = {
     393                                IPC_GET_ARG2(*call), IPC_GET_ARG3(*call),
     394                                IPC_GET_ARG4(*call) };
     395                        i8042_write(fun, (char*)message, size);
     396                        async_answer_0(id, size);
     397                } else {
     398                        async_answer_0(id, ELIMIT);
     399                }
     400
     401        default:
     402                async_answer_0(id, EINVAL);
     403        }
    368404}
    369405/**
Note: See TracChangeset for help on using the changeset viewer.