Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/driver.c

    r58563585 r8820544  
    4949#include <str_error.h>
    5050#include <ctype.h>
     51#include <errno.h>
    5152#include <inttypes.h>
    5253#include <devman.h>
     54
     55#include <ipc/driver.h>
    5356
    5457#include "dev_iface.h"
     
    120123        devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
    121124       
    122         char *dev_name = NULL;
    123         int rc = async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);
    124         if (rc != EOK) {
    125                 async_answer_0(iid, rc);
    126                 return;
    127         }
    128        
    129125        ddf_dev_t *dev = create_device();
    130         if (!dev) {
    131                 free(dev_name);
    132                 async_answer_0(iid, ENOMEM);
    133                 return;
    134         }
    135126       
    136127        /* Add one reference that will be dropped by driver_dev_remove() */
    137128        dev_add_ref(dev);
    138129        dev->handle = dev_handle;
     130       
     131        char *dev_name = NULL;
     132        async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);
    139133        dev->name = dev_name;
    140134       
     
    284278}
    285279
    286 static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall,
    287     void *arg)
     280static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall)
    288281{
    289282        /* Accept connection */
     
    335328        fibril_mutex_lock(&functions_mutex);
    336329        ddf_fun_t *fun = driver_get_function(handle);
    337         if (fun != NULL)
    338                 fun_add_ref(fun);
    339330        fibril_mutex_unlock(&functions_mutex);
     331        /* XXX Need a lock on fun */
    340332       
    341333        if (fun == NULL) {
     
    349341                /* Driver has a custom connection handler. */
    350342                (*fun->conn_handler)(iid, icall, (void *)fun);
    351                 fun_del_ref(fun);
    352343                return;
    353344        }
     
    364355       
    365356        async_answer_0(iid, ret);
    366         if (ret != EOK) {
    367                 fun_del_ref(fun);
     357        if (ret != EOK)
    368358                return;
    369         }
    370359       
    371360        while (true) {
     
    380369                                (*fun->ops->close)(fun);
    381370                        async_answer_0(callid, EOK);
    382                         fun_del_ref(fun);
    383371                        return;
    384372                }
     
    448436}
    449437
    450 static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall,
    451     void *arg)
     438static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
    452439{
    453440        driver_connection_gen(iid, icall, true);
    454441}
    455442
    456 static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall,
    457     void *arg)
     443static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall)
    458444{
    459445        driver_connection_gen(iid, icall, false);
     446}
     447
     448/** Function for handling connections to device driver. */
     449static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     450{
     451        sysarg_t conn_type;
     452
     453        if (iid == 0) {
     454                /* Callback connection from devman */
     455                /* XXX Use separate handler for this type of connection */
     456                conn_type = DRIVER_DEVMAN;
     457        } else {
     458                conn_type = IPC_GET_ARG1(*icall);
     459        }
     460
     461        /* Select interface */
     462        switch (conn_type) {
     463        case DRIVER_DEVMAN:
     464                /* Handle request from device manager */
     465                driver_connection_devman(iid, icall);
     466                break;
     467        case DRIVER_DRIVER:
     468                /* Handle request from drivers of child devices */
     469                driver_connection_driver(iid, icall);
     470                break;
     471        case DRIVER_CLIENT:
     472                /* Handle request from client applications */
     473                driver_connection_client(iid, icall);
     474                break;
     475        default:
     476                /* No such interface */
     477                async_answer_0(iid, ENOENT);
     478        }
    460479}
    461480
     
    503522        if (dev->driver_data != NULL)
    504523                free(dev->driver_data);
    505         if (dev->name)
    506                 free(dev->name);
    507524        free(dev);
    508525}
     
    603620 * The session will be automatically closed when @a dev is destroyed.
    604621 *
    605  * @param dev Device
    606  *
    607  * @return New session or NULL if session could not be created
    608  *
    609  */
    610 async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev)
     622 * @param dev   Device
     623 * @param mgmt  Exchange management style
     624 * @return      New session or NULL if session could not be created
     625 */
     626async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev, exch_mgmt_t mgmt)
    611627{
    612628        assert(dev->parent_sess == NULL);
    613         dev->parent_sess = devman_parent_device_connect(dev->handle,
     629        dev->parent_sess = devman_parent_device_connect(mgmt, dev->handle,
    614630            IPC_FLAG_BLOCKING);
    615631
     
    786802        assert(fun->bound == false);
    787803        assert(fun->name != NULL);
    788         assert(fun->dev != NULL);
    789804       
    790805        add_to_functions_list(fun);
     
    891906
    892907/** Set function ops. */
    893 void ddf_fun_set_ops(ddf_fun_t *fun, const ddf_dev_ops_t *dev_ops)
     908void ddf_fun_set_ops(ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)
    894909{
    895910        assert(fun->conn_handler == NULL);
     
    901916 * This allows handling connections the non-devman way.
    902917 */
    903 void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_port_handler_t conn)
     918void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_client_conn_t conn)
    904919{
    905920        assert(fun->ops == NULL);
     
    940955         * incoming connections.
    941956         */
    942         port_id_t port;
    943         int rc = async_create_port(INTERFACE_DDF_DRIVER, driver_connection_driver,
    944             NULL, &port);
    945         if (rc != EOK)
    946                 return rc;
    947        
    948         rc = async_create_port(INTERFACE_DDF_DEVMAN, driver_connection_devman,
    949             NULL, &port);
    950         if (rc != EOK)
    951                 return rc;
    952        
    953         async_set_fallback_port_handler(driver_connection_client, NULL);
    954        
    955         rc = devman_driver_register(driver->name);
     957        async_set_client_connection(driver_connection);
     958        int rc = devman_driver_register(driver->name);
    956959        if (rc != EOK) {
    957960                printf("Error: Failed to register driver with device manager "
    958                     "(%s).\n", (rc == EEXIST) ? "driver already started" :
     961                    "(%s).\n", (rc == EEXISTS) ? "driver already started" :
    959962                    str_error(rc));
    960963               
Note: See TracChangeset for help on using the changeset viewer.