Ignore:
File:
1 edited

Legend:

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

    r8820544 rb454a22  
    4949#include <str_error.h>
    5050#include <ctype.h>
    51 #include <errno.h>
    5251#include <inttypes.h>
    5352#include <devman.h>
    54 
    55 #include <ipc/driver.h>
    5653
    5754#include "dev_iface.h"
     
    123120        devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
    124121       
     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
    125129        ddf_dev_t *dev = create_device();
    126        
     130        if (!dev) {
     131                free(dev_name);
     132                async_answer_0(iid, ENOMEM);
     133                return;
     134        }
     135
    127136        /* Add one reference that will be dropped by driver_dev_remove() */
    128137        dev_add_ref(dev);
    129138        dev->handle = dev_handle;
    130        
    131         char *dev_name = NULL;
    132         async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);
    133139        dev->name = dev_name;
    134140       
     
    278284}
    279285
    280 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)
    281288{
    282289        /* Accept connection */
     
    328335        fibril_mutex_lock(&functions_mutex);
    329336        ddf_fun_t *fun = driver_get_function(handle);
     337        if (fun != NULL)
     338                fun_add_ref(fun);
    330339        fibril_mutex_unlock(&functions_mutex);
    331         /* XXX Need a lock on fun */
    332340       
    333341        if (fun == NULL) {
     
    341349                /* Driver has a custom connection handler. */
    342350                (*fun->conn_handler)(iid, icall, (void *)fun);
     351                fun_del_ref(fun);
    343352                return;
    344353        }
     
    355364       
    356365        async_answer_0(iid, ret);
    357         if (ret != EOK)
     366        if (ret != EOK) {
     367                fun_del_ref(fun);
    358368                return;
     369        }
    359370       
    360371        while (true) {
     
    369380                                (*fun->ops->close)(fun);
    370381                        async_answer_0(callid, EOK);
     382                        fun_del_ref(fun);
    371383                        return;
    372384                }
     
    436448}
    437449
    438 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)
    439452{
    440453        driver_connection_gen(iid, icall, true);
    441454}
    442455
    443 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)
    444458{
    445459        driver_connection_gen(iid, icall, false);
    446 }
    447 
    448 /** Function for handling connections to device driver. */
    449 static 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         }
    479460}
    480461
     
    522503        if (dev->driver_data != NULL)
    523504                free(dev->driver_data);
     505        if (dev->name)
     506                free(dev->name);
    524507        free(dev);
    525508}
     
    620603 * The session will be automatically closed when @a dev is destroyed.
    621604 *
    622  * @param dev   Device
    623  * @param mgmt  Exchange management style
    624  * @return      New session or NULL if session could not be created
    625  */
    626 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)
    627611{
    628612        assert(dev->parent_sess == NULL);
    629         dev->parent_sess = devman_parent_device_connect(mgmt, dev->handle,
     613        dev->parent_sess = devman_parent_device_connect(dev->handle,
    630614            IPC_FLAG_BLOCKING);
    631615
     
    916900 * This allows handling connections the non-devman way.
    917901 */
    918 void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_client_conn_t conn)
     902void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_port_handler_t conn)
    919903{
    920904        assert(fun->ops == NULL);
     
    955939         * incoming connections.
    956940         */
    957         async_set_client_connection(driver_connection);
    958         int rc = devman_driver_register(driver->name);
     941        port_id_t port;
     942        int rc = async_create_port(INTERFACE_DDF_DRIVER, driver_connection_driver,
     943            NULL, &port);
     944        if (rc != EOK)
     945                return rc;
     946       
     947        rc = async_create_port(INTERFACE_DDF_DEVMAN, driver_connection_devman,
     948            NULL, &port);
     949        if (rc != EOK)
     950                return rc;
     951       
     952        async_set_fallback_port_handler(driver_connection_client, NULL);
     953       
     954        rc = devman_driver_register(driver->name);
    959955        if (rc != EOK) {
    960956                printf("Error: Failed to register driver with device manager "
    961                     "(%s).\n", (rc == EEXISTS) ? "driver already started" :
     957                    "(%s).\n", (rc == EEXIST) ? "driver already started" :
    962958                    str_error(rc));
    963959               
Note: See TracChangeset for help on using the changeset viewer.