Changeset 38e52c92 in mainline


Ignore:
Timestamp:
2013-09-10T18:51:53Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
59dc181
Parents:
d1bafbf
Message:

Move fun-dev-related functionality to a separate devman module.

Location:
uspace/srv/devman
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/Makefile

    rd1bafbf r38e52c92  
    3636        devman.c \
    3737        driver.c \
     38        fun.c \
    3839        main.c \
    3940        match.c \
  • uspace/srv/devman/devman.c

    rd1bafbf r38e52c92  
    6363#include "devman.h"
    6464#include "driver.h"
    65 
    66 static fun_node_t *find_node_child(dev_tree_t *, fun_node_t *, const char *);
     65#include "fun.h"
    6766
    6867/* hash table operations */
     
    455454}
    456455
    457 /* Function nodes */
    458 
    459 /** Create a new function node.
    460  *
    461  * @return              A function node structure.
    462  */
    463 fun_node_t *create_fun_node(void)
    464 {
    465         fun_node_t *fun;
    466 
    467         fun = calloc(1, sizeof(fun_node_t));
    468         if (fun == NULL)
    469                 return NULL;
    470        
    471         fun->state = FUN_INIT;
    472         atomic_set(&fun->refcnt, 0);
    473         fibril_mutex_initialize(&fun->busy_lock);
    474         link_initialize(&fun->dev_functions);
    475         list_initialize(&fun->match_ids.ids);
    476        
    477         return fun;
    478 }
    479 
    480 /** Delete a function node.
    481  *
    482  * @param fun           The device node structure.
    483  */
    484 void delete_fun_node(fun_node_t *fun)
    485 {
    486         assert(fun->dev == NULL);
    487         assert(fun->child == NULL);
    488        
    489         clean_match_ids(&fun->match_ids);
    490         free(fun->name);
    491         free(fun->pathname);
    492         free(fun);
    493 }
    494 
    495 /** Increase function node reference count.
    496  *
    497  * @param fun   Function node
    498  */
    499 void fun_add_ref(fun_node_t *fun)
    500 {
    501         atomic_inc(&fun->refcnt);
    502 }
    503 
    504 /** Decrease function node reference count.
    505  *
    506  * When the count drops to zero the function node is freed.
    507  *
    508  * @param fun   Function node
    509  */
    510 void fun_del_ref(fun_node_t *fun)
    511 {
    512         if (atomic_predec(&fun->refcnt) == 0)
    513                 delete_fun_node(fun);
    514 }
    515 
    516 /** Make function busy for reconfiguration operations. */
    517 void fun_busy_lock(fun_node_t *fun)
    518 {
    519         fibril_mutex_lock(&fun->busy_lock);
    520 }
    521 
    522 /** Mark end of reconfiguration operation. */
    523 void fun_busy_unlock(fun_node_t *fun)
    524 {
    525         fibril_mutex_unlock(&fun->busy_lock);
    526 }
    527 
    528 /** Find the function node with the specified handle.
    529  *
    530  * @param tree          The device tree where we look for the device node.
    531  * @param handle        The handle of the function.
    532  * @return              The function node.
    533  */
    534 fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, devman_handle_t handle)
    535 {
    536         fun_node_t *fun;
    537        
    538         assert(fibril_rwlock_is_locked(&tree->rwlock));
    539        
    540         ht_link_t *link = hash_table_find(&tree->devman_functions, &handle);
    541         if (link == NULL)
    542                 return NULL;
    543        
    544         fun = hash_table_get_inst(link, fun_node_t, devman_fun);
    545        
    546         return fun;
    547 }
    548 
    549 /** Find the function node with the specified handle.
    550  *
    551  * @param tree          The device tree where we look for the device node.
    552  * @param handle        The handle of the function.
    553  * @return              The function node.
    554  */
    555 fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle)
    556 {
    557         fun_node_t *fun = NULL;
    558        
    559         fibril_rwlock_read_lock(&tree->rwlock);
    560        
    561         fun = find_fun_node_no_lock(tree, handle);
    562         if (fun != NULL)
    563                 fun_add_ref(fun);
    564        
    565         fibril_rwlock_read_unlock(&tree->rwlock);
    566        
    567         return fun;
    568 }
    569 
    570 /** Create and set device's full path in device tree.
    571  *
    572  * @param tree          Device tree
    573  * @param node          The device's device node.
    574  * @param parent        The parent device node.
    575  * @return              True on success, false otherwise (insufficient
    576  *                      resources etc.).
    577  */
    578 static bool set_fun_path(dev_tree_t *tree, fun_node_t *fun, fun_node_t *parent)
    579 {
    580         assert(fibril_rwlock_is_write_locked(&tree->rwlock));
    581         assert(fun->name != NULL);
    582        
    583         size_t pathsize = (str_size(fun->name) + 1);
    584         if (parent != NULL)
    585                 pathsize += str_size(parent->pathname) + 1;
    586        
    587         fun->pathname = (char *) malloc(pathsize);
    588         if (fun->pathname == NULL) {
    589                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to allocate device path.");
    590                 return false;
    591         }
    592        
    593         if (parent != NULL) {
    594                 str_cpy(fun->pathname, pathsize, parent->pathname);
    595                 str_append(fun->pathname, pathsize, "/");
    596                 str_append(fun->pathname, pathsize, fun->name);
    597         } else {
    598                 str_cpy(fun->pathname, pathsize, fun->name);
    599         }
    600        
    601         return true;
    602 }
    603 
    604456/** Insert new device into device tree.
    605457 *
     
    712564}
    713565
    714 /** Find function node with a specified path in the device tree.
    715  *
    716  * @param path          The path of the function node in the device tree.
    717  * @param tree          The device tree.
    718  * @return              The function node if it is present in the tree, NULL
    719  *                      otherwise.
    720  */
    721 fun_node_t *find_fun_node_by_path(dev_tree_t *tree, char *path)
    722 {
    723         assert(path != NULL);
    724 
    725         bool is_absolute = path[0] == '/';
    726         if (!is_absolute) {
    727                 return NULL;
    728         }
    729 
    730         fibril_rwlock_read_lock(&tree->rwlock);
    731        
    732         fun_node_t *fun = tree->root_node;
    733         fun_add_ref(fun);
    734         /*
    735          * Relative path to the function from its parent (but with '/' at the
    736          * beginning)
    737          */
    738         char *rel_path = path;
    739         char *next_path_elem = NULL;
    740         bool cont = (rel_path[1] != '\0');
    741        
    742         while (cont && fun != NULL) {
    743                 next_path_elem  = get_path_elem_end(rel_path + 1);
    744                 if (next_path_elem[0] == '/') {
    745                         cont = true;
    746                         next_path_elem[0] = 0;
    747                 } else {
    748                         cont = false;
    749                 }
    750                
    751                 fun_node_t *cfun = find_node_child(tree, fun, rel_path + 1);
    752                 fun_del_ref(fun);
    753                 fun = cfun;
    754                
    755                 if (cont) {
    756                         /* Restore the original path. */
    757                         next_path_elem[0] = '/';
    758                 }
    759                 rel_path = next_path_elem;
    760         }
    761        
    762         fibril_rwlock_read_unlock(&tree->rwlock);
    763        
    764         return fun;
    765 }
    766 
    767 /** Find function with a specified name belonging to given device.
    768  *
    769  * Device tree rwlock should be held at least for reading.
    770  *
    771  * @param tree Device tree
    772  * @param dev Device the function belongs to.
    773  * @param name Function name (not path).
    774  * @return Function node.
    775  * @retval NULL No function with given name.
    776  */
    777 fun_node_t *find_fun_node_in_device(dev_tree_t *tree, dev_node_t *dev,
    778     const char *name)
    779 {
    780         assert(name != NULL);
    781         assert(fibril_rwlock_is_locked(&tree->rwlock));
    782 
    783         fun_node_t *fun;
    784 
    785         list_foreach(dev->functions, link) {
    786                 fun = list_get_instance(link, fun_node_t, dev_functions);
    787 
    788                 if (str_cmp(name, fun->name) == 0) {
    789                         fun_add_ref(fun);
    790                         return fun;
    791                 }
    792         }
    793 
    794         return NULL;
    795 }
    796 
    797 /** Find child function node with a specified name.
    798  *
    799  * Device tree rwlock should be held at least for reading.
    800  *
    801  * @param tree          Device tree
    802  * @param parent        The parent function node.
    803  * @param name          The name of the child function.
    804  * @return              The child function node.
    805  */
    806 static fun_node_t *find_node_child(dev_tree_t *tree, fun_node_t *pfun,
    807     const char *name)
    808 {
    809         return find_fun_node_in_device(tree, pfun->child, name);
    810 }
    811 
    812566/* loc devices */
    813567
  • uspace/srv/devman/devman.h

    rd1bafbf r38e52c92  
    244244extern char *read_id(const char **);
    245245
    246 /* Function nodes */
    247 
    248 extern fun_node_t *create_fun_node(void);
    249 extern void delete_fun_node(fun_node_t *);
    250 extern void fun_add_ref(fun_node_t *);
    251 extern void fun_del_ref(fun_node_t *);
    252 extern void fun_busy_lock(fun_node_t *);
    253 extern void fun_busy_unlock(fun_node_t *);
    254 extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree,
    255     devman_handle_t handle);
    256 extern fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle);
    257 extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *);
    258 extern fun_node_t *find_fun_node_in_device(dev_tree_t *tree, dev_node_t *,
    259     const char *);
    260 
    261246/* Device tree */
    262247
  • uspace/srv/devman/main.c

    rd1bafbf r38e52c92  
    6161#include "devman.h"
    6262#include "driver.h"
     63#include "fun.h"
    6364
    6465#define DRIVER_DEFAULT_STORE  "/drv"
Note: See TracChangeset for help on using the changeset viewer.