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


Ignore:
Timestamp:
2018-01-30T03:20:45Z (8 years ago)
Author:
Jenda <jenda.jzqk73@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5a6cc679
Parents:
8bfb163 (diff), 6a5d05b (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 commit '6a5d05bd2551e64111bea4f9332dd7448c26ce84' into forwardport

Separate return value from error code in gen_irq_code*().

File:
1 edited

Legend:

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

    r8bfb163 r132ab5d1  
    3737#include <ddi.h>
    3838#include <errno.h>
    39 #include <ipc/char.h>
    40 #include <sysinfo.h>
     39#include <io/chardev_srv.h>
    4140
    4241#include "msim-con.h"
     
    4443static void msim_con_connection(ipc_callid_t, ipc_call_t *, void *);
    4544
    46 static irq_pio_range_t msim_ranges[] = {
    47         {
    48                 .base = 0,
    49                 .size = 1
    50         }
     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
    5151};
    5252
    53 static irq_cmd_t msim_cmds[] = {
     53static irq_cmd_t msim_cmds_proto[] = {
    5454        {
    5555                .cmd = CMD_PIO_READ_8,
     
    6262};
    6363
    64 static irq_code_t msim_kbd = {
    65         sizeof(msim_ranges) / sizeof(irq_pio_range_t),
    66         msim_ranges,
    67         sizeof(msim_cmds) / sizeof(irq_cmd_t),
    68         msim_cmds
    69 };
    70 
    71 static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg)
     64static void msim_irq_handler(ipc_call_t *call, void *arg)
    7265{
    7366        msim_con_t *con = (msim_con_t *) arg;
    7467        uint8_t c;
     68        int rc;
     69
     70        fibril_mutex_lock(&con->buf_lock);
    7571
    7672        c = IPC_GET_ARG2(*call);
    77 
    78         if (con->client_sess != NULL) {
    79                 async_exch_t *exch = async_exchange_begin(con->client_sess);
    80                 async_msg_1(exch, CHAR_NOTIF_BYTE, c);
    81                 async_exchange_end(exch);
    82         }
     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);
    8379}
    8480
    8581/** Add msim console device. */
    86 int msim_con_add(msim_con_t *con)
     82int msim_con_add(msim_con_t *con, msim_con_res_t *res)
    8783{
    8884        ddf_fun_t *fun = NULL;
    8985        bool subscribed = false;
     86        irq_cmd_t *msim_cmds = NULL;
    9087        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);
     92
     93        msim_cmds = malloc(sizeof(msim_cmds_proto));
     94        if (msim_cmds == NULL) {
     95                rc = ENOMEM;
     96                goto error;
     97        }
     98
     99        con->res = *res;
    91100
    92101        fun = ddf_fun_create(con->dev, fun_exposed, "a");
     
    97106        }
    98107
     108        rc = pio_enable((void *)res->base, 1, (void **) &con->out_reg);
     109        if (rc != EOK) {
     110                ddf_msg(LVL_ERROR, "Error enabling I/O");
     111                goto error;
     112        }
     113
    99114        ddf_fun_set_conn_handler(fun, msim_con_connection);
    100115
    101         sysarg_t paddr;
    102         if (sysinfo_get_value("kbd.address.physical", &paddr) != EOK) {
    103                 rc = ENOENT;
    104                 goto error;
    105         }
    106 
    107         sysarg_t inr;
    108         if (sysinfo_get_value("kbd.inr", &inr) != EOK) {
    109                 rc = ENOENT;
    110                 goto error;
    111         }
    112 
    113         msim_ranges[0].base = paddr;
    114         msim_cmds[0].addr = (void *) paddr;
    115         async_irq_subscribe(inr, msim_irq_handler, con, &msim_kbd);
     116        con->irq_range[0].base = res->base;
     117        con->irq_range[0].size = 1;
     118
     119        memcpy(msim_cmds, msim_cmds_proto, sizeof(msim_cmds_proto));
     120        msim_cmds[0].addr = (void *) res->base;
     121
     122        con->irq_code.rangecount = 1;
     123        con->irq_code.ranges = con->irq_range;
     124        con->irq_code.cmdcount = sizeof(msim_cmds_proto) / sizeof(irq_cmd_t);
     125        con->irq_code.cmds = msim_cmds;
     126
     127        async_irq_subscribe(res->irq, msim_irq_handler, con, &con->irq_code, NULL);
    116128        subscribed = true;
     129
     130        chardev_srvs_init(&con->cds);
     131        con->cds.ops = &msim_con_chardev_ops;
     132        con->cds.sarg = con;
    117133
    118134        rc = ddf_fun_bind(fun);
     
    122138        }
    123139
     140        ddf_fun_add_to_category(fun, "console");
     141
    124142        return EOK;
    125143error:
    126144        if (subscribed)
    127                 async_irq_unsubscribe(inr);
     145                async_irq_unsubscribe(res->irq);
    128146        if (fun != NULL)
    129147                ddf_fun_destroy(fun);
     148        free(msim_cmds);
    130149
    131150        return rc;
     
    146165static void msim_con_putchar(msim_con_t *con, uint8_t ch)
    147166{
     167        pio_write_8(con->out_reg, ch);
     168}
     169
     170/** Read from msim console device */
     171static int msim_con_read(chardev_srv_t *srv, void *buf, size_t size,
     172    size_t *nread)
     173{
     174        msim_con_t *con = (msim_con_t *) srv->srvs->sarg;
     175        size_t p;
     176        uint8_t *bp = (uint8_t *) buf;
     177        int rc;
     178
     179        fibril_mutex_lock(&con->buf_lock);
     180
     181        while (circ_buf_nused(&con->cbuf) == 0)
     182                fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
     183
     184        p = 0;
     185        while (p < size) {
     186                rc = circ_buf_pop(&con->cbuf, &bp[p]);
     187                if (rc != EOK)
     188                        break;
     189                ++p;
     190        }
     191
     192        fibril_mutex_unlock(&con->buf_lock);
     193
     194        *nread = p;
     195        return EOK;
     196}
     197
     198/** Write to msim console device */
     199static int msim_con_write(chardev_srv_t *srv, const void *data, size_t size,
     200    size_t *nwr)
     201{
     202        msim_con_t *con = (msim_con_t *) srv->srvs->sarg;
     203        size_t i;
     204        uint8_t *dp = (uint8_t *) data;
     205
     206        for (i = 0; i < size; i++)
     207                msim_con_putchar(con, dp[i]);
     208
     209        *nwr = size;
     210        return EOK;
    148211}
    149212
     
    152215    void *arg)
    153216{
    154         msim_con_t *con;
    155 
    156         /* Answer the IPC_M_CONNECT_ME_TO call. */
    157         async_answer_0(iid, EOK);
    158 
    159         con = (msim_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
    160 
    161         while (true) {
    162                 ipc_call_t call;
    163                 ipc_callid_t callid = async_get_call(&call);
    164                 sysarg_t method = IPC_GET_IMETHOD(call);
    165 
    166                 if (!method) {
    167                         /* The other side has hung up. */
    168                         async_answer_0(callid, EOK);
    169                         return;
    170                 }
    171 
    172                 async_sess_t *sess =
    173                     async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
    174                 if (sess != NULL) {
    175                         if (con->client_sess == NULL) {
    176                                 con->client_sess = sess;
    177                                 async_answer_0(callid, EOK);
    178                         } else
    179                                 async_answer_0(callid, ELIMIT);
    180                 } else {
    181                         switch (method) {
    182                         case CHAR_WRITE_BYTE:
    183                                 ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n",
    184                                     IPC_GET_ARG1(call));
    185                                 msim_con_putchar(con, (uint8_t) IPC_GET_ARG1(call));
    186                                 async_answer_0(callid, EOK);
    187                                 break;
    188                         default:
    189                                 async_answer_0(callid, EINVAL);
    190                         }
    191                 }
    192         }
     217        msim_con_t *con = (msim_con_t *) ddf_dev_data_get(
     218            ddf_fun_get_dev((ddf_fun_t *) arg));
     219
     220        chardev_conn(iid, icall, &con->cds);
    193221}
    194222
Note: See TracChangeset for help on using the changeset viewer.