Changeset 38e52c92 in mainline
- Timestamp:
- 2013-09-10T18:51:53Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 59dc181
- Parents:
- d1bafbf
- Location:
- uspace/srv/devman
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/Makefile
rd1bafbf r38e52c92 36 36 devman.c \ 37 37 driver.c \ 38 fun.c \ 38 39 main.c \ 39 40 match.c \ -
uspace/srv/devman/devman.c
rd1bafbf r38e52c92 63 63 #include "devman.h" 64 64 #include "driver.h" 65 66 static fun_node_t *find_node_child(dev_tree_t *, fun_node_t *, const char *); 65 #include "fun.h" 67 66 68 67 /* hash table operations */ … … 455 454 } 456 455 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 node498 */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 node509 */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 tree573 * @param node The device's device node.574 * @param parent The parent device node.575 * @return True on success, false otherwise (insufficient576 * 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 604 456 /** Insert new device into device tree. 605 457 * … … 712 564 } 713 565 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, NULL719 * 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 the736 * 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 tree772 * @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 tree802 * @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 812 566 /* loc devices */ 813 567 -
uspace/srv/devman/devman.h
rd1bafbf r38e52c92 244 244 extern char *read_id(const char **); 245 245 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 261 246 /* Device tree */ 262 247 -
uspace/srv/devman/main.c
rd1bafbf r38e52c92 61 61 #include "devman.h" 62 62 #include "driver.h" 63 #include "fun.h" 63 64 64 65 #define DRIVER_DEFAULT_STORE "/drv"
Note:
See TracChangeset
for help on using the changeset viewer.