Ignore:
File:
1 edited

Legend:

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

    r3e6a98c5 r58563585  
    3636/** @file
    3737 */
    38 
    39 #define _DDF_DATA_IMPLANT
    4038
    4139#include <assert.h>
     
    5149#include <str_error.h>
    5250#include <ctype.h>
    53 #include <errno.h>
    5451#include <inttypes.h>
    5552#include <devman.h>
    56 
    57 #include <ipc/driver.h>
    5853
    5954#include "dev_iface.h"
     
    6358
    6459/** Driver structure */
    65 static driver_t *driver;
     60static const driver_t *driver;
    6661
    6762/** Devices */
     
    9893static ddf_dev_t *driver_get_device(devman_handle_t handle)
    9994{
    100         ddf_dev_t *dev = NULL;
    101        
    10295        assert(fibril_mutex_is_locked(&devices_mutex));
    10396       
    104         list_foreach(devices, link) {
    105                 dev = list_get_instance(link, ddf_dev_t, link);
     97        list_foreach(devices, link, ddf_dev_t, dev) {
    10698                if (dev->handle == handle)
    10799                        return dev;
     
    113105static ddf_fun_t *driver_get_function(devman_handle_t handle)
    114106{
    115         ddf_fun_t *fun = NULL;
    116        
    117107        assert(fibril_mutex_is_locked(&functions_mutex));
    118108       
    119         list_foreach(functions, link) {
    120                 fun = list_get_instance(link, ddf_fun_t, link);
     109        list_foreach(functions, link, ddf_fun_t, fun) {
    121110                if (fun->handle == handle)
    122111                        return fun;
     
    131120        devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
    132121       
     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       
    133129        ddf_dev_t *dev = create_device();
     130        if (!dev) {
     131                free(dev_name);
     132                async_answer_0(iid, ENOMEM);
     133                return;
     134        }
    134135       
    135136        /* Add one reference that will be dropped by driver_dev_remove() */
    136137        dev_add_ref(dev);
    137138        dev->handle = dev_handle;
    138        
    139         char *dev_name = NULL;
    140         async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);
    141139        dev->name = dev_name;
    142140       
     
    286284}
    287285
    288 static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall)
     286static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall,
     287    void *arg)
    289288{
    290289        /* Accept connection */
     
    336335        fibril_mutex_lock(&functions_mutex);
    337336        ddf_fun_t *fun = driver_get_function(handle);
     337        if (fun != NULL)
     338                fun_add_ref(fun);
    338339        fibril_mutex_unlock(&functions_mutex);
    339         /* XXX Need a lock on fun */
    340340       
    341341        if (fun == NULL) {
     
    349349                /* Driver has a custom connection handler. */
    350350                (*fun->conn_handler)(iid, icall, (void *)fun);
     351                fun_del_ref(fun);
    351352                return;
    352353        }
     
    363364       
    364365        async_answer_0(iid, ret);
    365         if (ret != EOK)
     366        if (ret != EOK) {
     367                fun_del_ref(fun);
    366368                return;
     369        }
    367370       
    368371        while (true) {
     
    377380                                (*fun->ops->close)(fun);
    378381                        async_answer_0(callid, EOK);
     382                        fun_del_ref(fun);
    379383                        return;
    380384                }
     
    419423                 * handling ("remote interface").
    420424                 */
    421                 remote_iface_t *rem_iface = get_remote_iface(iface_idx);
     425                const remote_iface_t *rem_iface = get_remote_iface(iface_idx);
    422426                assert(rem_iface != NULL);
    423427               
     
    444448}
    445449
    446 static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
     450static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall,
     451    void *arg)
    447452{
    448453        driver_connection_gen(iid, icall, true);
    449454}
    450455
    451 static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall)
     456static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall,
     457    void *arg)
    452458{
    453459        driver_connection_gen(iid, icall, false);
    454 }
    455 
    456 /** Function for handling connections to device driver. */
    457 static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    458 {
    459         sysarg_t conn_type;
    460 
    461         if (iid == 0) {
    462                 /* Callback connection from devman */
    463                 /* XXX Use separate handler for this type of connection */
    464                 conn_type = DRIVER_DEVMAN;
    465         } else {
    466                 conn_type = IPC_GET_ARG1(*icall);
    467         }
    468 
    469         /* Select interface */
    470         switch (conn_type) {
    471         case DRIVER_DEVMAN:
    472                 /* Handle request from device manager */
    473                 driver_connection_devman(iid, icall);
    474                 break;
    475         case DRIVER_DRIVER:
    476                 /* Handle request from drivers of child devices */
    477                 driver_connection_driver(iid, icall);
    478                 break;
    479         case DRIVER_CLIENT:
    480                 /* Handle request from client applications */
    481                 driver_connection_client(iid, icall);
    482                 break;
    483         default:
    484                 /* No such interface */
    485                 async_answer_0(iid, ENOENT);
    486         }
    487460}
    488461
     
    530503        if (dev->driver_data != NULL)
    531504                free(dev->driver_data);
     505        if (dev->name)
     506                free(dev->name);
    532507        free(dev);
    533508}
     
    602577}
    603578
    604 /** Implant foreign driver-specific device data.
    605  *
    606  * XXX This is used to transition USB to new interface. Do not use
    607  * in new code. Use of this function must be removed.
    608  */
    609 void ddf_fun_data_implant(ddf_fun_t *fun, void *data)
    610 {
    611         assert(fun->driver_data == NULL);
    612         fun->driver_data = data;
    613 }
    614 
    615579/** Return driver-specific device data. */
    616580void *ddf_dev_data_get(ddf_dev_t *dev)
     
    639603 * The session will be automatically closed when @a dev is destroyed.
    640604 *
    641  * @param dev   Device
    642  * @param mgmt  Exchange management style
    643  * @return      New session or NULL if session could not be created
    644  */
    645 async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev, exch_mgmt_t mgmt)
     605 * @param dev Device
     606 *
     607 * @return New session or NULL if session could not be created
     608 *
     609 */
     610async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev)
    646611{
    647612        assert(dev->parent_sess == NULL);
    648         dev->parent_sess = devman_parent_device_connect(mgmt, dev->handle,
     613        dev->parent_sess = devman_parent_device_connect(dev->handle,
    649614            IPC_FLAG_BLOCKING);
    650615
     
    821786        assert(fun->bound == false);
    822787        assert(fun->name != NULL);
     788        assert(fun->dev != NULL);
    823789       
    824790        add_to_functions_list(fun);
     
    925891
    926892/** Set function ops. */
    927 void ddf_fun_set_ops(ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)
     893void ddf_fun_set_ops(ddf_fun_t *fun, const ddf_dev_ops_t *dev_ops)
    928894{
    929895        assert(fun->conn_handler == NULL);
     
    935901 * This allows handling connections the non-devman way.
    936902 */
    937 void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_client_conn_t conn)
     903void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_port_handler_t conn)
    938904{
    939905        assert(fun->ops == NULL);
     
    962928}
    963929
    964 int ddf_driver_main(driver_t *drv)
     930int ddf_driver_main(const driver_t *drv)
    965931{
    966932        /*
     
    970936        driver = drv;
    971937       
    972         /* Initialize interrupt module */
    973         interrupt_init();
    974        
    975938        /*
    976939         * Register driver with device manager using generic handler for
    977940         * incoming connections.
    978941         */
    979         async_set_client_connection(driver_connection);
    980         int rc = devman_driver_register(driver->name);
     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);
    981956        if (rc != EOK) {
    982957                printf("Error: Failed to register driver with device manager "
    983                     "(%s).\n", (rc == EEXISTS) ? "driver already started" :
     958                    "(%s).\n", (rc == EEXIST) ? "driver already started" :
    984959                    str_error(rc));
    985960               
Note: See TracChangeset for help on using the changeset viewer.