Changeset ff381a7 in mainline for uspace/srv/devman/main.c


Ignore:
Timestamp:
2015-11-02T20:54:19Z (8 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d8513177
Parents:
3feeab2 (diff), 5265eea4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/main.c

    r3feeab2 rff381a7  
    4949#include <io/log.h>
    5050#include <ipc/devman.h>
    51 #include <ipc/driver.h>
    5251#include <loc.h>
    5352
     
    6665dev_tree_t device_tree;
    6766
    68 static void devman_forward(ipc_callid_t iid, ipc_call_t *icall,
    69     bool drv_to_parent)
     67static void devman_connection_device(ipc_callid_t iid, ipc_call_t *icall,
     68    void *arg)
    7069{
    7170        devman_handle_t handle = IPC_GET_ARG2(*icall);
    72         devman_handle_t fwd_h;
    73         fun_node_t *fun = NULL;
    7471        dev_node_t *dev = NULL;
    7572       
    76         fun = find_fun_node(&device_tree, handle);
    77         if (fun == NULL)
     73        fun_node_t *fun = find_fun_node(&device_tree, handle);
     74        if (fun == NULL) {
    7875                dev = find_dev_node(&device_tree, handle);
    79         else {
     76        } else {
    8077                fibril_rwlock_read_lock(&device_tree.rwlock);
     78               
    8179                dev = fun->dev;
    8280                if (dev != NULL)
    8381                        dev_add_ref(dev);
     82               
    8483                fibril_rwlock_read_unlock(&device_tree.rwlock);
    8584        }
    86 
     85       
    8786        /*
    8887         * For a valid function to connect to we need a device. The root
     
    9796                goto cleanup;
    9897        }
    99 
    100         if (fun == NULL && !drv_to_parent) {
     98       
     99        if (fun == NULL) {
    101100                log_msg(LOG_DEFAULT, LVL_ERROR, NAME ": devman_forward error - cannot "
    102101                    "connect to handle %" PRIun ", refers to a device.",
     
    106105        }
    107106       
    108         driver_t *driver = NULL;
    109        
    110107        fibril_rwlock_read_lock(&device_tree.rwlock);
    111108       
    112         if (drv_to_parent) {
    113                 /* Connect to parent function of a device (or device function). */
    114                 if (dev->pfun->dev != NULL)
    115                         driver = dev->pfun->dev->drv;
    116                
    117                 fwd_h = dev->pfun->handle;
    118         } else {
    119                 /* Connect to the specified function */
    120                 driver = dev->drv;
    121                 fwd_h = handle;
    122         }
     109        /* Connect to the specified function */
     110        driver_t *driver = dev->drv;
    123111       
    124112        fibril_rwlock_read_unlock(&device_tree.rwlock);
     
    130118                goto cleanup;
    131119        }
    132        
    133         int method;
    134         if (drv_to_parent)
    135                 method = DRIVER_DRIVER;
    136         else
    137                 method = DRIVER_CLIENT;
    138120       
    139121        if (!driver->sess) {
     
    143125                goto cleanup;
    144126        }
    145 
     127       
    146128        if (fun != NULL) {
    147129                log_msg(LOG_DEFAULT, LVL_DEBUG,
     
    155137       
    156138        async_exch_t *exch = async_exchange_begin(driver->sess);
    157         async_forward_fast(iid, exch, method, fwd_h, 0, IPC_FF_NONE);
     139        async_forward_fast(iid, exch, INTERFACE_DDF_CLIENT, handle, 0, IPC_FF_NONE);
    158140        async_exchange_end(exch);
    159141       
     
    166148}
    167149
    168 /** Function for handling connections from a client forwarded by the location
    169  * service to the device manager. */
    170 static void devman_connection_loc(ipc_callid_t iid, ipc_call_t *icall)
    171 {
     150static void devman_connection_parent(ipc_callid_t iid, ipc_call_t *icall,
     151    void *arg)
     152{
     153        devman_handle_t handle = IPC_GET_ARG2(*icall);
     154        dev_node_t *dev = NULL;
     155       
     156        fun_node_t *fun = find_fun_node(&device_tree, handle);
     157        if (fun == NULL) {
     158                dev = find_dev_node(&device_tree, handle);
     159        } else {
     160                fibril_rwlock_read_lock(&device_tree.rwlock);
     161               
     162                dev = fun->dev;
     163                if (dev != NULL)
     164                        dev_add_ref(dev);
     165               
     166                fibril_rwlock_read_unlock(&device_tree.rwlock);
     167        }
     168       
     169        /*
     170         * For a valid function to connect to we need a device. The root
     171         * function, for example, has no device and cannot be connected to.
     172         * This means @c dev needs to be valid regardless whether we are
     173         * connecting to a device or to a function.
     174         */
     175        if (dev == NULL) {
     176                log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding failed - no device or "
     177                    "function with handle %" PRIun " was found.", handle);
     178                async_answer_0(iid, ENOENT);
     179                goto cleanup;
     180        }
     181       
     182        driver_t *driver = NULL;
     183       
     184        fibril_rwlock_read_lock(&device_tree.rwlock);
     185       
     186        /* Connect to parent function of a device (or device function). */
     187        if (dev->pfun->dev != NULL)
     188                driver = dev->pfun->dev->drv;
     189       
     190        devman_handle_t fun_handle = dev->pfun->handle;
     191       
     192        fibril_rwlock_read_unlock(&device_tree.rwlock);
     193       
     194        if (driver == NULL) {
     195                log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding refused - " \
     196                    "the device %" PRIun " is not in usable state.", handle);
     197                async_answer_0(iid, ENOENT);
     198                goto cleanup;
     199        }
     200       
     201        if (!driver->sess) {
     202                log_msg(LOG_DEFAULT, LVL_ERROR,
     203                    "Could not forward to driver `%s'.", driver->name);
     204                async_answer_0(iid, EINVAL);
     205                goto cleanup;
     206        }
     207       
     208        if (fun != NULL) {
     209                log_msg(LOG_DEFAULT, LVL_DEBUG,
     210                    "Forwarding request for `%s' function to driver `%s'.",
     211                    fun->pathname, driver->name);
     212        } else {
     213                log_msg(LOG_DEFAULT, LVL_DEBUG,
     214                    "Forwarding request for `%s' device to driver `%s'.",
     215                    dev->pfun->pathname, driver->name);
     216        }
     217       
     218        async_exch_t *exch = async_exchange_begin(driver->sess);
     219        async_forward_fast(iid, exch, INTERFACE_DDF_DRIVER, fun_handle, 0, IPC_FF_NONE);
     220        async_exchange_end(exch);
     221       
     222cleanup:
     223        if (dev != NULL)
     224                dev_del_ref(dev);
     225       
     226        if (fun != NULL)
     227                fun_del_ref(fun);
     228}
     229
     230static void devman_forward(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     231{
     232        iface_t iface = IPC_GET_ARG1(*icall);
    172233        service_id_t service_id = IPC_GET_ARG2(*icall);
    173         fun_node_t *fun;
    174         dev_node_t *dev;
    175         devman_handle_t handle;
    176         driver_t *driver;
    177 
    178         fun = find_loc_tree_function(&device_tree, service_id);
     234       
     235        fun_node_t *fun = find_loc_tree_function(&device_tree, service_id);
    179236       
    180237        fibril_rwlock_read_lock(&device_tree.rwlock);
    181238       
    182         if (fun == NULL || fun->dev == NULL || fun->dev->drv == NULL) {
    183                 log_msg(LOG_DEFAULT, LVL_WARN, "devman_connection_loc(): function "
     239        if ((fun == NULL) || (fun->dev == NULL) || (fun->dev->drv == NULL)) {
     240                log_msg(LOG_DEFAULT, LVL_WARN, "devman_forward(): function "
    184241                    "not found.\n");
    185242                fibril_rwlock_read_unlock(&device_tree.rwlock);
     
    188245        }
    189246       
    190         dev = fun->dev;
    191         driver = dev->drv;
    192         handle = fun->handle;
     247        dev_node_t *dev = fun->dev;
     248        driver_t *driver = dev->drv;
     249        devman_handle_t handle = fun->handle;
    193250       
    194251        fibril_rwlock_read_unlock(&device_tree.rwlock);
    195252       
    196253        async_exch_t *exch = async_exchange_begin(driver->sess);
    197         async_forward_fast(iid, exch, DRIVER_CLIENT, handle, 0,
    198             IPC_FF_NONE);
     254        async_forward_fast(iid, exch, iface, handle, 0, IPC_FF_NONE);
    199255        async_exchange_end(exch);
    200256       
    201257        log_msg(LOG_DEFAULT, LVL_DEBUG,
    202             "Forwarding loc service request for `%s' function to driver `%s'.",
     258            "Forwarding service request for `%s' function to driver `%s'.",
    203259            fun->pathname, driver->name);
    204 
     260       
    205261        fun_del_ref(fun);
    206 }
    207 
    208 /** Function for handling connections to device manager. */
    209 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    210 {
    211         /* Select port. */
    212         switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
    213         case DEVMAN_DRIVER:
    214                 devman_connection_driver(iid, icall);
    215                 break;
    216         case DEVMAN_CLIENT:
    217                 devman_connection_client(iid, icall);
    218                 break;
    219         case DEVMAN_CONNECT_TO_DEVICE:
    220                 /* Connect client to selected device. */
    221                 devman_forward(iid, icall, false);
    222                 break;
    223         case DEVMAN_CONNECT_FROM_LOC:
    224                 /* Someone connected through loc node. */
    225                 devman_connection_loc(iid, icall);
    226                 break;
    227         case DEVMAN_CONNECT_TO_PARENTS_DEVICE:
    228                 /* Connect client to selected device. */
    229                 devman_forward(iid, icall, true);
    230                 break;
    231         default:
    232                 /* No such interface */
    233                 async_answer_0(iid, ENOENT);
    234         }
    235262}
    236263
     
    298325        async_set_client_data_constructor(devman_client_data_create);
    299326        async_set_client_data_destructor(devman_client_data_destroy);
    300         async_set_client_connection(devman_connection);
     327       
     328        port_id_t port;
     329        rc = async_create_port(INTERFACE_DDF_DRIVER,
     330            devman_connection_driver, NULL, &port);
     331        if (rc != EOK)
     332                return rc;
     333       
     334        rc = async_create_port(INTERFACE_DDF_CLIENT,
     335            devman_connection_client, NULL, &port);
     336        if (rc != EOK)
     337                return rc;
     338       
     339        rc = async_create_port(INTERFACE_DEVMAN_DEVICE,
     340            devman_connection_device, NULL, &port);
     341        if (rc != EOK)
     342                return rc;
     343       
     344        rc = async_create_port(INTERFACE_DEVMAN_PARENT,
     345            devman_connection_parent, NULL, &port);
     346        if (rc != EOK)
     347                return rc;
     348       
     349        async_set_fallback_port_handler(devman_forward, NULL);
    301350       
    302351        if (!devman_init()) {
Note: See TracChangeset for help on using the changeset viewer.