Ignore:
File:
1 edited

Legend:

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

    r128c78b r1dc4a5e  
    5959
    6060#include <devman.h>
    61 #include <ns.h>
    6261#include <ipc/devman.h>
    63 #include <ipc/services.h>
    64 #include <ipc/irc.h>
    6562#include <device/hw_res.h>
    6663#include <ipc/serial_ctl.h>
     
    114111        /** The fibril mutex for synchronizing the access to the device. */
    115112        fibril_mutex_t mutex;
    116         /** True if device is removed. */
    117         bool removed;
    118113} 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);
     139}
    119140
    120141/** Find out if there is some incomming data available on the serial port.
     
    224245
    225246static int ns8250_add_device(ddf_dev_t *dev);
    226 static int ns8250_dev_remove(ddf_dev_t *dev);
    227247
    228248/** The serial port device driver's standard operations. */
    229249static driver_ops_t ns8250_ops = {
    230         .add_device = &ns8250_add_device,
    231         .dev_remove = &ns8250_dev_remove
     250        .add_device = &ns8250_add_device
    232251};
    233252
     
    412431static int ns8250_interrupt_enable(ns8250_t *ns)
    413432{
    414         /*
    415          * Enable interrupt using IRC service.
    416          * TODO: This is a temporary solution until the device framework
    417          * takes care of this itself.
    418          */
    419         async_sess_t *irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
    420             SERVICE_IRC, 0, 0);
    421         if (!irc_sess) {
    422                 return EIO;
    423         }
    424 
    425         async_exch_t *exch = async_exchange_begin(irc_sess);
    426         if (!exch) {
    427                 return EIO;
    428         }
    429         async_msg_1(exch, IRC_ENABLE_INTERRUPT, ns->irq);
    430         async_exchange_end(exch);
    431 
    432433        /* Enable interrupt on the serial port. */
    433434        ns8250_port_interrupts_enable(ns->port);
     
    635636         */
    636637        pio_write_8(port + 4, 0x0B);
    637 }
    638 
    639 /** Deinitialize the serial port device.
    640  *
    641  * @param ns            Serial port device
    642  */
    643 static void ns8250_port_cleanup(ns8250_t *ns)
    644 {
    645         /* Disable FIFO */
    646         pio_write_8(ns->port + 2, 0x00);
    647         /* Disable DTR, RTS, OUT1, OUT2 (int. enable) */
    648         pio_write_8(ns->port + 4, 0x00);
    649         /* Disable all interrupts from the port */
    650         ns8250_port_interrupts_disable(ns->port);
    651638}
    652639
     
    734721       
    735722        /* Allocate soft-state for the device */
    736         ns = ddf_dev_data_alloc(dev, sizeof(ns8250_t));
     723        ns = ns8250_new();
    737724        if (ns == NULL) {
    738725                rc = ENOMEM;
     
    740727        }
    741728       
    742         fibril_mutex_initialize(&ns->mutex);
    743729        ns->dev = dev;
     730        dev->driver_data = ns;
    744731       
    745732        rc = ns8250_dev_initialize(ns);
     
    805792        if (need_cleanup)
    806793                ns8250_dev_cleanup(ns);
     794        if (ns != NULL)
     795                ns8250_delete(ns);
    807796        return rc;
    808 }
    809 
    810 static int ns8250_dev_remove(ddf_dev_t *dev)
    811 {
    812         ns8250_t *ns = NS8250_FROM_DEV(dev);
    813         int rc;
    814        
    815         fibril_mutex_lock(&ns->mutex);
    816         if (ns->client_connected) {
    817                 fibril_mutex_unlock(&ns->mutex);
    818                 return EBUSY;
    819         }
    820         ns->removed = true;
    821         fibril_mutex_unlock(&ns->mutex);
    822        
    823         rc = ddf_fun_unbind(ns->fun);
    824         if (rc != EOK) {
    825                 ddf_msg(LVL_ERROR, "Failed to unbind function.");
    826                 return rc;
    827         }
    828        
    829         ddf_fun_destroy(ns->fun);
    830        
    831         ns8250_port_cleanup(ns);
    832         ns8250_unregister_interrupt_handler(ns);
    833         ns8250_dev_cleanup(ns);
    834         return EOK;
    835797}
    836798
     
    844806static int ns8250_open(ddf_fun_t *fun)
    845807{
    846         ns8250_t *ns = NS8250(fun);
     808        ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
    847809        int res;
    848810       
    849         fibril_mutex_lock(&ns->mutex);
    850         if (ns->client_connected) {
     811        fibril_mutex_lock(&data->mutex);
     812        if (data->client_connected) {
    851813                res = ELIMIT;
    852         } else if (ns->removed) {
    853                 res = ENXIO;
    854814        } else {
    855815                res = EOK;
    856                 ns->client_connected = true;
    857         }
    858         fibril_mutex_unlock(&ns->mutex);
     816                data->client_connected = true;
     817        }
     818        fibril_mutex_unlock(&data->mutex);
    859819       
    860820        return res;
Note: See TracChangeset for help on using the changeset viewer.