Ignore:
File:
1 edited

Legend:

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

    rd51838f rdd8ab1c  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2011 Jiri Svoboda
     3 * Copyright (c) 2017 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    4040#include <stdio.h>
    4141#include <errno.h>
     42#include <str_error.h>
    4243#include <stdbool.h>
    4344#include <fibril_synch.h>
     
    4647#include <ctype.h>
    4748#include <macros.h>
    48 #include <malloc.h>
     49#include <stdlib.h>
    4950#include <dirent.h>
    5051#include <ddi.h>
     
    5354#include <ddf/interrupt.h>
    5455#include <ddf/log.h>
    55 #include <ops/char_dev.h>
     56#include <io/chardev_srv.h>
    5657
    5758#include <device/hw_res.h>
     
    153154        /** DDF function node */
    154155        ddf_fun_t *fun;
     156        /** Character device service */
     157        chardev_srvs_t cds;
    155158        /** Parent session */
    156159        async_sess_t *parent_sess;
     
    189192}
    190193
     194/** Obtain soft-state structure from chardev srv */
     195static ns8250_t *srv_ns8250(chardev_srv_t *srv)
     196{
     197        return (ns8250_t *)srv->srvs->sarg;
     198}
     199
     200
    191201/** Find out if there is some incoming data available on the serial port.
    192202 *
     
    234244/** Read data from the serial port device.
    235245 *
    236  * @param fun           The serial port function
     246 * @param srv           Server-side connection data
    237247 * @param buf           The output buffer for read data.
    238248 * @param count         The number of bytes to be read.
    239  *
    240  * @return              The number of bytes actually read on success, negative
    241  *                      error number otherwise.
    242  */
    243 static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count)
    244 {
    245         ns8250_t *ns = fun_ns8250(fun);
    246         int ret = 0;
    247        
    248         if (count == 0) return 0;
     249 * @param nread         Place to store number of bytes actually read
     250 *
     251 * @return              EOK on success or non-zero error code
     252 */
     253static 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        }
    249263       
    250264        fibril_mutex_lock(&ns->mutex);
    251265        while (buf_is_empty(&ns->input_buffer))
    252266                fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
    253         while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) {
    254                 buf[ret] = (char)buf_pop_front(&ns->input_buffer);
    255                 ret++;
     267        while (!buf_is_empty(&ns->input_buffer) && pos < count) {
     268                bp[pos] = (char)buf_pop_front(&ns->input_buffer);
     269                pos++;
    256270        }
    257271        fibril_mutex_unlock(&ns->mutex);
    258272       
    259         return ret;
     273        *nread = pos;
     274        return EOK;
    260275}
    261276
     
    274289/** Write data to the serial port.
    275290 *
    276  * @param fun           The serial port function
     291 * @param srv           Server-side connection data
    277292 * @param buf           The data to be written
    278293 * @param count         The number of bytes to be written
    279  * @return              Zero on success
    280  */
    281 static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count)
    282 {
    283         ns8250_t *ns = fun_ns8250(fun);
     294 * @param nwritten      Place to store number of bytes successfully written
     295 * @return              EOK on success or non-zero error code
     296 */
     297static 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);
    284301        size_t idx;
     302        uint8_t *bp = (uint8_t *) buf;
    285303       
    286304        for (idx = 0; idx < count; idx++)
    287                 ns8250_putchar(ns, (uint8_t) buf[idx]);
    288        
    289         return count;
    290 }
    291 
    292 static ddf_dev_ops_t ns8250_dev_ops;
     305                ns8250_putchar(ns, bp[idx]);
     306       
     307        *nwritten = count;
     308        return EOK;
     309}
     310
     311static int ns8250_open(chardev_srvs_t *, chardev_srv_t *);
     312static int ns8250_close(chardev_srv_t *);
     313static void ns8250_default_handler(chardev_srv_t *, ipc_callid_t, ipc_call_t *);
    293314
    294315/** The character interface's callbacks. */
    295 static char_dev_ops_t ns8250_char_dev_ops = {
    296         .read = &ns8250_read,
    297         .write = &ns8250_write
     316static 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
    298322};
     323
     324static void ns8250_char_conn(ipc_callid_t, ipc_call_t *, void *);
    299325
    300326static int ns8250_dev_add(ddf_dev_t *dev);
     
    758784 *
    759785 */
    760 static inline void ns8250_interrupt_handler(ipc_callid_t iid, ipc_call_t *icall,
    761     ddf_dev_t *dev)
     786static inline void ns8250_interrupt_handler(ipc_call_t *icall, ddf_dev_t *dev)
    762787{
    763788        ns8250_t *ns = dev_ns8250(dev);
     
    778803 * @param ns            Serial port device
    779804 */
    780 static inline int ns8250_register_interrupt_handler(ns8250_t *ns)
     805static inline int ns8250_register_interrupt_handler(ns8250_t *ns,
     806    cap_handle_t *handle)
    781807{
    782808        return register_interrupt_handler(ns->dev, ns->irq,
    783             ns8250_interrupt_handler, NULL);
     809            ns8250_interrupt_handler, NULL, handle);
    784810}
    785811
     
    850876       
    851877        /* Register interrupt handler. */
    852         ns->irq_cap = ns8250_register_interrupt_handler(ns);
    853         if (ns->irq_cap < 0) {
     878        rc = ns8250_register_interrupt_handler(ns, &ns->irq_cap);
     879        if (rc != EOK) {
    854880                ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
    855881                rc = EADDRNOTAVAIL;
     
    862888        if (rc != EOK) {
    863889                ddf_msg(LVL_ERROR, "Failed to enable the interrupt. Error code = "
    864                     "%d.", rc);
     890                    "%s.", str_error_name(rc));
    865891                goto fail;
    866892        }
     
    872898        }
    873899       
    874         /* Set device operations. */
    875         ddf_fun_set_ops(fun, &ns8250_dev_ops);
     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       
    876906        rc = ddf_fun_bind(fun);
    877907        if (rc != EOK) {
     
    930960 * device.
    931961 *
    932  * @param dev           The device.
    933  */
    934 static int ns8250_open(ddf_fun_t *fun)
    935 {
    936         ns8250_t *ns = fun_ns8250(fun);
     962 * @param srvs          Service structure
     963 * @param srv           Server-side connection structure
     964 */
     965static int ns8250_open(chardev_srvs_t *srvs, chardev_srv_t *srv)
     966{
     967        ns8250_t *ns = srv_ns8250(srv);
    937968        int res;
    938969       
     
    954985 * the device.
    955986 *
    956  * @param dev           The device.
    957  */
    958 static void ns8250_close(ddf_fun_t *fun)
    959 {
    960         ns8250_t *data = fun_ns8250(fun);
     987 * @param srv           Server-side connection structure
     988 */
     989static int ns8250_close(chardev_srv_t *srv)
     990{
     991        ns8250_t *data = srv_ns8250(srv);
    961992       
    962993        fibril_mutex_lock(&data->mutex);
     
    968999       
    9691000        fibril_mutex_unlock(&data->mutex);
     1001       
     1002        return EOK;
    9701003}
    9711004
     
    10341067 * Configure the parameters of the serial communication.
    10351068 */
    1036 static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid,
     1069static void ns8250_default_handler(chardev_srv_t *srv, ipc_callid_t callid,
    10371070    ipc_call_t *call)
    10381071{
     1072        ns8250_t *ns8250 = srv_ns8250(srv);
    10391073        sysarg_t method = IPC_GET_IMETHOD(*call);
    10401074        int ret;
     
    10431077        switch (method) {
    10441078        case SERIAL_GET_COM_PROPS:
    1045                 ns8250_get_props(ddf_fun_get_dev(fun), &baud_rate, &parity, &word_length,
     1079                ns8250_get_props(ns8250->dev, &baud_rate, &parity, &word_length,
    10461080                    &stop_bits);
    10471081                async_answer_4(callid, EOK, baud_rate, parity, word_length,
     
    10541088                word_length = IPC_GET_ARG3(*call);
    10551089                stop_bits = IPC_GET_ARG4(*call);
    1056                 ret = ns8250_set_props(ddf_fun_get_dev(fun), baud_rate, parity, word_length,
     1090                ret = ns8250_set_props(ns8250->dev, baud_rate, parity, word_length,
    10571091                    stop_bits);
    10581092                async_answer_0(callid, ret);
     
    10641098}
    10651099
     1100void 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
    10661107/** Initialize the serial port driver.
    10671108 *
     
    10721113{
    10731114        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;
    10801115}
    10811116
Note: See TracChangeset for help on using the changeset viewer.