Changeset 75751db6 in mainline for uspace/drv/char/pl050/pl050.c


Ignore:
Timestamp:
2014-08-29T20:32:20Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af0a2c7
Parents:
312e5ff
Message:

Factor out chardev IPC from pl050, i8042, xtkbd and ps2mouse.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/pl050/pl050.c

    r312e5ff r75751db6  
    3838#include <ddf/log.h>
    3939#include <device/hw_res_parsed.h>
     40#include <io/chardev_srv.h>
    4041
    4142#define NAME "pl050"
     
    4546
    4647#define PL050_STAT_RXFULL  (1 << 4)
    47 
    48 enum {
    49         IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
    50         IPC_CHAR_WRITE,
    51 };
    5248
    5349enum {
     
    5955static int pl050_fun_offline(ddf_fun_t *);
    6056static void pl050_char_conn(ipc_callid_t, ipc_call_t *, void *);
     57static int pl050_read(chardev_srv_t *, void *, size_t);
     58static int pl050_write(chardev_srv_t *, const void *, size_t);
    6159
    6260static driver_ops_t driver_ops = {
     
    7169};
    7270
     71static chardev_ops_t pl050_chardev_ops = {
     72        .read = pl050_read,
     73        .write = pl050_write
     74};
     75
    7376typedef struct {
     77        async_sess_t *parent_sess;
    7478        ddf_dev_t *dev;
     79
    7580        ddf_fun_t *fun_a;
    76         async_sess_t *parent_sess;
     81        chardev_srvs_t cds;
     82
    7783        uintptr_t iobase;
    7884        size_t iosize;
     
    135141        size_t nidx;
    136142
     143        ddf_msg(LVL_NOTE, "Interrupt");
     144
    137145        fibril_mutex_lock(&pl050->buf_lock);
    138146        nidx = (pl050->buf_wp + 1) % buffer_size;
     
    209217}
    210218
    211 static int pl050_read(pl050_t *pl050, void *buffer, size_t size)
    212 {
     219static int pl050_read(chardev_srv_t *srv, void *buffer, size_t size)
     220{
     221        pl050_t *pl050 = (pl050_t *)srv->srvs->sarg;
    213222        uint8_t *bp = buffer;
     223        size_t left;
    214224        fibril_mutex_lock(&pl050->buf_lock);
    215225
    216         while (size > 0) {
     226        left = size;
     227        while (left > 0) {
    217228                while (pl050->buf_rp == pl050->buf_wp)
    218229                        fibril_condvar_wait(&pl050->buf_cv, &pl050->buf_lock);
    219230                *bp++ = pl050->buffer[pl050->buf_rp];
    220                 --size;
     231                --left;
    221232                pl050->buf_rp = (pl050->buf_rp + 1) % buffer_size;
    222233        }
     
    224235        fibril_mutex_unlock(&pl050->buf_lock);
    225236
    226         return EOK;
    227 }
    228 
    229 static int pl050_write(pl050_t *pl050, void *data, size_t size)
    230 {
    231         return EOK;
     237        return size;
     238}
     239
     240static int pl050_write(chardev_srv_t *srv, const void *data, size_t size)
     241{
     242        return size;
    232243}
    233244
     
    236247        pl050_t *pl050 = pl050_from_fun((ddf_fun_t *)arg);
    237248
    238         /* Accept the connection */
    239         async_answer_0(iid, EOK);
    240 
    241         while (true) {
    242                 ipc_call_t call;
    243                 ipc_callid_t callid = async_get_call(&call);
    244                 sysarg_t method = IPC_GET_IMETHOD(call);
    245                 size_t size = IPC_GET_ARG1(call);
    246 
    247                 if (!method) {
    248                         /* The other side has hung up */
    249                         async_answer_0(callid, EOK);
    250                         break;
    251                 }
    252 
    253                 switch (method) {
    254                 case IPC_CHAR_READ:
    255                         if (size <= 4 * sizeof(sysarg_t)) {
    256                                 sysarg_t message[4] = {};
    257 
    258                                 pl050_read(pl050, (char *) message, size);
    259                                 async_answer_4(callid, size, message[0], message[1],
    260                                     message[2], message[3]);
    261                         } else
    262                                 async_answer_0(callid, ELIMIT);
    263                         break;
    264 
    265                 case IPC_CHAR_WRITE:
    266                         if (size <= 3 * sizeof(sysarg_t)) {
    267                                 const sysarg_t message[3] = {
    268                                         IPC_GET_ARG2(call),
    269                                         IPC_GET_ARG3(call),
    270                                         IPC_GET_ARG4(call)
    271                                 };
    272 
    273                                 pl050_write(pl050, (char *) message, size);
    274                                 async_answer_0(callid, size);
    275                         } else
    276                                 async_answer_0(callid, ELIMIT);
    277 
    278                 default:
    279                         async_answer_0(callid, EINVAL);
    280                 }
    281         }
     249        chardev_conn(iid, icall, &pl050->cds);
    282250}
    283251
     
    289257        int rc;
    290258
    291         ddf_msg(LVL_DEBUG, "pl050_dev_add()");
     259        ddf_msg(LVL_NOTE, "pl050_dev_add()");
    292260
    293261        pl050 = ddf_dev_data_alloc(dev, sizeof(pl050_t));
     
    308276        pl050->dev = dev;
    309277
     278if (1) {
    310279        rc = pl050_init(pl050);
    311280        if (rc != EOK)
    312281                goto error;
    313 
     282}
    314283        rc = ddf_fun_add_match_id(fun_a, "char/xtkbd", 10);
    315284        if (rc != EOK) {
     
    319288        }
    320289
     290        ddf_msg(LVL_NOTE, "Init srvs");
     291        if (1) {
     292        chardev_srvs_init(&pl050->cds);
     293        pl050->cds.ops = &pl050_chardev_ops;
     294        pl050->cds.sarg = pl050;
     295
    321296        ddf_fun_set_conn_handler(fun_a, pl050_char_conn);
    322 
     297}
    323298        rc = ddf_fun_bind(fun_a);
    324299        if (rc != EOK) {
     
    328303        }
    329304
     305        ddf_msg(LVL_NOTE, "Device added");
    330306        ddf_msg(LVL_DEBUG, "Device added.");
    331307        return EOK;
Note: See TracChangeset for help on using the changeset viewer.