Changeset 4820360 in mainline


Ignore:
Timestamp:
2012-08-13T14:44:07Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
14c5005, 4802dd7, 72cf064
Parents:
cd529c4
Message:

Synchronize device tree transitions.

Location:
uspace/srv/devman
Files:
3 edited

Legend:

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

    rcd529c4 r4820360  
    10521052}
    10531053
    1054 
    10551054/** Find the device node structure of the device witch has the specified handle.
    10561055 *
     
    11421141        fun->state = FUN_INIT;
    11431142        atomic_set(&fun->refcnt, 0);
     1143        fibril_mutex_initialize(&fun->busy_lock);
    11441144        link_initialize(&fun->dev_functions);
    11451145        list_initialize(&fun->match_ids.ids);
     
    11841184        if (atomic_predec(&fun->refcnt) == 0)
    11851185                delete_fun_node(fun);
     1186}
     1187
     1188/** Make function busy for reconfiguration operations. */
     1189void fun_busy_lock(fun_node_t *fun)
     1190{
     1191        fibril_mutex_lock(&fun->busy_lock);
     1192}
     1193
     1194/** Mark end of reconfiguration operation. */
     1195void fun_busy_unlock(fun_node_t *fun)
     1196{
     1197        fibril_mutex_unlock(&fun->busy_lock);
    11861198}
    11871199
  • uspace/srv/devman/devman.h

    rcd529c4 r4820360  
    174174        /** State */
    175175        fun_state_t state;
     176        /** Locked while performing reconfiguration operations */
     177        fibril_mutex_t busy_lock;
    176178       
    177179        /** The global unique identifier of the function */
     
    279281extern void dev_add_ref(dev_node_t *);
    280282extern void dev_del_ref(dev_node_t *);
     283
    281284extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree,
    282285    devman_handle_t handle);
     
    290293extern void fun_add_ref(fun_node_t *);
    291294extern void fun_del_ref(fun_node_t *);
     295extern void fun_busy_lock(fun_node_t *);
     296extern void fun_busy_unlock(fun_node_t *);
    292297extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree,
    293298    devman_handle_t handle);
  • uspace/srv/devman/main.c

    rcd529c4 r4820360  
    432432       
    433433        fun_node_t *fun = create_fun_node();
     434        /* One reference for creation, one for us */
     435        fun_add_ref(fun);
    434436        fun_add_ref(fun);
    435437        fun->ftype = ftype;
     438       
     439        /*
     440         * We can lock the function here even when holding the tree because
     441         * we know it cannot be held by anyone else yet.
     442         */
     443        fun_busy_lock(fun);
    436444       
    437445        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
    438446                fibril_rwlock_write_unlock(&tree->rwlock);
    439447                dev_del_ref(pdev);
     448                fun_busy_unlock(fun);
     449                fun_del_ref(fun);
    440450                delete_fun_node(fun);
    441451                async_answer_0(callid, ENOMEM);
     
    450460        rc = online_function(fun);
    451461        if (rc != EOK) {
    452                 /* XXX clean up */
     462                /* XXX Set some failed state? */
     463                fun_busy_unlock(fun);
     464                fun_del_ref(fun);
    453465                async_answer_0(callid, rc);
    454466                return;
    455467        }
     468       
     469        fun_busy_unlock(fun);
     470        fun_del_ref(fun);
    456471       
    457472        /* Return device handle to parent's driver. */
     
    522537        }
    523538       
     539        fun_busy_lock(fun);
     540       
    524541        fibril_rwlock_read_lock(&device_tree.rwlock);
    525542        if (fun->dev == NULL || fun->dev->drv != drv) {
    526543                fibril_rwlock_read_unlock(&device_tree.rwlock);
     544                fun_busy_unlock(fun);
    527545                fun_del_ref(fun);
    528546                async_answer_0(iid, ENOENT);
     
    533551        rc = online_function(fun);
    534552        if (rc != EOK) {
     553                fun_busy_unlock(fun);
    535554                fun_del_ref(fun);
    536555                async_answer_0(iid, (sysarg_t) rc);
     
    538557        }
    539558       
     559        fun_busy_unlock(fun);
    540560        fun_del_ref(fun);
    541561       
     
    559579        }
    560580       
     581        fun_busy_lock(fun);
     582       
    561583        fibril_rwlock_write_lock(&device_tree.rwlock);
    562584        if (fun->dev == NULL || fun->dev->drv != drv) {
     585                fun_busy_unlock(fun);
    563586                fun_del_ref(fun);
    564587                async_answer_0(iid, ENOENT);
     
    569592        rc = offline_function(fun);
    570593        if (rc != EOK) {
     594                fun_busy_unlock(fun);
    571595                fun_del_ref(fun);
    572596                async_answer_0(iid, (sysarg_t) rc);
     
    574598        }
    575599       
     600        fun_busy_unlock(fun);
    576601        fun_del_ref(fun);
    577602        async_answer_0(iid, (sysarg_t) EOK);
     
    591616        }
    592617       
     618        fun_busy_lock(fun);
     619       
    593620        fibril_rwlock_write_lock(&tree->rwlock);
    594621       
     
    598625        if (fun->state == FUN_REMOVED) {
    599626                fibril_rwlock_write_unlock(&tree->rwlock);
     627                fun_busy_unlock(fun);
     628                fun_del_ref(fun);
    600629                async_answer_0(callid, ENOENT);
    601630                return;
     
    638667                                if (gone_rc == EOK)
    639668                                        gone_rc = ENOTSUP;
     669                                fun_busy_unlock(fun);
     670                                fun_del_ref(fun);
    640671                                async_answer_0(callid, gone_rc);
    641672                                return;
     
    664695                                    "service.");
    665696                                fibril_rwlock_write_unlock(&tree->rwlock);
     697                                fun_busy_unlock(fun);
    666698                                fun_del_ref(fun);
    667699                                async_answer_0(callid, EIO);
     
    673705        remove_fun_node(&device_tree, fun);
    674706        fibril_rwlock_write_unlock(&tree->rwlock);
     707        fun_busy_unlock(fun);
    675708       
    676709        /* Delete ref added when inserting function into tree */
Note: See TracChangeset for help on using the changeset viewer.