Ignore:
File:
1 edited

Legend:

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

    r7a6065c r19d2ce01  
    11/*
    22 * Copyright (c) 2008 Pavel Rimsky
    3  * Copyright (c) 2017 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3636#include <ddi.h>
    3737#include <errno.h>
    38 #include <io/chardev_srv.h>
     38#include <ipc/char.h>
    3939#include <stdbool.h>
    4040#include <thread.h>
     
    6262static input_buffer_t input_buffer;
    6363
    64 static int sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *);
    65 static int sun4v_con_write(chardev_srv_t *, const void *, size_t, size_t *);
    66 
    67 static chardev_ops_t sun4v_con_chardev_ops = {
    68         .read = sun4v_con_read,
    69         .write = sun4v_con_write
    70 };
     64static void sun4v_thread_impl(void *arg);
    7165
    7266static void sun4v_con_putchar(sun4v_con_t *con, uint8_t data)
     
    9286        }
    9387
    94         chardev_srvs_init(&con->cds);
    95         con->cds.ops = &sun4v_con_chardev_ops;
    96         con->cds.sarg = con;
    97 
    9888        ddf_fun_set_conn_handler(fun, sun4v_con_connection);
    9989
     
    10595        }
    10696
     97        thread_id_t tid;
     98        rc = thread_create(sun4v_thread_impl, con, "kbd_poll", &tid);
     99        if (rc != EOK)
     100                goto error;
     101
    107102        rc = ddf_fun_bind(fun);
    108103        if (rc != EOK) {
     
    136131}
    137132
    138 /** Read from Sun4v console device */
    139 static int sun4v_con_read(chardev_srv_t *srv, void *buf, size_t size,
    140     size_t *nread)
    141 {
    142         size_t p;
    143         uint8_t *bp = (uint8_t *) buf;
     133/**
     134 * Called regularly by the polling thread. Reads codes of all the
     135 * pressed keys from the buffer.
     136 */
     137static void sun4v_key_pressed(sun4v_con_t *con)
     138{
    144139        char c;
    145140
    146         while (input_buffer->read_ptr == input_buffer->write_ptr)
    147                 fibril_usleep(POLL_INTERVAL);
    148 
    149         p = 0;
    150         while (p < size && input_buffer->read_ptr != input_buffer->write_ptr) {
     141        while (input_buffer->read_ptr != input_buffer->write_ptr) {
    151142                c = input_buffer->data[input_buffer->read_ptr];
    152143                input_buffer->read_ptr =
    153144                    ((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE;
    154                 bp[p++] = c;
    155         }
    156 
    157         *nread = p;
    158         return EOK;
    159 }
    160 
    161 /** Write to Sun4v console device */
    162 static int sun4v_con_write(chardev_srv_t *srv, const void *data, size_t size,
    163     size_t *nwr)
    164 {
    165         sun4v_con_t *con = (sun4v_con_t *) srv->srvs->sarg;
    166         size_t i;
    167         uint8_t *dp = (uint8_t *) data;
    168 
    169         for (i = 0; i < size; i++)
    170                 sun4v_con_putchar(con, dp[i]);
    171 
    172         *nwr = size;
    173         return EOK;
     145                if (con->client_sess != NULL) {
     146                        async_exch_t *exch = async_exchange_begin(con->client_sess);
     147                        async_msg_1(exch, CHAR_NOTIF_BYTE, c);
     148                        async_exchange_end(exch);
     149                }
     150                (void) c;
     151        }
     152}
     153
     154/**
     155 * Thread to poll Sun4v console for keypresses.
     156 */
     157static void sun4v_thread_impl(void *arg)
     158{
     159        sun4v_con_t *con = (sun4v_con_t *) arg;
     160
     161        while (true) {
     162                sun4v_key_pressed(con);
     163                thread_usleep(POLL_INTERVAL);
     164        }
    174165}
    175166
     
    178169    void *arg)
    179170{
    180         sun4v_con_t *con = (sun4v_con_t *) ddf_dev_data_get(
    181             ddf_fun_get_dev((ddf_fun_t *) arg));
    182 
    183         chardev_conn(iid, icall, &con->cds);
     171        sun4v_con_t *con;
     172
     173        /* Answer the IPC_M_CONNECT_ME_TO call. */
     174        async_answer_0(iid, EOK);
     175
     176        con = (sun4v_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
     177
     178        while (true) {
     179                ipc_call_t call;
     180                ipc_callid_t callid = async_get_call(&call);
     181                sysarg_t method = IPC_GET_IMETHOD(call);
     182
     183                if (!method) {
     184                        /* The other side has hung up. */
     185                        async_answer_0(callid, EOK);
     186                        return;
     187                }
     188
     189                async_sess_t *sess =
     190                    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
     191                if (sess != NULL) {
     192                        if (con->client_sess == NULL) {
     193                                con->client_sess = sess;
     194                                async_answer_0(callid, EOK);
     195                        } else
     196                                async_answer_0(callid, ELIMIT);
     197                } else {
     198                        switch (method) {
     199                        case CHAR_WRITE_BYTE:
     200                                ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n",
     201                                    IPC_GET_ARG1(call));
     202                                sun4v_con_putchar(con, (uint8_t) IPC_GET_ARG1(call));
     203                                async_answer_0(callid, EOK);
     204                                break;
     205                        default:
     206                                async_answer_0(callid, EINVAL);
     207                        }
     208                }
     209        }
    184210}
    185211
Note: See TracChangeset for help on using the changeset viewer.