Ignore:
File:
1 edited

Legend:

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

    r0851a3d r677cad5  
    22 * Copyright (c) 2001-2004 Jakub Jermar
    33 * Copyright (c) 2006 Josef Cejka
    4  * Copyright (c) 2017 Jiri Svoboda
     4 * Copyright (c) 2014 Jiri Svoboda
    55 * Copyright (c) 2011 Jan Vesely
    66 * All rights reserved.
     
    3939 */
    4040
    41 #include <adt/circ_buf.h>
    4241#include <ddf/log.h>
    4342#include <ddf/interrupt.h>
     
    131130{
    132131        i8042_t *controller = ddf_dev_data_get(dev);
    133         int rc;
    134132       
    135133        const uint8_t status = IPC_GET_ARG1(*call);
    136134        const uint8_t data = IPC_GET_ARG2(*call);
    137135       
    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);
     136        buffer_t *buffer = (status & i8042_AUX_DATA) ?
     137            &controller->aux_buffer : &controller->kbd_buffer;
     138       
     139        buffer_write(buffer, data);
    149140}
    150141
     
    168159        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    169160        irq_cmd_t cmds[cmd_count];
    170         ddf_fun_t *kbd_fun;
    171         ddf_fun_t *aux_fun;
    172161        i8042_regs_t *ar;
    173        
     162
    174163        int rc;
    175164        bool kbd_bound = false;
    176165        bool aux_bound = false;
     166
     167        dev->kbd_fun = NULL;
     168        dev->aux_fun = NULL;
    177169       
    178170        if (regs->size < sizeof(i8042_regs_t)) {
     
    186178        }
    187179       
    188         kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    189         if (kbd_fun == NULL) {
     180        dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
     181        if (dev->kbd_fun == NULL) {
    190182                rc = ENOMEM;
    191183                goto error;
    192184        };
    193185       
    194         dev->kbd = ddf_fun_data_alloc(kbd_fun, sizeof(i8042_port_t));
     186        dev->kbd = ddf_fun_data_alloc(dev->kbd_fun, sizeof(i8042_port_t));
    195187        if (dev->kbd == NULL) {
    196188                rc = ENOMEM;
     
    198190        }
    199191       
    200         dev->kbd->fun = kbd_fun;
    201192        dev->kbd->ctl = dev;
    202193        chardev_srvs_init(&dev->kbd->cds);
    203194        dev->kbd->cds.ops = &i8042_chardev_ops;
    204195        dev->kbd->cds.sarg = dev->kbd;
    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);
     196       
     197        rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
    209198        if (rc != EOK)
    210199                goto error;
    211200       
    212         aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    213         if (aux_fun == NULL) {
     201        dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
     202        if (dev->aux_fun == NULL) {
    214203                rc = ENOMEM;
    215204                goto error;
    216205        }
    217206       
    218         dev->aux = ddf_fun_data_alloc(aux_fun, sizeof(i8042_port_t));
     207        dev->aux = ddf_fun_data_alloc(dev->aux_fun, sizeof(i8042_port_t));
    219208        if (dev->aux == NULL) {
    220209                rc = ENOMEM;
     
    222211        }
    223212       
    224         dev->aux->fun = aux_fun;
    225213        dev->aux->ctl = dev;
    226214        chardev_srvs_init(&dev->aux->cds);
    227215        dev->aux->cds.ops = &i8042_chardev_ops;
    228216        dev->aux->cds.sarg = dev->aux;
    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);
     217       
     218        rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
    233219        if (rc != EOK)
    234220                goto error;
    235221       
    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);
     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);
    241227        fibril_mutex_initialize(&dev->write_guard);
    242228       
    243         rc = ddf_fun_bind(dev->kbd->fun);
     229        rc = ddf_fun_bind(dev->kbd_fun);
    244230        if (rc != EOK) {
    245231                ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.",
    246                     ddf_fun_get_name(dev->kbd->fun));
     232                    ddf_fun_get_name(dev->kbd_fun));
    247233                goto error;
    248234        }
    249235        kbd_bound = true;
    250236       
    251         rc = ddf_fun_bind(dev->aux->fun);
     237        rc = ddf_fun_bind(dev->aux_fun);
    252238        if (rc != EOK) {
    253239                ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.",
    254                     ddf_fun_get_name(dev->aux->fun));
     240                    ddf_fun_get_name(dev->aux_fun));
    255241                goto error;
    256242        }
     
    331317error:
    332318        if (kbd_bound)
    333                 ddf_fun_unbind(dev->kbd->fun);
     319                ddf_fun_unbind(dev->kbd_fun);
    334320        if (aux_bound)
    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);
     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);
    340326
    341327        return rc;
     
    391377{
    392378        i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
    393         size_t p;
     379        i8042_t *i8042 = port->ctl;
    394380        uint8_t *destp = (uint8_t *)dest;
    395381        int rc;
    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]);
     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);
    405389                if (rc != EOK)
    406390                        break;
    407                 ++p;
    408         }
    409 
    410         fibril_mutex_unlock(&port->buf_lock);
    411 
    412         *nread = p;
     391                ++destp;
     392        }
     393       
     394        *nread = i;
    413395        return EOK;
    414396}
Note: See TracChangeset for help on using the changeset viewer.