Ignore:
File:
1 edited

Legend:

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

    r33dbbd2 rebcb05a  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    5253#include <libarch/ddi.h>
    5354
    54 #include <driver.h>
    55 #include <char.h>
    56 #include <resource.h>
     55#include <ddf/driver.h>
     56#include <ddf/interrupt.h>
     57#include <ddf/log.h>
     58#include <ops/char_dev.h>
    5759
    5860#include <devman.h>
     
    6870#define MAX_BAUD_RATE 115200
    6971#define DLAB_MASK (1 << 7)
     72
     73/** Obtain soft-state structure from function node */
     74#define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data))
     75
     76/** Obtain soft-state structure from device node */
     77#define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data))
    7078
    7179/** The number of bits of one data unit send by the serial port. */
     
    8694
    8795/** The driver data for the serial port devices. */
    88 typedef struct ns8250_dev_data {
     96typedef struct ns8250 {
     97        /** DDF device node */
     98        ddf_dev_t *dev;
     99        /** DDF function node */
     100        ddf_fun_t *fun;
    89101        /** Is there any client conntected to the device? */
    90102        bool client_connected;
     
    99111        /** The fibril mutex for synchronizing the access to the device. */
    100112        fibril_mutex_t mutex;
    101 } ns8250_dev_data_t;
    102 
    103 /** Create driver data for a device.
    104  *
    105  * @return              The driver data.
    106  */
    107 static ns8250_dev_data_t *create_ns8250_dev_data(void)
    108 {
    109         ns8250_dev_data_t *data;
    110        
    111         data = (ns8250_dev_data_t *) malloc(sizeof(ns8250_dev_data_t));
    112         if (NULL != data) {
    113                 memset(data, 0, sizeof(ns8250_dev_data_t));
    114                 fibril_mutex_initialize(&data->mutex);
    115         }
    116         return data;
    117 }
    118 
    119 /** Delete driver data.
    120  *
    121  * @param data          The driver data structure.
    122  */
    123 static void delete_ns8250_dev_data(ns8250_dev_data_t *data)
    124 {
    125         if (data != NULL)
    126                 free(data);
     113} ns8250_t;
     114
     115/** Create per-device soft-state structure.
     116 *
     117 * @return      Pointer to soft-state structure.
     118 */
     119static ns8250_t *ns8250_new(void)
     120{
     121        ns8250_t *ns;
     122       
     123        ns = (ns8250_t *) calloc(1, sizeof(ns8250_t));
     124        if (ns == NULL)
     125                return NULL;
     126       
     127        fibril_mutex_initialize(&ns->mutex);
     128        return ns;
     129}
     130
     131/** Delete soft-state structure.
     132 *
     133 * @param ns    The driver data structure.
     134 */
     135static void ns8250_delete(ns8250_t *ns)
     136{
     137        assert(ns != NULL);
     138        free(ns);
    127139}
    128140
     
    172184/** Read data from the serial port device.
    173185 *
    174  * @param dev           The serial port device.
     186 * @param fun           The serial port function
    175187 * @param buf           The ouput buffer for read data.
    176188 * @param count         The number of bytes to be read.
     
    179191 *                      error number otherwise.
    180192 */
    181 static int ns8250_read(device_t *dev, char *buf, size_t count)
    182 {
     193static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count)
     194{
     195        ns8250_t *ns = NS8250(fun);
    183196        int ret = EOK;
    184         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    185        
    186         fibril_mutex_lock(&data->mutex);
    187         while (!buf_is_empty(&data->input_buffer) && (size_t)ret < count) {
    188                 buf[ret] = (char)buf_pop_front(&data->input_buffer);
     197       
     198        fibril_mutex_lock(&ns->mutex);
     199        while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) {
     200                buf[ret] = (char)buf_pop_front(&ns->input_buffer);
    189201                ret++;
    190202        }
    191         fibril_mutex_unlock(&data->mutex);
     203        fibril_mutex_unlock(&ns->mutex);
    192204       
    193205        return ret;
     
    196208/** Write a character to the serial port.
    197209 *
    198  * @param data          The serial port device's driver data.
    199  * @param c             The character to be written.
    200  */
    201 static inline void ns8250_putchar(ns8250_dev_data_t *data, uint8_t c)
    202 {
    203         fibril_mutex_lock(&data->mutex);
    204         ns8250_write_8(data->port, c);
    205         fibril_mutex_unlock(&data->mutex);
     210 * @param ns            Serial port device
     211 * @param c             The character to be written
     212 */
     213static inline void ns8250_putchar(ns8250_t *ns, uint8_t c)
     214{
     215        fibril_mutex_lock(&ns->mutex);
     216        ns8250_write_8(ns->port, c);
     217        fibril_mutex_unlock(&ns->mutex);
    206218}
    207219
    208220/** Write data to the serial port.
    209221 *
    210  * @param dev           The serial port device.
    211  * @param buf           The data to be written.
    212  * @param count         The number of bytes to be written.
    213  * @return              Zero on success.
    214  */
    215 static int ns8250_write(device_t *dev, char *buf, size_t count)
    216 {
    217         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     222 * @param fun           The serial port function
     223 * @param buf           The data to be written
     224 * @param count         The number of bytes to be written
     225 * @return              Zero on success
     226 */
     227static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count)
     228{
     229        ns8250_t *ns = NS8250(fun);
    218230        size_t idx;
    219231       
    220232        for (idx = 0; idx < count; idx++)
    221                 ns8250_putchar(data, (uint8_t) buf[idx]);
     233                ns8250_putchar(ns, (uint8_t) buf[idx]);
    222234       
    223235        return 0;
    224236}
    225237
    226 static device_ops_t ns8250_dev_ops;
     238static ddf_dev_ops_t ns8250_dev_ops;
    227239
    228240/** The character interface's callbacks. */
    229 static char_iface_t ns8250_char_iface = {
     241static char_dev_ops_t ns8250_char_dev_ops = {
    230242        .read = &ns8250_read,
    231243        .write = &ns8250_write
    232244};
    233245
    234 static int ns8250_add_device(device_t *dev);
     246static int ns8250_add_device(ddf_dev_t *dev);
    235247
    236248/** The serial port device driver's standard operations. */
     
    245257};
    246258
    247 /** Clean up the serial port device structure.
    248  *
    249  * @param dev           The device structure.
    250  */
    251 static void ns8250_dev_cleanup(device_t *dev)
    252 {
    253         if (dev->driver_data != NULL) {
    254                 delete_ns8250_dev_data((ns8250_dev_data_t*) dev->driver_data);
    255                 dev->driver_data = NULL;
    256         }
    257        
    258         if (dev->parent_phone > 0) {
    259                 ipc_hangup(dev->parent_phone);
    260                 dev->parent_phone = 0;
     259/** Clean up the serial port soft-state
     260 *
     261 * @param ns            Serial port device
     262 */
     263static void ns8250_dev_cleanup(ns8250_t *ns)
     264{
     265        if (ns->dev->parent_phone > 0) {
     266                async_hangup(ns->dev->parent_phone);
     267                ns->dev->parent_phone = 0;
    261268        }
    262269}
     
    264271/** Enable the i/o ports of the device.
    265272 *
    266  * @param dev           The serial port device.
    267  * @return              True on success, false otherwise.
    268  */
    269 static bool ns8250_pio_enable(device_t *dev)
    270 {
    271         printf(NAME ": ns8250_pio_enable %s\n", dev->name);
    272        
    273         ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;
     273 * @param ns            Serial port device
     274 * @return              True on success, false otherwise
     275 */
     276static bool ns8250_pio_enable(ns8250_t *ns)
     277{
     278        ddf_msg(LVL_DEBUG, "ns8250_pio_enable %s", ns->dev->name);
    274279       
    275280        /* Gain control over port's registers. */
    276         if (pio_enable((void *) data->io_addr, REG_COUNT,
    277             (void **) &data->port)) {
    278                 printf(NAME ": error - cannot gain the port %lx for device "
    279                     "%s.\n", data->io_addr, dev->name);
     281        if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT,
     282            (void **) &ns->port)) {
     283                ddf_msg(LVL_ERROR, "Cannot map the port %#" PRIx32
     284                    " for device %s.", ns->io_addr, ns->dev->name);
    280285                return false;
    281286        }
     
    286291/** Probe the serial port device for its presence.
    287292 *
    288  * @param dev           The serial port device.
    289  * @return              True if the device is present, false otherwise.
    290  */
    291 static bool ns8250_dev_probe(device_t *dev)
    292 {
    293         printf(NAME ": ns8250_dev_probe %s\n", dev->name);
    294        
    295         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    296         ioport8_t *port_addr = data->port;
     293 * @param ns            Serial port device
     294 * @return              True if the device is present, false otherwise
     295 */
     296static bool ns8250_dev_probe(ns8250_t *ns)
     297{
     298        ddf_msg(LVL_DEBUG, "ns8250_dev_probe %s", ns->dev->name);
     299       
     300        ioport8_t *port_addr = ns->port;
    297301        bool res = true;
    298302        uint8_t olddata;
     
    310314        pio_write_8(port_addr + 4, olddata);
    311315       
    312         if (!res)
    313                 printf(NAME ": device %s is not present.\n", dev->name);
     316        if (!res) {
     317                ddf_msg(LVL_DEBUG, "Device %s is not present.",
     318                    ns->dev->name);
     319        }
    314320       
    315321        return res;
     
    318324/** Initialize serial port device.
    319325 *
    320  * @param dev           The serial port device.
    321  * @return              Zero on success, negative error number otherwise.
    322  */
    323 static int ns8250_dev_initialize(device_t *dev)
    324 {
    325         printf(NAME ": ns8250_dev_initialize %s\n", dev->name);
     326 * @param ns            Serial port device
     327 * @return              Zero on success, negative error number otherwise
     328 */
     329static int ns8250_dev_initialize(ns8250_t *ns)
     330{
     331        ddf_msg(LVL_DEBUG, "ns8250_dev_initialize %s", ns->dev->name);
    326332       
    327333        int ret = EOK;
     
    330336        memset(&hw_resources, 0, sizeof(hw_resource_list_t));
    331337       
    332         /* Allocate driver data for the device. */
    333         ns8250_dev_data_t *data = create_ns8250_dev_data();
    334         if (data == NULL)
    335                 return ENOMEM;
    336         dev->driver_data = data;
    337        
    338338        /* Connect to the parent's driver. */
    339         dev->parent_phone = devman_parent_device_connect(dev->handle,
     339        ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle,
    340340            IPC_FLAG_BLOCKING);
    341         if (dev->parent_phone < 0) {
    342                 printf(NAME ": failed to connect to the parent driver of the "
    343                     "device %s.\n", dev->name);
    344                 ret = EPARTY;   /* FIXME: use another EC */
     341        if (ns->dev->parent_phone < 0) {
     342                ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
     343                    "device %s.", ns->dev->name);
     344                ret = ns->dev->parent_phone;
    345345                goto failed;
    346346        }
    347347       
    348348        /* Get hw resources. */
    349         if (!get_hw_resources(dev->parent_phone, &hw_resources)) {
    350                 printf(NAME ": failed to get hw resources for the device "
    351                     "%s.\n", dev->name);
    352                 ret = EPARTY;   /* FIXME: use another EC */
     349        ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources);
     350        if (ret != EOK) {
     351                ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
     352                    "%s.", ns->dev->name);
    353353                goto failed;
    354354        }
     
    363363                switch (res->type) {
    364364                case INTERRUPT:
    365                         data->irq = res->res.interrupt.irq;
     365                        ns->irq = res->res.interrupt.irq;
    366366                        irq = true;
    367                         printf(NAME ": the %s device was asigned irq = 0x%x.\n",
    368                             dev->name, data->irq);
     367                        ddf_msg(LVL_NOTE, "Device %s was asigned irq = 0x%x.",
     368                            ns->dev->name, ns->irq);
    369369                        break;
    370370                       
    371371                case IO_RANGE:
    372                         data->io_addr = res->res.io_range.address;
     372                        ns->io_addr = res->res.io_range.address;
    373373                        if (res->res.io_range.size < REG_COUNT) {
    374                                 printf(NAME ": i/o range assigned to the device "
    375                                     "%s is too small.\n", dev->name);
    376                                 ret = EPARTY;   /* FIXME: use another EC */
     374                                ddf_msg(LVL_ERROR, "I/O range assigned to "
     375                                    "device %s is too small.", ns->dev->name);
     376                                ret = ELIMIT;
    377377                                goto failed;
    378378                        }
    379379                        ioport = true;
    380                         printf(NAME ": the %s device was asigned i/o address = "
    381                             "0x%x.\n", dev->name, data->io_addr);
    382                         break;
     380                        ddf_msg(LVL_NOTE, "Device %s was asigned I/O address = "
     381                            "0x%x.", ns->dev->name, ns->io_addr);
     382                        break;
    383383                       
    384384                default:
     
    388388       
    389389        if (!irq || !ioport) {
    390                 printf(NAME ": missing hw resource(s) for the device %s.\n",
    391                     dev->name);
    392                 ret = EPARTY;   /* FIXME: use another EC */
     390                ddf_msg(LVL_ERROR, "Missing HW resource(s) for device %s.",
     391                    ns->dev->name);
     392                ret = ENOENT;
    393393                goto failed;
    394394        }
    395395       
    396         clean_hw_resource_list(&hw_resources);
     396        hw_res_clean_resource_list(&hw_resources);
    397397        return ret;
    398398       
    399399failed:
    400         ns8250_dev_cleanup(dev);
    401         clean_hw_resource_list(&hw_resources);
     400        ns8250_dev_cleanup(ns);
     401        hw_res_clean_resource_list(&hw_resources);
    402402        return ret;
    403403}
     
    405405/** Enable interrupts on the serial port device.
    406406 *
    407  * Interrupt when data is received.
     407 * Interrupt when data is received
    408408 *
    409409 * @param port          The base address of the serial port device's ports.
    410410 */
    411411static inline void ns8250_port_interrupts_enable(ioport8_t *port)
    412 {       
     412{
    413413        pio_write_8(port + 1, 0x1);     /* Interrupt when data received. */
    414414        pio_write_8(port + 4, 0xB);
     
    417417/** Disable interrupts on the serial port device.
    418418 *
    419  * @param port          The base address of the serial port device's ports.
     419 * @param port          The base address of the serial port device's ports
    420420 */
    421421static inline void ns8250_port_interrupts_disable(ioport8_t *port)
     
    426426/** Enable interrupts for the serial port device.
    427427 *
    428  * @param dev           The device.
    429  * @return              Zero on success, negative error number otherwise.
    430  */
    431 static int ns8250_interrupt_enable(device_t *dev)
    432 {
    433         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    434         int res;
    435        
    436         /* Enable interrupt globally. */
    437         res = interrupt_enable(data->irq);
    438         if (res != EOK)
    439                 return res;
    440        
     428 * @param ns            Serial port device
     429 * @return              Zero on success, negative error number otherwise
     430 */
     431static int ns8250_interrupt_enable(ns8250_t *ns)
     432{
    441433        /* Enable interrupt on the serial port. */
    442         ns8250_port_interrupts_enable(data->port);
     434        ns8250_port_interrupts_enable(ns->port);
    443435       
    444436        return EOK;
     
    481473       
    482474        if (baud_rate < 50 || MAX_BAUD_RATE % baud_rate != 0) {
    483                 printf(NAME ": error - somebody tried to set invalid baud rate "
    484                     "%d\n", baud_rate);
     475                ddf_msg(LVL_ERROR, "Invalid baud rate %d requested.",
     476                    baud_rate);
    485477                return EINVAL;
    486478        }
     
    625617 * Set the default parameters of the serial communication.
    626618 *
    627  * @param dev           The serial port device.
    628  */
    629 static void ns8250_initialize_port(device_t *dev)
    630 {
    631         ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;
    632         ioport8_t *port = data->port;
     619 * @param ns            Serial port device
     620 */
     621static void ns8250_initialize_port(ns8250_t *ns)
     622{
     623        ioport8_t *port = ns->port;
    633624       
    634625        /* Disable interrupts. */
     
    650641 * buffer.
    651642 *
    652  * @param dev           The serial port device.
    653  */
    654 static void ns8250_read_from_device(device_t *dev)
    655 {
    656         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    657         ioport8_t *port = data->port;
     643 * @param ns            Serial port device
     644 */
     645static void ns8250_read_from_device(ns8250_t *ns)
     646{
     647        ioport8_t *port = ns->port;
    658648        bool cont = true;
    659649       
    660650        while (cont) {
    661                 fibril_mutex_lock(&data->mutex);
     651                fibril_mutex_lock(&ns->mutex);
    662652               
    663653                cont = ns8250_received(port);
     
    665655                        uint8_t val = ns8250_read_8(port);
    666656                       
    667                         if (data->client_connected) {
    668                                 if (!buf_push_back(&data->input_buffer, val)) {
    669                                         printf(NAME ": buffer overflow on "
    670                                             "%s.\n", dev->name);
     657                        if (ns->client_connected) {
     658                                if (!buf_push_back(&ns->input_buffer, val)) {
     659                                        ddf_msg(LVL_WARN, "Buffer overflow on "
     660                                            "%s.", ns->dev->name);
    671661                                } else {
    672                                         printf(NAME ": the character %c saved "
    673                                             "to the buffer of %s.\n",
    674                                             val, dev->name);
     662                                        ddf_msg(LVL_DEBUG2, "Character %c saved "
     663                                            "to the buffer of %s.",
     664                                            val, ns->dev->name);
    675665                                }
    676666                        }
    677667                }
    678668               
    679                 fibril_mutex_unlock(&data->mutex);
     669                fibril_mutex_unlock(&ns->mutex);
    680670                fibril_yield();
    681671        }
     
    689679 * @param dev           The serial port device.
    690680 */
    691 static inline void ns8250_interrupt_handler(device_t *dev, ipc_callid_t iid,
     681static inline void ns8250_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid,
    692682    ipc_call_t *icall)
    693683{
    694         ns8250_read_from_device(dev);
     684        ns8250_read_from_device(NS8250_FROM_DEV(dev));
    695685}
    696686
    697687/** Register the interrupt handler for the device.
    698688 *
     689 * @param ns            Serial port device
     690 */
     691static inline int ns8250_register_interrupt_handler(ns8250_t *ns)
     692{
     693        return register_interrupt_handler(ns->dev, ns->irq,
     694            ns8250_interrupt_handler, NULL);
     695}
     696
     697/** Unregister the interrupt handler for the device.
     698 *
     699 * @param ns            Serial port device
     700 */
     701static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns)
     702{
     703        return unregister_interrupt_handler(ns->dev, ns->irq);
     704}
     705
     706/** The add_device callback method of the serial port driver.
     707 *
     708 * Probe and initialize the newly added device.
     709 *
    699710 * @param dev           The serial port device.
    700711 */
    701 static inline int ns8250_register_interrupt_handler(device_t *dev)
    702 {
    703         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    704        
    705         return register_interrupt_handler(dev, data->irq,
    706             ns8250_interrupt_handler, NULL);
    707 }
    708 
    709 /** Unregister the interrupt handler for the device.
    710  *
    711  * @param dev           The serial port device.
    712  */
    713 static inline int ns8250_unregister_interrupt_handler(device_t *dev)
    714 {
    715         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    716        
    717         return unregister_interrupt_handler(dev, data->irq);
    718 }
    719 
    720 /** The add_device callback method of the serial port driver.
    721  *
    722  * Probe and initialize the newly added device.
    723  *
    724  * @param dev           The serial port device.
    725  */
    726 static int ns8250_add_device(device_t *dev)
    727 {
    728         printf(NAME ": ns8250_add_device %s (handle = %d)\n",
    729             dev->name, dev->handle);
    730        
    731         int res = ns8250_dev_initialize(dev);
    732         if (res != EOK)
    733                 return res;
    734        
    735         if (!ns8250_pio_enable(dev)) {
    736                 ns8250_dev_cleanup(dev);
    737                 return EADDRNOTAVAIL;
     712static int ns8250_add_device(ddf_dev_t *dev)
     713{
     714        ns8250_t *ns = NULL;
     715        ddf_fun_t *fun = NULL;
     716        bool need_cleanup = false;
     717        int rc;
     718       
     719        ddf_msg(LVL_DEBUG, "ns8250_add_device %s (handle = %d)",
     720            dev->name, (int) dev->handle);
     721       
     722        /* Allocate soft-state for the device */
     723        ns = ns8250_new();
     724        if (ns == NULL) {
     725                rc = ENOMEM;
     726                goto fail;
     727        }
     728       
     729        ns->dev = dev;
     730        dev->driver_data = ns;
     731       
     732        rc = ns8250_dev_initialize(ns);
     733        if (rc != EOK)
     734                goto fail;
     735       
     736        need_cleanup = true;
     737       
     738        if (!ns8250_pio_enable(ns)) {
     739                rc = EADDRNOTAVAIL;
     740                goto fail;
    738741        }
    739742       
    740743        /* Find out whether the device is present. */
    741         if (!ns8250_dev_probe(dev)) {
    742                 ns8250_dev_cleanup(dev);
    743                 return ENOENT;
     744        if (!ns8250_dev_probe(ns)) {
     745                rc = ENOENT;
     746                goto fail;
    744747        }
    745748       
    746749        /* Serial port initialization (baud rate etc.). */
    747         ns8250_initialize_port(dev);
     750        ns8250_initialize_port(ns);
    748751       
    749752        /* Register interrupt handler. */
    750         if (ns8250_register_interrupt_handler(dev) != EOK) {
    751                 printf(NAME ": failed to register interrupt handler.\n");
    752                 ns8250_dev_cleanup(dev);
    753                 return res;
     753        if (ns8250_register_interrupt_handler(ns) != EOK) {
     754                ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
     755                rc = EADDRNOTAVAIL;
     756                goto fail;
    754757        }
    755758       
    756759        /* Enable interrupt. */
    757         res = ns8250_interrupt_enable(dev);
    758         if (res != EOK) {
    759                 printf(NAME ": failed to enable the interrupt. Error code = "
    760                     "%d.\n", res);
    761                 ns8250_dev_cleanup(dev);
    762                 ns8250_unregister_interrupt_handler(dev);
    763                 return res;
     760        rc = ns8250_interrupt_enable(ns);
     761        if (rc != EOK) {
     762                ddf_msg(LVL_ERROR, "Failed to enable the interrupt. Error code = "
     763                    "%d.", rc);
     764                goto fail;
     765        }
     766       
     767        fun = ddf_fun_create(dev, fun_exposed, "a");
     768        if (fun == NULL) {
     769                ddf_msg(LVL_ERROR, "Failed creating function.");
     770                goto fail;
    764771        }
    765772       
    766773        /* Set device operations. */
    767         dev->ops = &ns8250_dev_ops;
    768        
    769         add_device_to_class(dev, "serial");
    770        
    771         printf(NAME ": the %s device has been successfully initialized.\n",
     774        fun->ops = &ns8250_dev_ops;
     775        rc = ddf_fun_bind(fun);
     776        if (rc != EOK) {
     777                ddf_msg(LVL_ERROR, "Failed binding function.");
     778                goto fail;
     779        }
     780
     781        ns->fun = fun;
     782       
     783        ddf_fun_add_to_class(fun, "serial");
     784       
     785        ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
    772786            dev->name);
    773787       
    774788        return EOK;
     789fail:
     790        if (fun != NULL)
     791                ddf_fun_destroy(fun);
     792        if (need_cleanup)
     793                ns8250_dev_cleanup(ns);
     794        if (ns != NULL)
     795                ns8250_delete(ns);
     796        return rc;
    775797}
    776798
     
    782804 * @param dev           The device.
    783805 */
    784 static int ns8250_open(device_t *dev)
    785 {
    786         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     806static int ns8250_open(ddf_fun_t *fun)
     807{
     808        ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
    787809        int res;
    788810       
     
    795817        }
    796818        fibril_mutex_unlock(&data->mutex);
    797 
     819       
    798820        return res;
    799821}
     
    806828 * @param dev           The device.
    807829 */
    808 static void ns8250_close(device_t *dev)
    809 {
    810         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     830static void ns8250_close(ddf_fun_t *fun)
     831{
     832        ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
    811833       
    812834        fibril_mutex_lock(&data->mutex);
     
    830852 */
    831853static void
    832 ns8250_get_props(device_t *dev, unsigned int *baud_rate, unsigned int *parity,
     854ns8250_get_props(ddf_dev_t *dev, unsigned int *baud_rate, unsigned int *parity,
    833855    unsigned int *word_length, unsigned int* stop_bits)
    834856{
    835         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     857        ns8250_t *data = (ns8250_t *) dev->driver_data;
    836858        ioport8_t *port = data->port;
    837859       
     
    843865        fibril_mutex_unlock(&data->mutex);
    844866       
    845         printf(NAME ": ns8250_get_props: baud rate %d, parity 0x%x, word "
    846             "length %d, stop bits %d\n", *baud_rate, *parity, *word_length,
     867        ddf_msg(LVL_DEBUG, "ns8250_get_props: baud rate %d, parity 0x%x, word "
     868            "length %d, stop bits %d", *baud_rate, *parity, *word_length,
    847869            *stop_bits);
    848870}
     
    857879 * @param stop_bits     The number of stop bits to be used.
    858880 */
    859 static int ns8250_set_props(device_t *dev, unsigned int baud_rate,
     881static int ns8250_set_props(ddf_dev_t *dev, unsigned int baud_rate,
    860882    unsigned int parity, unsigned int word_length, unsigned int stop_bits)
    861883{
    862         printf(NAME ": ns8250_set_props: baud rate %d, parity 0x%x, word "
    863             "length %d, stop bits %d\n", baud_rate, parity, word_length,
     884        ddf_msg(LVL_DEBUG, "ns8250_set_props: baud rate %d, parity 0x%x, word "
     885            "length %d, stop bits %d", baud_rate, parity, word_length,
    864886            stop_bits);
    865887       
    866         ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
     888        ns8250_t *data = (ns8250_t *) dev->driver_data;
    867889        ioport8_t *port = data->port;
    868890        int ret;
     
    884906 * Configure the parameters of the serial communication.
    885907 */
    886 static void ns8250_default_handler(device_t *dev, ipc_callid_t callid,
     908static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid,
    887909    ipc_call_t *call)
    888910{
    889         ipcarg_t method = IPC_GET_METHOD(*call);
     911        sysarg_t method = IPC_GET_IMETHOD(*call);
    890912        int ret;
    891913        unsigned int baud_rate, parity, word_length, stop_bits;
     
    893915        switch (method) {
    894916        case SERIAL_GET_COM_PROPS:
    895                 ns8250_get_props(dev, &baud_rate, &parity, &word_length,
     917                ns8250_get_props(fun->dev, &baud_rate, &parity, &word_length,
    896918                    &stop_bits);
    897                 ipc_answer_4(callid, EOK, baud_rate, parity, word_length,
     919                async_answer_4(callid, EOK, baud_rate, parity, word_length,
    898920                    stop_bits);
    899921                break;
     
    904926                word_length = IPC_GET_ARG3(*call);
    905927                stop_bits = IPC_GET_ARG4(*call);
    906                 ret = ns8250_set_props(dev, baud_rate, parity, word_length,
     928                ret = ns8250_set_props(fun->dev, baud_rate, parity, word_length,
    907929                    stop_bits);
    908                 ipc_answer_0(callid, ret);
     930                async_answer_0(callid, ret);
    909931                break;
    910932               
    911933        default:
    912                 ipc_answer_0(callid, ENOTSUP);
     934                async_answer_0(callid, ENOTSUP);
    913935        }
    914936}
     
    921943static void ns8250_init(void)
    922944{
     945        ddf_log_init(NAME, LVL_ERROR);
     946       
    923947        ns8250_dev_ops.open = &ns8250_open;
    924948        ns8250_dev_ops.close = &ns8250_close;
    925949       
    926         ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_iface;
     950        ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_dev_ops;
    927951        ns8250_dev_ops.default_handler = &ns8250_default_handler;
    928952}
     
    932956        printf(NAME ": HelenOS serial port driver\n");
    933957        ns8250_init();
    934         return driver_main(&ns8250_driver);
     958        return ddf_driver_main(&ns8250_driver);
    935959}
    936960
Note: See TracChangeset for help on using the changeset viewer.