Ignore:
File:
1 edited

Legend:

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

    r7a6065c r92232331  
    3737#include <ddi.h>
    3838#include <errno.h>
    39 #include <io/chardev_srv.h>
     39#include <ipc/char.h>
    4040
    4141#include "msim-con.h"
    4242
    4343static void msim_con_connection(ipc_callid_t, ipc_call_t *, void *);
    44 
    45 static int msim_con_read(chardev_srv_t *, void *, size_t, size_t *);
    46 static int msim_con_write(chardev_srv_t *, const void *, size_t, size_t *);
    47 
    48 static chardev_ops_t msim_con_chardev_ops = {
    49         .read = msim_con_read,
    50         .write = msim_con_write
    51 };
    5244
    5345static irq_cmd_t msim_cmds_proto[] = {
     
    6658        msim_con_t *con = (msim_con_t *) arg;
    6759        uint8_t c;
    68         int rc;
    69 
    70         fibril_mutex_lock(&con->buf_lock);
    7160
    7261        c = IPC_GET_ARG2(*call);
    73         rc = circ_buf_push(&con->cbuf, &c);
    74         if (rc != EOK)
    75                 ddf_msg(LVL_ERROR, "Buffer overrun");
    7662
    77         fibril_mutex_unlock(&con->buf_lock);
    78         fibril_condvar_broadcast(&con->buf_cv);
     63        if (con->client_sess != NULL) {
     64                async_exch_t *exch = async_exchange_begin(con->client_sess);
     65                async_msg_1(exch, CHAR_NOTIF_BYTE, c);
     66                async_exchange_end(exch);
     67        }
    7968}
    8069
     
    8675        irq_cmd_t *msim_cmds = NULL;
    8776        int rc;
    88 
    89         circ_buf_init(&con->cbuf, con->buf, msim_con_buf_size, 1);
    90         fibril_mutex_initialize(&con->buf_lock);
    91         fibril_condvar_initialize(&con->buf_cv);
    9277
    9378        msim_cmds = malloc(sizeof(msim_cmds_proto));
     
    121106        async_irq_subscribe(res->irq, msim_irq_handler, con, &con->irq_code);
    122107        subscribed = true;
    123 
    124         chardev_srvs_init(&con->cds);
    125         con->cds.ops = &msim_con_chardev_ops;
    126         con->cds.sarg = con;
    127108
    128109        rc = ddf_fun_bind(fun);
     
    159140}
    160141
    161 /** Read from msim console device */
    162 static int msim_con_read(chardev_srv_t *srv, void *buf, size_t size,
    163     size_t *nread)
    164 {
    165         msim_con_t *con = (msim_con_t *) srv->srvs->sarg;
    166         size_t p;
    167         uint8_t *bp = (uint8_t *) buf;
    168         int rc;
    169 
    170         fibril_mutex_lock(&con->buf_lock);
    171 
    172         while (circ_buf_nused(&con->cbuf) == 0)
    173                 fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
    174 
    175         p = 0;
    176         while (p < size) {
    177                 rc = circ_buf_pop(&con->cbuf, &bp[p]);
    178                 if (rc != EOK)
    179                         break;
    180                 ++p;
    181         }
    182 
    183         fibril_mutex_unlock(&con->buf_lock);
    184 
    185         *nread = p;
    186         return EOK;
    187 }
    188 
    189 /** Write to msim console device */
    190 static int msim_con_write(chardev_srv_t *srv, const void *data, size_t size,
    191     size_t *nwr)
    192 {
    193         msim_con_t *con = (msim_con_t *) srv->srvs->sarg;
    194         size_t i;
    195         uint8_t *dp = (uint8_t *) data;
    196 
    197         for (i = 0; i < size; i++)
    198                 msim_con_putchar(con, dp[i]);
    199 
    200         *nwr = size;
    201         return EOK;
    202 }
    203 
    204142/** Character device connection handler. */
    205143static void msim_con_connection(ipc_callid_t iid, ipc_call_t *icall,
    206144    void *arg)
    207145{
    208         msim_con_t *con = (msim_con_t *) ddf_dev_data_get(
    209             ddf_fun_get_dev((ddf_fun_t *) arg));
     146        msim_con_t *con;
    210147
    211         chardev_conn(iid, icall, &con->cds);
     148        /* Answer the IPC_M_CONNECT_ME_TO call. */
     149        async_answer_0(iid, EOK);
     150
     151        con = (msim_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
     152
     153        while (true) {
     154                ipc_call_t call;
     155                ipc_callid_t callid = async_get_call(&call);
     156                sysarg_t method = IPC_GET_IMETHOD(call);
     157
     158                if (!method) {
     159                        /* The other side has hung up. */
     160                        async_answer_0(callid, EOK);
     161                        return;
     162                }
     163
     164                async_sess_t *sess =
     165                    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
     166                if (sess != NULL) {
     167                        if (con->client_sess == NULL) {
     168                                con->client_sess = sess;
     169                                async_answer_0(callid, EOK);
     170                        } else
     171                                async_answer_0(callid, ELIMIT);
     172                } else {
     173                        switch (method) {
     174                        case CHAR_WRITE_BYTE:
     175                                ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n",
     176                                    IPC_GET_ARG1(call));
     177                                msim_con_putchar(con, (uint8_t) IPC_GET_ARG1(call));
     178                                async_answer_0(callid, EOK);
     179                                break;
     180                        default:
     181                                async_answer_0(callid, EINVAL);
     182                        }
     183                }
     184        }
    212185}
    213186
Note: See TracChangeset for help on using the changeset viewer.