Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified uspace/drv/char/ns8250/ns8250.c

    rdd8ab1c rd51838f  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2017 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    4040#include <stdio.h>
    4141#include <errno.h>
    42 #include <str_error.h>
    4342#include <stdbool.h>
    4443#include <fibril_synch.h>
     
    4746#include <ctype.h>
    4847#include <macros.h>
    49 #include <stdlib.h>
     48#include <malloc.h>
    5049#include <dirent.h>
    5150#include <ddi.h>
     
    5453#include <ddf/interrupt.h>
    5554#include <ddf/log.h>
    56 #include <io/chardev_srv.h>
     55#include <ops/char_dev.h>
    5756
    5857#include <device/hw_res.h>
     
    154153        /** DDF function node */
    155154        ddf_fun_t *fun;
    156         /** Character device service */
    157         chardev_srvs_t cds;
    158155        /** Parent session */
    159156        async_sess_t *parent_sess;
     
    192189}
    193190
    194 /** Obtain soft-state structure from chardev srv */
    195 static ns8250_t *srv_ns8250(chardev_srv_t *srv)
    196 {
    197         return (ns8250_t *)srv->srvs->sarg;
    198 }
    199 
    200 
    201191/** Find out if there is some incoming data available on the serial port.
    202192 *
     
    244234/** Read data from the serial port device.
    245235 *
    246  * @param srv           Server-side connection data
     236 * @param fun           The serial port function
    247237 * @param buf           The output buffer for read data.
    248238 * @param count         The number of bytes to be read.
    249  * @param nread         Place to store number of bytes actually read
    250  *
    251  * @return              EOK on success or non-zero error code
    252  */
    253 static int ns8250_read(chardev_srv_t *srv, void *buf, size_t count, size_t *nread)
    254 {
    255         ns8250_t *ns = srv_ns8250(srv);
    256         char *bp = (char *) buf;
    257         size_t pos = 0;
    258        
    259         if (count == 0) {
    260                 *nread = 0;
    261                 return EOK;
    262         }
     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;
    263249       
    264250        fibril_mutex_lock(&ns->mutex);
    265251        while (buf_is_empty(&ns->input_buffer))
    266252                fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
    267         while (!buf_is_empty(&ns->input_buffer) && pos < count) {
    268                 bp[pos] = (char)buf_pop_front(&ns->input_buffer);
    269                 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++;
    270256        }
    271257        fibril_mutex_unlock(&ns->mutex);
    272258       
    273         *nread = pos;
    274         return EOK;
     259        return ret;
    275260}
    276261
     
    289274/** Write data to the serial port.
    290275 *
    291  * @param srv           Server-side connection data
     276 * @param fun           The serial port function
    292277 * @param buf           The data to be written
    293278 * @param count         The number of bytes to be written
    294  * @param nwritten      Place to store number of bytes successfully written
    295  * @return              EOK on success or non-zero error code
    296  */
    297 static int ns8250_write(chardev_srv_t *srv, const void *buf, size_t count,
    298     size_t *nwritten)
    299 {
    300         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);
    301284        size_t idx;
    302         uint8_t *bp = (uint8_t *) buf;
    303285       
    304286        for (idx = 0; idx < count; idx++)
    305                 ns8250_putchar(ns, bp[idx]);
    306        
    307         *nwritten = count;
    308         return EOK;
    309 }
    310 
    311 static int ns8250_open(chardev_srvs_t *, chardev_srv_t *);
    312 static int ns8250_close(chardev_srv_t *);
    313 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;
    314293
    315294/** The character interface's callbacks. */
    316 static chardev_ops_t ns8250_chardev_ops = {
    317         .open = ns8250_open,
    318         .close = ns8250_close,
    319         .read = ns8250_read,
    320         .write = ns8250_write,
    321         .def_handler = ns8250_default_handler
     295static char_dev_ops_t ns8250_char_dev_ops = {
     296        .read = &ns8250_read,
     297        .write = &ns8250_write
    322298};
    323 
    324 static void ns8250_char_conn(ipc_callid_t, ipc_call_t *, void *);
    325299
    326300static int ns8250_dev_add(ddf_dev_t *dev);
     
    784758 *
    785759 */
    786 static inline void ns8250_interrupt_handler(ipc_call_t *icall, ddf_dev_t *dev)
     760static inline void ns8250_interrupt_handler(ipc_callid_t iid, ipc_call_t *icall,
     761    ddf_dev_t *dev)
    787762{
    788763        ns8250_t *ns = dev_ns8250(dev);
     
    803778 * @param ns            Serial port device
    804779 */
    805 static inline int ns8250_register_interrupt_handler(ns8250_t *ns,
    806     cap_handle_t *handle)
     780static inline int ns8250_register_interrupt_handler(ns8250_t *ns)
    807781{
    808782        return register_interrupt_handler(ns->dev, ns->irq,
    809             ns8250_interrupt_handler, NULL, handle);
     783            ns8250_interrupt_handler, NULL);
    810784}
    811785
     
    876850       
    877851        /* Register interrupt handler. */
    878         rc = ns8250_register_interrupt_handler(ns, &ns->irq_cap);
    879         if (rc != EOK) {
     852        ns->irq_cap = ns8250_register_interrupt_handler(ns);
     853        if (ns->irq_cap < 0) {
    880854                ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
    881855                rc = EADDRNOTAVAIL;
     
    888862        if (rc != EOK) {
    889863                ddf_msg(LVL_ERROR, "Failed to enable the interrupt. Error code = "
    890                     "%s.", str_error_name(rc));
     864                    "%d.", rc);
    891865                goto fail;
    892866        }
     
    898872        }
    899873       
    900         ddf_fun_set_conn_handler(fun, ns8250_char_conn);
    901        
    902         chardev_srvs_init(&ns->cds);
    903         ns->cds.ops = &ns8250_chardev_ops;
    904         ns->cds.sarg = ns;
    905        
     874        /* Set device operations. */
     875        ddf_fun_set_ops(fun, &ns8250_dev_ops);
    906876        rc = ddf_fun_bind(fun);
    907877        if (rc != EOK) {
     
    960930 * device.
    961931 *
    962  * @param srvs          Service structure
    963  * @param srv           Server-side connection structure
    964  */
    965 static int ns8250_open(chardev_srvs_t *srvs, chardev_srv_t *srv)
    966 {
    967         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);
    968937        int res;
    969938       
     
    985954 * the device.
    986955 *
    987  * @param srv           Server-side connection structure
    988  */
    989 static int ns8250_close(chardev_srv_t *srv)
    990 {
    991         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);
    992961       
    993962        fibril_mutex_lock(&data->mutex);
     
    999968       
    1000969        fibril_mutex_unlock(&data->mutex);
    1001        
    1002         return EOK;
    1003970}
    1004971
     
    10671034 * Configure the parameters of the serial communication.
    10681035 */
    1069 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,
    10701037    ipc_call_t *call)
    10711038{
    1072         ns8250_t *ns8250 = srv_ns8250(srv);
    10731039        sysarg_t method = IPC_GET_IMETHOD(*call);
    10741040        int ret;
     
    10771043        switch (method) {
    10781044        case SERIAL_GET_COM_PROPS:
    1079                 ns8250_get_props(ns8250->dev, &baud_rate, &parity, &word_length,
     1045                ns8250_get_props(ddf_fun_get_dev(fun), &baud_rate, &parity, &word_length,
    10801046                    &stop_bits);
    10811047                async_answer_4(callid, EOK, baud_rate, parity, word_length,
     
    10881054                word_length = IPC_GET_ARG3(*call);
    10891055                stop_bits = IPC_GET_ARG4(*call);
    1090                 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,
    10911057                    stop_bits);
    10921058                async_answer_0(callid, ret);
     
    10981064}
    10991065
    1100 void ns8250_char_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    1101 {
    1102         ns8250_t *ns8250 = fun_ns8250((ddf_fun_t *)arg);
    1103 
    1104         chardev_conn(iid, icall, &ns8250->cds);
    1105 }
    1106 
    11071066/** Initialize the serial port driver.
    11081067 *
     
    11131072{
    11141073        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;
    11151080}
    11161081
Note: See TracChangeset for help on using the changeset viewer.