Changes in / [ac307b2:f571ca49] in mainline


Ignore:
Files:
7 added
3 deleted
36 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    rac307b2 rf571ca49  
    248248uspace/dist/logo.tga
    249249uspace/dist/srv/cdfs
    250 uspace/dist/srv/chardev-test
    251250uspace/dist/srv/clipboard
    252251uspace/dist/srv/compositor
     
    421420uspace/srv/ns/ns
    422421uspace/srv/taskmon/taskmon
    423 uspace/srv/test/chardev-test/chardev-test
    424422uspace/srv/vfs/vfs
    425423uspace/srv/volsrv/volsrv
  • uspace/app/sportdmp/sportdmp.c

    rac307b2 rf571ca49  
    2727 */
    2828
     29#include <char_dev_iface.h>
    2930#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>
    3534
    3635#define BUF_SIZE 1
     
    4544        sysarg_t baud = 9600;
    4645        service_id_t svc_id;
    47         chardev_t *chardev;
    4846        serial_t *serial;
    49         size_t nread;
    5047
    5148        int arg = 1;
     
    122119        }
    123120
    124         rc = chardev_open(sess, &chardev);
    125         if (rc != EOK) {
    126                 fprintf(stderr, "Failed opening character device\n");
    127                 return 2;
    128         }
    129 
    130121        rc = serial_open(sess, &serial);
    131122        if (rc != EOK) {
     
    147138
    148139        while (true) {
    149                 rc = chardev_read(chardev, buf, BUF_SIZE, &nread);
    150                 for (size_t i = 0; i < nread; i++) {
     140                ssize_t read = char_dev_read(sess, buf, BUF_SIZE);
     141                if (read < 0) {
     142                        fprintf(stderr, "Failed reading from serial device\n");
     143                        break;
     144                }
     145                ssize_t i;
     146                for (i = 0; i < read; i++) {
    151147                        printf("%02hhx ", buf[i]);
    152                 }
    153                 if (rc != EOK) {
    154                         fprintf(stderr, "\nFailed reading from serial device\n");
    155                         break;
    156148                }
    157149                fflush(stdout);
     
    160152        free(buf);
    161153        serial_close(serial);
    162         chardev_close(chardev);
    163154        async_hangup(sess);
    164155        return 0;
  • uspace/app/tester/Makefile

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

    rac307b2 rf571ca49  
    3535 */
    3636
    37 #include <async.h>
     37#include <inttypes.h>
    3838#include <errno.h>
    39 #include <io/chardev.h>
    40 #include <io/serial.h>
    41 #include <ipc/services.h>
    42 #include <loc.h>
    4339#include <stdlib.h>
    4440#include <stdio.h>
    4541#include <stddef.h>
     42#include <async.h>
     43#include <thread.h>
     44#include <ipc/services.h>
     45#include <loc.h>
     46#include <char_dev_iface.h>
    4647#include <str.h>
    47 #include <thread.h>
     48#include <io/serial.h>
    4849#include "../../tester.h"
    4950
     
    5657        size_t cnt;
    5758        serial_t *serial;
    58         chardev_t *chardev;
    59         int rc;
    60         size_t nread;
    61         size_t nwritten;
    6259       
    6360        if (test_argc < 1)
     
    8683                return "Failed connecting to serial device";
    8784       
    88         res = chardev_open(sess, &chardev);
    89         if (res != EOK) {
    90                 async_hangup(sess);
     85        res = serial_open(sess, &serial);
     86        if (res != EOK)
    9187                return "Failed opening serial port";
    92         }
    93        
    94         res = serial_open(sess, &serial);
    95         if (res != EOK) {
    96                 chardev_close(chardev);
    97                 async_hangup(sess);
    98                 return "Failed opening serial port";
    99         }
    10088       
    10189        char *buf = (char *) malloc(cnt + 1);
    10290        if (buf == NULL) {
    103                 chardev_close(chardev);
    10491                serial_close(serial);
    10592                async_hangup(sess);
     
    116103        if (res != EOK) {
    117104                free(buf);
    118                 chardev_close(chardev);
    119105                serial_close(serial);
    120106                async_hangup(sess);
     
    125111        if (EOK != res) {
    126112                free(buf);
    127                 chardev_close(chardev);
    128113                serial_close(serial);
    129114                async_hangup(sess);
     
    136121        size_t total = 0;
    137122        while (total < cnt) {
    138                
    139                 rc = chardev_read(chardev, buf, cnt - total, &nread);
    140                 if (rc != EOK) {
     123                ssize_t read = char_dev_read(sess, buf, cnt - total);
     124               
     125                if (read < 0) {
    141126                        (void) serial_set_comm_props(serial, old_baud,
    142127                            old_par, old_word_size, old_stop);
    143128                       
    144129                        free(buf);
    145                         chardev_close(chardev);
    146130                        serial_close(serial);
    147131                        async_hangup(sess);
     
    149133                }
    150134               
    151                 if (nread > cnt - total) {
     135                if ((size_t) read > cnt - total) {
    152136                        (void) serial_set_comm_props(serial, old_baud,
    153137                            old_par, old_word_size, old_stop);
    154138                       
    155139                        free(buf);
    156                         chardev_close(chardev);
    157140                        serial_close(serial);
    158141                        async_hangup(sess);
     
    160143                }
    161144               
    162                 TPRINTF("Read %zd bytes\n", nread);
    163                
    164                 if (nread == 0)
     145                TPRINTF("Read %zd bytes\n", read);
     146               
     147                if (read == 0)
    165148                        thread_usleep(DEFAULT_SLEEP);
    166149                else {
    167                         buf[nread] = 0;
     150                        buf[read] = 0;
    168151                       
    169152                        /*
     
    171154                         * direction of data transfer.
    172155                         */
    173                         rc = chardev_write(chardev, buf, nread, &nwritten);
    174                         if (rc != EOK) {
     156                        ssize_t written = char_dev_write(sess, buf, read);
     157                       
     158                        if (written < 0) {
    175159                                (void) serial_set_comm_props(serial, old_baud,
    176160                                    old_par, old_word_size, old_stop);
    177161                               
    178162                                free(buf);
    179                                 chardev_close(chardev);
    180163                                serial_close(serial);
    181164                                async_hangup(sess);
     
    183166                        }
    184167                       
    185                         if (nwritten != nread) {
     168                        if (written != read) {
    186169                                (void) serial_set_comm_props(serial, old_baud,
    187170                                    old_par, old_word_size, old_stop);
    188171                               
    189172                                free(buf);
    190                                 chardev_close(chardev);
    191173                                serial_close(serial);
    192174                                async_hangup(sess);
     
    194176                        }
    195177                       
    196                         TPRINTF("Written %zd bytes\n", nwritten);
    197                 }
    198                
    199                 total += nread;
     178                        TPRINTF("Written %zd bytes\n", written);
     179                }
     180               
     181                total += read;
    200182        }
    201183       
     
    203185       
    204186        size_t eot_size = str_size(EOT);
    205         rc = chardev_write(chardev, (void *) EOT, eot_size, &nwritten);
     187        ssize_t written = char_dev_write(sess, (void *) EOT, eot_size);
    206188       
    207189        (void) serial_set_comm_props(serial, old_baud, old_par, old_word_size,
     
    209191       
    210192        free(buf);
    211         chardev_close(chardev);
    212193        serial_close(serial);
    213194        async_hangup(sess);
    214195       
    215         if (rc != EOK)
     196        if (written < 0)
    216197                return "Failed to write EOT banner to serial device";
    217198       
    218         if (nwritten != eot_size)
     199        if ((size_t) written != eot_size)
    219200                return "Written less data than the size of the EOT banner "
    220201                    "to serial device";
  • uspace/app/tester/tester.c

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

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

    rac307b2 rf571ca49  
    22 * Copyright (c) 2001-2004 Jakub Jermar
    33 * Copyright (c) 2006 Josef Cejka
    4  * Copyright (c) 2017 Jiri Svoboda
     4 * Copyright (c) 2014 Jiri Svoboda
    55 * Copyright (c) 2011 Jan Vesely
    66 * All rights reserved.
     
    3939 */
    4040
    41 #include <adt/circ_buf.h>
    4241#include <ddf/log.h>
    4342#include <ddf/interrupt.h>
     
    131130{
    132131        i8042_t *controller = ddf_dev_data_get(dev);
    133         int rc;
    134132       
    135133        const uint8_t status = IPC_GET_ARG1(*call);
    136134        const uint8_t data = IPC_GET_ARG2(*call);
    137135       
    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);
     136        buffer_t *buffer = (status & i8042_AUX_DATA) ?
     137            &controller->aux_buffer : &controller->kbd_buffer;
     138       
     139        buffer_write(buffer, data);
    149140}
    150141
     
    168159        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    169160        irq_cmd_t cmds[cmd_count];
    170         ddf_fun_t *kbd_fun;
    171         ddf_fun_t *aux_fun;
    172161        i8042_regs_t *ar;
    173        
     162
    174163        int rc;
    175164        bool kbd_bound = false;
    176165        bool aux_bound = false;
     166
     167        dev->kbd_fun = NULL;
     168        dev->aux_fun = NULL;
    177169       
    178170        if (regs->size < sizeof(i8042_regs_t)) {
     
    186178        }
    187179       
    188         kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    189         if (kbd_fun == NULL) {
     180        dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
     181        if (dev->kbd_fun == NULL) {
    190182                rc = ENOMEM;
    191183                goto error;
    192184        };
    193185       
    194         dev->kbd = ddf_fun_data_alloc(kbd_fun, sizeof(i8042_port_t));
     186        dev->kbd = ddf_fun_data_alloc(dev->kbd_fun, sizeof(i8042_port_t));
    195187        if (dev->kbd == NULL) {
    196188                rc = ENOMEM;
     
    198190        }
    199191       
    200         dev->kbd->fun = kbd_fun;
    201192        dev->kbd->ctl = dev;
    202193        chardev_srvs_init(&dev->kbd->cds);
    203194        dev->kbd->cds.ops = &i8042_chardev_ops;
    204195        dev->kbd->cds.sarg = dev->kbd;
    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);
     196       
     197        rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
    209198        if (rc != EOK)
    210199                goto error;
    211200       
    212         aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    213         if (aux_fun == NULL) {
     201        dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
     202        if (dev->aux_fun == NULL) {
    214203                rc = ENOMEM;
    215204                goto error;
    216205        }
    217206       
    218         dev->aux = ddf_fun_data_alloc(aux_fun, sizeof(i8042_port_t));
     207        dev->aux = ddf_fun_data_alloc(dev->aux_fun, sizeof(i8042_port_t));
    219208        if (dev->aux == NULL) {
    220209                rc = ENOMEM;
     
    222211        }
    223212       
    224         dev->aux->fun = aux_fun;
    225213        dev->aux->ctl = dev;
    226214        chardev_srvs_init(&dev->aux->cds);
    227215        dev->aux->cds.ops = &i8042_chardev_ops;
    228216        dev->aux->cds.sarg = dev->aux;
    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);
     217       
     218        rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
    233219        if (rc != EOK)
    234220                goto error;
    235221       
    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);
     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);
    241227        fibril_mutex_initialize(&dev->write_guard);
    242228       
    243         rc = ddf_fun_bind(dev->kbd->fun);
     229        rc = ddf_fun_bind(dev->kbd_fun);
    244230        if (rc != EOK) {
    245231                ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.",
    246                     ddf_fun_get_name(dev->kbd->fun));
     232                    ddf_fun_get_name(dev->kbd_fun));
    247233                goto error;
    248234        }
    249235        kbd_bound = true;
    250236       
    251         rc = ddf_fun_bind(dev->aux->fun);
     237        rc = ddf_fun_bind(dev->aux_fun);
    252238        if (rc != EOK) {
    253239                ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.",
    254                     ddf_fun_get_name(dev->aux->fun));
     240                    ddf_fun_get_name(dev->aux_fun));
    255241                goto error;
    256242        }
     
    331317error:
    332318        if (kbd_bound)
    333                 ddf_fun_unbind(dev->kbd->fun);
     319                ddf_fun_unbind(dev->kbd_fun);
    334320        if (aux_bound)
    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);
     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);
    340326
    341327        return rc;
     
    391377{
    392378        i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
    393         size_t p;
     379        i8042_t *i8042 = port->ctl;
    394380        uint8_t *destp = (uint8_t *)dest;
    395381        int rc;
    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]);
     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);
    405389                if (rc != EOK)
    406390                        break;
    407                 ++p;
    408         }
    409 
    410         fibril_mutex_unlock(&port->buf_lock);
    411 
    412         *nread = p;
     391                ++destp;
     392        }
     393       
     394        *nread = i;
    413395        return EOK;
    414396}
  • uspace/drv/char/i8042/i8042.h

    rac307b2 rf571ca49  
    22 * Copyright (c) 2006 Josef Cejka
    33 * Copyright (c) 2011 Jan Vesely
    4  * Copyright (c) 2017 Jiri Svoboda
    54 * All rights reserved.
    65 *
     
    4140#define i8042_H_
    4241
    43 #include <adt/circ_buf.h>
    4442#include <io/chardev_srv.h>
    4543#include <ddi.h>
    4644#include <fibril_synch.h>
    4745#include <ddf/driver.h>
     46#include "buffer.h"
    4847
    4948#define NAME  "i8042"
     
    6059/** i8042 Port. */
    6160typedef struct {
    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;
     61        struct i8042 *ctl;              /**< Controller */
     62        chardev_srvs_t cds;             /**< Character device server data */
    7663} i8042_port_t;
    7764
    7865/** i8042 Controller. */
    7966typedef struct i8042 {
    80         /**< I/O registers. */
    81         i8042_regs_t *regs;
    82         /** Keyboard port */
     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. */
    8374        i8042_port_t *kbd;
    84         /** AUX port */
    8575        i8042_port_t *aux;
    86         /** Prevents simultanous port writes.*/
    87         fibril_mutex_t write_guard;
     76        fibril_mutex_t write_guard;     /**< Prevents simultanous port writes.*/
    8877} i8042_t;
     78
    8979
    9080extern int i8042_init(i8042_t *, addr_range_t *, int, int, ddf_dev_t *);
  • uspace/drv/char/msim-con/msim-con.c

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

    rac307b2 rf571ca49  
    3636#define MSIM_CON_H
    3737
    38 #include <adt/circ_buf.h>
    3938#include <async.h>
    4039#include <ddf/driver.h>
    41 #include <fibril_synch.h>
    42 #include <io/chardev_srv.h>
    4340#include <loc.h>
    4441#include <stdint.h>
    45 
    46 enum {
    47         msim_con_buf_size = 64
    48 };
    4942
    5043/** MSIM console resources */
     
    5851        async_sess_t *client_sess;
    5952        ddf_dev_t *dev;
    60         chardev_srvs_t cds;
    6153        msim_con_res_t res;
    6254        irq_pio_range_t irq_range[1];
    6355        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;
    6856} msim_con_t;
    6957
  • uspace/drv/char/ns8250/ns8250.c

    rac307b2 rf571ca49  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2017 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    5353#include <ddf/interrupt.h>
    5454#include <ddf/log.h>
    55 #include <io/chardev_srv.h>
     55#include <ops/char_dev.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;
    157155        /** Parent session */
    158156        async_sess_t *parent_sess;
     
    191189}
    192190
    193 /** Obtain soft-state structure from chardev srv */
    194 static ns8250_t *srv_ns8250(chardev_srv_t *srv)
    195 {
    196         return (ns8250_t *)srv->srvs->sarg;
    197 }
    198 
    199 
    200191/** Find out if there is some incoming data available on the serial port.
    201192 *
     
    243234/** Read data from the serial port device.
    244235 *
    245  * @param srv           Server-side connection data
     236 * @param fun           The serial port function
    246237 * @param buf           The output buffer for read data.
    247238 * @param count         The number of bytes to be read.
    248  * @param nread         Place to store number of bytes actually read
    249  *
    250  * @return              EOK on success or non-zero error code
    251  */
    252 static 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         }
     239 *
     240 * @return              The number of bytes actually read on success, negative
     241 *                      error number otherwise.
     242 */
     243static 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;
    262249       
    263250        fibril_mutex_lock(&ns->mutex);
    264251        while (buf_is_empty(&ns->input_buffer))
    265252                fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
    266         while (!buf_is_empty(&ns->input_buffer) && pos < count) {
    267                 bp[pos] = (char)buf_pop_front(&ns->input_buffer);
    268                 pos++;
     253        while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) {
     254                buf[ret] = (char)buf_pop_front(&ns->input_buffer);
     255                ret++;
    269256        }
    270257        fibril_mutex_unlock(&ns->mutex);
    271258       
    272         *nread = pos;
    273         return EOK;
     259        return ret;
    274260}
    275261
     
    288274/** Write data to the serial port.
    289275 *
    290  * @param srv           Server-side connection data
     276 * @param fun           The serial port function
    291277 * @param buf           The data to be written
    292278 * @param count         The number of bytes to be written
    293  * @param nwritten      Place to store number of bytes successfully written
    294  * @return              EOK on success or non-zero error code
    295  */
    296 static 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);
     279 * @return              Zero on success
     280 */
     281static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count)
     282{
     283        ns8250_t *ns = fun_ns8250(fun);
    300284        size_t idx;
    301         uint8_t *bp = (uint8_t *) buf;
    302285       
    303286        for (idx = 0; idx < count; idx++)
    304                 ns8250_putchar(ns, bp[idx]);
    305        
    306         *nwritten = count;
    307         return EOK;
    308 }
    309 
    310 static int ns8250_open(chardev_srvs_t *, chardev_srv_t *);
    311 static int ns8250_close(chardev_srv_t *);
    312 static void ns8250_default_handler(chardev_srv_t *, ipc_callid_t, ipc_call_t *);
     287                ns8250_putchar(ns, (uint8_t) buf[idx]);
     288       
     289        return count;
     290}
     291
     292static ddf_dev_ops_t ns8250_dev_ops;
    313293
    314294/** The character interface's callbacks. */
    315 static 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
     295static char_dev_ops_t ns8250_char_dev_ops = {
     296        .read = &ns8250_read,
     297        .write = &ns8250_write
    321298};
    322 
    323 static void ns8250_char_conn(ipc_callid_t, ipc_call_t *, void *);
    324299
    325300static int ns8250_dev_add(ddf_dev_t *dev);
     
    897872        }
    898873       
    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        
     874        /* Set device operations. */
     875        ddf_fun_set_ops(fun, &ns8250_dev_ops);
    905876        rc = ddf_fun_bind(fun);
    906877        if (rc != EOK) {
     
    959930 * device.
    960931 *
    961  * @param srvs          Service structure
    962  * @param srv           Server-side connection structure
    963  */
    964 static int ns8250_open(chardev_srvs_t *srvs, chardev_srv_t *srv)
    965 {
    966         ns8250_t *ns = srv_ns8250(srv);
     932 * @param dev           The device.
     933 */
     934static int ns8250_open(ddf_fun_t *fun)
     935{
     936        ns8250_t *ns = fun_ns8250(fun);
    967937        int res;
    968938       
     
    984954 * the device.
    985955 *
    986  * @param srv           Server-side connection structure
    987  */
    988 static int ns8250_close(chardev_srv_t *srv)
    989 {
    990         ns8250_t *data = srv_ns8250(srv);
     956 * @param dev           The device.
     957 */
     958static void ns8250_close(ddf_fun_t *fun)
     959{
     960        ns8250_t *data = fun_ns8250(fun);
    991961       
    992962        fibril_mutex_lock(&data->mutex);
     
    998968       
    999969        fibril_mutex_unlock(&data->mutex);
    1000        
    1001         return EOK;
    1002970}
    1003971
     
    10661034 * Configure the parameters of the serial communication.
    10671035 */
    1068 static void ns8250_default_handler(chardev_srv_t *srv, ipc_callid_t callid,
     1036static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid,
    10691037    ipc_call_t *call)
    10701038{
    1071         ns8250_t *ns8250 = srv_ns8250(srv);
    10721039        sysarg_t method = IPC_GET_IMETHOD(*call);
    10731040        int ret;
     
    10761043        switch (method) {
    10771044        case SERIAL_GET_COM_PROPS:
    1078                 ns8250_get_props(ns8250->dev, &baud_rate, &parity, &word_length,
     1045                ns8250_get_props(ddf_fun_get_dev(fun), &baud_rate, &parity, &word_length,
    10791046                    &stop_bits);
    10801047                async_answer_4(callid, EOK, baud_rate, parity, word_length,
     
    10871054                word_length = IPC_GET_ARG3(*call);
    10881055                stop_bits = IPC_GET_ARG4(*call);
    1089                 ret = ns8250_set_props(ns8250->dev, baud_rate, parity, word_length,
     1056                ret = ns8250_set_props(ddf_fun_get_dev(fun), baud_rate, parity, word_length,
    10901057                    stop_bits);
    10911058                async_answer_0(callid, ret);
     
    10971064}
    10981065
    1099 void 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 
    11061066/** Initialize the serial port driver.
    11071067 *
     
    11121072{
    11131073        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;
    11141080}
    11151081
  • uspace/drv/char/ski-con/ski-con.c

    rac307b2 rf571ca49  
    11/*
    22 * Copyright (c) 2005 Jakub Jermar
    3  * Copyright (c) 2017 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3434#include <ddf/log.h>
    3535#include <errno.h>
    36 #include <fibril.h>
    37 #include <io/chardev.h>
     36#include <ipc/char.h>
    3837#include <stdint.h>
    3938#include <stdlib.h>
     39#include <thread.h>
    4040#include <stdbool.h>
    4141
     
    4646#define POLL_INTERVAL           10000
    4747
    48 static int ski_con_fibril(void *arg);
     48static void ski_con_thread_impl(void *arg);
    4949static int32_t ski_con_getchar(void);
    5050static void ski_con_connection(ipc_callid_t, ipc_call_t *, void *);
    5151
    52 static int ski_con_read(chardev_srv_t *, void *, size_t, size_t *);
    53 static int ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);
    54 
    55 static chardev_ops_t ski_con_chardev_ops = {
    56         .read = ski_con_read,
    57         .write = ski_con_write
    58 };
    59 
    6052/** Add ski console device. */
    6153int ski_con_add(ski_con_t *con)
    6254{
    63         fid_t fid;
     55        thread_id_t tid;
    6456        ddf_fun_t *fun = NULL;
    6557        bool bound = false;
    6658        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);
    7159
    7260        fun = ddf_fun_create(con->dev, fun_exposed, "a");
     
    7967        ddf_fun_set_conn_handler(fun, ski_con_connection);
    8068
    81         chardev_srvs_init(&con->cds);
    82         con->cds.ops = &ski_con_chardev_ops;
    83         con->cds.sarg = con;
    84 
    8569        rc = ddf_fun_bind(fun);
    8670        if (rc != EOK) {
     
    9175        bound = true;
    9276
    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);
     77        rc = thread_create(ski_con_thread_impl, con, "kbd_poll", &tid);
     78        if (rc != 0) {
     79                return rc;
     80        }
     81
    10182        return EOK;
    10283error:
     
    121102}
    122103
    123 /** Poll Ski for keypresses. */
    124 static int ski_con_fibril(void *arg)
     104/** Thread to poll Ski for keypresses. */
     105static void ski_con_thread_impl(void *arg)
    125106{
    126107        int32_t c;
    127108        ski_con_t *con = (ski_con_t *) arg;
    128         int rc;
    129109
    130110        while (1) {
     
    134114                                break;
    135115
    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);
     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                        }
    144121                }
    145122
    146                 fibril_usleep(POLL_INTERVAL);
    147         }
    148 
    149         return 0;
     123                thread_usleep(POLL_INTERVAL);
     124        }
    150125}
    151126
     
    182157}
    183158
    184 /** Read from Ski console device */
    185 static 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 */
    213 static 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 
    227159/** Character device connection handler. */
    228160static void ski_con_connection(ipc_callid_t iid, ipc_call_t *icall,
    229161    void *arg)
    230162{
    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);
     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        }
    235202}
    236203
  • uspace/drv/char/ski-con/ski-con.h

    rac307b2 rf571ca49  
    3636#define SKI_CON_H
    3737
    38 #include <adt/circ_buf.h>
    3938#include <async.h>
    4039#include <ddf/driver.h>
    41 #include <io/chardev_srv.h>
    4240#include <loc.h>
    4341#include <stdint.h>
    44 
    45 enum {
    46         ski_con_buf_size = 64
    47 };
    4842
    4943/** Ski console */
     
    5145        async_sess_t *client_sess;
    5246        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;
    5847} ski_con_t;
    5948
  • uspace/drv/char/sun4v-con/sun4v-con.c

    rac307b2 rf571ca49  
    11/*
    22 * Copyright (c) 2008 Pavel Rimsky
    3  * Copyright (c) 2017 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3636#include <ddi.h>
    3737#include <errno.h>
    38 #include <io/chardev_srv.h>
     38#include <ipc/char.h>
    3939#include <stdbool.h>
    4040#include <thread.h>
     
    6262static input_buffer_t input_buffer;
    6363
    64 static int sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *);
    65 static int sun4v_con_write(chardev_srv_t *, const void *, size_t, size_t *);
    66 
    67 static chardev_ops_t sun4v_con_chardev_ops = {
    68         .read = sun4v_con_read,
    69         .write = sun4v_con_write
    70 };
     64static void sun4v_thread_impl(void *arg);
    7165
    7266static void sun4v_con_putchar(sun4v_con_t *con, uint8_t data)
     
    9286        }
    9387
    94         chardev_srvs_init(&con->cds);
    95         con->cds.ops = &sun4v_con_chardev_ops;
    96         con->cds.sarg = con;
    97 
    9888        ddf_fun_set_conn_handler(fun, sun4v_con_connection);
    9989
     
    10595        }
    10696
     97        thread_id_t tid;
     98        rc = thread_create(sun4v_thread_impl, con, "kbd_poll", &tid);
     99        if (rc != EOK)
     100                goto error;
     101
    107102        rc = ddf_fun_bind(fun);
    108103        if (rc != EOK) {
     
    136131}
    137132
    138 /** Read from Sun4v console device */
    139 static int sun4v_con_read(chardev_srv_t *srv, void *buf, size_t size,
    140     size_t *nread)
    141 {
    142         size_t p;
    143         uint8_t *bp = (uint8_t *) buf;
     133/**
     134 * Called regularly by the polling thread. Reads codes of all the
     135 * pressed keys from the buffer.
     136 */
     137static void sun4v_key_pressed(sun4v_con_t *con)
     138{
    144139        char c;
    145140
    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) {
     141        while (input_buffer->read_ptr != input_buffer->write_ptr) {
    151142                c = input_buffer->data[input_buffer->read_ptr];
    152143                input_buffer->read_ptr =
    153144                    ((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE;
    154                 bp[p++] = c;
    155         }
    156 
    157         *nread = p;
    158         return EOK;
    159 }
    160 
    161 /** Write to Sun4v console device */
    162 static int sun4v_con_write(chardev_srv_t *srv, const void *data, size_t size,
    163     size_t *nwr)
    164 {
    165         sun4v_con_t *con = (sun4v_con_t *) srv->srvs->sarg;
    166         size_t i;
    167         uint8_t *dp = (uint8_t *) data;
    168 
    169         for (i = 0; i < size; i++)
    170                 sun4v_con_putchar(con, dp[i]);
    171 
    172         *nwr = size;
    173         return EOK;
     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;
     151        }
     152}
     153
     154/**
     155 * Thread to poll Sun4v console for keypresses.
     156 */
     157static void sun4v_thread_impl(void *arg)
     158{
     159        sun4v_con_t *con = (sun4v_con_t *) arg;
     160
     161        while (true) {
     162                sun4v_key_pressed(con);
     163                thread_usleep(POLL_INTERVAL);
     164        }
    174165}
    175166
     
    178169    void *arg)
    179170{
    180         sun4v_con_t *con = (sun4v_con_t *) ddf_dev_data_get(
    181             ddf_fun_get_dev((ddf_fun_t *) arg));
    182 
    183         chardev_conn(iid, icall, &con->cds);
     171        sun4v_con_t *con;
     172
     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        }
    184210}
    185211
  • uspace/drv/char/sun4v-con/sun4v-con.h

    rac307b2 rf571ca49  
    3838#include <async.h>
    3939#include <ddf/driver.h>
    40 #include <io/chardev_srv.h>
    4140#include <loc.h>
    4241#include <stdint.h>
     
    5150        async_sess_t *client_sess;
    5251        ddf_dev_t *dev;
    53         chardev_srvs_t cds;
    5452        sun4v_con_res_t res;
    5553} sun4v_con_t;
  • uspace/drv/root/virt/devices.def

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

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

    rac307b2 rf571ca49  
    177177        ddf_fun_add_to_category(fun_a, "virtual");
    178178
    179         if (str_cmp(dev_name, "test1") == 0) {
     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) {
    180183                (void) register_fun_verbose(dev,
    181184                    "cloning myself ;-)", "clone",
  • uspace/drv/test/test1/test1.h

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

    rac307b2 rf571ca49  
    143143        generic/getopt.c \
    144144        generic/adt/checksum.c \
    145         generic/adt/circ_buf.c \
    146145        generic/adt/list.c \
    147146        generic/adt/hash_table.c \
     
    182181
    183182TEST_SOURCES = \
    184         test/adt/circ_buf.c \
    185183        test/fibril/timer.c \
    186184        test/main.c \
  • uspace/lib/c/generic/io/chardev_srv.c

    rac307b2 rf571ca49  
    169169                        break;
    170170                default:
    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);
     171                        async_answer_0(callid, EINVAL);
    175172                }
    176173        }
  • uspace/lib/c/include/io/chardev_srv.h

    rac307b2 rf571ca49  
    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 *);
    6463};
    6564
  • uspace/lib/c/include/ipc/chardev.h

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

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

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

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

    rac307b2 rf571ca49  
    4242#include "remote_hw_res.h"
    4343#include "remote_pio_window.h"
     44#include "remote_char_dev.h"
    4445#include "remote_clock_dev.h"
    4546#include "remote_led_dev.h"
     
    6162                [HW_RES_DEV_IFACE] = &remote_hw_res_iface,
    6263                [PIO_WINDOW_DEV_IFACE] = &remote_pio_window_iface,
     64                [CHAR_DEV_IFACE] = &remote_char_dev_iface,
    6365                [NIC_DEV_IFACE] = &remote_nic_iface,
    6466                [IEEE80211_DEV_IFACE] = &remote_ieee80211_iface,
  • uspace/srv/hid/input/input.c

    rac307b2 rf571ca49  
    3737 */
    3838
     39#include <adt/list.h>
     40#include <stdbool.h>
     41#include <fibril_synch.h>
     42#include <ipc/services.h>
     43#include <ipc/input.h>
     44#include <config.h>
     45#include <stdio.h>
     46#include <stdlib.h>
     47#include <ns.h>
     48#include <async.h>
     49#include <errno.h>
    3950#include <adt/fifo.h>
    40 #include <adt/list.h>
    41 #include <async.h>
    42 #include <config.h>
    43 #include <errno.h>
    44 #include <fibril.h>
    45 #include <fibril_synch.h>
    46 #include <io/chardev.h>
    4751#include <io/console.h>
    4852#include <io/keycode.h>
    49 #include <ipc/services.h>
    50 #include <ipc/input.h>
    5153#include <loc.h>
    52 #include <ns.h>
    53 #include <stdbool.h>
    54 #include <stdio.h>
    55 #include <stdlib.h>
    5654#include <str_error.h>
    57 
    58 #include "input.h"
     55#include <char_dev_iface.h>
     56#include <fibril.h>
     57#include "layout.h"
    5958#include "kbd.h"
    6059#include "kbd_port.h"
    6160#include "kbd_ctl.h"
    62 #include "layout.h"
    6361#include "mouse.h"
    6462#include "mouse_proto.h"
    6563#include "serial.h"
     64#include "input.h"
    6665
    6766#define NUM_LAYOUTS  4
     
    537536        while (true) {
    538537                uint8_t data;
    539                 size_t nread;
    540 
    541                 chardev_read(sdev->chardev, &data, sizeof(data), &nread);
    542                 /* XXX Handle error */
     538
     539                char_dev_read(sdev->sess, &data, sizeof(data));
    543540                kbd_push_data(sdev->kdev, data);
    544541        }
     
    555552{
    556553        bool match = false;
    557         int rc;
    558554
    559555        serial_dev_t *sdev = serial_dev_new();
     
    563559        sdev->kdev->svc_id = service_id;
    564560       
    565         rc = loc_service_get_name(service_id, &sdev->kdev->svc_name);
     561        int rc = loc_service_get_name(service_id, &sdev->kdev->svc_name);
    566562        if (rc != EOK)
    567563                goto fail;
     
    586582                sdev->sess = loc_service_connect(service_id, INTERFACE_DDF,
    587583                    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                 }
    596584
    597585                fid_t fid = fibril_create(serial_consumer, sdev);
  • uspace/srv/hid/input/port/chardev.c

    rac307b2 rf571ca49  
    3535 */
    3636
     37#include <ipc/char.h>
    3738#include <async.h>
     39#include <loc.h>
    3840#include <errno.h>
    39 #include <fibril.h>
    40 #include <io/chardev.h>
    41 #include <loc.h>
    4241#include <stdio.h>
    4342#include "../input.h"
     
    4544#include "../kbd.h"
    4645
    47 static int kbd_port_fibril(void *);
     46static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    4847
    4948static int chardev_port_init(kbd_dev_t *);
    50 static void chardev_port_write(uint8_t);
     49static void chardev_port_write(uint8_t data);
    5150
    5251kbd_port_ops_t chardev_port = {
     
    5756static kbd_dev_t *kbd_dev;
    5857static async_sess_t *dev_sess;
    59 static chardev_t *chardev;
    6058
    6159/** List of devices to try connecting to. */
     
    7270{
    7371        service_id_t service_id;
     72        async_exch_t *exch;
    7473        unsigned int i;
    75         fid_t fid;
    7674        int rc;
    7775       
     
    9896        }
    9997       
    100         rc = chardev_open(dev_sess, &chardev);
    101         if (rc != EOK) {
    102                 printf("%s: Failed opening character device\n", NAME);
     98        exch = async_exchange_begin(dev_sess);
     99        if (exch == NULL) {
     100                printf("%s: Failed starting exchange with device\n", NAME);
    103101                async_hangup(dev_sess);
    104102                return ENOMEM;
    105103        }
    106104       
    107         fid = fibril_create(kbd_port_fibril, NULL);
    108         if (fid == 0) {
    109                 printf("%s: Failed creating fibril\n", NAME);
    110                 chardev_close(chardev);
     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);
    111113                async_hangup(dev_sess);
    112                 return ENOMEM;
     114                return -1;
    113115        }
    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         int rc;
    124         size_t nwr;
     123        async_exch_t *exch = async_exchange_begin(dev_sess);
     124        if (exch == NULL) {
     125                printf("%s: Failed starting exchange with device\n", NAME);
     126                return;
     127        }
    125128
    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);
    129                 return;
     129        async_msg_1(exch, CHAR_WRITE_BYTE, data);
     130        async_exchange_end(exch);
     131}
     132
     133static 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);
    130156        }
    131157}
    132158
    133 static 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 }
    151159
    152160/**
  • uspace/srv/hid/input/serial.h

    rac307b2 rf571ca49  
    3939
    4040#include <async.h>
    41 #include <io/chardev.h>
    4241#include "kbd.h"
    4342
     
    4645        link_t link;
    4746        async_sess_t *sess;
    48         chardev_t *chardev;
    4947} serial_dev_t;
    5048
  • uspace/srv/hid/isdv4_tablet/isdv4.c

    rac307b2 rf571ca49  
    2727 */
    2828
     29#include <char_dev_iface.h>
    2930#include <errno.h>
    30 #include <io/chardev.h>
    31 #include <mem.h>
    3231#include <stdbool.h>
    3332#include <stdint.h>
    3433#include <stdlib.h>
     34#include <mem.h>
    3535#include <thread.h>
    3636
     
    298298        bool reading = true;
    299299        while (reading) {
    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)
     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)
    306303                        return EIO;
    307                 state->buf_end += nread;
     304                state->buf_end += read;
    308305
    309306                size_t i = 0;
     
    360357        return EOK;
    361358}
    362 
    363 static 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;
     359static bool write_command(async_sess_t *sess, uint8_t command)
     360{
     361        return char_dev_write(sess, &command, 1) == 1;
    370362}
    371363
     
    373365    isdv4_event_fn event_fn)
    374366{
    375         chardev_t *chardev;
    376         int rc;
    377 
    378         rc = chardev_open(sess, &chardev);
    379         if (rc != EOK)
    380                 return rc;
    381 
    382367        memset(state, 0, sizeof(isdv4_state_t));
    383 
    384368        state->sess = sess;
    385         state->chardev = chardev;
    386 
    387369        state->buf = malloc(BUF_SIZE);
    388         if (state->buf == NULL) {
    389                 chardev_close(chardev);
     370        if (state->buf == NULL)
    390371                return ENOMEM;
    391         }
    392 
    393372        state->buf_size = BUF_SIZE;
    394373        state->emit_event_fn = event_fn;
     
    398377int isdv4_init_tablet(isdv4_state_t *state)
    399378{
    400         if (!write_command(state->chardev, CMD_STOP))
     379        if (!write_command(state->sess, CMD_STOP))
    401380                return EIO;
    402381
     
    404383
    405384        // FIXME: Read all possible garbage before sending commands
    406         if (!write_command(state->chardev, CMD_QUERY_STYLUS))
     385        if (!write_command(state->sess, CMD_QUERY_STYLUS))
    407386                return EIO;
    408387
     
    411390                return rc;
    412391
    413         if (!write_command(state->chardev, CMD_QUERY_TOUCH))
     392        if (!write_command(state->sess, CMD_QUERY_TOUCH))
    414393                return EIO;
    415394
     
    418397                return rc;
    419398
    420         if (!write_command(state->chardev, CMD_START))
     399        if (!write_command(state->sess, CMD_START))
    421400                return EIO;
    422401
  • uspace/srv/hid/isdv4_tablet/isdv4.h

    rac307b2 rf571ca49  
    3131
    3232#include <async.h>
    33 #include <io/chardev.h>
    3433
    3534typedef struct isdv4_event isdv4_event_t;
     
    5958        bool finger1_pressed; /* Reported as touch button 1 */
    6059
    61         /** Session with the serial device */
     60        /* Session to the serial device */
    6261        async_sess_t *sess;
    63         /** Character device */
    64         chardev_t *chardev;
    6562
    6663        /* Receive buffer state */
     
    6966        size_t buf_end;
    7067
    71         /** Callbacks */
     68        /* Callbacks */
    7269        isdv4_event_fn emit_event_fn;
    7370} isdv4_state_t;
  • uspace/srv/hid/output/port/chardev.c

    rac307b2 rf571ca49  
    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>
    3832#include <stddef.h>
    3933#include <stdint.h>
     34#include <char_dev_iface.h>
    4035#include <stdio.h>
    4136#include <stdlib.h>
     37#include <async.h>
     38#include <fibril_synch.h>
     39#include <loc.h>
     40#include <errno.h>
    4241#include <str.h>
     42#include <config.h>
    4343#include "../ctl/serial.h"
    4444#include "../output.h"
     
    4848
    4949static async_sess_t *sess;
    50 static chardev_t *chardev;
    5150static service_id_t serial_cat_id;
    5251
     
    5857{
    5958        uint8_t byte = (uint8_t) ch;
    60         size_t nwr;
    61         chardev_write(chardev, &byte, 1, &nwr);
    62         /* XXX Handle error */
     59        char_dev_write(sess, &byte, 1);
    6360}
    6461
    6562static void chardev_control_puts(const char *str)
    6663{
    67         size_t nwr;
    68         chardev_write(chardev, (void *) str, str_size(str), &nwr);
    69         /* XXX Handle error */
     64        char_dev_write(sess, (void *) str, str_size(str));
    7065}
    7166
     
    131126                return;
    132127        }
    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 
    141128        serial_init(chardev_putchar, chardev_control_puts);
    142129
  • uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c

    rac307b2 rf571ca49  
    2727 */
    2828
     29/** @addtogroup driver_serial
     30 * @{
     31 */
    2932/**
    3033 * @file
     
    3437 */
    3538
     39#include <ddi.h>
     40#include <loc.h>
     41#include <ipc/char.h>
    3642#include <async.h>
    37 #include <ddi.h>
    38 #include <errno.h>
    39 #include <inttypes.h>
    40 #include <io/chardev_srv.h>
    41 #include <loc.h>
    4243#include <stdio.h>
    4344#include <stdlib.h>
    4445#include <sysinfo.h>
     46#include <errno.h>
     47#include <inttypes.h>
    4548#include "s3c24xx_uart.h"
    4649
     
    6972static void s3c24xx_uart_sendb(s3c24xx_uart_t *, uint8_t);
    7073
    71 static int s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *);
    72 static int s3c24xx_uart_write(chardev_srv_t *, const void *, size_t, size_t *);
    73 
    74 static chardev_ops_t s3c24xx_uart_chardev_ops = {
    75         .read = s3c24xx_uart_read,
    76         .write = s3c24xx_uart_write
    77 };
    78 
    7974int main(int argc, char *argv[])
    8075{
    8176        printf("%s: S3C24xx on-chip UART driver\n", NAME);
    8277       
    83         async_set_fallback_port_handler(s3c24xx_uart_connection, uart);
     78        async_set_fallback_port_handler(s3c24xx_uart_connection, NULL);
    8479        int rc = loc_server_register(NAME);
    8580        if (rc != EOK) {
     
    116111    void *arg)
    117112{
    118         s3c24xx_uart_t *uart = (s3c24xx_uart_t *) arg;
    119 
    120         chardev_conn(iid, icall, &uart->cds);
    121 }
    122 
     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}
    123149
    124150static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call,
    125151    void *arg)
    126152{
    127         int rc;
    128 
    129153        (void) iid;
    130154        (void) call;
     
    135159                uint32_t status = pio_read_32(&uart->io->uerstat);
    136160
    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);
     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                }
    145166
    146167                if (status != 0)
     
    155176        sysarg_t inr;
    156177
    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 
    161178        if (sysinfo_get_value("s3c24xx_uart.address.physical",
    162179            &uart->paddr) != EOK)
     
    171188
    172189        uart->io = vaddr;
     190        uart->client_sess = NULL;
    173191
    174192        printf(NAME ": device at physical address %p, inr %" PRIun ".\n",
     
    185203            pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL);
    186204
    187         chardev_srvs_init(&uart->cds);
    188         uart->cds.ops = &s3c24xx_uart_chardev_ops;
    189         uart->cds.sarg = uart;
    190 
    191205        return EOK;
    192206}
     
    202216}
    203217
    204 static 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 
    231 static 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 
    246218/** @}
    247219 */
  • uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h

    rac307b2 rf571ca49  
    3838#define S3C24XX_UART_H_
    3939
    40 #include <adt/circ_buf.h>
     40#include <stdint.h>
    4141#include <async.h>
    42 #include <fibril_synch.h>
    43 #include <io/chardev_srv.h>
    44 #include <stdint.h>
    4542
    4643/** S3C24xx UART I/O */
     
    7976#define UFCON_FIFO_ENABLE               0x01
    8077
    81 enum {
    82         s3c24xx_uart_buf_size = 64
    83 };
    8478
    8579/** S3C24xx UART instance */
     
    9185        s3c24xx_uart_io_t *io;
    9286
    93         /** Character device service */
    94         chardev_srvs_t cds;
     87        /** Callback session to the client */
     88        async_sess_t *client_sess;
    9589
    9690        /** Service ID */
    9791        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;
    10792} s3c24xx_uart_t;
    10893
  • uspace/srv/net/slip/slip.c

    rac307b2 rf571ca49  
    4040#include <inet/addr.h>
    4141#include <inet/iplink_srv.h>
    42 #include <io/chardev.h>
     42#include <char_dev_iface.h>
    4343#include <io/log.h>
    4444#include <errno.h>
     
    9696}
    9797
    98 static void write_flush(chardev_t *chardev)
     98static void write_flush(async_sess_t *sess)
    9999{
    100100        size_t written = 0;
    101101
    102102        while (slip_send_pending > 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) {
     103                ssize_t size;
     104
     105                size = char_dev_write(sess, &slip_send_buf[written],
     106                    slip_send_pending);
     107                if (size < 0) {
    109108                        log_msg(LOG_DEFAULT, LVL_ERROR,
    110                             "chardev_write() returned %d", rc);
     109                            "char_dev_write() returned %d",
     110                            (int) size);
    111111                        slip_send_pending = 0;
    112112                        break;
    113113                }
    114                 written += nwr;
    115                 slip_send_pending -= nwr;
    116         }
    117 }
    118 
    119 static void write_buffered(chardev_t *chardev, uint8_t ch)
     114                written += size;
     115                slip_send_pending -= size;
     116        }
     117}
     118
     119static void write_buffered(async_sess_t *sess, uint8_t ch)
    120120{
    121121        if (slip_send_pending == sizeof(slip_send_buf))
    122                 write_flush(chardev);
     122                write_flush(sess);
    123123        slip_send_buf[slip_send_pending++] = ch;
    124124}
     
    128128        log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send()");
    129129       
    130         chardev_t *chardev = (chardev_t *) srv->arg;
     130        async_sess_t *sess = (async_sess_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(chardev, SLIP_END);
     138        write_buffered(sess, SLIP_END);
    139139       
    140140        for (size_t i = 0; i < sdu->size; i++) {
    141141                switch (data[i]) {
    142142                case SLIP_END:
    143                         write_buffered(chardev, SLIP_ESC);
    144                         write_buffered(chardev, SLIP_ESC_END);
     143                        write_buffered(sess, SLIP_ESC);
     144                        write_buffered(sess, SLIP_ESC_END);
    145145                        break;
    146146                case SLIP_ESC:
    147                         write_buffered(chardev, SLIP_ESC);
    148                         write_buffered(chardev, SLIP_ESC_ESC);
     147                        write_buffered(sess, SLIP_ESC);
     148                        write_buffered(sess, SLIP_ESC_ESC);
    149149                        break;
    150150                default:
    151                         write_buffered(chardev, data[i]);
     151                        write_buffered(sess, data[i]);
    152152                        break;
    153153                }
    154154        }
    155155       
    156         write_buffered(chardev, SLIP_END);
    157         write_flush(chardev);
     156        write_buffered(sess, SLIP_END);
     157        write_flush(sess);
    158158       
    159159        return EOK;
     
    203203}
    204204
    205 static uint8_t read_buffered(chardev_t *chardev)
     205static uint8_t read_buffered(async_sess_t *sess)
    206206{
    207207        while (slip_recv_pending == 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) {
     208                ssize_t size;
     209
     210                size = char_dev_read(sess, slip_recv_buf,
     211                    sizeof(slip_recv_buf));
     212                if (size < 0) {
    214213                        log_msg(LOG_DEFAULT, LVL_ERROR,
    215                             "char_dev_read() returned %d", rc);
     214                            "char_dev_read() returned %d", (int) size);
     215                        return SLIP_END;
    216216                }
    217 
    218                 if (nread == 0)
    219                         return SLIP_END;
    220 
    221                 slip_recv_pending = nread;
     217                slip_recv_pending = size;
    222218                slip_recv_read = 0;
    223219        }
     
    228224static int slip_recv_fibril(void *arg)
    229225{
    230         chardev_t *chardev = (chardev_t *) arg;
     226        async_sess_t *sess = (async_sess_t *) arg;
    231227        static uint8_t recv_final[SLIP_MTU];
    232228        iplink_recv_sdu_t sdu;
     
    238234        while (true) {
    239235                for (sdu.size = 0; sdu.size < sizeof(recv_final); /**/) {
    240                         ch = read_buffered(chardev);
     236                        ch = read_buffered(sess);
    241237                        switch (ch) {
    242238                        case SLIP_END:
     
    250246
    251247                        case SLIP_ESC:
    252                                 ch = read_buffered(chardev);
     248                                ch = read_buffered(sess);
    253249                                if (ch == SLIP_ESC_END) {
    254250                                        recv_final[sdu.size++] = SLIP_END;
    255251                                        break;
    256                                 } else if (ch == SLIP_ESC_ESC) {
     252                                } else if (ch ==  SLIP_ESC_ESC) {
    257253                                        recv_final[sdu.size++] = SLIP_ESC;
    258254                                        break;
     
    299295        async_sess_t *sess_in = NULL;
    300296        async_sess_t *sess_out = NULL;
    301         chardev_t *chardev_in = NULL;
    302         chardev_t *chardev_out = NULL;
    303297        fid_t fid;
    304298        int rc;
     
    342336                return ENOENT;
    343337        }
    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;
     338        slip_iplink.arg = sess_out;
    353339
    354340        sess_in = loc_service_connect(svcid, INTERFACE_DDF, 0);
     
    361347        }
    362348
    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 
    370349        rc = loc_service_register(linkstr, &linksid);
    371350        if (rc != EOK) {
     
    384363        }
    385364
    386         fid = fibril_create(slip_recv_fibril, chardev_in);
     365        fid = fibril_create(slip_recv_fibril, sess_in);
    387366        if (!fid) {
    388367                log_msg(LOG_DEFAULT, LVL_ERROR,
     
    396375
    397376fail:
    398         chardev_close(chardev_out);
    399377        if (sess_out)
    400378                async_hangup(sess_out);
    401         chardev_close(chardev_in);
    402379        if (sess_in)
    403380                async_hangup(sess_in);
Note: See TracChangeset for help on using the changeset viewer.