Ignore:
File:
1 edited

Legend:

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

    r39026d7c 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 *
     
    3131 */
    3232
    33 #include <async.h>
    3433#include <ddf/driver.h>
    3534#include <ddf/log.h>
    3635#include <errno.h>
    37 #include <fibril.h>
    38 #include <io/chardev.h>
     36#include <ipc/char.h>
    3937#include <stdint.h>
    4038#include <stdlib.h>
     39#include <thread.h>
    4140#include <stdbool.h>
    4241
     
    4443
    4544#define SKI_GETCHAR             21
    46 #define SKI_PUTCHAR             31
    4745
    4846#define POLL_INTERVAL           10000
    4947
    50 static int ski_con_fibril(void *arg);
     48static void ski_con_thread_impl(void *arg);
    5149static int32_t ski_con_getchar(void);
    5250static void ski_con_connection(ipc_callid_t, ipc_call_t *, void *);
    5351
    54 static int ski_con_read(chardev_srv_t *, void *, size_t, size_t *);
    55 static int ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);
    56 
    57 static chardev_ops_t ski_con_chardev_ops = {
    58         .read = ski_con_read,
    59         .write = ski_con_write
    60 };
    61 
    62 static void ski_con_putchar(ski_con_t *con, char ch); /* XXX */
    63 
    6452/** Add ski console device. */
    6553int ski_con_add(ski_con_t *con)
    6654{
    67         fid_t fid;
     55        thread_id_t tid;
    6856        ddf_fun_t *fun = NULL;
    6957        bool bound = false;
    7058        int rc;
    71 
    72         circ_buf_init(&con->cbuf, con->buf, ski_con_buf_size, 1);
    73         fibril_mutex_initialize(&con->buf_lock);
    74         fibril_condvar_initialize(&con->buf_cv);
    7559
    7660        fun = ddf_fun_create(con->dev, fun_exposed, "a");
     
    8367        ddf_fun_set_conn_handler(fun, ski_con_connection);
    8468
    85         chardev_srvs_init(&con->cds);
    86         con->cds.ops = &ski_con_chardev_ops;
    87         con->cds.sarg = con;
    88 
    8969        rc = ddf_fun_bind(fun);
    9070        if (rc != EOK) {
     
    9373        }
    9474
    95         ddf_fun_add_to_category(fun, "console");
    96 
    9775        bound = true;
    9876
    99         fid = fibril_create(ski_con_fibril, con);
    100         if (fid == 0) {
    101                 ddf_msg(LVL_ERROR, "Error creating fibril.");
    102                 rc = ENOMEM;
    103                 goto error;
    104         }
    105 
    106         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
    10782        return EOK;
    10883error:
     
    127102}
    128103
    129 /** Poll Ski for keypresses. */
    130 static int ski_con_fibril(void *arg)
     104/** Thread to poll Ski for keypresses. */
     105static void ski_con_thread_impl(void *arg)
    131106{
    132107        int32_t c;
    133108        ski_con_t *con = (ski_con_t *) arg;
    134         int rc;
    135109
    136110        while (1) {
     
    140114                                break;
    141115
    142                         fibril_mutex_lock(&con->buf_lock);
    143 
    144                         rc = circ_buf_push(&con->cbuf, &c);
    145                         if (rc != EOK)
    146                                 ddf_msg(LVL_ERROR, "Buffer overrun");
    147 
    148                         fibril_mutex_unlock(&con->buf_lock);
    149                         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                        }
    150121                }
    151122
    152                 async_usleep(POLL_INTERVAL);
    153         }
    154 
    155         return 0;
     123                thread_usleep(POLL_INTERVAL);
     124        }
    156125}
    157126
     
    183152}
    184153
    185 
    186 /** Display character on ski debug console
    187  *
    188  * Use SSC (Simulator System Call) to
    189  * display character on debug console.
    190  *
    191  * @param c Character to be printed.
    192  *
    193  */
    194154static void ski_con_putchar(ski_con_t *con, char ch)
    195155{
    196         if (ch == '\n')
    197                 ski_con_putchar(con, '\r');
    198 
    199 #ifdef UARCH_ia64
    200         asm volatile (
    201                 "mov r15 = %0\n"
    202                 "mov r32 = %1\n"   /* r32 is in0 */
    203                 "break 0x80000\n"  /* modifies r8 */
    204                 :
    205                 : "i" (SKI_PUTCHAR), "r" (ch)
    206                 : "r15", "in0", "r8"
    207         );
    208 #else
    209         (void) ch;
    210 #endif
    211 }
    212 
    213 /** Read from Ski console device */
    214 static int ski_con_read(chardev_srv_t *srv, void *buf, size_t size,
    215     size_t *nread)
    216 {
    217         ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
    218         size_t p;
    219         uint8_t *bp = (uint8_t *) buf;
    220         int rc;
    221 
    222         fibril_mutex_lock(&con->buf_lock);
    223 
    224         while (circ_buf_nused(&con->cbuf) == 0)
    225                 fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
    226 
    227         p = 0;
    228         while (p < size) {
    229                 rc = circ_buf_pop(&con->cbuf, &bp[p]);
    230                 if (rc != EOK)
    231                         break;
    232                 ++p;
    233         }
    234 
    235         fibril_mutex_unlock(&con->buf_lock);
    236 
    237         *nread = p;
    238         return EOK;
    239 }
    240 
    241 /** Write to Ski console device */
    242 static int ski_con_write(chardev_srv_t *srv, const void *data, size_t size,
    243     size_t *nwr)
    244 {
    245         ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
    246         size_t i;
    247         uint8_t *dp = (uint8_t *) data;
    248 
    249         for (i = 0; i < size; i++)
    250                 ski_con_putchar(con, dp[i]);
    251 
    252         *nwr = size;
    253         return EOK;
     156       
    254157}
    255158
     
    258161    void *arg)
    259162{
    260         ski_con_t *con = (ski_con_t *) ddf_dev_data_get(
    261             ddf_fun_get_dev((ddf_fun_t *) arg));
    262 
    263         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        }
    264202}
    265203
Note: See TracChangeset for help on using the changeset viewer.