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


Ignore:
Timestamp:
2017-11-25T11:12:23Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
98cb5e0d
Parents:
f571ca49 (diff), 0851a3d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into callcaps

File:
1 edited

Legend:

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

    rf571ca49 rac307b2  
    22 * Copyright (c) 2001-2004 Jakub Jermar
    33 * Copyright (c) 2006 Josef Cejka
    4  * Copyright (c) 2014 Jiri Svoboda
     4 * Copyright (c) 2017 Jiri Svoboda
    55 * Copyright (c) 2011 Jan Vesely
    66 * All rights reserved.
     
    3939 */
    4040
     41#include <adt/circ_buf.h>
    4142#include <ddf/log.h>
    4243#include <ddf/interrupt.h>
     
    130131{
    131132        i8042_t *controller = ddf_dev_data_get(dev);
     133        int rc;
    132134       
    133135        const uint8_t status = IPC_GET_ARG1(*call);
    134136        const uint8_t data = IPC_GET_ARG2(*call);
    135137       
    136         buffer_t *buffer = (status & i8042_AUX_DATA) ?
    137             &controller->aux_buffer : &controller->kbd_buffer;
    138        
    139         buffer_write(buffer, data);
     138        i8042_port_t *port = (status & i8042_AUX_DATA) ?
     139            controller->aux : controller->kbd;
     140       
     141        fibril_mutex_lock(&port->buf_lock);
     142       
     143        rc = circ_buf_push(&port->cbuf, &data);
     144        if (rc != EOK)
     145                ddf_msg(LVL_ERROR, "Buffer overrun");
     146
     147        fibril_mutex_unlock(&port->buf_lock);
     148        fibril_condvar_broadcast(&port->buf_cv);
    140149}
    141150
     
    159168        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    160169        irq_cmd_t cmds[cmd_count];
     170        ddf_fun_t *kbd_fun;
     171        ddf_fun_t *aux_fun;
    161172        i8042_regs_t *ar;
    162 
     173       
    163174        int rc;
    164175        bool kbd_bound = false;
    165176        bool aux_bound = false;
    166 
    167         dev->kbd_fun = NULL;
    168         dev->aux_fun = NULL;
    169177       
    170178        if (regs->size < sizeof(i8042_regs_t)) {
     
    178186        }
    179187       
    180         dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    181         if (dev->kbd_fun == NULL) {
     188        kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
     189        if (kbd_fun == NULL) {
    182190                rc = ENOMEM;
    183191                goto error;
    184192        };
    185193       
    186         dev->kbd = ddf_fun_data_alloc(dev->kbd_fun, sizeof(i8042_port_t));
     194        dev->kbd = ddf_fun_data_alloc(kbd_fun, sizeof(i8042_port_t));
    187195        if (dev->kbd == NULL) {
    188196                rc = ENOMEM;
     
    190198        }
    191199       
     200        dev->kbd->fun = kbd_fun;
    192201        dev->kbd->ctl = dev;
    193202        chardev_srvs_init(&dev->kbd->cds);
    194203        dev->kbd->cds.ops = &i8042_chardev_ops;
    195204        dev->kbd->cds.sarg = dev->kbd;
    196        
    197         rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
     205        fibril_mutex_initialize(&dev->kbd->buf_lock);
     206        fibril_condvar_initialize(&dev->kbd->buf_cv);
     207       
     208        rc = ddf_fun_add_match_id(dev->kbd->fun, "char/xtkbd", 90);
    198209        if (rc != EOK)
    199210                goto error;
    200211       
    201         dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    202         if (dev->aux_fun == NULL) {
     212        aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
     213        if (aux_fun == NULL) {
    203214                rc = ENOMEM;
    204215                goto error;
    205216        }
    206217       
    207         dev->aux = ddf_fun_data_alloc(dev->aux_fun, sizeof(i8042_port_t));
     218        dev->aux = ddf_fun_data_alloc(aux_fun, sizeof(i8042_port_t));
    208219        if (dev->aux == NULL) {
    209220                rc = ENOMEM;
     
    211222        }
    212223       
     224        dev->aux->fun = aux_fun;
    213225        dev->aux->ctl = dev;
    214226        chardev_srvs_init(&dev->aux->cds);
    215227        dev->aux->cds.ops = &i8042_chardev_ops;
    216228        dev->aux->cds.sarg = dev->aux;
    217        
    218         rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
     229        fibril_mutex_initialize(&dev->aux->buf_lock);
     230        fibril_condvar_initialize(&dev->aux->buf_cv);
     231       
     232        rc = ddf_fun_add_match_id(dev->aux->fun, "char/ps2mouse", 90);
    219233        if (rc != EOK)
    220234                goto error;
    221235       
    222         ddf_fun_set_conn_handler(dev->kbd_fun, i8042_char_conn);
    223         ddf_fun_set_conn_handler(dev->aux_fun, i8042_char_conn);
    224        
    225         buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
    226         buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE);
     236        ddf_fun_set_conn_handler(dev->kbd->fun, i8042_char_conn);
     237        ddf_fun_set_conn_handler(dev->aux->fun, i8042_char_conn);
     238       
     239        circ_buf_init(&dev->kbd->cbuf, dev->kbd->buf_data, BUFFER_SIZE, 1);
     240        circ_buf_init(&dev->aux->cbuf, dev->aux->buf_data, BUFFER_SIZE, 1);
    227241        fibril_mutex_initialize(&dev->write_guard);
    228242       
    229         rc = ddf_fun_bind(dev->kbd_fun);
     243        rc = ddf_fun_bind(dev->kbd->fun);
    230244        if (rc != EOK) {
    231245                ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.",
    232                     ddf_fun_get_name(dev->kbd_fun));
     246                    ddf_fun_get_name(dev->kbd->fun));
    233247                goto error;
    234248        }
    235249        kbd_bound = true;
    236250       
    237         rc = ddf_fun_bind(dev->aux_fun);
     251        rc = ddf_fun_bind(dev->aux->fun);
    238252        if (rc != EOK) {
    239253                ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.",
    240                     ddf_fun_get_name(dev->aux_fun));
     254                    ddf_fun_get_name(dev->aux->fun));
    241255                goto error;
    242256        }
     
    317331error:
    318332        if (kbd_bound)
    319                 ddf_fun_unbind(dev->kbd_fun);
     333                ddf_fun_unbind(dev->kbd->fun);
    320334        if (aux_bound)
    321                 ddf_fun_unbind(dev->aux_fun);
    322         if (dev->kbd_fun != NULL)
    323                 ddf_fun_destroy(dev->kbd_fun);
    324         if (dev->aux_fun != NULL)
    325                 ddf_fun_destroy(dev->aux_fun);
     335                ddf_fun_unbind(dev->aux->fun);
     336        if (dev->kbd->fun != NULL)
     337                ddf_fun_destroy(dev->kbd->fun);
     338        if (dev->aux->fun != NULL)
     339                ddf_fun_destroy(dev->aux->fun);
    326340
    327341        return rc;
     
    377391{
    378392        i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
    379         i8042_t *i8042 = port->ctl;
     393        size_t p;
    380394        uint8_t *destp = (uint8_t *)dest;
    381395        int rc;
    382         size_t i;
    383        
    384         buffer_t *buffer = (port == i8042->aux) ?
    385             &i8042->aux_buffer : &i8042->kbd_buffer;
    386        
    387         for (i = 0; i < size; ++i) {
    388                 rc = buffer_read(buffer, destp, i == 0);
     396       
     397        fibril_mutex_lock(&port->buf_lock);
     398       
     399        while (circ_buf_nused(&port->cbuf) == 0)
     400                fibril_condvar_wait(&port->buf_cv, &port->buf_lock);
     401
     402        p = 0;
     403        while (p < size) {
     404                rc = circ_buf_pop(&port->cbuf, &destp[p]);
    389405                if (rc != EOK)
    390406                        break;
    391                 ++destp;
    392         }
    393        
    394         *nread = i;
     407                ++p;
     408        }
     409
     410        fibril_mutex_unlock(&port->buf_lock);
     411
     412        *nread = p;
    395413        return EOK;
    396414}
Note: See TracChangeset for help on using the changeset viewer.