Changeset ac307b2 in mainline


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

Files:
1 added
5 deleted
36 edited
2 moved

Legend:

Unmodified
Added
Removed
  • .gitignore

    rf571ca49 rac307b2  
    248248uspace/dist/logo.tga
    249249uspace/dist/srv/cdfs
     250uspace/dist/srv/chardev-test
    250251uspace/dist/srv/clipboard
    251252uspace/dist/srv/compositor
     
    420421uspace/srv/ns/ns
    421422uspace/srv/taskmon/taskmon
     423uspace/srv/test/chardev-test/chardev-test
    422424uspace/srv/vfs/vfs
    423425uspace/srv/volsrv/volsrv
  • uspace/app/sportdmp/sportdmp.c

    rf571ca49 rac307b2  
    2727 */
    2828
    29 #include <char_dev_iface.h>
    3029#include <errno.h>
     30#include <io/chardev.h>
    3131#include <io/serial.h>
    3232#include <loc.h>
    3333#include <stdio.h>
     34#include <stdlib.h>
    3435
    3536#define BUF_SIZE 1
     
    4445        sysarg_t baud = 9600;
    4546        service_id_t svc_id;
     47        chardev_t *chardev;
    4648        serial_t *serial;
     49        size_t nread;
    4750
    4851        int arg = 1;
     
    119122        }
    120123
     124        rc = chardev_open(sess, &chardev);
     125        if (rc != EOK) {
     126                fprintf(stderr, "Failed opening character device\n");
     127                return 2;
     128        }
     129
    121130        rc = serial_open(sess, &serial);
    122131        if (rc != EOK) {
     
    138147
    139148        while (true) {
    140                 ssize_t read = char_dev_read(sess, buf, BUF_SIZE);
    141                 if (read < 0) {
    142                         fprintf(stderr, "Failed reading from serial device\n");
     149                rc = chardev_read(chardev, buf, BUF_SIZE, &nread);
     150                for (size_t i = 0; i < nread; i++) {
     151                        printf("%02hhx ", buf[i]);
     152                }
     153                if (rc != EOK) {
     154                        fprintf(stderr, "\nFailed reading from serial device\n");
    143155                        break;
    144                 }
    145                 ssize_t i;
    146                 for (i = 0; i < read; i++) {
    147                         printf("%02hhx ", buf[i]);
    148156                }
    149157                fflush(stdout);
     
    152160        free(buf);
    153161        serial_close(serial);
     162        chardev_close(chardev);
    154163        async_hangup(sess);
    155164        return 0;
  • uspace/app/tester/Makefile

    rf571ca49 rac307b2  
    6868        mm/mapping1.c \
    6969        mm/pager1.c \
    70         hw/misc/virtchar1.c \
    7170        hw/serial/serial1.c \
    7271        chardev/chardev1.c
  • uspace/app/tester/hw/serial/serial1.c

    rf571ca49 rac307b2  
    3535 */
    3636
    37 #include <inttypes.h>
     37#include <async.h>
    3838#include <errno.h>
     39#include <io/chardev.h>
     40#include <io/serial.h>
     41#include <ipc/services.h>
     42#include <loc.h>
    3943#include <stdlib.h>
    4044#include <stdio.h>
    4145#include <stddef.h>
    42 #include <async.h>
     46#include <str.h>
    4347#include <thread.h>
    44 #include <ipc/services.h>
    45 #include <loc.h>
    46 #include <char_dev_iface.h>
    47 #include <str.h>
    48 #include <io/serial.h>
    4948#include "../../tester.h"
    5049
     
    5756        size_t cnt;
    5857        serial_t *serial;
     58        chardev_t *chardev;
     59        int rc;
     60        size_t nread;
     61        size_t nwritten;
    5962       
    6063        if (test_argc < 1)
     
    8386                return "Failed connecting to serial device";
    8487       
     88        res = chardev_open(sess, &chardev);
     89        if (res != EOK) {
     90                async_hangup(sess);
     91                return "Failed opening serial port";
     92        }
     93       
    8594        res = serial_open(sess, &serial);
    86         if (res != EOK)
     95        if (res != EOK) {
     96                chardev_close(chardev);
     97                async_hangup(sess);
    8798                return "Failed opening serial port";
     99        }
    88100       
    89101        char *buf = (char *) malloc(cnt + 1);
    90102        if (buf == NULL) {
     103                chardev_close(chardev);
    91104                serial_close(serial);
    92105                async_hangup(sess);
     
    103116        if (res != EOK) {
    104117                free(buf);
     118                chardev_close(chardev);
    105119                serial_close(serial);
    106120                async_hangup(sess);
     
    111125        if (EOK != res) {
    112126                free(buf);
     127                chardev_close(chardev);
    113128                serial_close(serial);
    114129                async_hangup(sess);
     
    121136        size_t total = 0;
    122137        while (total < cnt) {
    123                 ssize_t read = char_dev_read(sess, buf, cnt - total);
    124                
    125                 if (read < 0) {
     138               
     139                rc = chardev_read(chardev, buf, cnt - total, &nread);
     140                if (rc != EOK) {
    126141                        (void) serial_set_comm_props(serial, old_baud,
    127142                            old_par, old_word_size, old_stop);
    128143                       
    129144                        free(buf);
     145                        chardev_close(chardev);
    130146                        serial_close(serial);
    131147                        async_hangup(sess);
     
    133149                }
    134150               
    135                 if ((size_t) read > cnt - total) {
     151                if (nread > cnt - total) {
    136152                        (void) serial_set_comm_props(serial, old_baud,
    137153                            old_par, old_word_size, old_stop);
    138154                       
    139155                        free(buf);
     156                        chardev_close(chardev);
    140157                        serial_close(serial);
    141158                        async_hangup(sess);
     
    143160                }
    144161               
    145                 TPRINTF("Read %zd bytes\n", read);
    146                
    147                 if (read == 0)
     162                TPRINTF("Read %zd bytes\n", nread);
     163               
     164                if (nread == 0)
    148165                        thread_usleep(DEFAULT_SLEEP);
    149166                else {
    150                         buf[read] = 0;
     167                        buf[nread] = 0;
    151168                       
    152169                        /*
     
    154171                         * direction of data transfer.
    155172                         */
    156                         ssize_t written = char_dev_write(sess, buf, read);
    157                        
    158                         if (written < 0) {
     173                        rc = chardev_write(chardev, buf, nread, &nwritten);
     174                        if (rc != EOK) {
    159175                                (void) serial_set_comm_props(serial, old_baud,
    160176                                    old_par, old_word_size, old_stop);
    161177                               
    162178                                free(buf);
     179                                chardev_close(chardev);
    163180                                serial_close(serial);
    164181                                async_hangup(sess);
     
    166183                        }
    167184                       
    168                         if (written != read) {
     185                        if (nwritten != nread) {
    169186                                (void) serial_set_comm_props(serial, old_baud,
    170187                                    old_par, old_word_size, old_stop);
    171188                               
    172189                                free(buf);
     190                                chardev_close(chardev);
    173191                                serial_close(serial);
    174192                                async_hangup(sess);
     
    176194                        }
    177195                       
    178                         TPRINTF("Written %zd bytes\n", written);
    179                 }
    180                
    181                 total += read;
     196                        TPRINTF("Written %zd bytes\n", nwritten);
     197                }
     198               
     199                total += nread;
    182200        }
    183201       
     
    185203       
    186204        size_t eot_size = str_size(EOT);
    187         ssize_t written = char_dev_write(sess, (void *) EOT, eot_size);
     205        rc = chardev_write(chardev, (void *) EOT, eot_size, &nwritten);
    188206       
    189207        (void) serial_set_comm_props(serial, old_baud, old_par, old_word_size,
     
    191209       
    192210        free(buf);
     211        chardev_close(chardev);
    193212        serial_close(serial);
    194213        async_hangup(sess);
    195214       
    196         if (written < 0)
     215        if (rc != EOK)
    197216                return "Failed to write EOT banner to serial device";
    198217       
    199         if ((size_t) written != eot_size)
     218        if (nwritten != eot_size)
    200219                return "Written less data than the size of the EOT banner "
    201220                    "to serial device";
  • uspace/app/tester/tester.c

    rf571ca49 rac307b2  
    7676#include "mm/pager1.def"
    7777#include "hw/serial/serial1.def"
    78 #include "hw/misc/virtchar1.def"
    7978#include "chardev/chardev1.def"
    8079        {NULL, NULL, NULL, false}
  • uspace/app/tester/tester.h

    rf571ca49 rac307b2  
    108108extern const char *test_pager1(void);
    109109extern const char *test_serial1(void);
    110 extern const char *test_virtchar1(void);
    111110extern const char *test_devman1(void);
    112111extern const char *test_devman2(void);
  • uspace/drv/char/i8042/i8042.c

    rf571ca49 rac307b2  
    22 * Copyright (c) 2001-2004 Jakub Jermar
    33 * Copyright (c) 2006 Josef Cejka
    4  * Copyright (c) 2014 Jiri Svoboda
     4 * Copyright (c) 2017 Jiri Svoboda
    55 * Copyright (c) 2011 Jan Vesely
    66 * All rights reserved.
     
    3939 */
    4040
     41#include <adt/circ_buf.h>
    4142#include <ddf/log.h>
    4243#include <ddf/interrupt.h>
     
    130131{
    131132        i8042_t *controller = ddf_dev_data_get(dev);
     133        int rc;
    132134       
    133135        const uint8_t status = IPC_GET_ARG1(*call);
    134136        const uint8_t data = IPC_GET_ARG2(*call);
    135137       
    136         buffer_t *buffer = (status & i8042_AUX_DATA) ?
    137             &controller->aux_buffer : &controller->kbd_buffer;
    138        
    139         buffer_write(buffer, data);
     138        i8042_port_t *port = (status & i8042_AUX_DATA) ?
     139            controller->aux : controller->kbd;
     140       
     141        fibril_mutex_lock(&port->buf_lock);
     142       
     143        rc = circ_buf_push(&port->cbuf, &data);
     144        if (rc != EOK)
     145                ddf_msg(LVL_ERROR, "Buffer overrun");
     146
     147        fibril_mutex_unlock(&port->buf_lock);
     148        fibril_condvar_broadcast(&port->buf_cv);
    140149}
    141150
     
    159168        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    160169        irq_cmd_t cmds[cmd_count];
     170        ddf_fun_t *kbd_fun;
     171        ddf_fun_t *aux_fun;
    161172        i8042_regs_t *ar;
    162 
     173       
    163174        int rc;
    164175        bool kbd_bound = false;
    165176        bool aux_bound = false;
    166 
    167         dev->kbd_fun = NULL;
    168         dev->aux_fun = NULL;
    169177       
    170178        if (regs->size < sizeof(i8042_regs_t)) {
     
    178186        }
    179187       
    180         dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    181         if (dev->kbd_fun == NULL) {
     188        kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
     189        if (kbd_fun == NULL) {
    182190                rc = ENOMEM;
    183191                goto error;
    184192        };
    185193       
    186         dev->kbd = ddf_fun_data_alloc(dev->kbd_fun, sizeof(i8042_port_t));
     194        dev->kbd = ddf_fun_data_alloc(kbd_fun, sizeof(i8042_port_t));
    187195        if (dev->kbd == NULL) {
    188196                rc = ENOMEM;
     
    190198        }
    191199       
     200        dev->kbd->fun = kbd_fun;
    192201        dev->kbd->ctl = dev;
    193202        chardev_srvs_init(&dev->kbd->cds);
    194203        dev->kbd->cds.ops = &i8042_chardev_ops;
    195204        dev->kbd->cds.sarg = dev->kbd;
    196        
    197         rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
     205        fibril_mutex_initialize(&dev->kbd->buf_lock);
     206        fibril_condvar_initialize(&dev->kbd->buf_cv);
     207       
     208        rc = ddf_fun_add_match_id(dev->kbd->fun, "char/xtkbd", 90);
    198209        if (rc != EOK)
    199210                goto error;
    200211       
    201         dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    202         if (dev->aux_fun == NULL) {
     212        aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
     213        if (aux_fun == NULL) {
    203214                rc = ENOMEM;
    204215                goto error;
    205216        }
    206217       
    207         dev->aux = ddf_fun_data_alloc(dev->aux_fun, sizeof(i8042_port_t));
     218        dev->aux = ddf_fun_data_alloc(aux_fun, sizeof(i8042_port_t));
    208219        if (dev->aux == NULL) {
    209220                rc = ENOMEM;
     
    211222        }
    212223       
     224        dev->aux->fun = aux_fun;
    213225        dev->aux->ctl = dev;
    214226        chardev_srvs_init(&dev->aux->cds);
    215227        dev->aux->cds.ops = &i8042_chardev_ops;
    216228        dev->aux->cds.sarg = dev->aux;
    217        
    218         rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
     229        fibril_mutex_initialize(&dev->aux->buf_lock);
     230        fibril_condvar_initialize(&dev->aux->buf_cv);
     231       
     232        rc = ddf_fun_add_match_id(dev->aux->fun, "char/ps2mouse", 90);
    219233        if (rc != EOK)
    220234                goto error;
    221235       
    222         ddf_fun_set_conn_handler(dev->kbd_fun, i8042_char_conn);
    223         ddf_fun_set_conn_handler(dev->aux_fun, i8042_char_conn);
    224        
    225         buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
    226         buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE);
     236        ddf_fun_set_conn_handler(dev->kbd->fun, i8042_char_conn);
     237        ddf_fun_set_conn_handler(dev->aux->fun, i8042_char_conn);
     238       
     239        circ_buf_init(&dev->kbd->cbuf, dev->kbd->buf_data, BUFFER_SIZE, 1);
     240        circ_buf_init(&dev->aux->cbuf, dev->aux->buf_data, BUFFER_SIZE, 1);
    227241        fibril_mutex_initialize(&dev->write_guard);
    228242       
    229         rc = ddf_fun_bind(dev->kbd_fun);
     243        rc = ddf_fun_bind(dev->kbd->fun);
    230244        if (rc != EOK) {
    231245                ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.",
    232                     ddf_fun_get_name(dev->kbd_fun));
     246                    ddf_fun_get_name(dev->kbd->fun));
    233247                goto error;
    234248        }
    235249        kbd_bound = true;
    236250       
    237         rc = ddf_fun_bind(dev->aux_fun);
     251        rc = ddf_fun_bind(dev->aux->fun);
    238252        if (rc != EOK) {
    239253                ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.",
    240                     ddf_fun_get_name(dev->aux_fun));
     254                    ddf_fun_get_name(dev->aux->fun));
    241255                goto error;
    242256        }
     
    317331error:
    318332        if (kbd_bound)
    319                 ddf_fun_unbind(dev->kbd_fun);
     333                ddf_fun_unbind(dev->kbd->fun);
    320334        if (aux_bound)
    321                 ddf_fun_unbind(dev->aux_fun);
    322         if (dev->kbd_fun != NULL)
    323                 ddf_fun_destroy(dev->kbd_fun);
    324         if (dev->aux_fun != NULL)
    325                 ddf_fun_destroy(dev->aux_fun);
     335                ddf_fun_unbind(dev->aux->fun);
     336        if (dev->kbd->fun != NULL)
     337                ddf_fun_destroy(dev->kbd->fun);
     338        if (dev->aux->fun != NULL)
     339                ddf_fun_destroy(dev->aux->fun);
    326340
    327341        return rc;
     
    377391{
    378392        i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
    379         i8042_t *i8042 = port->ctl;
     393        size_t p;
    380394        uint8_t *destp = (uint8_t *)dest;
    381395        int rc;
    382         size_t i;
    383        
    384         buffer_t *buffer = (port == i8042->aux) ?
    385             &i8042->aux_buffer : &i8042->kbd_buffer;
    386        
    387         for (i = 0; i < size; ++i) {
    388                 rc = buffer_read(buffer, destp, i == 0);
     396       
     397        fibril_mutex_lock(&port->buf_lock);
     398       
     399        while (circ_buf_nused(&port->cbuf) == 0)
     400                fibril_condvar_wait(&port->buf_cv, &port->buf_lock);
     401
     402        p = 0;
     403        while (p < size) {
     404                rc = circ_buf_pop(&port->cbuf, &destp[p]);
    389405                if (rc != EOK)
    390406                        break;
    391                 ++destp;
    392         }
    393        
    394         *nread = i;
     407                ++p;
     408        }
     409
     410        fibril_mutex_unlock(&port->buf_lock);
     411
     412        *nread = p;
    395413        return EOK;
    396414}
  • uspace/drv/char/i8042/i8042.h

    rf571ca49 rac307b2  
    22 * Copyright (c) 2006 Josef Cejka
    33 * Copyright (c) 2011 Jan Vesely
     4 * Copyright (c) 2017 Jiri Svoboda
    45 * All rights reserved.
    56 *
     
    4041#define i8042_H_
    4142
     43#include <adt/circ_buf.h>
    4244#include <io/chardev_srv.h>
    4345#include <ddi.h>
    4446#include <fibril_synch.h>
    4547#include <ddf/driver.h>
    46 #include "buffer.h"
    4748
    4849#define NAME  "i8042"
     
    5960/** i8042 Port. */
    6061typedef struct {
    61         struct i8042 *ctl;              /**< Controller */
    62         chardev_srvs_t cds;             /**< Character device server data */
     62        /** Controller */
     63        struct i8042 *ctl;
     64        /** Device function */
     65        ddf_fun_t *fun;
     66        /** Character device server data */
     67        chardev_srvs_t cds;
     68        /** Circular buffer */
     69        circ_buf_t cbuf;
     70        /** Buffer data space */
     71        uint8_t buf_data[BUFFER_SIZE];
     72        /** Protect buffer */
     73        fibril_mutex_t buf_lock;
     74        /** Signal new data in buffer */
     75        fibril_condvar_t buf_cv;
    6376} i8042_port_t;
    6477
    6578/** i8042 Controller. */
    6679typedef struct i8042 {
    67         i8042_regs_t *regs;             /**< I/O registers. */
    68         ddf_fun_t *kbd_fun;             /**< Pirmary port device function. */
    69         ddf_fun_t *aux_fun;             /**< Auxiliary port device function. */
    70         buffer_t kbd_buffer;            /**< Primary port buffer. */
    71         buffer_t aux_buffer;            /**< Aux. port buffer. */
    72         uint8_t aux_data[BUFFER_SIZE];  /**< Primary port buffer space. */
    73         uint8_t kbd_data[BUFFER_SIZE];  /**< Aux. port buffer space. */
     80        /**< I/O registers. */
     81        i8042_regs_t *regs;
     82        /** Keyboard port */
    7483        i8042_port_t *kbd;
     84        /** AUX port */
    7585        i8042_port_t *aux;
    76         fibril_mutex_t write_guard;     /**< Prevents simultanous port writes.*/
     86        /** Prevents simultanous port writes.*/
     87        fibril_mutex_t write_guard;
    7788} i8042_t;
    78 
    7989
    8090extern int i8042_init(i8042_t *, addr_range_t *, int, int, ddf_dev_t *);
  • 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
  • uspace/drv/char/msim-con/msim-con.h

    rf571ca49 rac307b2  
    3636#define MSIM_CON_H
    3737
     38#include <adt/circ_buf.h>
    3839#include <async.h>
    3940#include <ddf/driver.h>
     41#include <fibril_synch.h>
     42#include <io/chardev_srv.h>
    4043#include <loc.h>
    4144#include <stdint.h>
     45
     46enum {
     47        msim_con_buf_size = 64
     48};
    4249
    4350/** MSIM console resources */
     
    5158        async_sess_t *client_sess;
    5259        ddf_dev_t *dev;
     60        chardev_srvs_t cds;
    5361        msim_con_res_t res;
    5462        irq_pio_range_t irq_range[1];
    5563        irq_code_t irq_code;
     64        circ_buf_t cbuf;
     65        uint8_t buf[msim_con_buf_size];
     66        fibril_mutex_t buf_lock;
     67        fibril_condvar_t buf_cv;
    5668} msim_con_t;
    5769
  • uspace/drv/char/ns8250/ns8250.c

    rf571ca49 rac307b2  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2011 Jiri Svoboda
     3 * Copyright (c) 2017 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    5353#include <ddf/interrupt.h>
    5454#include <ddf/log.h>
    55 #include <ops/char_dev.h>
     55#include <io/chardev_srv.h>
    5656
    5757#include <device/hw_res.h>
     
    153153        /** DDF function node */
    154154        ddf_fun_t *fun;
     155        /** Character device service */
     156        chardev_srvs_t cds;
    155157        /** Parent session */
    156158        async_sess_t *parent_sess;
     
    189191}
    190192
     193/** Obtain soft-state structure from chardev srv */
     194static ns8250_t *srv_ns8250(chardev_srv_t *srv)
     195{
     196        return (ns8250_t *)srv->srvs->sarg;
     197}
     198
     199
    191200/** Find out if there is some incoming data available on the serial port.
    192201 *
     
    234243/** Read data from the serial port device.
    235244 *
    236  * @param fun           The serial port function
     245 * @param srv           Server-side connection data
    237246 * @param buf           The output buffer for read data.
    238247 * @param count         The number of bytes to be read.
    239  *
    240  * @return              The number of bytes actually read on success, negative
    241  *                      error number otherwise.
    242  */
    243 static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count)
    244 {
    245         ns8250_t *ns = fun_ns8250(fun);
    246         int ret = 0;
    247        
    248         if (count == 0) return 0;
     248 * @param nread         Place to store number of bytes actually read
     249 *
     250 * @return              EOK on success or non-zero error code
     251 */
     252static int ns8250_read(chardev_srv_t *srv, void *buf, size_t count, size_t *nread)
     253{
     254        ns8250_t *ns = srv_ns8250(srv);
     255        char *bp = (char *) buf;
     256        size_t pos = 0;
     257       
     258        if (count == 0) {
     259                *nread = 0;
     260                return EOK;
     261        }
    249262       
    250263        fibril_mutex_lock(&ns->mutex);
    251264        while (buf_is_empty(&ns->input_buffer))
    252265                fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
    253         while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) {
    254                 buf[ret] = (char)buf_pop_front(&ns->input_buffer);
    255                 ret++;
     266        while (!buf_is_empty(&ns->input_buffer) && pos < count) {
     267                bp[pos] = (char)buf_pop_front(&ns->input_buffer);
     268                pos++;
    256269        }
    257270        fibril_mutex_unlock(&ns->mutex);
    258271       
    259         return ret;
     272        *nread = pos;
     273        return EOK;
    260274}
    261275
     
    274288/** Write data to the serial port.
    275289 *
    276  * @param fun           The serial port function
     290 * @param srv           Server-side connection data
    277291 * @param buf           The data to be written
    278292 * @param count         The number of bytes to be written
    279  * @return              Zero on success
    280  */
    281 static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count)
    282 {
    283         ns8250_t *ns = fun_ns8250(fun);
     293 * @param nwritten      Place to store number of bytes successfully written
     294 * @return              EOK on success or non-zero error code
     295 */
     296static int ns8250_write(chardev_srv_t *srv, const void *buf, size_t count,
     297    size_t *nwritten)
     298{
     299        ns8250_t *ns = srv_ns8250(srv);
    284300        size_t idx;
     301        uint8_t *bp = (uint8_t *) buf;
    285302       
    286303        for (idx = 0; idx < count; idx++)
    287                 ns8250_putchar(ns, (uint8_t) buf[idx]);
    288        
    289         return count;
    290 }
    291 
    292 static ddf_dev_ops_t ns8250_dev_ops;
     304                ns8250_putchar(ns, bp[idx]);
     305       
     306        *nwritten = count;
     307        return EOK;
     308}
     309
     310static int ns8250_open(chardev_srvs_t *, chardev_srv_t *);
     311static int ns8250_close(chardev_srv_t *);
     312static void ns8250_default_handler(chardev_srv_t *, ipc_callid_t, ipc_call_t *);
    293313
    294314/** The character interface's callbacks. */
    295 static char_dev_ops_t ns8250_char_dev_ops = {
    296         .read = &ns8250_read,
    297         .write = &ns8250_write
     315static chardev_ops_t ns8250_chardev_ops = {
     316        .open = ns8250_open,
     317        .close = ns8250_close,
     318        .read = ns8250_read,
     319        .write = ns8250_write,
     320        .def_handler = ns8250_default_handler
    298321};
     322
     323static void ns8250_char_conn(ipc_callid_t, ipc_call_t *, void *);
    299324
    300325static int ns8250_dev_add(ddf_dev_t *dev);
     
    872897        }
    873898       
    874         /* Set device operations. */
    875         ddf_fun_set_ops(fun, &ns8250_dev_ops);
     899        ddf_fun_set_conn_handler(fun, ns8250_char_conn);
     900       
     901        chardev_srvs_init(&ns->cds);
     902        ns->cds.ops = &ns8250_chardev_ops;
     903        ns->cds.sarg = ns;
     904       
    876905        rc = ddf_fun_bind(fun);
    877906        if (rc != EOK) {
     
    930959 * device.
    931960 *
    932  * @param dev           The device.
    933  */
    934 static int ns8250_open(ddf_fun_t *fun)
    935 {
    936         ns8250_t *ns = fun_ns8250(fun);
     961 * @param srvs          Service structure
     962 * @param srv           Server-side connection structure
     963 */
     964static int ns8250_open(chardev_srvs_t *srvs, chardev_srv_t *srv)
     965{
     966        ns8250_t *ns = srv_ns8250(srv);
    937967        int res;
    938968       
     
    954984 * the device.
    955985 *
    956  * @param dev           The device.
    957  */
    958 static void ns8250_close(ddf_fun_t *fun)
    959 {
    960         ns8250_t *data = fun_ns8250(fun);
     986 * @param srv           Server-side connection structure
     987 */
     988static int ns8250_close(chardev_srv_t *srv)
     989{
     990        ns8250_t *data = srv_ns8250(srv);
    961991       
    962992        fibril_mutex_lock(&data->mutex);
     
    968998       
    969999        fibril_mutex_unlock(&data->mutex);
     1000       
     1001        return EOK;
    9701002}
    9711003
     
    10341066 * Configure the parameters of the serial communication.
    10351067 */
    1036 static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid,
     1068static void ns8250_default_handler(chardev_srv_t *srv, ipc_callid_t callid,
    10371069    ipc_call_t *call)
    10381070{
     1071        ns8250_t *ns8250 = srv_ns8250(srv);
    10391072        sysarg_t method = IPC_GET_IMETHOD(*call);
    10401073        int ret;
     
    10431076        switch (method) {
    10441077        case SERIAL_GET_COM_PROPS:
    1045                 ns8250_get_props(ddf_fun_get_dev(fun), &baud_rate, &parity, &word_length,
     1078                ns8250_get_props(ns8250->dev, &baud_rate, &parity, &word_length,
    10461079                    &stop_bits);
    10471080                async_answer_4(callid, EOK, baud_rate, parity, word_length,
     
    10541087                word_length = IPC_GET_ARG3(*call);
    10551088                stop_bits = IPC_GET_ARG4(*call);
    1056                 ret = ns8250_set_props(ddf_fun_get_dev(fun), baud_rate, parity, word_length,
     1089                ret = ns8250_set_props(ns8250->dev, baud_rate, parity, word_length,
    10571090                    stop_bits);
    10581091                async_answer_0(callid, ret);
     
    10641097}
    10651098
     1099void ns8250_char_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     1100{
     1101        ns8250_t *ns8250 = fun_ns8250((ddf_fun_t *)arg);
     1102
     1103        chardev_conn(iid, icall, &ns8250->cds);
     1104}
     1105
    10661106/** Initialize the serial port driver.
    10671107 *
     
    10721112{
    10731113        ddf_log_init(NAME);
    1074        
    1075         ns8250_dev_ops.open = &ns8250_open;
    1076         ns8250_dev_ops.close = &ns8250_close;
    1077        
    1078         ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_dev_ops;
    1079         ns8250_dev_ops.default_handler = &ns8250_default_handler;
    10801114}
    10811115
  • uspace/drv/char/ski-con/ski-con.c

    rf571ca49 rac307b2  
    11/*
    22 * Copyright (c) 2005 Jakub Jermar
    3  * Copyright (c) 2011 Jiri Svoboda
     3 * Copyright (c) 2017 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3434#include <ddf/log.h>
    3535#include <errno.h>
    36 #include <ipc/char.h>
     36#include <fibril.h>
     37#include <io/chardev.h>
    3738#include <stdint.h>
    3839#include <stdlib.h>
    39 #include <thread.h>
    4040#include <stdbool.h>
    4141
     
    4646#define POLL_INTERVAL           10000
    4747
    48 static void ski_con_thread_impl(void *arg);
     48static int ski_con_fibril(void *arg);
    4949static int32_t ski_con_getchar(void);
    5050static void ski_con_connection(ipc_callid_t, ipc_call_t *, void *);
    5151
     52static int ski_con_read(chardev_srv_t *, void *, size_t, size_t *);
     53static int ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);
     54
     55static chardev_ops_t ski_con_chardev_ops = {
     56        .read = ski_con_read,
     57        .write = ski_con_write
     58};
     59
    5260/** Add ski console device. */
    5361int ski_con_add(ski_con_t *con)
    5462{
    55         thread_id_t tid;
     63        fid_t fid;
    5664        ddf_fun_t *fun = NULL;
    5765        bool bound = false;
    5866        int rc;
     67
     68        circ_buf_init(&con->cbuf, con->buf, ski_con_buf_size, 1);
     69        fibril_mutex_initialize(&con->buf_lock);
     70        fibril_condvar_initialize(&con->buf_cv);
    5971
    6072        fun = ddf_fun_create(con->dev, fun_exposed, "a");
     
    6779        ddf_fun_set_conn_handler(fun, ski_con_connection);
    6880
     81        chardev_srvs_init(&con->cds);
     82        con->cds.ops = &ski_con_chardev_ops;
     83        con->cds.sarg = con;
     84
    6985        rc = ddf_fun_bind(fun);
    7086        if (rc != EOK) {
     
    7591        bound = true;
    7692
    77         rc = thread_create(ski_con_thread_impl, con, "kbd_poll", &tid);
    78         if (rc != 0) {
    79                 return rc;
    80         }
    81 
     93        fid = fibril_create(ski_con_fibril, con);
     94        if (fid == 0) {
     95                ddf_msg(LVL_ERROR, "Error creating fibril.");
     96                rc = ENOMEM;
     97                goto error;
     98        }
     99
     100        fibril_add_ready(fid);
    82101        return EOK;
    83102error:
     
    102121}
    103122
    104 /** Thread to poll Ski for keypresses. */
    105 static void ski_con_thread_impl(void *arg)
     123/** Poll Ski for keypresses. */
     124static int ski_con_fibril(void *arg)
    106125{
    107126        int32_t c;
    108127        ski_con_t *con = (ski_con_t *) arg;
     128        int rc;
    109129
    110130        while (1) {
     
    114134                                break;
    115135
    116                         if (con->client_sess != NULL) {
    117                                 async_exch_t *exch = async_exchange_begin(con->client_sess);
    118                                 async_msg_1(exch, CHAR_NOTIF_BYTE, c);
    119                                 async_exchange_end(exch);
    120                         }
     136                        fibril_mutex_lock(&con->buf_lock);
     137
     138                        rc = circ_buf_push(&con->cbuf, &c);
     139                        if (rc != EOK)
     140                                ddf_msg(LVL_ERROR, "Buffer overrun");
     141
     142                        fibril_mutex_unlock(&con->buf_lock);
     143                        fibril_condvar_broadcast(&con->buf_cv);
    121144                }
    122145
    123                 thread_usleep(POLL_INTERVAL);
    124         }
     146                fibril_usleep(POLL_INTERVAL);
     147        }
     148
     149        return 0;
    125150}
    126151
     
    157182}
    158183
     184/** Read from Ski console device */
     185static int ski_con_read(chardev_srv_t *srv, void *buf, size_t size,
     186    size_t *nread)
     187{
     188        ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
     189        size_t p;
     190        uint8_t *bp = (uint8_t *) buf;
     191        int rc;
     192
     193        fibril_mutex_lock(&con->buf_lock);
     194
     195        while (circ_buf_nused(&con->cbuf) == 0)
     196                fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
     197
     198        p = 0;
     199        while (p < size) {
     200                rc = circ_buf_pop(&con->cbuf, &bp[p]);
     201                if (rc != EOK)
     202                        break;
     203                ++p;
     204        }
     205
     206        fibril_mutex_unlock(&con->buf_lock);
     207
     208        *nread = p;
     209        return EOK;
     210}
     211
     212/** Write to Ski console device */
     213static int ski_con_write(chardev_srv_t *srv, const void *data, size_t size,
     214    size_t *nwr)
     215{
     216        ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
     217        size_t i;
     218        uint8_t *dp = (uint8_t *) data;
     219
     220        for (i = 0; i < size; i++)
     221                ski_con_putchar(con, dp[i]);
     222
     223        *nwr = size;
     224        return EOK;
     225}
     226
    159227/** Character device connection handler. */
    160228static void ski_con_connection(ipc_callid_t iid, ipc_call_t *icall,
    161229    void *arg)
    162230{
    163         ski_con_t *con;
    164 
    165         /* Answer the IPC_M_CONNECT_ME_TO call. */
    166         async_answer_0(iid, EOK);
    167 
    168         con = (ski_con_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
    169 
    170         while (true) {
    171                 ipc_call_t call;
    172                 ipc_callid_t callid = async_get_call(&call);
    173                 sysarg_t method = IPC_GET_IMETHOD(call);
    174 
    175                 if (!method) {
    176                         /* The other side has hung up. */
    177                         async_answer_0(callid, EOK);
    178                         return;
    179                 }
    180 
    181                 async_sess_t *sess =
    182                     async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
    183                 if (sess != NULL) {
    184                         if (con->client_sess == NULL) {
    185                                 con->client_sess = sess;
    186                                 async_answer_0(callid, EOK);
    187                         } else
    188                                 async_answer_0(callid, ELIMIT);
    189                 } else {
    190                         switch (method) {
    191                         case CHAR_WRITE_BYTE:
    192                                 ddf_msg(LVL_DEBUG, "Write %" PRIun " to device\n",
    193                                     IPC_GET_ARG1(call));
    194                                 ski_con_putchar(con, (uint8_t) IPC_GET_ARG1(call));
    195                                 async_answer_0(callid, EOK);
    196                                 break;
    197                         default:
    198                                 async_answer_0(callid, EINVAL);
    199                         }
    200                 }
    201         }
     231        ski_con_t *con = (ski_con_t *) ddf_dev_data_get(
     232            ddf_fun_get_dev((ddf_fun_t *) arg));
     233
     234        chardev_conn(iid, icall, &con->cds);
    202235}
    203236
  • uspace/drv/char/ski-con/ski-con.h

    rf571ca49 rac307b2  
    3636#define SKI_CON_H
    3737
     38#include <adt/circ_buf.h>
    3839#include <async.h>
    3940#include <ddf/driver.h>
     41#include <io/chardev_srv.h>
    4042#include <loc.h>
    4143#include <stdint.h>
     44
     45enum {
     46        ski_con_buf_size = 64
     47};
    4248
    4349/** Ski console */
     
    4551        async_sess_t *client_sess;
    4652        ddf_dev_t *dev;
     53        chardev_srvs_t cds;
     54        circ_buf_t cbuf;
     55        uint8_t buf[ski_con_buf_size];
     56        fibril_mutex_t buf_lock;
     57        fibril_condvar_t buf_cv;
    4758} ski_con_t;
    4859
  • uspace/drv/char/sun4v-con/sun4v-con.c

    rf571ca49 rac307b2  
    11/*
    22 * Copyright (c) 2008 Pavel Rimsky
    3  * Copyright (c) 2011 Jiri Svoboda
     3 * Copyright (c) 2017 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3636#include <ddi.h>
    3737#include <errno.h>
    38 #include <ipc/char.h>
     38#include <io/chardev_srv.h>
    3939#include <stdbool.h>
    4040#include <thread.h>
     
    6262static input_buffer_t input_buffer;
    6363
    64 static void sun4v_thread_impl(void *arg);
     64static int sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *);
     65static int sun4v_con_write(chardev_srv_t *, const void *, size_t, size_t *);
     66
     67static chardev_ops_t sun4v_con_chardev_ops = {
     68        .read = sun4v_con_read,
     69        .write = sun4v_con_write
     70};
    6571
    6672static void sun4v_con_putchar(sun4v_con_t *con, uint8_t data)
     
    8692        }
    8793
     94        chardev_srvs_init(&con->cds);
     95        con->cds.ops = &sun4v_con_chardev_ops;
     96        con->cds.sarg = con;
     97
    8898        ddf_fun_set_conn_handler(fun, sun4v_con_connection);
    8999
     
    94104                goto error;
    95105        }
    96 
    97         thread_id_t tid;
    98         rc = thread_create(sun4v_thread_impl, con, "kbd_poll", &tid);
    99         if (rc != EOK)
    100                 goto error;
    101106
    102107        rc = ddf_fun_bind(fun);
     
    131136}
    132137
    133 /**
    134  * Called regularly by the polling thread. Reads codes of all the
    135  * pressed keys from the buffer.
    136  */
    137 static void sun4v_key_pressed(sun4v_con_t *con)
     138/** Read from Sun4v console device */
     139static int sun4v_con_read(chardev_srv_t *srv, void *buf, size_t size,
     140    size_t *nread)
    138141{
     142        size_t p;
     143        uint8_t *bp = (uint8_t *) buf;
    139144        char c;
    140145
    141         while (input_buffer->read_ptr != input_buffer->write_ptr) {
     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) {
    142151                c = input_buffer->data[input_buffer->read_ptr];
    143152                input_buffer->read_ptr =
    144153                    ((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE;
    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;
     154                bp[p++] = c;
    151155        }
     156
     157        *nread = p;
     158        return EOK;
    152159}
    153160
    154 /**
    155  * Thread to poll Sun4v console for keypresses.
    156  */
    157 static void sun4v_thread_impl(void *arg)
     161/** Write to Sun4v console device */
     162static int sun4v_con_write(chardev_srv_t *srv, const void *data, size_t size,
     163    size_t *nwr)
    158164{
    159         sun4v_con_t *con = (sun4v_con_t *) arg;
     165        sun4v_con_t *con = (sun4v_con_t *) srv->srvs->sarg;
     166        size_t i;
     167        uint8_t *dp = (uint8_t *) data;
    160168
    161         while (true) {
    162                 sun4v_key_pressed(con);
    163                 thread_usleep(POLL_INTERVAL);
    164         }
     169        for (i = 0; i < size; i++)
     170                sun4v_con_putchar(con, dp[i]);
     171
     172        *nwr = size;
     173        return EOK;
    165174}
    166175
     
    169178    void *arg)
    170179{
    171         sun4v_con_t *con;
     180        sun4v_con_t *con = (sun4v_con_t *) ddf_dev_data_get(
     181            ddf_fun_get_dev((ddf_fun_t *) arg));
    172182
    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         }
     183        chardev_conn(iid, icall, &con->cds);
    210184}
    211185
  • uspace/drv/char/sun4v-con/sun4v-con.h

    rf571ca49 rac307b2  
    3838#include <async.h>
    3939#include <ddf/driver.h>
     40#include <io/chardev_srv.h>
    4041#include <loc.h>
    4142#include <stdint.h>
     
    5051        async_sess_t *client_sess;
    5152        ddf_dev_t *dev;
     53        chardev_srvs_t cds;
    5254        sun4v_con_res_t res;
    5355} sun4v_con_t;
  • uspace/drv/root/virt/devices.def

    rf571ca49 rac307b2  
    2626},
    2727{
    28         .name = "null",
    29         .match_id = "virtual&test1"
    30 },
    31 {
    3228        .name = "test3",
    3329        .match_id = "virtual&test3"
  • uspace/drv/test/test1/Makefile

    rf571ca49 rac307b2  
    3232
    3333SOURCES = \
    34         char.c \
    3534        test1.c
    3635
  • uspace/drv/test/test1/test1.c

    rf571ca49 rac307b2  
    177177        ddf_fun_add_to_category(fun_a, "virtual");
    178178
    179         if (str_cmp(dev_name, "null") == 0) {
    180                 ddf_fun_set_ops(fun_a,  &char_device_ops);
    181                 ddf_fun_add_to_category(fun_a, "virt-null");
    182         } else if (str_cmp(dev_name, "test1") == 0) {
     179        if (str_cmp(dev_name, "test1") == 0) {
    183180                (void) register_fun_verbose(dev,
    184181                    "cloning myself ;-)", "clone",
  • uspace/drv/test/test1/test1.h

    rf571ca49 rac307b2  
    3636#define NAME "test1"
    3737
    38 extern ddf_dev_ops_t char_device_ops;
    39 
    4038#endif
  • uspace/lib/c/Makefile

    rf571ca49 rac307b2  
    143143        generic/getopt.c \
    144144        generic/adt/checksum.c \
     145        generic/adt/circ_buf.c \
    145146        generic/adt/list.c \
    146147        generic/adt/hash_table.c \
     
    181182
    182183TEST_SOURCES = \
     184        test/adt/circ_buf.c \
    183185        test/fibril/timer.c \
    184186        test/main.c \
  • uspace/lib/c/generic/io/chardev_srv.c

    rf571ca49 rac307b2  
    169169                        break;
    170170                default:
    171                         async_answer_0(callid, EINVAL);
     171                        if (srv->srvs->ops->def_handler != NULL)
     172                                srv->srvs->ops->def_handler(srv, callid, &call);
     173                        else
     174                                async_answer_0(callid, ENOTSUP);
    172175                }
    173176        }
  • uspace/lib/c/include/adt/circ_buf.h

    rf571ca49 rac307b2  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2017 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libcipc
     29/** @addtogroup libc
    3030 * @{
    3131 */
    32 /** @file
    33  * @brief Character device interface.
     32/** @file Circular buffer
    3433 */
    3534
    36 #ifndef LIBC_IPC_CHAR_H_
    37 #define LIBC_IPC_CHAR_H_
     35#ifndef LIBC_CIRC_BUF_H_
     36#define LIBC_CIRC_BUF_H_
    3837
    39 #include <ipc/common.h>
     38#include <stddef.h>
    4039
    41 typedef enum {
    42         CHAR_WRITE_BYTE = IPC_FIRST_USER_METHOD
    43 } char_request_t;
     40/** Circular buffer */
     41typedef struct {
     42        /** Buffer */
     43        void *buf;
     44        /** Number of buffer members */
     45        size_t nmemb;
     46        /** Member size */
     47        size_t size;
     48        /** Read position */
     49        size_t rp;
     50        /** Write position */
     51        size_t wp;
     52        /** Number of used entries */
     53        size_t nused;
     54} circ_buf_t;
    4455
    45 typedef enum {
    46         CHAR_NOTIF_BYTE = IPC_FIRST_USER_METHOD
    47 } char_notif_t;
     56extern void circ_buf_init(circ_buf_t *, void *, size_t, size_t);
     57extern size_t circ_buf_nfree(circ_buf_t *);
     58extern size_t circ_buf_nused(circ_buf_t *);
     59extern int circ_buf_push(circ_buf_t *, const void *);
     60extern int circ_buf_pop(circ_buf_t *, void *);
    4861
    4962#endif
  • uspace/lib/c/include/io/chardev_srv.h

    rf571ca49 rac307b2  
    6161        int (*read)(chardev_srv_t *, void *, size_t, size_t *);
    6262        int (*write)(chardev_srv_t *, const void *, size_t, size_t *);
     63        void (*def_handler)(chardev_srv_t *, ipc_callid_t, ipc_call_t *);
    6364};
    6465
  • uspace/lib/c/include/ipc/chardev.h

    rf571ca49 rac307b2  
    4141typedef enum {
    4242        CHARDEV_READ = IPC_FIRST_USER_METHOD,
    43         CHARDEV_WRITE
     43        CHARDEV_WRITE,
    4444} chardev_request_t;
     45
     46enum {
     47        CHARDEV_LIMIT = CHARDEV_WRITE + 1
     48};
    4549
    4650#endif
  • uspace/lib/c/include/ipc/serial_ctl.h

    rf571ca49 rac307b2  
    3030#define LIBC_IPC_SERIAL_CTL_H_
    3131
    32 #include <ipc/dev_iface.h>
     32#include <ipc/chardev.h>
    3333
    3434/** IPC methods for getting/setting serial communication properties
     
    4141 */
    4242typedef enum {
    43         SERIAL_GET_COM_PROPS = DEV_FIRST_CUSTOM_METHOD,
     43        SERIAL_GET_COM_PROPS = CHARDEV_LIMIT,
    4444        SERIAL_SET_COM_PROPS
    4545} serial_ctl_t;
  • uspace/lib/c/test/adt/circ_buf.c

    rf571ca49 rac307b2  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2017 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @file
     29#include <adt/circ_buf.h>
     30#include <pcut/pcut.h>
     31
     32PCUT_INIT
     33
     34PCUT_TEST_SUITE(circ_buf);
     35
     36enum {
     37        buffer_size = 16
     38};
     39
     40static int buffer[buffer_size];
     41
     42/** Basic insertion/deletion test.
     43 *
     44 * Test initialization, emptiness, pushing buffer until it is full,
     45 * then emptying it again.
    3046 */
     47PCUT_TEST(push_pop)
     48{
     49        circ_buf_t cbuf;
     50        int i;
     51        int j;
     52        int rc;
    3153
    32 #include <assert.h>
    33 #include <errno.h>
    34 #include <mem.h>
    35 #include <ops/char_dev.h>
     54        circ_buf_init(&cbuf, buffer, buffer_size, sizeof(int));
    3655
    37 #include "test1.h"
     56        for (i = 0; i < buffer_size; i++) {
     57                PCUT_ASSERT_INT_EQUALS(buffer_size - i, circ_buf_nfree(&cbuf));
     58                PCUT_ASSERT_INT_EQUALS(i, circ_buf_nused(&cbuf));
     59                rc = circ_buf_push(&cbuf, &i);
     60                PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     61        }
    3862
    39 static int impl_char_read(ddf_fun_t *fun, char *buf, size_t count) {
    40         memset(buf, 0, count);
    41         return count;
     63        rc = circ_buf_push(&cbuf, &i);
     64        PCUT_ASSERT_ERRNO_VAL(EAGAIN, rc);
     65
     66        for (i = 0; i < buffer_size; i++) {
     67                PCUT_ASSERT_INT_EQUALS(i, circ_buf_nfree(&cbuf));
     68                PCUT_ASSERT_INT_EQUALS(buffer_size - i, circ_buf_nused(&cbuf));
     69                rc = circ_buf_pop(&cbuf, &j);
     70                PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     71                PCUT_ASSERT_INT_EQUALS(i, j);
     72        }
     73
     74        PCUT_ASSERT_INT_EQUALS(buffer_size, circ_buf_nfree(&cbuf));
     75        PCUT_ASSERT_INT_EQUALS(0, circ_buf_nused(&cbuf));
     76
     77        rc = circ_buf_pop(&cbuf, &j);
     78        PCUT_ASSERT_ERRNO_VAL(EAGAIN, rc);
    4279}
    4380
    44 static int imp_char_write(ddf_fun_t *fun, char *buf, size_t count) {
    45         return count;
    46 }
    47 
    48 static char_dev_ops_t char_dev_ops = {
    49         .read = &impl_char_read,
    50         .write = &imp_char_write
    51 };
    52 
    53 ddf_dev_ops_t char_device_ops = {
    54         .interfaces[CHAR_DEV_IFACE] = &char_dev_ops
    55 };
    56 
     81PCUT_EXPORT(circ_buf);
  • uspace/lib/c/test/main.c

    rf571ca49 rac307b2  
    3232PCUT_INIT
    3333
     34PCUT_IMPORT(circ_buf);
    3435PCUT_IMPORT(fibril_timer);
    3536PCUT_IMPORT(odict);
  • uspace/lib/drv/Makefile

    rf571ca49 rac307b2  
    4343        generic/remote_hw_res.c \
    4444        generic/remote_pio_window.c \
    45         generic/remote_char_dev.c \
    4645        generic/remote_nic.c \
    4746        generic/remote_ieee80211.c \
  • uspace/lib/drv/generic/dev_iface.c

    rf571ca49 rac307b2  
    4242#include "remote_hw_res.h"
    4343#include "remote_pio_window.h"
    44 #include "remote_char_dev.h"
    4544#include "remote_clock_dev.h"
    4645#include "remote_led_dev.h"
     
    6261                [HW_RES_DEV_IFACE] = &remote_hw_res_iface,
    6362                [PIO_WINDOW_DEV_IFACE] = &remote_pio_window_iface,
    64                 [CHAR_DEV_IFACE] = &remote_char_dev_iface,
    6563                [NIC_DEV_IFACE] = &remote_nic_iface,
    6664                [IEEE80211_DEV_IFACE] = &remote_ieee80211_iface,
  • uspace/srv/hid/input/input.c

    rf571ca49 rac307b2  
    3737 */
    3838
     39#include <adt/fifo.h>
    3940#include <adt/list.h>
    40 #include <stdbool.h>
     41#include <async.h>
     42#include <config.h>
     43#include <errno.h>
     44#include <fibril.h>
    4145#include <fibril_synch.h>
     46#include <io/chardev.h>
     47#include <io/console.h>
     48#include <io/keycode.h>
    4249#include <ipc/services.h>
    4350#include <ipc/input.h>
    44 #include <config.h>
     51#include <loc.h>
     52#include <ns.h>
     53#include <stdbool.h>
    4554#include <stdio.h>
    4655#include <stdlib.h>
    47 #include <ns.h>
    48 #include <async.h>
    49 #include <errno.h>
    50 #include <adt/fifo.h>
    51 #include <io/console.h>
    52 #include <io/keycode.h>
    53 #include <loc.h>
    5456#include <str_error.h>
    55 #include <char_dev_iface.h>
    56 #include <fibril.h>
    57 #include "layout.h"
     57
     58#include "input.h"
    5859#include "kbd.h"
    5960#include "kbd_port.h"
    6061#include "kbd_ctl.h"
     62#include "layout.h"
    6163#include "mouse.h"
    6264#include "mouse_proto.h"
    6365#include "serial.h"
    64 #include "input.h"
    6566
    6667#define NUM_LAYOUTS  4
     
    536537        while (true) {
    537538                uint8_t data;
    538 
    539                 char_dev_read(sdev->sess, &data, sizeof(data));
     539                size_t nread;
     540
     541                chardev_read(sdev->chardev, &data, sizeof(data), &nread);
     542                /* XXX Handle error */
    540543                kbd_push_data(sdev->kdev, data);
    541544        }
     
    552555{
    553556        bool match = false;
     557        int rc;
    554558
    555559        serial_dev_t *sdev = serial_dev_new();
     
    559563        sdev->kdev->svc_id = service_id;
    560564       
    561         int rc = loc_service_get_name(service_id, &sdev->kdev->svc_name);
     565        rc = loc_service_get_name(service_id, &sdev->kdev->svc_name);
    562566        if (rc != EOK)
    563567                goto fail;
     
    582586                sdev->sess = loc_service_connect(service_id, INTERFACE_DDF,
    583587                    IPC_FLAG_BLOCKING);
     588
     589                rc = chardev_open(sdev->sess, &sdev->chardev);
     590                if (rc != EOK) {
     591                        async_hangup(sdev->sess);
     592                        sdev->sess = NULL;
     593                        list_remove(&sdev->link);
     594                        goto fail;
     595                }
    584596
    585597                fid_t fid = fibril_create(serial_consumer, sdev);
  • uspace/srv/hid/input/port/chardev.c

    rf571ca49 rac307b2  
    3535 */
    3636
    37 #include <ipc/char.h>
    3837#include <async.h>
     38#include <errno.h>
     39#include <fibril.h>
     40#include <io/chardev.h>
    3941#include <loc.h>
    40 #include <errno.h>
    4142#include <stdio.h>
    4243#include "../input.h"
     
    4445#include "../kbd.h"
    4546
    46 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
     47static int kbd_port_fibril(void *);
    4748
    4849static int chardev_port_init(kbd_dev_t *);
    49 static void chardev_port_write(uint8_t data);
     50static void chardev_port_write(uint8_t);
    5051
    5152kbd_port_ops_t chardev_port = {
     
    5657static kbd_dev_t *kbd_dev;
    5758static async_sess_t *dev_sess;
     59static chardev_t *chardev;
    5860
    5961/** List of devices to try connecting to. */
     
    7072{
    7173        service_id_t service_id;
    72         async_exch_t *exch;
    7374        unsigned int i;
     75        fid_t fid;
    7476        int rc;
    7577       
     
    9698        }
    9799       
    98         exch = async_exchange_begin(dev_sess);
    99         if (exch == NULL) {
    100                 printf("%s: Failed starting exchange with device\n", NAME);
     100        rc = chardev_open(dev_sess, &chardev);
     101        if (rc != EOK) {
     102                printf("%s: Failed opening character device\n", NAME);
    101103                async_hangup(dev_sess);
    102104                return ENOMEM;
    103105        }
    104106       
    105         port_id_t port;
    106         rc = async_create_callback_port(exch, INTERFACE_CHAR_CB, 0, 0,
    107             kbd_port_events, NULL, &port);
    108        
    109         async_exchange_end(exch);
    110        
    111         if (rc != 0) {
    112                 printf("%s: Failed to create callback from device\n", NAME);
     107        fid = fibril_create(kbd_port_fibril, NULL);
     108        if (fid == 0) {
     109                printf("%s: Failed creating fibril\n", NAME);
     110                chardev_close(chardev);
    113111                async_hangup(dev_sess);
    114                 return -1;
     112                return ENOMEM;
    115113        }
     114
     115        fibril_add_ready(fid);
    116116       
    117117        printf("%s: Found input device '%s'\n", NAME, in_devs[i]);
     
    121121static void chardev_port_write(uint8_t data)
    122122{
    123         async_exch_t *exch = async_exchange_begin(dev_sess);
    124         if (exch == NULL) {
    125                 printf("%s: Failed starting exchange with device\n", NAME);
     123        int rc;
     124        size_t nwr;
     125
     126        rc = chardev_write(chardev, &data, sizeof(data), &nwr);
     127        if (rc != EOK || nwr != sizeof(data)) {
     128                printf("%s: Failed writing to character device\n", NAME);
    126129                return;
    127         }
    128 
    129         async_msg_1(exch, CHAR_WRITE_BYTE, data);
    130         async_exchange_end(exch);
    131 }
    132 
    133 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    134 {
    135         /* Ignore parameters, the connection is already opened */
    136         while (true) {
    137 
    138                 ipc_call_t call;
    139                 ipc_callid_t callid = async_get_call(&call);
    140                
    141                 if (!IPC_GET_IMETHOD(call)) {
    142                         /* TODO: Handle hangup */
    143                         return;
    144                 }
    145 
    146                 int retval = EOK;
    147 
    148                 switch (IPC_GET_IMETHOD(call)) {
    149                 case CHAR_NOTIF_BYTE:
    150                         kbd_push_data(kbd_dev, IPC_GET_ARG1(call));
    151                         break;
    152                 default:
    153                         retval = ENOENT;
    154                 }
    155                 async_answer_0(callid, retval);
    156130        }
    157131}
    158132
     133static int kbd_port_fibril(void *arg)
     134{
     135        int rc;
     136        size_t nread;
     137        uint8_t b;
     138
     139        while (true) {
     140                rc = chardev_read(chardev, &b, sizeof(b), &nread);
     141                if (rc != EOK || nread != sizeof(b)) {
     142                        printf("%s: Error reading data", NAME);
     143                        continue;
     144                }
     145
     146                kbd_push_data(kbd_dev, b);
     147        }
     148
     149        return 0;
     150}
    159151
    160152/**
  • uspace/srv/hid/input/serial.h

    rf571ca49 rac307b2  
    3939
    4040#include <async.h>
     41#include <io/chardev.h>
    4142#include "kbd.h"
    4243
     
    4546        link_t link;
    4647        async_sess_t *sess;
     48        chardev_t *chardev;
    4749} serial_dev_t;
    4850
  • uspace/srv/hid/isdv4_tablet/isdv4.c

    rf571ca49 rac307b2  
    2727 */
    2828
    29 #include <char_dev_iface.h>
    3029#include <errno.h>
     30#include <io/chardev.h>
     31#include <mem.h>
    3132#include <stdbool.h>
    3233#include <stdint.h>
    3334#include <stdlib.h>
    34 #include <mem.h>
    3535#include <thread.h>
    3636
     
    298298        bool reading = true;
    299299        while (reading) {
    300                 ssize_t read = char_dev_read(state->sess, state->buf + state->buf_end,
    301                     state->buf_size - state->buf_end);
    302                 if (read < 0)
     300                size_t nread;
     301                int rc;
     302
     303                rc = chardev_read(state->chardev, state->buf + state->buf_end,
     304                    state->buf_size - state->buf_end, &nread);
     305                if (rc != EOK && nread == 0)
    303306                        return EIO;
    304                 state->buf_end += read;
     307                state->buf_end += nread;
    305308
    306309                size_t i = 0;
     
    357360        return EOK;
    358361}
    359 static bool write_command(async_sess_t *sess, uint8_t command)
    360 {
    361         return char_dev_write(sess, &command, 1) == 1;
     362
     363static bool write_command(chardev_t *chardev, uint8_t command)
     364{
     365        int rc;
     366        size_t nwr;
     367
     368        rc = chardev_write(chardev, &command, 1, &nwr);
     369        return rc == EOK;
    362370}
    363371
     
    365373    isdv4_event_fn event_fn)
    366374{
     375        chardev_t *chardev;
     376        int rc;
     377
     378        rc = chardev_open(sess, &chardev);
     379        if (rc != EOK)
     380                return rc;
     381
    367382        memset(state, 0, sizeof(isdv4_state_t));
     383
    368384        state->sess = sess;
     385        state->chardev = chardev;
     386
    369387        state->buf = malloc(BUF_SIZE);
    370         if (state->buf == NULL)
     388        if (state->buf == NULL) {
     389                chardev_close(chardev);
    371390                return ENOMEM;
     391        }
     392
    372393        state->buf_size = BUF_SIZE;
    373394        state->emit_event_fn = event_fn;
     
    377398int isdv4_init_tablet(isdv4_state_t *state)
    378399{
    379         if (!write_command(state->sess, CMD_STOP))
     400        if (!write_command(state->chardev, CMD_STOP))
    380401                return EIO;
    381402
     
    383404
    384405        // FIXME: Read all possible garbage before sending commands
    385         if (!write_command(state->sess, CMD_QUERY_STYLUS))
     406        if (!write_command(state->chardev, CMD_QUERY_STYLUS))
    386407                return EIO;
    387408
     
    390411                return rc;
    391412
    392         if (!write_command(state->sess, CMD_QUERY_TOUCH))
     413        if (!write_command(state->chardev, CMD_QUERY_TOUCH))
    393414                return EIO;
    394415
     
    397418                return rc;
    398419
    399         if (!write_command(state->sess, CMD_START))
     420        if (!write_command(state->chardev, CMD_START))
    400421                return EIO;
    401422
  • uspace/srv/hid/isdv4_tablet/isdv4.h

    rf571ca49 rac307b2  
    3131
    3232#include <async.h>
     33#include <io/chardev.h>
    3334
    3435typedef struct isdv4_event isdv4_event_t;
     
    5859        bool finger1_pressed; /* Reported as touch button 1 */
    5960
    60         /* Session to the serial device */
     61        /** Session with the serial device */
    6162        async_sess_t *sess;
     63        /** Character device */
     64        chardev_t *chardev;
    6265
    6366        /* Receive buffer state */
     
    6669        size_t buf_end;
    6770
    68         /* Callbacks */
     71        /** Callbacks */
    6972        isdv4_event_fn emit_event_fn;
    7073} isdv4_state_t;
  • uspace/srv/hid/output/port/chardev.c

    rf571ca49 rac307b2  
    3030 */
    3131
     32#include <async.h>
     33#include <config.h>
     34#include <errno.h>
     35#include <fibril_synch.h>
     36#include <io/chardev.h>
     37#include <loc.h>
    3238#include <stddef.h>
    3339#include <stdint.h>
    34 #include <char_dev_iface.h>
    3540#include <stdio.h>
    3641#include <stdlib.h>
    37 #include <async.h>
    38 #include <fibril_synch.h>
    39 #include <loc.h>
    40 #include <errno.h>
    4142#include <str.h>
    42 #include <config.h>
    4343#include "../ctl/serial.h"
    4444#include "../output.h"
     
    4848
    4949static async_sess_t *sess;
     50static chardev_t *chardev;
    5051static service_id_t serial_cat_id;
    5152
     
    5758{
    5859        uint8_t byte = (uint8_t) ch;
    59         char_dev_write(sess, &byte, 1);
     60        size_t nwr;
     61        chardev_write(chardev, &byte, 1, &nwr);
     62        /* XXX Handle error */
    6063}
    6164
    6265static void chardev_control_puts(const char *str)
    6366{
    64         char_dev_write(sess, (void *) str, str_size(str));
     67        size_t nwr;
     68        chardev_write(chardev, (void *) str, str_size(str), &nwr);
     69        /* XXX Handle error */
    6570}
    6671
     
    126131                return;
    127132        }
     133
     134        rc = chardev_open(sess, &chardev);
     135        if (rc != EOK) {
     136                fibril_mutex_unlock(&discovery_lock);
     137                printf("%s: Failed opening character device\n", NAME);
     138                return;
     139        }
     140
    128141        serial_init(chardev_putchar, chardev_control_puts);
    129142
  • uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c

    rf571ca49 rac307b2  
    2727 */
    2828
    29 /** @addtogroup driver_serial
    30  * @{
    31  */
    3229/**
    3330 * @file
     
    3734 */
    3835
     36#include <async.h>
    3937#include <ddi.h>
     38#include <errno.h>
     39#include <inttypes.h>
     40#include <io/chardev_srv.h>
    4041#include <loc.h>
    41 #include <ipc/char.h>
    42 #include <async.h>
    4342#include <stdio.h>
    4443#include <stdlib.h>
    4544#include <sysinfo.h>
    46 #include <errno.h>
    47 #include <inttypes.h>
    4845#include "s3c24xx_uart.h"
    4946
     
    7269static void s3c24xx_uart_sendb(s3c24xx_uart_t *, uint8_t);
    7370
     71static int s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *);
     72static int s3c24xx_uart_write(chardev_srv_t *, const void *, size_t, size_t *);
     73
     74static chardev_ops_t s3c24xx_uart_chardev_ops = {
     75        .read = s3c24xx_uart_read,
     76        .write = s3c24xx_uart_write
     77};
     78
    7479int main(int argc, char *argv[])
    7580{
    7681        printf("%s: S3C24xx on-chip UART driver\n", NAME);
    7782       
    78         async_set_fallback_port_handler(s3c24xx_uart_connection, NULL);
     83        async_set_fallback_port_handler(s3c24xx_uart_connection, uart);
    7984        int rc = loc_server_register(NAME);
    8085        if (rc != EOK) {
     
    111116    void *arg)
    112117{
    113         /* Answer the IPC_M_CONNECT_ME_TO call. */
    114         async_answer_0(iid, EOK);
    115        
    116         while (true) {
    117                 ipc_call_t call;
    118                 ipc_callid_t callid = async_get_call(&call);
    119                 sysarg_t method = IPC_GET_IMETHOD(call);
    120                
    121                 if (!method) {
    122                         /* The other side has hung up. */
    123                         async_answer_0(callid, EOK);
    124                         return;
    125                 }
    126                
    127                 async_sess_t *sess =
    128                     async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
    129                 if (sess != NULL) {
    130                         if (uart->client_sess == NULL) {
    131                                 uart->client_sess = sess;
    132                                 async_answer_0(callid, EOK);
    133                         } else
    134                                 async_answer_0(callid, ELIMIT);
    135                 } else {
    136                         switch (method) {
    137                         case CHAR_WRITE_BYTE:
    138                                 printf(NAME ": write %" PRIun " to device\n",
    139                                     IPC_GET_ARG1(call));
    140                                 s3c24xx_uart_sendb(uart, (uint8_t) IPC_GET_ARG1(call));
    141                                 async_answer_0(callid, EOK);
    142                                 break;
    143                         default:
    144                                 async_answer_0(callid, EINVAL);
    145                         }
    146                 }
    147         }
    148 }
     118        s3c24xx_uart_t *uart = (s3c24xx_uart_t *) arg;
     119
     120        chardev_conn(iid, icall, &uart->cds);
     121}
     122
    149123
    150124static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call,
    151125    void *arg)
    152126{
     127        int rc;
     128
    153129        (void) iid;
    154130        (void) call;
     
    159135                uint32_t status = pio_read_32(&uart->io->uerstat);
    160136
    161                 if (uart->client_sess != NULL) {
    162                         async_exch_t *exch = async_exchange_begin(uart->client_sess);
    163                         async_msg_1(exch, CHAR_NOTIF_BYTE, data);
    164                         async_exchange_end(exch);
    165                 }
     137                fibril_mutex_lock(&uart->buf_lock);
     138
     139                rc = circ_buf_push(&uart->cbuf, &data);
     140                if (rc != EOK)
     141                        printf(NAME ": Buffer overrun\n");
     142
     143                fibril_mutex_unlock(&uart->buf_lock);
     144                fibril_condvar_broadcast(&uart->buf_cv);
    166145
    167146                if (status != 0)
     
    176155        sysarg_t inr;
    177156
     157        circ_buf_init(&uart->cbuf, uart->buf, s3c24xx_uart_buf_size, 1);
     158        fibril_mutex_initialize(&uart->buf_lock);
     159        fibril_condvar_initialize(&uart->buf_cv);
     160
    178161        if (sysinfo_get_value("s3c24xx_uart.address.physical",
    179162            &uart->paddr) != EOK)
     
    188171
    189172        uart->io = vaddr;
    190         uart->client_sess = NULL;
    191173
    192174        printf(NAME ": device at physical address %p, inr %" PRIun ".\n",
     
    203185            pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL);
    204186
     187        chardev_srvs_init(&uart->cds);
     188        uart->cds.ops = &s3c24xx_uart_chardev_ops;
     189        uart->cds.sarg = uart;
     190
    205191        return EOK;
    206192}
     
    216202}
    217203
     204static int s3c24xx_uart_read(chardev_srv_t *srv, void *buf, size_t size,
     205    size_t *nread)
     206{
     207        s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg;
     208        size_t p;
     209        uint8_t *bp = (uint8_t *) buf;
     210        int rc;
     211
     212        fibril_mutex_lock(&uart->buf_lock);
     213
     214        while (circ_buf_nused(&uart->cbuf) == 0)
     215                fibril_condvar_wait(&uart->buf_cv, &uart->buf_lock);
     216
     217        p = 0;
     218        while (p < size) {
     219                rc = circ_buf_pop(&uart->cbuf, &bp[p]);
     220                if (rc != EOK)
     221                        break;
     222                ++p;
     223        }
     224
     225        fibril_mutex_unlock(&uart->buf_lock);
     226
     227        *nread = p;
     228        return EOK;
     229}
     230
     231static int s3c24xx_uart_write(chardev_srv_t *srv, const void *data, size_t size,
     232    size_t *nwr)
     233{
     234        s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg;
     235        size_t i;
     236        uint8_t *dp = (uint8_t *) data;
     237
     238        for (i = 0; i < size; i++)
     239                s3c24xx_uart_sendb(uart, dp[i]);
     240
     241        *nwr = size;
     242        return EOK;
     243}
     244
     245
    218246/** @}
    219247 */
  • uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h

    rf571ca49 rac307b2  
    3838#define S3C24XX_UART_H_
    3939
     40#include <adt/circ_buf.h>
     41#include <async.h>
     42#include <fibril_synch.h>
     43#include <io/chardev_srv.h>
    4044#include <stdint.h>
    41 #include <async.h>
    4245
    4346/** S3C24xx UART I/O */
     
    7679#define UFCON_FIFO_ENABLE               0x01
    7780
     81enum {
     82        s3c24xx_uart_buf_size = 64
     83};
    7884
    7985/** S3C24xx UART instance */
     
    8591        s3c24xx_uart_io_t *io;
    8692
    87         /** Callback session to the client */
    88         async_sess_t *client_sess;
     93        /** Character device service */
     94        chardev_srvs_t cds;
    8995
    9096        /** Service ID */
    9197        service_id_t service_id;
     98
     99        /** Circular buffer */
     100        circ_buf_t cbuf;
     101        /** Buffer */
     102        uint8_t buf[s3c24xx_uart_buf_size];
     103        /** Buffer lock */
     104        fibril_mutex_t buf_lock;
     105        /** Signal newly added data in buffer */
     106        fibril_condvar_t buf_cv;
    92107} s3c24xx_uart_t;
    93108
  • uspace/srv/net/slip/slip.c

    rf571ca49 rac307b2  
    4040#include <inet/addr.h>
    4141#include <inet/iplink_srv.h>
    42 #include <char_dev_iface.h>
     42#include <io/chardev.h>
    4343#include <io/log.h>
    4444#include <errno.h>
     
    9696}
    9797
    98 static void write_flush(async_sess_t *sess)
     98static void write_flush(chardev_t *chardev)
    9999{
    100100        size_t written = 0;
    101101
    102102        while (slip_send_pending > 0) {
    103                 ssize_t size;
    104 
    105                 size = char_dev_write(sess, &slip_send_buf[written],
    106                     slip_send_pending);
    107                 if (size < 0) {
     103                int rc;
     104                size_t nwr;
     105
     106                rc = chardev_write(chardev, &slip_send_buf[written],
     107                    slip_send_pending, &nwr);
     108                if (rc != EOK) {
    108109                        log_msg(LOG_DEFAULT, LVL_ERROR,
    109                             "char_dev_write() returned %d",
    110                             (int) size);
     110                            "chardev_write() returned %d", rc);
    111111                        slip_send_pending = 0;
    112112                        break;
    113113                }
    114                 written += size;
    115                 slip_send_pending -= size;
    116         }
    117 }
    118 
    119 static void write_buffered(async_sess_t *sess, uint8_t ch)
     114                written += nwr;
     115                slip_send_pending -= nwr;
     116        }
     117}
     118
     119static void write_buffered(chardev_t *chardev, uint8_t ch)
    120120{
    121121        if (slip_send_pending == sizeof(slip_send_buf))
    122                 write_flush(sess);
     122                write_flush(chardev);
    123123        slip_send_buf[slip_send_pending++] = ch;
    124124}
     
    128128        log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send()");
    129129       
    130         async_sess_t *sess = (async_sess_t *) srv->arg;
     130        chardev_t *chardev = (chardev_t *) srv->arg;
    131131        uint8_t *data = sdu->data;
    132132       
     
    136136         * measure for dealing with previous possible noise on the line.
    137137         */
    138         write_buffered(sess, SLIP_END);
     138        write_buffered(chardev, SLIP_END);
    139139       
    140140        for (size_t i = 0; i < sdu->size; i++) {
    141141                switch (data[i]) {
    142142                case SLIP_END:
    143                         write_buffered(sess, SLIP_ESC);
    144                         write_buffered(sess, SLIP_ESC_END);
     143                        write_buffered(chardev, SLIP_ESC);
     144                        write_buffered(chardev, SLIP_ESC_END);
    145145                        break;
    146146                case SLIP_ESC:
    147                         write_buffered(sess, SLIP_ESC);
    148                         write_buffered(sess, SLIP_ESC_ESC);
     147                        write_buffered(chardev, SLIP_ESC);
     148                        write_buffered(chardev, SLIP_ESC_ESC);
    149149                        break;
    150150                default:
    151                         write_buffered(sess, data[i]);
     151                        write_buffered(chardev, data[i]);
    152152                        break;
    153153                }
    154154        }
    155155       
    156         write_buffered(sess, SLIP_END);
    157         write_flush(sess);
     156        write_buffered(chardev, SLIP_END);
     157        write_flush(chardev);
    158158       
    159159        return EOK;
     
    203203}
    204204
    205 static uint8_t read_buffered(async_sess_t *sess)
     205static uint8_t read_buffered(chardev_t *chardev)
    206206{
    207207        while (slip_recv_pending == 0) {
    208                 ssize_t size;
    209 
    210                 size = char_dev_read(sess, slip_recv_buf,
    211                     sizeof(slip_recv_buf));
    212                 if (size < 0) {
     208                int rc;
     209                size_t nread;
     210
     211                rc = chardev_read(chardev, slip_recv_buf,
     212                    sizeof(slip_recv_buf), &nread);
     213                if (rc != EOK) {
    213214                        log_msg(LOG_DEFAULT, LVL_ERROR,
    214                             "char_dev_read() returned %d", (int) size);
     215                            "char_dev_read() returned %d", rc);
     216                }
     217
     218                if (nread == 0)
    215219                        return SLIP_END;
    216                 }
    217                 slip_recv_pending = size;
     220
     221                slip_recv_pending = nread;
    218222                slip_recv_read = 0;
    219223        }
     
    224228static int slip_recv_fibril(void *arg)
    225229{
    226         async_sess_t *sess = (async_sess_t *) arg;
     230        chardev_t *chardev = (chardev_t *) arg;
    227231        static uint8_t recv_final[SLIP_MTU];
    228232        iplink_recv_sdu_t sdu;
     
    234238        while (true) {
    235239                for (sdu.size = 0; sdu.size < sizeof(recv_final); /**/) {
    236                         ch = read_buffered(sess);
     240                        ch = read_buffered(chardev);
    237241                        switch (ch) {
    238242                        case SLIP_END:
     
    246250
    247251                        case SLIP_ESC:
    248                                 ch = read_buffered(sess);
     252                                ch = read_buffered(chardev);
    249253                                if (ch == SLIP_ESC_END) {
    250254                                        recv_final[sdu.size++] = SLIP_END;
    251255                                        break;
    252                                 } else if (ch ==  SLIP_ESC_ESC) {
     256                                } else if (ch == SLIP_ESC_ESC) {
    253257                                        recv_final[sdu.size++] = SLIP_ESC;
    254258                                        break;
     
    295299        async_sess_t *sess_in = NULL;
    296300        async_sess_t *sess_out = NULL;
     301        chardev_t *chardev_in = NULL;
     302        chardev_t *chardev_out = NULL;
    297303        fid_t fid;
    298304        int rc;
     
    336342                return ENOENT;
    337343        }
    338         slip_iplink.arg = sess_out;
     344
     345        rc = chardev_open(sess_out, &chardev_out);
     346        if (rc != EOK) {
     347                log_msg(LOG_DEFAULT, LVL_ERROR,
     348                    "Failed opening character device.");
     349                return ENOENT;
     350        }
     351
     352        slip_iplink.arg = chardev_out;
    339353
    340354        sess_in = loc_service_connect(svcid, INTERFACE_DDF, 0);
     
    347361        }
    348362
     363        rc = chardev_open(sess_in, &chardev_in);
     364        if (rc != EOK) {
     365                log_msg(LOG_DEFAULT, LVL_ERROR,
     366                    "Failed opening character device.");
     367                return ENOENT;
     368        }
     369
    349370        rc = loc_service_register(linkstr, &linksid);
    350371        if (rc != EOK) {
     
    363384        }
    364385
    365         fid = fibril_create(slip_recv_fibril, sess_in);
     386        fid = fibril_create(slip_recv_fibril, chardev_in);
    366387        if (!fid) {
    367388                log_msg(LOG_DEFAULT, LVL_ERROR,
     
    375396
    376397fail:
     398        chardev_close(chardev_out);
    377399        if (sess_out)
    378400                async_hangup(sess_out);
     401        chardev_close(chardev_in);
    379402        if (sess_in)
    380403                async_hangup(sess_in);
Note: See TracChangeset for help on using the changeset viewer.