Changeset 7a6065c in mainline for uspace/drv/char/ski-con/ski-con.c


Ignore:
Timestamp:
2017-11-23T11:56:31Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
221176c1
Parents:
74017ce
git-author:
Jiri Svoboda <jiri@…> (2017-11-22 19:55:36)
git-committer:
Jiri Svoboda <jiri@…> (2017-11-23 11:56:31)
Message:

Convert ipc/char.h users to chardev.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/ski-con/ski-con.c

    r74017ce r7a6065c  
    11/*
    22 * Copyright (c) 2005 Jakub Jermar
    3  * Copyright (c) 2011 Jiri Svoboda
     3 * Copyright (c) 2017 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3434#include <ddf/log.h>
    3535#include <errno.h>
    36 #include <ipc/char.h>
     36#include <fibril.h>
     37#include <io/chardev.h>
    3738#include <stdint.h>
    3839#include <stdlib.h>
    39 #include <thread.h>
    4040#include <stdbool.h>
    4141
     
    4646#define POLL_INTERVAL           10000
    4747
    48 static void ski_con_thread_impl(void *arg);
     48static int ski_con_fibril(void *arg);
    4949static int32_t ski_con_getchar(void);
    5050static void ski_con_connection(ipc_callid_t, ipc_call_t *, void *);
    5151
     52static int ski_con_read(chardev_srv_t *, void *, size_t, size_t *);
     53static int ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);
     54
     55static chardev_ops_t ski_con_chardev_ops = {
     56        .read = ski_con_read,
     57        .write = ski_con_write
     58};
     59
    5260/** Add ski console device. */
    5361int ski_con_add(ski_con_t *con)
    5462{
    55         thread_id_t tid;
     63        fid_t fid;
    5664        ddf_fun_t *fun = NULL;
    5765        bool bound = false;
    5866        int rc;
     67
     68        circ_buf_init(&con->cbuf, con->buf, ski_con_buf_size, 1);
     69        fibril_mutex_initialize(&con->buf_lock);
     70        fibril_condvar_initialize(&con->buf_cv);
    5971
    6072        fun = ddf_fun_create(con->dev, fun_exposed, "a");
     
    6779        ddf_fun_set_conn_handler(fun, ski_con_connection);
    6880
     81        chardev_srvs_init(&con->cds);
     82        con->cds.ops = &ski_con_chardev_ops;
     83        con->cds.sarg = con;
     84
    6985        rc = ddf_fun_bind(fun);
    7086        if (rc != EOK) {
     
    7591        bound = true;
    7692
    77         rc = thread_create(ski_con_thread_impl, con, "kbd_poll", &tid);
    78         if (rc != 0) {
    79                 return rc;
    80         }
    81 
     93        fid = fibril_create(ski_con_fibril, con);
     94        if (fid == 0) {
     95                ddf_msg(LVL_ERROR, "Error creating fibril.");
     96                rc = ENOMEM;
     97                goto error;
     98        }
     99
     100        fibril_add_ready(fid);
    82101        return EOK;
    83102error:
     
    102121}
    103122
    104 /** Thread to poll Ski for keypresses. */
    105 static void ski_con_thread_impl(void *arg)
     123/** Poll Ski for keypresses. */
     124static int ski_con_fibril(void *arg)
    106125{
    107126        int32_t c;
    108127        ski_con_t *con = (ski_con_t *) arg;
     128        int rc;
    109129
    110130        while (1) {
     
    114134                                break;
    115135
    116                         if (con->client_sess != NULL) {
    117                                 async_exch_t *exch = async_exchange_begin(con->client_sess);
    118                                 async_msg_1(exch, CHAR_NOTIF_BYTE, c);
    119                                 async_exchange_end(exch);
    120                         }
     136                        fibril_mutex_lock(&con->buf_lock);
     137
     138                        rc = circ_buf_push(&con->cbuf, &c);
     139                        if (rc != EOK)
     140                                ddf_msg(LVL_ERROR, "Buffer overrun");
     141
     142                        fibril_mutex_unlock(&con->buf_lock);
     143                        fibril_condvar_broadcast(&con->buf_cv);
    121144                }
    122145
    123                 thread_usleep(POLL_INTERVAL);
    124         }
     146                fibril_usleep(POLL_INTERVAL);
     147        }
     148
     149        return 0;
    125150}
    126151
     
    157182}
    158183
     184/** Read from Ski console device */
     185static int ski_con_read(chardev_srv_t *srv, void *buf, size_t size,
     186    size_t *nread)
     187{
     188        ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
     189        size_t p;
     190        uint8_t *bp = (uint8_t *) buf;
     191        int rc;
     192
     193        fibril_mutex_lock(&con->buf_lock);
     194
     195        while (circ_buf_nused(&con->cbuf) == 0)
     196                fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
     197
     198        p = 0;
     199        while (p < size) {
     200                rc = circ_buf_pop(&con->cbuf, &bp[p]);
     201                if (rc != EOK)
     202                        break;
     203                ++p;
     204        }
     205
     206        fibril_mutex_unlock(&con->buf_lock);
     207
     208        *nread = p;
     209        return EOK;
     210}
     211
     212/** Write to Ski console device */
     213static int ski_con_write(chardev_srv_t *srv, const void *data, size_t size,
     214    size_t *nwr)
     215{
     216        ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
     217        size_t i;
     218        uint8_t *dp = (uint8_t *) data;
     219
     220        for (i = 0; i < size; i++)
     221                ski_con_putchar(con, dp[i]);
     222
     223        *nwr = size;
     224        return EOK;
     225}
     226
    159227/** Character device connection handler. */
    160228static void ski_con_connection(ipc_callid_t iid, ipc_call_t *icall,
    161229    void *arg)
    162230{
    163         ski_con_t *con;
    164 
    165         /* Answer the IPC_M_CONNECT_ME_TO call. */
    166         async_answer_0(iid, EOK);
    167 
    168         con = (ski_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
    169 
    170         while (true) {
    171                 ipc_call_t call;
    172                 ipc_callid_t callid = async_get_call(&call);
    173                 sysarg_t method = IPC_GET_IMETHOD(call);
    174 
    175                 if (!method) {
    176                         /* The other side has hung up. */
    177                         async_answer_0(callid, EOK);
    178                         return;
    179                 }
    180 
    181                 async_sess_t *sess =
    182                     async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
    183                 if (sess != NULL) {
    184                         if (con->client_sess == NULL) {
    185                                 con->client_sess = sess;
    186                                 async_answer_0(callid, EOK);
    187                         } else
    188                                 async_answer_0(callid, ELIMIT);
    189                 } else {
    190                         switch (method) {
    191                         case CHAR_WRITE_BYTE:
    192                                 ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n",
    193                                     IPC_GET_ARG1(call));
    194                                 ski_con_putchar(con, (uint8_t) IPC_GET_ARG1(call));
    195                                 async_answer_0(callid, EOK);
    196                                 break;
    197                         default:
    198                                 async_answer_0(callid, EINVAL);
    199                         }
    200                 }
    201         }
     231        ski_con_t *con = (ski_con_t *) ddf_dev_data_get(
     232            ddf_fun_get_dev((ddf_fun_t *) arg));
     233
     234        chardev_conn(iid, icall, &con->cds);
    202235}
    203236
Note: See TracChangeset for help on using the changeset viewer.