Ignore:
File:
1 edited

Legend:

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

    r7a6065c r676e833  
    11/*
    22 * Copyright (c) 2005 Jakub Jermar
    3  * Copyright (c) 2017 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3434#include <ddf/log.h>
    3535#include <errno.h>
    36 #include <fibril.h>
    37 #include <io/chardev.h>
     36#include <ipc/char.h>
    3837#include <stdint.h>
    3938#include <stdlib.h>
     39#include <thread.h>
    4040#include <stdbool.h>
    4141
     
    4646#define POLL_INTERVAL           10000
    4747
    48 static int ski_con_fibril(void *arg);
     48static void ski_con_thread_impl(void *arg);
    4949static int32_t ski_con_getchar(void);
    5050static void ski_con_connection(ipc_callid_t, ipc_call_t *, void *);
    5151
    52 static int ski_con_read(chardev_srv_t *, void *, size_t, size_t *);
    53 static int ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);
    54 
    55 static chardev_ops_t ski_con_chardev_ops = {
    56         .read = ski_con_read,
    57         .write = ski_con_write
    58 };
    59 
    6052/** Add ski console device. */
    6153int ski_con_add(ski_con_t *con)
    6254{
    63         fid_t fid;
     55        thread_id_t tid;
    6456        ddf_fun_t *fun = NULL;
    6557        bool bound = false;
    6658        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);
    7159
    7260        fun = ddf_fun_create(con->dev, fun_exposed, "a");
     
    7967        ddf_fun_set_conn_handler(fun, ski_con_connection);
    8068
    81         chardev_srvs_init(&con->cds);
    82         con->cds.ops = &ski_con_chardev_ops;
    83         con->cds.sarg = con;
    84 
    8569        rc = ddf_fun_bind(fun);
    8670        if (rc != EOK) {
     
    9175        bound = true;
    9276
    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);
     77        rc = thread_create(ski_con_thread_impl, con, "kbd_poll", &tid);
     78        if (rc != 0) {
     79                return rc;
     80        }
     81
    10182        return EOK;
    10283error:
     
    121102}
    122103
    123 /** Poll Ski for keypresses. */
    124 static int ski_con_fibril(void *arg)
     104/** Thread to poll Ski for keypresses. */
     105static void ski_con_thread_impl(void *arg)
    125106{
    126107        int32_t c;
    127108        ski_con_t *con = (ski_con_t *) arg;
    128         int rc;
    129109
    130110        while (1) {
     
    134114                                break;
    135115
    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);
     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                        }
    144121                }
    145122
    146                 fibril_usleep(POLL_INTERVAL);
    147         }
    148 
    149         return 0;
     123                thread_usleep(POLL_INTERVAL);
     124        }
    150125}
    151126
     
    182157}
    183158
    184 /** Read from Ski console device */
    185 static 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 */
    213 static 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 
    227159/** Character device connection handler. */
    228160static void ski_con_connection(ipc_callid_t iid, ipc_call_t *icall,
    229161    void *arg)
    230162{
    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);
     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        }
    235202}
    236203
Note: See TracChangeset for help on using the changeset viewer.