Changeset ba38f72c in mainline
- Timestamp:
- 2011-02-07T22:15:37Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1b367b4
- Parents:
- 8b5690f
- Location:
- uspace/srv/devman
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r8b5690f rba38f72c 41 41 #include "devman.h" 42 42 43 fun_node_t *find_node_child(fun_node_t *parent, const char *name); 44 43 45 /* hash table operations */ 44 46 … … 51 53 link_t *item) 52 54 { 53 node_t *dev = hash_table_get_instance(item, node_t, devman_link);55 dev_node_t *dev = hash_table_get_instance(item, dev_node_t, devman_dev); 54 56 return (dev->handle == (devman_handle_t) key[0]); 55 57 } 56 58 57 static int devma p_devices_compare(unsigned long key[], hash_count_t keys,59 static int devman_functions_compare(unsigned long key[], hash_count_t keys, 58 60 link_t *item) 59 61 { 60 node_t *dev = hash_table_get_instance(item, node_t, devmap_link); 61 return (dev->devmap_handle == (devmap_handle_t) key[0]); 62 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devman_fun); 63 return (fun->handle == (devman_handle_t) key[0]); 64 } 65 66 static int devmap_functions_compare(unsigned long key[], hash_count_t keys, 67 link_t *item) 68 { 69 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devmap_fun); 70 return (fun->devmap_handle == (devmap_handle_t) key[0]); 62 71 } 63 72 … … 82 91 }; 83 92 93 static hash_table_operations_t devman_functions_ops = { 94 .hash = devices_hash, 95 .compare = devman_functions_compare, 96 .remove_callback = devices_remove_callback 97 }; 98 84 99 static hash_table_operations_t devmap_devices_ops = { 85 100 .hash = devices_hash, 86 .compare = devmap_ devices_compare,101 .compare = devmap_functions_compare, 87 102 .remove_callback = devices_remove_callback 88 103 }; … … 373 388 } 374 389 375 /** Create root device node in the device tree.390 /** Create root device and function node in the device tree. 376 391 * 377 392 * @param tree The device tree. 378 393 * @return True on success, false otherwise. 379 394 */ 380 bool create_root_node(dev_tree_t *tree) 381 { 382 node_t *node; 383 384 printf(NAME ": create_root_node\n"); 385 395 bool create_root_nodes(dev_tree_t *tree) 396 { 397 fun_node_t *fun; 398 dev_node_t *dev; 399 400 printf(NAME ": create_root_nodes\n"); 401 386 402 fibril_rwlock_write_lock(&tree->rwlock); 387 node = create_dev_node(); 388 if (node != NULL) { 389 insert_dev_node(tree, node, clone_string(""), NULL); 390 match_id_t *id = create_match_id(); 391 id->id = clone_string("root"); 392 id->score = 100; 393 add_match_id(&node->match_ids, id); 394 tree->root_node = node; 395 } 403 404 /* 405 * Create root function. This is a pseudo function to which 406 * the root device node is attached. It allows us to match 407 * the root device driver in a standard manner, i.e. against 408 * the parent function. 409 */ 410 411 fun = create_fun_node(); 412 if (fun == NULL) { 413 fibril_rwlock_write_unlock(&tree->rwlock); 414 return false; 415 } 416 417 insert_fun_node(tree, fun, clone_string(""), NULL); 418 match_id_t *id = create_match_id(); 419 id->id = clone_string("root"); 420 id->score = 100; 421 add_match_id(&fun->match_ids, id); 422 tree->root_node = fun; 423 424 /* 425 * Create root device node. 426 */ 427 dev = create_dev_node(); 428 if (dev == NULL) { 429 fibril_rwlock_write_unlock(&tree->rwlock); 430 return false; 431 } 432 433 insert_dev_node(tree, dev, fun); 434 396 435 fibril_rwlock_write_unlock(&tree->rwlock); 397 398 return node!= NULL;436 437 return dev != NULL; 399 438 } 400 439 … … 414 453 * is found. 415 454 */ 416 driver_t *find_best_match_driver(driver_list_t *drivers_list, node_t *node)455 driver_t *find_best_match_driver(driver_list_t *drivers_list, dev_node_t *node) 417 456 { 418 457 driver_t *best_drv = NULL, *drv = NULL; … … 442 481 * @param drv The driver. 443 482 */ 444 void attach_driver( node_t *node, driver_t *drv)483 void attach_driver(dev_node_t *dev, driver_t *drv) 445 484 { 446 485 printf(NAME ": attach_driver %s to device %s\n", 447 drv->name, node->pathname);486 drv->name, dev->pfun->pathname); 448 487 449 488 fibril_mutex_lock(&drv->driver_mutex); 450 489 451 node->drv = drv;452 list_append(& node->driver_devices, &drv->devices);490 dev->drv = drv; 491 list_append(&dev->driver_devices, &drv->devices); 453 492 454 493 fibril_mutex_unlock(&drv->driver_mutex); … … 530 569 static void pass_devices_to_driver(driver_t *driver, dev_tree_t *tree) 531 570 { 532 node_t *dev;571 dev_node_t *dev; 533 572 link_t *link; 534 573 int phone; … … 551 590 link = driver->devices.next; 552 591 while (link != &driver->devices) { 553 dev = list_get_instance(link, node_t, driver_devices);592 dev = list_get_instance(link, dev_node_t, driver_devices); 554 593 if (dev->passed_to_driver) { 555 594 link = link->next; … … 669 708 } 670 709 671 /** Create devmap path and name for the device. */672 static void devmap_register_tree_ device(node_t *node, dev_tree_t *tree)710 /** Create devmap path and name for the function. */ 711 static void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree) 673 712 { 674 713 char *devmap_pathname = NULL; 675 714 char *devmap_name = NULL; 676 715 677 asprintf(&devmap_name, "%s", node->pathname);716 asprintf(&devmap_name, "%s", fun->pathname); 678 717 if (devmap_name == NULL) 679 718 return; … … 689 728 690 729 devmap_device_register_with_iface(devmap_pathname, 691 & node->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);692 693 tree_add_devmap_ device(tree, node);730 &fun->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP); 731 732 tree_add_devmap_function(tree, fun); 694 733 695 734 free(devmap_name); … … 702 741 * @param node The device's node in the device tree. 703 742 */ 704 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)743 void add_device(int phone, driver_t *drv, dev_node_t *dev, dev_tree_t *tree) 705 744 { 706 745 /* … … 709 748 */ 710 749 printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name, 711 node->name);750 dev->pfun->name); 712 751 713 752 sysarg_t rc; … … 716 755 /* Send the device to the driver. */ 717 756 devman_handle_t parent_handle; 718 if ( node->parent) {719 parent_handle = node->parent->handle;757 if (dev->pfun) { 758 parent_handle = dev->pfun->handle; 720 759 } else { 721 760 parent_handle = 0; 722 761 } 723 762 724 aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,763 aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, dev->handle, 725 764 parent_handle, &answer); 726 765 727 766 /* Send the device's name to the driver. */ 728 rc = async_data_write_start(phone, node->name,729 str_size( node->name) + 1);767 rc = async_data_write_start(phone, dev->pfun->name, 768 str_size(dev->pfun->name) + 1); 730 769 if (rc != EOK) { 731 770 /* TODO handle error */ … … 737 776 switch(rc) { 738 777 case EOK: 739 node->state = DEVICE_USABLE; 740 devmap_register_tree_device(node, tree); 778 dev->state = DEVICE_USABLE; 779 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 780 if (0) devmap_register_tree_function(NULL, tree); 781 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 741 782 break; 742 783 case ENOENT: 743 node->state = DEVICE_NOT_PRESENT;784 dev->state = DEVICE_NOT_PRESENT; 744 785 break; 745 786 default: 746 node->state = DEVICE_INVALID;747 } 748 749 node->passed_to_driver = true;787 dev->state = DEVICE_INVALID; 788 } 789 790 dev->passed_to_driver = true; 750 791 751 792 return; … … 759 800 * successfully assigned to the device, false otherwise. 760 801 */ 761 bool assign_driver(node_t *node, driver_list_t *drivers_list, dev_tree_t *tree) 762 { 802 bool assign_driver(dev_node_t *dev, driver_list_t *drivers_list, 803 dev_tree_t *tree) 804 { 805 assert(dev != NULL); 806 assert(drivers_list != NULL); 807 assert(tree != NULL); 808 763 809 /* 764 810 * Find the driver which is the most suitable for handling this device. 765 811 */ 766 driver_t *drv = find_best_match_driver(drivers_list, node);812 driver_t *drv = find_best_match_driver(drivers_list, dev); 767 813 if (drv == NULL) { 768 814 printf(NAME ": no driver found for device '%s'.\n", 769 node->pathname);815 dev->pfun->pathname); 770 816 return false; 771 817 } 772 818 773 819 /* Attach the driver to the device. */ 774 attach_driver( node, drv);820 attach_driver(dev, drv); 775 821 776 822 fibril_mutex_lock(&drv->driver_mutex); … … 786 832 int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0); 787 833 if (phone >= 0) { 788 add_device(phone, drv, node, tree);834 add_device(phone, drv, dev, tree); 789 835 async_hangup(phone); 790 836 } … … 810 856 hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, 811 857 &devman_devices_ops); 812 hash_table_create(&tree->devmap_devices, DEVICE_BUCKETS, 1, 858 hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1, 859 &devman_functions_ops); 860 hash_table_create(&tree->devmap_functions, DEVICE_BUCKETS, 1, 813 861 &devmap_devices_ops); 814 862 815 863 fibril_rwlock_initialize(&tree->rwlock); 816 864 817 /* Create root node and add itto the device tree. */818 if (!create_root_node (tree))865 /* Create root function and root device and add them to the device tree. */ 866 if (!create_root_nodes(tree)) 819 867 return false; 820 868 821 869 /* Find suitable driver and start it. */ 822 return assign_driver(tree->root_node , drivers_list, tree);870 return assign_driver(tree->root_node->child, drivers_list, tree); 823 871 } 824 872 … … 829 877 * @return A device node structure. 830 878 */ 831 node_t *create_dev_node(void)832 { 833 node_t *res = malloc(sizeof(node_t));879 dev_node_t *create_dev_node(void) 880 { 881 dev_node_t *res = malloc(sizeof(dev_node_t)); 834 882 835 883 if (res != NULL) { 836 memset(res, 0, sizeof( node_t));837 list_initialize(&res-> children);838 li st_initialize(&res->match_ids.ids);839 li st_initialize(&res->classes);884 memset(res, 0, sizeof(dev_node_t)); 885 list_initialize(&res->functions); 886 link_initialize(&res->driver_devices); 887 link_initialize(&res->devman_dev); 840 888 } 841 889 … … 847 895 * @param node The device node structure. 848 896 */ 849 void delete_dev_node(node_t *node) 850 { 851 assert(list_empty(&node->children)); 852 assert(node->parent == NULL); 853 assert(node->drv == NULL); 854 855 clean_match_ids(&node->match_ids); 856 free_not_null(node->name); 857 free_not_null(node->pathname); 858 free(node); 897 void delete_dev_node(dev_node_t *dev) 898 { 899 assert(list_empty(&dev->functions)); 900 assert(dev->pfun == NULL); 901 assert(dev->drv == NULL); 902 903 free(dev); 859 904 } 860 905 … … 865 910 * @return The device node. 866 911 */ 867 node_t *find_dev_node_no_lock(dev_tree_t *tree, devman_handle_t handle)912 dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 868 913 { 869 914 unsigned long key = handle; … … 873 918 874 919 link = hash_table_find(&tree->devman_devices, &key); 875 return hash_table_get_instance(link, node_t, devman_link);920 return hash_table_get_instance(link, dev_node_t, devman_dev); 876 921 } 877 922 … … 882 927 * @return The device node. 883 928 */ 884 node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle)885 { 886 node_t *node= NULL;929 dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle) 930 { 931 dev_node_t *dev = NULL; 887 932 888 933 fibril_rwlock_read_lock(&tree->rwlock); 889 node= find_dev_node_no_lock(tree, handle);934 dev = find_dev_node_no_lock(tree, handle); 890 935 fibril_rwlock_read_unlock(&tree->rwlock); 891 936 892 return node; 893 } 894 937 return dev; 938 } 939 940 /* Function nodes */ 941 942 /** Create a new function node. 943 * 944 * @return A function node structure. 945 */ 946 fun_node_t *create_fun_node(void) 947 { 948 fun_node_t *res = malloc(sizeof(fun_node_t)); 949 950 if (res != NULL) { 951 memset(res, 0, sizeof(fun_node_t)); 952 link_initialize(&res->dev_functions); 953 list_initialize(&res->match_ids.ids); 954 list_initialize(&res->classes); 955 link_initialize(&res->devman_fun); 956 link_initialize(&res->devmap_fun); 957 } 958 959 return res; 960 } 961 962 /** Delete a function node. 963 * 964 * @param fun The device node structure. 965 */ 966 void delete_fun_node(fun_node_t *fun) 967 { 968 assert(fun->dev == NULL); 969 assert(fun->child == NULL); 970 971 clean_match_ids(&fun->match_ids); 972 free_not_null(fun->name); 973 free_not_null(fun->pathname); 974 free(fun); 975 } 976 977 /** Find the function node with the specified handle. 978 * 979 * @param tree The device tree where we look for the device node. 980 * @param handle The handle of the function. 981 * @return The function node. 982 */ 983 fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 984 { 985 unsigned long key = handle; 986 link_t *link; 987 988 assert(fibril_rwlock_is_locked(&tree->rwlock)); 989 990 link = hash_table_find(&tree->devman_functions, &key); 991 if (link == NULL) 992 return NULL; 993 994 return hash_table_get_instance(link, fun_node_t, devman_fun); 995 } 996 997 /** Find the function node with the specified handle. 998 * 999 * @param tree The device tree where we look for the device node. 1000 * @param handle The handle of the function. 1001 * @return The function node. 1002 */ 1003 fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle) 1004 { 1005 fun_node_t *fun = NULL; 1006 1007 fibril_rwlock_read_lock(&tree->rwlock); 1008 fun = find_fun_node_no_lock(tree, handle); 1009 fibril_rwlock_read_unlock(&tree->rwlock); 1010 1011 return fun; 1012 } 895 1013 896 1014 /** Create and set device's full path in device tree. … … 901 1019 * resources etc.). 902 1020 */ 903 static bool set_ dev_path(node_t *node,node_t *parent)904 { 905 assert( node->name != NULL);906 907 size_t pathsize = (str_size( node->name) + 1);1021 static bool set_fun_path(fun_node_t *fun, fun_node_t *parent) 1022 { 1023 assert(fun->name != NULL); 1024 1025 size_t pathsize = (str_size(fun->name) + 1); 908 1026 if (parent != NULL) 909 1027 pathsize += str_size(parent->pathname) + 1; 910 1028 911 node->pathname = (char *) malloc(pathsize);912 if ( node->pathname == NULL) {1029 fun->pathname = (char *) malloc(pathsize); 1030 if (fun->pathname == NULL) { 913 1031 printf(NAME ": failed to allocate device path.\n"); 914 1032 return false; … … 916 1034 917 1035 if (parent != NULL) { 918 str_cpy( node->pathname, pathsize, parent->pathname);919 str_append( node->pathname, pathsize, "/");920 str_append( node->pathname, pathsize, node->name);1036 str_cpy(fun->pathname, pathsize, parent->pathname); 1037 str_append(fun->pathname, pathsize, "/"); 1038 str_append(fun->pathname, pathsize, fun->name); 921 1039 } else { 922 str_cpy( node->pathname, pathsize, node->name);1040 str_cpy(fun->pathname, pathsize, fun->name); 923 1041 } 924 1042 … … 936 1054 * etc.). 937 1055 */ 938 bool insert_dev_node(dev_tree_t *tree, node_t *node, char *dev_name, 939 node_t *parent) 940 { 941 assert(node != NULL); 1056 bool insert_dev_node(dev_tree_t *tree, dev_node_t *dev, fun_node_t *pfun) 1057 { 1058 assert(dev != NULL); 942 1059 assert(tree != NULL); 943 assert(dev_name != NULL);944 1060 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 945 1061 946 node->name = dev_name; 947 if (!set_dev_path(node, parent)) { 1062 /* Add the node to the handle-to-node map. */ 1063 dev->handle = ++tree->current_handle; 1064 unsigned long key = dev->handle; 1065 hash_table_insert(&tree->devman_devices, &key, &dev->devman_dev); 1066 1067 /* Add the node to the list of its parent's children. */ 1068 printf("insert_dev_node: dev=%p, dev->pfun := %p\n", dev, pfun); 1069 dev->pfun = pfun; 1070 pfun->child = dev; 1071 1072 return true; 1073 } 1074 1075 /** Insert new function into device tree. 1076 * 1077 * @param tree The device tree. 1078 * @param node The newly added function node. 1079 * @param dev_name The name of the newly added function. 1080 * @param parent Owning device node. 1081 * 1082 * @return True on success, false otherwise (insufficient resources 1083 * etc.). 1084 */ 1085 bool insert_fun_node(dev_tree_t *tree, fun_node_t *fun, char *fun_name, 1086 dev_node_t *dev) 1087 { 1088 fun_node_t *pfun; 1089 1090 assert(fun != NULL); 1091 assert(tree != NULL); 1092 assert(fun_name != NULL); 1093 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 1094 1095 /* 1096 * The root function is a special case, it does not belong to any 1097 * device so for the root function dev == NULL. 1098 */ 1099 pfun = (dev != NULL) ? dev->pfun : NULL; 1100 1101 fun->name = fun_name; 1102 if (!set_fun_path(fun, pfun)) { 948 1103 return false; 949 1104 } 950 1105 951 1106 /* Add the node to the handle-to-node map. */ 952 node->handle = ++tree->current_handle;953 unsigned long key = node->handle;954 hash_table_insert(&tree->devman_ devices, &key, &node->devman_link);1107 fun->handle = ++tree->current_handle; 1108 unsigned long key = fun->handle; 1109 hash_table_insert(&tree->devman_functions, &key, &fun->devman_fun); 955 1110 956 1111 /* Add the node to the list of its parent's children. */ 957 node->parent = parent;958 if ( parent!= NULL)959 list_append(& node->sibling, &parent->children);1112 fun->dev = dev; 1113 if (dev != NULL) 1114 list_append(&fun->dev_functions, &dev->functions); 960 1115 961 1116 return true; 962 1117 } 963 1118 964 /** Find devicenode with a specified path in the device tree.1119 /** Find function node with a specified path in the device tree. 965 1120 * 966 * @param path The path of the devicenode in the device tree.1121 * @param path The path of the function node in the device tree. 967 1122 * @param tree The device tree. 968 * @return The devicenode if it is present in the tree, NULL1123 * @return The function node if it is present in the tree, NULL 969 1124 * otherwise. 970 1125 */ 971 node_t *find_dev_node_by_path(dev_tree_t *tree, char *path)1126 fun_node_t *find_fun_node_by_path(dev_tree_t *tree, char *path) 972 1127 { 973 1128 fibril_rwlock_read_lock(&tree->rwlock); 974 1129 975 node_t *dev= tree->root_node;1130 fun_node_t *fun = tree->root_node; 976 1131 /* 977 * Relative path to the devicefrom its parent (but with '/' at the1132 * Relative path to the function from its parent (but with '/' at the 978 1133 * beginning) 979 1134 */ … … 982 1137 bool cont = (rel_path[0] == '/'); 983 1138 984 while (cont && dev!= NULL) {1139 while (cont && fun != NULL) { 985 1140 next_path_elem = get_path_elem_end(rel_path + 1); 986 1141 if (next_path_elem[0] == '/') { … … 991 1146 } 992 1147 993 dev = find_node_child(dev, rel_path + 1);1148 fun = find_node_child(fun, rel_path + 1); 994 1149 995 1150 if (cont) { … … 1002 1157 fibril_rwlock_read_unlock(&tree->rwlock); 1003 1158 1004 return dev;1005 } 1006 1007 /** Find child devicenode with a specified name.1159 return fun; 1160 } 1161 1162 /** Find child function node with a specified name. 1008 1163 * 1009 1164 * Device tree rwlock should be held at least for reading. 1010 1165 * 1011 * @param parent The parent devicenode.1012 * @param name The name of the child device node.1013 * @return The child devicenode.1014 */ 1015 node_t *find_node_child(node_t *parent, const char *name)1016 { 1017 node_t *dev;1166 * @param parent The parent function node. 1167 * @param name The name of the child function. 1168 * @return The child function node. 1169 */ 1170 fun_node_t *find_node_child(fun_node_t *pfun, const char *name) 1171 { 1172 fun_node_t *fun; 1018 1173 link_t *link; 1019 1174 1020 link = p arent->children.next;1021 1022 while (link != &p arent->children) {1023 dev = list_get_instance(link, node_t, sibling);1175 link = pfun->child->functions.next; 1176 1177 while (link != &pfun->child->functions) { 1178 fun = list_get_instance(link, fun_node_t, dev_functions); 1024 1179 1025 if (str_cmp(name, dev->name) == 0)1026 return dev;1180 if (str_cmp(name, fun->name) == 0) 1181 return fun; 1027 1182 1028 1183 link = link->next; … … 1107 1262 } 1108 1263 1109 /** Add the device to the class.1264 /** Add the device function to the class. 1110 1265 * 1111 1266 * The device may be added to multiple classes and a class may contain multiple … … 1120 1275 * with the class. 1121 1276 */ 1122 dev_class_info_t *add_ device_to_class(node_t *dev, dev_class_t *cl,1277 dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl, 1123 1278 const char *base_dev_name) 1124 1279 { 1125 dev_class_info_t *info = create_dev_class_info(); 1280 dev_class_info_t *info; 1281 1282 assert(fun != NULL); 1283 assert(cl != NULL); 1284 1285 info = create_dev_class_info(); 1286 1126 1287 1127 1288 if (info != NULL) { 1128 1289 info->dev_class = cl; 1129 info-> dev = dev;1290 info->fun = fun; 1130 1291 1131 1292 /* Add the device to the class. */ … … 1135 1296 1136 1297 /* Add the class to the device. */ 1137 list_append(&info->dev_classes, & dev->classes);1298 list_append(&info->dev_classes, &fun->classes); 1138 1299 1139 1300 /* Create unique name for the device within the class. */ … … 1189 1350 list_initialize(&class_list->classes); 1190 1351 fibril_rwlock_initialize(&class_list->rwlock); 1191 hash_table_create(&class_list->devmap_ devices, DEVICE_BUCKETS, 1,1352 hash_table_create(&class_list->devmap_functions, DEVICE_BUCKETS, 1, 1192 1353 &devmap_devices_class_ops); 1193 1354 } … … 1196 1357 /* Devmap devices */ 1197 1358 1198 node_t *find_devmap_tree_device(dev_tree_t *tree, devmap_handle_t devmap_handle)1199 { 1200 node_t *dev= NULL;1359 fun_node_t *find_devmap_tree_function(dev_tree_t *tree, devmap_handle_t devmap_handle) 1360 { 1361 fun_node_t *fun = NULL; 1201 1362 link_t *link; 1202 1363 unsigned long key = (unsigned long) devmap_handle; 1203 1364 1204 1365 fibril_rwlock_read_lock(&tree->rwlock); 1205 link = hash_table_find(&tree->devmap_ devices, &key);1366 link = hash_table_find(&tree->devmap_functions, &key); 1206 1367 if (link != NULL) 1207 dev = hash_table_get_instance(link, node_t, devmap_link);1368 fun = hash_table_get_instance(link, fun_node_t, devmap_fun); 1208 1369 fibril_rwlock_read_unlock(&tree->rwlock); 1209 1370 1210 return dev;1211 } 1212 1213 node_t *find_devmap_class_device(class_list_t *classes,1371 return fun; 1372 } 1373 1374 fun_node_t *find_devmap_class_function(class_list_t *classes, 1214 1375 devmap_handle_t devmap_handle) 1215 1376 { 1216 node_t *dev= NULL;1377 fun_node_t *fun = NULL; 1217 1378 dev_class_info_t *cli; 1218 1379 link_t *link; … … 1220 1381 1221 1382 fibril_rwlock_read_lock(&classes->rwlock); 1222 link = hash_table_find(&classes->devmap_ devices, &key);1383 link = hash_table_find(&classes->devmap_functions, &key); 1223 1384 if (link != NULL) { 1224 1385 cli = hash_table_get_instance(link, dev_class_info_t, 1225 1386 devmap_link); 1226 dev = cli->dev;1387 fun = cli->fun; 1227 1388 } 1228 1389 fibril_rwlock_read_unlock(&classes->rwlock); 1229 1390 1230 return dev;1231 } 1232 1233 void class_add_devmap_ device(class_list_t *class_list, dev_class_info_t *cli)1391 return fun; 1392 } 1393 1394 void class_add_devmap_function(class_list_t *class_list, dev_class_info_t *cli) 1234 1395 { 1235 1396 unsigned long key = (unsigned long) cli->devmap_handle; 1236 1397 1237 1398 fibril_rwlock_write_lock(&class_list->rwlock); 1238 hash_table_insert(&class_list->devmap_ devices, &key, &cli->devmap_link);1399 hash_table_insert(&class_list->devmap_functions, &key, &cli->devmap_link); 1239 1400 fibril_rwlock_write_unlock(&class_list->rwlock); 1240 1401 1241 assert(find_devmap_class_ device(class_list, cli->devmap_handle) != NULL);1242 } 1243 1244 void tree_add_devmap_ device(dev_tree_t *tree, node_t *node)1245 { 1246 unsigned long key = (unsigned long) node->devmap_handle;1402 assert(find_devmap_class_function(class_list, cli->devmap_handle) != NULL); 1403 } 1404 1405 void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun) 1406 { 1407 unsigned long key = (unsigned long) fun->devmap_handle; 1247 1408 fibril_rwlock_write_lock(&tree->rwlock); 1248 hash_table_insert(&tree->devmap_ devices, &key, &node->devmap_link);1409 hash_table_insert(&tree->devmap_functions, &key, &fun->devmap_fun); 1249 1410 fibril_rwlock_write_unlock(&tree->rwlock); 1250 1411 } -
uspace/srv/devman/devman.h
r8b5690f rba38f72c 56 56 #define DEVMAP_SEPARATOR '\\' 57 57 58 struct node; 59 typedef struct node node_t; 58 struct dev_node; 59 typedef struct dev_node dev_node_t; 60 61 struct fun_node; 62 typedef struct fun_node fun_node_t; 60 63 61 64 typedef enum { … … 117 120 } device_state_t; 118 121 119 /** Representation of anode in the device tree. */120 struct node {122 /** Device node in the device tree. */ 123 struct dev_node { 121 124 /** The global unique identifier of the device. */ 122 125 devman_handle_t handle; 123 /** The name of the device specified by its parent. */ 124 char *name; 125 126 /** 127 * Full path and name of the device in device hierarchi (i. e. in full 128 * path in device tree). 129 */ 130 char *pathname; 131 132 /** The node of the parent device. */ 133 node_t *parent; 134 135 /** 136 * Pointers to previous and next child devices in the linked list of 137 * parent device's node. 138 */ 139 link_t sibling; 140 141 /** List of child device nodes. */ 142 link_t children; 143 /** List of device ids for device-to-driver matching. */ 144 match_id_list_t match_ids; 126 127 /** (Parent) function the device is attached to. */ 128 fun_node_t *pfun; 129 130 /** List of device functions. */ 131 link_t functions; 145 132 /** Driver of this device. */ 146 133 driver_t *drv; 147 134 /** The state of the device. */ 148 135 device_state_t state; 149 /** 150 * Pointer to the previous and next device in the list of devices 151 * owned by one driver. 152 */ 136 /** Link to list of devices owned by driver (driver_t.devices) */ 153 137 link_t driver_devices; 154 138 155 /** The list of device classes to which this device belongs. */156 link_t classes;157 /** Devmap handle if the device is registered by devmapper. */158 devmap_handle_t devmap_handle;159 160 139 /** 161 140 * Used by the hash table of devices indexed by devman device handles. 162 141 */ 163 link_t devman_link; 164 165 /** 166 * Used by the hash table of devices indexed by devmap device handles. 167 */ 168 link_t devmap_link; 169 142 link_t devman_dev; 143 170 144 /** 171 145 * Whether this device was already passed to the driver. … … 173 147 bool passed_to_driver; 174 148 }; 149 150 /** Function node in the device tree. */ 151 struct fun_node { 152 /** The global unique identifier of the function */ 153 devman_handle_t handle; 154 /** Name of the function, assigned by the device driver */ 155 char *name; 156 157 /** Full path and name of the device in device hierarchy */ 158 char *pathname; 159 160 /** Device which this function belongs to */ 161 dev_node_t *dev; 162 163 /** Link to list of functions in the device (device_t.functions) */ 164 link_t dev_functions; 165 166 /** Child device node (if any attached). */ 167 dev_node_t *child; 168 /** List of device ids for device-to-driver matching. */ 169 match_id_list_t match_ids; 170 171 /** The list of device classes to which this device function belongs. */ 172 link_t classes; 173 /** Devmap handle if the device function is registered by devmap. */ 174 devmap_handle_t devmap_handle; 175 176 /** 177 * Used by the hash table of functions indexed by devman device handles. 178 */ 179 link_t devman_fun; 180 181 /** 182 * Used by the hash table of functions indexed by devmap device handles. 183 */ 184 link_t devmap_fun; 185 }; 186 175 187 176 188 /** Represents device tree. */ 177 189 typedef struct dev_tree { 178 190 /** Root device node. */ 179 node_t *root_node;191 fun_node_t *root_node; 180 192 181 193 /** … … 191 203 hash_table_t devman_devices; 192 204 205 /** Hash table of all devices indexed by devman handles. */ 206 hash_table_t devman_functions; 207 193 208 /** 194 209 * Hash table of devices registered by devmapper, indexed by devmap 195 210 * handles. 196 211 */ 197 hash_table_t devmap_ devices;212 hash_table_t devmap_functions; 198 213 } dev_tree_t; 199 214 … … 227 242 228 243 /** 229 * Provides n-to-m mapping between device nodes and classes - each device may230 * be register to the arbitrary number of classes and each class maycontain231 * the arbitrary number of devices.244 * Provides n-to-m mapping between function nodes and classes - each function 245 * can register in an arbitrary number of classes and each class can contain 246 * an arbitrary number of device functions. 232 247 */ 233 248 typedef struct dev_class_info { … … 235 250 dev_class_t *dev_class; 236 251 /** The device. */ 237 node_t *dev;252 fun_node_t *fun; 238 253 239 254 /** … … 249 264 link_t dev_classes; 250 265 251 /** The name of the device within the class. */266 /** The name of the device function within the class. */ 252 267 char *dev_name; 253 268 /** The handle of the device by device mapper in the class namespace. */ … … 270 285 * indexed by devmap handles. 271 286 */ 272 hash_table_t devmap_ devices;287 hash_table_t devmap_functions; 273 288 274 289 /** Fibril mutex for list of classes. */ … … 278 293 /* Match ids and scores */ 279 294 280 extern int get_match_score(driver_t *, node_t *);295 extern int get_match_score(driver_t *, dev_node_t *); 281 296 282 297 extern bool parse_match_ids(char *, match_id_list_t *); … … 292 307 extern int lookup_available_drivers(driver_list_t *, const char *); 293 308 294 extern driver_t *find_best_match_driver(driver_list_t *, node_t *);295 extern bool assign_driver( node_t *, driver_list_t *, dev_tree_t *);309 extern driver_t *find_best_match_driver(driver_list_t *, dev_node_t *); 310 extern bool assign_driver(dev_node_t *, driver_list_t *, dev_tree_t *); 296 311 297 312 extern void add_driver(driver_list_t *, driver_t *); 298 extern void attach_driver( node_t *, driver_t *);299 extern void add_device(int, driver_t *, node_t *, dev_tree_t *);313 extern void attach_driver(dev_node_t *, driver_t *); 314 extern void add_device(int, driver_t *, dev_node_t *, dev_tree_t *); 300 315 extern bool start_driver(driver_t *); 301 316 … … 310 325 /* Device nodes */ 311 326 312 extern node_t *create_dev_node(void);313 extern void delete_dev_node( node_t *node);314 extern node_t *find_dev_node_no_lock(dev_tree_t *tree,327 extern dev_node_t *create_dev_node(void); 328 extern void delete_dev_node(dev_node_t *node); 329 extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, 315 330 devman_handle_t handle); 316 extern node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle); 317 extern node_t *find_dev_node_by_path(dev_tree_t *, char *); 318 extern node_t *find_node_child(node_t *, const char *); 331 extern dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle); 332 extern dev_node_t *find_dev_function(dev_node_t *, const char *); 333 334 extern fun_node_t *create_fun_node(void); 335 extern void delete_fun_node(fun_node_t *); 336 extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, 337 devman_handle_t handle); 338 extern fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle); 339 extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *); 319 340 320 341 /* Device tree */ 321 342 322 343 extern bool init_device_tree(dev_tree_t *, driver_list_t *); 323 extern bool create_root_node(dev_tree_t *); 324 extern bool insert_dev_node(dev_tree_t *, node_t *, char *, node_t *); 344 extern bool create_root_nodes(dev_tree_t *); 345 extern bool insert_dev_node(dev_tree_t *, dev_node_t *, fun_node_t *); 346 extern bool insert_fun_node(dev_tree_t *, fun_node_t *, char *, dev_node_t *); 325 347 326 348 /* Device classes */ … … 330 352 extern size_t get_new_class_dev_idx(dev_class_t *); 331 353 extern char *create_dev_name_for_class(dev_class_t *, const char *); 332 extern dev_class_info_t *add_ device_to_class(node_t *, dev_class_t *,354 extern dev_class_info_t *add_function_to_class(fun_node_t *, dev_class_t *, 333 355 const char *); 334 356 … … 341 363 /* Devmap devices */ 342 364 343 extern node_t *find_devmap_tree_device(dev_tree_t *, devmap_handle_t);344 extern node_t *find_devmap_class_device(class_list_t *, devmap_handle_t);345 346 extern void class_add_devmap_ device(class_list_t *, dev_class_info_t *);347 extern void tree_add_devmap_ device(dev_tree_t *,node_t *);365 extern fun_node_t *find_devmap_tree_function(dev_tree_t *, devmap_handle_t); 366 extern fun_node_t *find_devmap_class_function(class_list_t *, devmap_handle_t); 367 368 extern void class_add_devmap_function(class_list_t *, dev_class_info_t *); 369 extern void tree_add_devmap_function(dev_tree_t *, fun_node_t *); 348 370 349 371 #endif -
uspace/srv/devman/main.c
r8b5690f rba38f72c 199 199 static int assign_driver_fibril(void *arg) 200 200 { 201 node_t *node = (node_t *) arg;202 assign_driver( node, &drivers_list, &device_tree);201 dev_node_t *dev_node = (dev_node_t *) arg; 202 assign_driver(dev_node, &drivers_list, &device_tree); 203 203 return EOK; 204 204 } … … 215 215 216 216 fibril_rwlock_write_lock(&tree->rwlock); 217 node_t *parent= find_dev_node_no_lock(&device_tree, parent_handle);218 219 if (p arent== NULL) {217 dev_node_t *pdev = find_dev_node_no_lock(&device_tree, parent_handle); 218 219 if (pdev == NULL) { 220 220 fibril_rwlock_write_unlock(&tree->rwlock); 221 221 async_answer_0(callid, ENOENT); … … 223 223 } 224 224 225 char * dev_name = NULL;226 int rc = async_data_write_accept((void **)& dev_name, true, 0, 0, 0, 0);225 char *fun_name = NULL; 226 int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0); 227 227 if (rc != EOK) { 228 228 fibril_rwlock_write_unlock(&tree->rwlock); … … 231 231 } 232 232 233 node_t *node = create_dev_node();234 if (!insert_ dev_node(&device_tree, node, dev_name, parent)) {233 fun_node_t *fun = create_fun_node(); 234 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 235 235 fibril_rwlock_write_unlock(&tree->rwlock); 236 delete_ dev_node(node);236 delete_fun_node(fun); 237 237 async_answer_0(callid, ENOMEM); 238 238 return; 239 239 } 240 240 241 dev_node_t *dev; 242 243 dev = create_dev_node(); 244 if (dev == NULL) { 245 fibril_rwlock_write_unlock(&tree->rwlock); 246 delete_fun_node(fun); 247 async_answer_0(callid, ENOMEM); 248 return; 249 } 250 251 insert_dev_node(tree, dev, fun); 252 241 253 fibril_rwlock_write_unlock(&tree->rwlock); 242 254 243 printf(NAME ": devman_add_child %s\n", node->pathname);244 245 devman_receive_match_ids(match_count, & node->match_ids);255 printf(NAME ": devman_add_child %s\n", fun->pathname); 256 257 devman_receive_match_ids(match_count, &fun->match_ids); 246 258 247 259 /* … … 252 264 * task spawning which could take some time. 253 265 */ 254 fid_t assign_fibril = fibril_create(assign_driver_fibril, node);266 fid_t assign_fibril = fibril_create(assign_driver_fibril, dev); 255 267 if (assign_fibril == 0) { 256 268 /* … … 258 270 * Probably not needed as we will die soon anyway ;-). 259 271 */ 260 (void) assign_driver_fibril( node);272 (void) assign_driver_fibril(fun); 261 273 } else { 262 274 fibril_add_ready(assign_fibril); … … 264 276 265 277 /* Return device handle to parent's driver. */ 266 async_answer_1(callid, EOK, node->handle);278 async_answer_1(callid, EOK, fun->handle); 267 279 } 268 280 … … 288 300 * mapper. 289 301 */ 290 class_add_devmap_ device(&class_list, cli);302 class_add_devmap_function(&class_list, cli); 291 303 292 304 free(devmap_pathname); 293 305 } 294 306 295 static void devman_add_ device_to_class(ipc_callid_t callid, ipc_call_t *call)307 static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call) 296 308 { 297 309 devman_handle_t handle = IPC_GET_ARG1(*call); … … 306 318 } 307 319 308 node_t *dev = find_dev_node(&device_tree, handle);309 if ( dev== NULL) {320 fun_node_t *fun = find_fun_node(&device_tree, handle); 321 if (fun == NULL) { 310 322 async_answer_0(callid, ENOENT); 311 323 return; … … 313 325 314 326 dev_class_t *cl = get_dev_class(&class_list, class_name); 315 dev_class_info_t *class_info = add_ device_to_class(dev, cl, NULL);327 dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL); 316 328 317 329 /* Register the device's class alias by devmapper. */ 318 330 devmap_register_class_dev(class_info); 319 331 320 printf(NAME ": device'%s' added to class '%s', class name '%s' was "321 "asigned to it\n", dev->pathname, class_name, class_info->dev_name);332 printf(NAME ": function'%s' added to class '%s', class name '%s' was " 333 "asigned to it\n", fun->pathname, class_name, class_info->dev_name); 322 334 323 335 async_answer_0(callid, EOK); … … 376 388 break; 377 389 case DEVMAN_ADD_DEVICE_TO_CLASS: 378 devman_add_ device_to_class(callid, &call);390 devman_add_function_to_class(callid, &call); 379 391 break; 380 392 default: … … 387 399 /** Find handle for the device instance identified by the device's path in the 388 400 * device tree. */ 389 static void devman_ device_get_handle(ipc_callid_t iid, ipc_call_t *icall)401 static void devman_function_get_handle(ipc_callid_t iid, ipc_call_t *icall) 390 402 { 391 403 char *pathname; … … 397 409 } 398 410 399 node_t * dev = find_dev_node_by_path(&device_tree, pathname);411 fun_node_t * fun = find_fun_node_by_path(&device_tree, pathname); 400 412 401 413 free(pathname); 402 414 403 if ( dev== NULL) {415 if (fun == NULL) { 404 416 async_answer_0(iid, ENOENT); 405 417 return; 406 418 } 407 419 408 async_answer_1(iid, EOK, dev->handle);420 async_answer_1(iid, EOK, fun->handle); 409 421 } 410 422 … … 426 438 continue; 427 439 case DEVMAN_DEVICE_GET_HANDLE: 428 devman_ device_get_handle(callid, &call);440 devman_function_get_handle(callid, &call); 429 441 break; 430 442 default: … … 439 451 devman_handle_t handle = IPC_GET_ARG2(*icall); 440 452 441 node_t *dev = find_dev_node(&device_tree, handle);442 if ( dev== NULL) {443 printf(NAME ": devman_forward error - no device with handle %" PRIun444 " was found.\n", handle);453 fun_node_t *fun = find_fun_node(&device_tree, handle); 454 if (fun == NULL) { 455 printf(NAME ": devman_forward error - no device function with " 456 "handle %" PRIun " was found.\n", handle); 445 457 async_answer_0(iid, ENOENT); 446 458 return; … … 450 462 451 463 if (drv_to_parent) { 452 if ( dev->parent!= NULL)453 driver = dev->parent->drv;454 } else if ( dev->state == DEVICE_USABLE) {455 driver = dev->drv;464 if (fun->dev->pfun != NULL) 465 driver = fun->dev->pfun->dev->drv; 466 } else if (fun->dev->state == DEVICE_USABLE) { 467 driver = fun->dev->drv; 456 468 assert(driver != NULL); 457 469 } … … 478 490 } 479 491 480 printf(NAME ": devman_forward: forward connection to device%s to "481 "driver %s.\n", dev->pathname, driver->name);482 async_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE);492 printf(NAME ": devman_forward: forward connection to function %s to " 493 "driver %s.\n", fun->pathname, driver->name); 494 async_forward_fast(iid, driver->phone, method, fun->handle, 0, IPC_FF_NONE); 483 495 } 484 496 … … 488 500 { 489 501 devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall); 490 node_t *dev; 491 492 dev = find_devmap_tree_device(&device_tree, devmap_handle); 493 if (dev == NULL) 494 dev = find_devmap_class_device(&class_list, devmap_handle); 495 496 if (dev == NULL || dev->drv == NULL) { 502 fun_node_t *fun; 503 dev_node_t *dev; 504 505 fun = find_devmap_tree_function(&device_tree, devmap_handle); 506 if (fun == NULL) 507 fun = find_devmap_class_function(&class_list, devmap_handle); 508 509 if (fun == NULL || fun->dev->drv == NULL) { 497 510 async_answer_0(iid, ENOENT); 498 511 return; 499 512 } 513 514 dev = fun->dev; 500 515 501 516 if (dev->state != DEVICE_USABLE || dev->drv->phone <= 0) { … … 507 522 IPC_FF_NONE); 508 523 printf(NAME ": devman_connection_devmapper: forwarded connection to " 509 "device %s to driver %s.\n", dev->pathname, dev->drv->name);524 "device %s to driver %s.\n", fun->pathname, dev->drv->name); 510 525 } 511 526 -
uspace/srv/devman/match.c
r8b5690f rba38f72c 57 57 } 58 58 59 int get_match_score(driver_t *drv, node_t *dev)59 int get_match_score(driver_t *drv, dev_node_t *dev) 60 60 { 61 61 link_t *drv_head = &drv->match_ids.ids; 62 link_t *dev_head = &dev-> match_ids.ids;62 link_t *dev_head = &dev->pfun->match_ids.ids; 63 63 64 64 if (list_empty(drv_head) || list_empty(dev_head))
Note:
See TracChangeset
for help on using the changeset viewer.