Changeset ac307b2 in mainline for uspace/drv/char/msim-con/msim-con.c


Ignore:
Timestamp:
2017-11-25T11:12:23Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
98cb5e0d
Parents:
f571ca49 (diff), 0851a3d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into callcaps

File:
1 edited

Legend:

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

    rf571ca49 rac307b2  
    3737#include <ddi.h>
    3838#include <errno.h>
    39 #include <ipc/char.h>
     39#include <io/chardev_srv.h>
    4040
    4141#include "msim-con.h"
    4242
    4343static void msim_con_connection(ipc_callid_t, ipc_call_t *, void *);
     44
     45static int msim_con_read(chardev_srv_t *, void *, size_t, size_t *);
     46static int msim_con_write(chardev_srv_t *, const void *, size_t, size_t *);
     47
     48static chardev_ops_t msim_con_chardev_ops = {
     49        .read = msim_con_read,
     50        .write = msim_con_write
     51};
    4452
    4553static irq_cmd_t msim_cmds_proto[] = {
     
    5866        msim_con_t *con = (msim_con_t *) arg;
    5967        uint8_t c;
     68        int rc;
     69
     70        fibril_mutex_lock(&con->buf_lock);
    6071
    6172        c = IPC_GET_ARG2(*call);
    62 
    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         }
     73        rc = circ_buf_push(&con->cbuf, &c);
     74        if (rc != EOK)
     75                ddf_msg(LVL_ERROR, "Buffer overrun");
     76
     77        fibril_mutex_unlock(&con->buf_lock);
     78        fibril_condvar_broadcast(&con->buf_cv);
    6879}
    6980
     
    7586        irq_cmd_t *msim_cmds = NULL;
    7687        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);
    7792
    7893        msim_cmds = malloc(sizeof(msim_cmds_proto));
     
    106121        async_irq_subscribe(res->irq, msim_irq_handler, con, &con->irq_code);
    107122        subscribed = true;
     123
     124        chardev_srvs_init(&con->cds);
     125        con->cds.ops = &msim_con_chardev_ops;
     126        con->cds.sarg = con;
    108127
    109128        rc = ddf_fun_bind(fun);
     
    140159}
    141160
     161/** Read from msim console device */
     162static 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 */
     190static 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
    142204/** Character device connection handler. */
    143205static void msim_con_connection(ipc_callid_t iid, ipc_call_t *icall,
    144206    void *arg)
    145207{
    146         msim_con_t *con;
    147 
    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         }
     208        msim_con_t *con = (msim_con_t *) ddf_dev_data_get(
     209            ddf_fun_get_dev((ddf_fun_t *) arg));
     210
     211        chardev_conn(iid, icall, &con->cds);
    185212}
    186213
Note: See TracChangeset for help on using the changeset viewer.