Changeset d0dd7b5 in mainline


Ignore:
Timestamp:
2011-08-18T20:10:47Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ef7052ec
Parents:
763e0cd
Message:

Work on device removal:

  • properly track service memberships in categories
  • implement loc_service_unregister()
  • ddf_fun_unbind() (limited to exposed functions for now)
Location:
uspace
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/devman.c

    r763e0cd rd0dd7b5  
    308308}
    309309
     310/** Remove function from device.
     311 *
     312 * Request devman to remove function owned by this driver task.
     313 * @param funh      Devman handle of the function
     314 *
     315 * @return EOK on success or negative error code.
     316 */
     317int devman_remove_function(devman_handle_t funh)
     318{
     319        async_exch_t *exch;
     320        sysarg_t retval;
     321       
     322        exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     323        retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh);
     324        devman_exchange_end(exch);
     325       
     326        return (int) retval;
     327}
     328
    310329async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    311330    devman_handle_t handle, unsigned int flags)
  • uspace/lib/c/generic/loc.c

    r763e0cd rd0dd7b5  
    267267}
    268268
    269 /** Register new device.
    270  *
    271  * The @p interface is used when forwarding connection to the driver.
     269/** Register new service.
     270 *
     271 * The @p interface is used when forwarding connection to the server.
    272272 * If not 0, the first argument is the interface and the second argument
    273273 * is the service ID.
     
    276276 * the handle (to ensure backward compatibility).
    277277 *
    278  * @param      fqdn      Fully qualified device name.
    279  * @param[out] handle    Handle to the created instance of device.
    280  * @param      interface Interface when forwarding.
    281  *
    282  */
    283 int loc_service_register_with_iface(const char *fqdn,
    284     service_id_t *handle, sysarg_t interface)
     278 * @param      fqsn      Fully qualified service name
     279 * @param[out] sid       Service ID of new service
     280 * @param      interface Interface when forwarding
     281 *
     282 */
     283int loc_service_register_with_iface(const char *fqsn,
     284    service_id_t *sid, sysarg_t interface)
    285285{
    286286        async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER);
     
    289289        aid_t req = async_send_2(exch, LOC_SERVICE_REGISTER, interface, 0,
    290290            &answer);
    291         sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn));
     291        sysarg_t retval = async_data_write_start(exch, fqsn, str_size(fqsn));
    292292       
    293293        loc_exchange_end(exch);
     
    301301       
    302302        if (retval != EOK) {
    303                 if (handle != NULL)
    304                         *handle = -1;
    305                
    306                 return retval;
    307         }
    308        
    309         if (handle != NULL)
    310                 *handle = (service_id_t) IPC_GET_ARG1(answer);
     303                if (sid != NULL)
     304                        *sid = -1;
     305               
     306                return retval;
     307        }
     308       
     309        if (sid != NULL)
     310                *sid = (service_id_t) IPC_GET_ARG1(answer);
    311311       
    312312        return retval;
    313313}
    314314
    315 /** Register new device.
    316  *
    317  * @param fqdn   Fully qualified device name.
    318  * @param handle Output: Handle to the created instance of device.
    319  *
    320  */
    321 int loc_service_register(const char *fqdn, service_id_t *handle)
    322 {
    323         return loc_service_register_with_iface(fqdn, handle, 0);
     315/** Register new service.
     316 *
     317 * @param fqsn  Fully qualified service name
     318 * @param sid   Output: ID of new service
     319 *
     320 */
     321int loc_service_register(const char *fqdn, service_id_t *sid)
     322{
     323        return loc_service_register_with_iface(fqdn, sid, 0);
     324}
     325
     326/** Unregister service.
     327 *
     328 * @param sid   Service ID
     329 */
     330int loc_service_unregister(service_id_t sid)
     331{
     332        async_exch_t *exch;
     333        sysarg_t retval;
     334       
     335        exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER);
     336        retval = async_req_1_0(exch, LOC_SERVICE_UNREGISTER, sid);
     337        loc_exchange_end(exch);
     338       
     339        return (int)retval;
    324340}
    325341
  • uspace/lib/c/include/devman.h

    r763e0cd rd0dd7b5  
    4949extern int devman_add_function(const char *, fun_type_t, match_id_list_t *,
    5050    devman_handle_t, devman_handle_t *);
     51extern int devman_remove_function(devman_handle_t);
    5152
    5253extern async_sess_t *devman_device_connect(exch_mgmt_t, devman_handle_t,
  • uspace/lib/c/include/ipc/devman.h

    r763e0cd rd0dd7b5  
    138138        DEVMAN_ADD_FUNCTION,
    139139        DEVMAN_ADD_MATCH_ID,
    140         DEVMAN_ADD_DEVICE_TO_CATEGORY
    141 
     140        DEVMAN_ADD_DEVICE_TO_CATEGORY,
     141        DEVMAN_REMOVE_FUNCTION
    142142} driver_to_devman_t;
    143143
  • uspace/lib/c/include/loc.h

    r763e0cd rd0dd7b5  
    5050extern int loc_service_register_with_iface(const char *, service_id_t *,
    5151    sysarg_t);
     52extern int loc_service_unregister(service_id_t);
    5253extern int loc_service_add_to_cat(service_id_t, category_id_t);
    5354
  • uspace/lib/drv/generic/driver.c

    r763e0cd rd0dd7b5  
    582582int ddf_fun_bind(ddf_fun_t *fun)
    583583{
     584        assert(fun->bound == false);
    584585        assert(fun->name != NULL);
    585586       
     
    596597        fun->bound = true;
    597598        return res;
     599}
     600
     601/** Unbind a function node.
     602 *
     603 * Unbind the specified function from the system. This effectively makes
     604 * the function invisible to the system.
     605 *
     606 * @param fun           Function to bind
     607 * @return              EOK on success or negative error code
     608 */
     609int ddf_fun_unbind(ddf_fun_t *fun)
     610{
     611        int res;
     612       
     613        assert(fun->bound == true);
     614       
     615        add_to_functions_list(fun);
     616        res = devman_remove_function(fun->handle);
     617        if (res != EOK)
     618                return res;
     619
     620        remove_from_functions_list(fun);
     621       
     622        fun->bound = false;
     623        return EOK;
    598624}
    599625
  • uspace/lib/drv/include/ddf/driver.h

    r763e0cd rd0dd7b5  
    149149extern void ddf_fun_destroy(ddf_fun_t *);
    150150extern int ddf_fun_bind(ddf_fun_t *);
     151extern int ddf_fun_unbind(ddf_fun_t *);
    151152extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
    152153
  • uspace/srv/devman/devman.c

    r763e0cd rd0dd7b5  
    11001100}
    11011101
     1102/** Remove function from device tree.
     1103 *
     1104 * @param tree          Device tree
     1105 * @param node          Function node to remove
     1106 */
     1107void remove_fun_node(dev_tree_t *tree, fun_node_t *fun)
     1108{
     1109        assert(tree != NULL);
     1110        assert(fun != NULL);
     1111        assert(fibril_rwlock_is_write_locked(&tree->rwlock));
     1112       
     1113        /* Remove the node from the handle-to-node map. */
     1114        unsigned long key = fun->handle;
     1115        hash_table_remove(&tree->devman_functions, &key, 1);
     1116       
     1117        /* Remove the node from the list of its parent's children. */
     1118        if (fun->dev != NULL)
     1119                list_remove(&fun->dev_functions);
     1120}
     1121
    11021122/** Find function node with a specified path in the device tree.
    11031123 *
  • uspace/srv/devman/devman.h

    r763e0cd rd0dd7b5  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    154155        /** Name of the function, assigned by the device driver */
    155156        char *name;
     157        /** Function type */
     158        fun_type_t ftype;
    156159       
    157160        /** Full path and name of the device in device hierarchy */
     
    265268extern bool insert_dev_node(dev_tree_t *, dev_node_t *, fun_node_t *);
    266269extern bool insert_fun_node(dev_tree_t *, fun_node_t *, char *, dev_node_t *);
     270extern void remove_fun_node(dev_tree_t *, fun_node_t *);
    267271
    268272/* Loc services */
  • uspace/srv/devman/main.c

    r763e0cd rd0dd7b5  
    278278                return;
    279279        }
    280 
     280       
    281281        fun_node_t *fun = create_fun_node();
     282        fun->ftype = ftype;
     283       
    282284        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
    283285                fibril_rwlock_write_unlock(&tree->rwlock);
     
    367369}
    368370
     371/** Remove function. */
     372static void devman_remove_function(ipc_callid_t callid, ipc_call_t *call)
     373{
     374        devman_handle_t fun_handle = IPC_GET_ARG1(*call);
     375        dev_tree_t *tree = &device_tree;
     376        int rc;
     377       
     378        fibril_rwlock_write_lock(&tree->rwlock);
     379       
     380        fun_node_t *fun = find_fun_node_no_lock(&device_tree, fun_handle);
     381        if (fun == NULL) {
     382                fibril_rwlock_write_unlock(&tree->rwlock);
     383                async_answer_0(callid, ENOENT);
     384                return;
     385        }
     386       
     387        log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname);
     388       
     389        if (fun->ftype == fun_inner) {
     390                /* Handle possible descendants */
     391                /* TODO */
     392                log_msg(LVL_WARN, "devman_remove_function(): not handling "
     393                    "descendants\n");
     394        } else {
     395                /* Unregister from location service */
     396                rc = loc_service_unregister(fun->service_id);
     397                if (rc != EOK) {
     398                        log_msg(LVL_ERROR, "Failed unregistering tree service.");
     399                        fibril_rwlock_write_unlock(&tree->rwlock);
     400                        async_answer_0(callid, EIO);
     401                        return;
     402                }
     403        }
     404       
     405        remove_fun_node(&device_tree, fun);
     406        fibril_rwlock_write_unlock(&tree->rwlock);
     407        delete_fun_node(fun);
     408       
     409        log_msg(LVL_DEBUG, "devman_remove_function() succeeded.");
     410        async_answer_0(callid, EOK);
     411}
     412
    369413/** Initialize driver which has registered itself as running and ready.
    370414 *
     
    418462                case DEVMAN_ADD_DEVICE_TO_CATEGORY:
    419463                        devman_add_function_to_cat(callid, &call);
     464                        break;
     465                case DEVMAN_REMOVE_FUNCTION:
     466                        devman_remove_function(callid, &call);
    420467                        break;
    421468                default:
  • uspace/srv/loc/category.c

    r763e0cd rd0dd7b5  
    9393        cat->id = loc_create_id();
    9494        link_initialize(&cat->cat_list);
    95         list_initialize(&cat->services);
     95        list_initialize(&cat->svc_memb);
    9696}
    9797
     
    113113{
    114114        assert(fibril_mutex_is_locked(&cat->mutex));
     115        assert(fibril_mutex_is_locked(&services_list_mutex));
    115116
    116117        /* Verify that category does not contain this service yet. */
    117         list_foreach(cat->services, item) {
    118 
    119                 loc_service_t *csvc = list_get_instance(item, loc_service_t,
    120                     cat_services);
    121                 if (csvc == svc) {
     118        list_foreach(cat->svc_memb, item) {
     119                svc_categ_t *memb = list_get_instance(item, svc_categ_t,
     120                    cat_link);
     121                if (memb->svc == svc) {
    122122                        return EEXIST;
    123123                }
    124124        }
    125125
    126         list_append(&svc->cat_services, &cat->services);
     126        svc_categ_t *nmemb = malloc(sizeof(svc_categ_t));
     127        if (nmemb == NULL)
     128                return ENOMEM;
     129
     130        nmemb->svc = svc;
     131        nmemb->cat = cat;
     132
     133        list_append(&nmemb->cat_link, &cat->svc_memb);
     134        list_append(&nmemb->svc_link, &svc->cat_memb);
     135
    127136        return EOK;
     137}
     138
     139/** Remove service from category. */
     140void category_remove_service(svc_categ_t *memb)
     141{
     142        assert(fibril_mutex_is_locked(&memb->cat->mutex));
     143        assert(fibril_mutex_is_locked(&services_list_mutex));
     144
     145        list_remove(&memb->cat_link);
     146        list_remove(&memb->svc_link);
     147
     148        free(memb);
    128149}
    129150
     
    169190        buf_cnt = buf_size / sizeof(service_id_t);
    170191
    171         act_cnt = list_count(&cat->services);
     192        act_cnt = list_count(&cat->svc_memb);
    172193        *act_size = act_cnt * sizeof(service_id_t);
    173194
     
    176197
    177198        size_t pos = 0;
    178         list_foreach(cat->services, item) {
    179                 loc_service_t *svc =
    180                     list_get_instance(item, loc_service_t, cat_services);
     199        list_foreach(cat->svc_memb, item) {
     200                svc_categ_t *memb =
     201                    list_get_instance(item, svc_categ_t, cat_link);
    181202
    182203                if (pos < buf_cnt)
    183                         id_buf[pos] = svc->id;
     204                        id_buf[pos] = memb->svc->id;
    184205                pos++;
    185206        }
  • uspace/srv/loc/category.h

    r763e0cd rd0dd7b5  
    5555        link_t cat_list;
    5656
    57         /** List of services in this category (loc_service_t) */
    58         list_t services;
     57        /** List of service memberships in this category (svc_categ_t) */
     58        list_t svc_memb;
    5959} category_t;
    6060
     
    6767} categ_dir_t;
    6868
     69/** Service in category membership. */
     70typedef struct {
     71        /** Link to category_t.svc_memb list */
     72        link_t cat_link;
     73        /** Link to loc_service_t.cat_memb list */
     74        link_t svc_link;
     75       
     76        /** Category */
     77        category_t *cat;
     78        /** Service */
     79        loc_service_t *svc;
     80} svc_categ_t;
     81
    6982extern void categ_dir_init(categ_dir_t *);
    7083extern void categ_dir_add_cat(categ_dir_t *, category_t *);
     
    7386extern category_t *category_new(const char *);
    7487extern int category_add_service(category_t *, loc_service_t *);
     88extern void category_remove_service(svc_categ_t *);
    7589extern category_t *category_get(categ_dir_t *, catid_t);
    7690extern category_t *category_find_by_name(categ_dir_t *, const char *);
  • uspace/srv/loc/loc.c

    r763e0cd rd0dd7b5  
    6767 **/
    6868
    69 static FIBRIL_MUTEX_INITIALIZE(services_list_mutex);
     69FIBRIL_MUTEX_INITIALIZE(services_list_mutex);
    7070static FIBRIL_CONDVAR_INITIALIZE(services_list_cv);
    7171static FIBRIL_MUTEX_INITIALIZE(servers_list_mutex);
     
    311311{
    312312        assert(fibril_mutex_is_locked(&services_list_mutex));
    313 
     313        assert(fibril_mutex_is_locked(&cdir.mutex));
     314       
    314315        loc_namespace_delref(service->namespace);
    315316        list_remove(&(service->services));
    316317        list_remove(&(service->server_services));
     318       
     319        /* Remove service from all categories. */
     320        while (!list_empty(&service->cat_memb)) {
     321                link_t *link = list_first(&service->cat_memb);
     322                svc_categ_t *memb = list_get_instance(link, svc_categ_t,
     323                    svc_link);
     324                fibril_mutex_lock(&memb->cat->mutex);
     325                category_remove_service(memb);
     326                fibril_mutex_unlock(&memb->cat->mutex);
     327        }
    317328       
    318329        free(service->name);
     
    415426        fibril_mutex_lock(&services_list_mutex);
    416427        fibril_mutex_lock(&server->services_mutex);
     428        fibril_mutex_lock(&cdir.mutex);
    417429       
    418430        while (!list_empty(&server->services)) {
     
    423435        }
    424436       
     437        fibril_mutex_unlock(&cdir.mutex);
    425438        fibril_mutex_unlock(&server->services_mutex);
    426439        fibril_mutex_unlock(&services_list_mutex);
     
    492505        link_initialize(&service->services);
    493506        link_initialize(&service->server_services);
     507        list_initialize(&service->cat_memb);
    494508       
    495509        /* Check that service is not already registered */
     
    529543 *
    530544 */
    531 static int loc_service_unregister(ipc_callid_t iid, ipc_call_t *icall,
     545static void loc_service_unregister(ipc_callid_t iid, ipc_call_t *icall,
    532546    loc_server_t *server)
    533547{
    534         /* TODO */
    535         return EOK;
     548        loc_service_t *svc;
     549       
     550        fibril_mutex_lock(&services_list_mutex);
     551        svc = loc_service_find_id(IPC_GET_ARG1(*icall));
     552        if (svc == NULL) {
     553                fibril_mutex_unlock(&services_list_mutex);
     554                async_answer_0(iid, ENOENT);
     555                return;
     556        }
     557       
     558        fibril_mutex_lock(&cdir.mutex);
     559        loc_service_unregister_core(svc);
     560        fibril_mutex_unlock(&cdir.mutex);
     561        fibril_mutex_unlock(&services_list_mutex);
     562        async_answer_0(iid, EOK);
    536563}
    537564
     
    11761203       
    11771204        fibril_mutex_lock(&services_list_mutex);
     1205        fibril_mutex_lock(&cdir.mutex);
    11781206        loc_service_unregister_core(null_services[i]);
     1207        fibril_mutex_unlock(&cdir.mutex);
    11791208        fibril_mutex_unlock(&services_list_mutex);
    11801209       
     
    12421271
    12431272        cat = category_new("usbhc");
     1273        categ_dir_add_cat(&cdir, cat);
     1274
     1275        cat = category_new("virtual");
    12441276        categ_dir_add_cat(&cdir, cat);
    12451277
  • uspace/srv/loc/loc.h

    r763e0cd rd0dd7b5  
    8989        /** Link to list of services in category (category_t.services) */
    9090        link_t cat_services;
     91        /** List of category memberships (svc_categ_t) */
     92        list_t cat_memb;
    9193        /** Unique service identifier */
    9294        service_id_t id;
     
    101103} loc_service_t;
    102104
     105extern fibril_mutex_t services_list_mutex;
     106
    103107extern service_id_t loc_create_id(void);
    104108extern void loc_category_change_event(void);
Note: See TracChangeset for help on using the changeset viewer.