Changes in uspace/srv/devman/devman.c [4022513:45059d6b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r4022513 r45059d6b 37 37 #include <ipc/driver.h> 38 38 #include <ipc/devman.h> 39 #include < devmap.h>39 #include <loc.h> 40 40 #include <str_error.h> 41 41 #include <stdio.h> … … 66 66 } 67 67 68 static int devmap_functions_compare(unsigned long key[], hash_count_t keys,68 static int loc_functions_compare(unsigned long key[], hash_count_t keys, 69 69 link_t *item) 70 70 { 71 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devmap_fun); 72 return (fun->devmap_handle == (devmap_handle_t) key[0]); 73 } 74 75 static int devmap_devices_class_compare(unsigned long key[], hash_count_t keys, 76 link_t *item) 77 { 78 dev_class_info_t *class_info 79 = hash_table_get_instance(item, dev_class_info_t, devmap_link); 80 assert(class_info != NULL); 81 82 return (class_info->devmap_handle == (devmap_handle_t) key[0]); 71 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, loc_fun); 72 return (fun->service_id == (service_id_t) key[0]); 83 73 } 84 74 … … 99 89 }; 100 90 101 static hash_table_operations_t devmap_devices_ops = {91 static hash_table_operations_t loc_devices_ops = { 102 92 .hash = devices_hash, 103 .compare = devmap_functions_compare, 104 .remove_callback = devices_remove_callback 105 }; 106 107 static hash_table_operations_t devmap_devices_class_ops = { 108 .hash = devices_hash, 109 .compare = devmap_devices_class_compare, 93 .compare = loc_functions_compare, 110 94 .remove_callback = devices_remove_callback 111 95 }; … … 564 548 565 549 fibril_mutex_lock(&driver->driver_mutex); 566 567 async_exch_t *exch = async_exchange_begin(driver->sess);568 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,569 DRIVER_DEVMAN, 0, 0);570 async_exchange_end(exch);571 572 if (!sess) {573 fibril_mutex_unlock(&driver->driver_mutex);574 return;575 }576 550 577 551 /* … … 599 573 fibril_mutex_unlock(&driver->driver_mutex); 600 574 601 add_device( sess,driver, dev, tree);575 add_device(driver, dev, tree); 602 576 603 577 /* … … 619 593 link = driver->devices.head.next; 620 594 } 621 622 async_hangup(sess);623 595 624 596 /* … … 701 673 } 702 674 703 /** Create devmappath and name for the function. */704 void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree)705 { 706 char * devmap_pathname = NULL;707 char * devmap_name = NULL;708 709 asprintf(& devmap_name, "%s", fun->pathname);710 if ( devmap_name == NULL)675 /** Create loc path and name for the function. */ 676 void loc_register_tree_function(fun_node_t *fun, dev_tree_t *tree) 677 { 678 char *loc_pathname = NULL; 679 char *loc_name = NULL; 680 681 asprintf(&loc_name, "%s", fun->pathname); 682 if (loc_name == NULL) 711 683 return; 712 684 713 replace_char( devmap_name, '/', DEVMAP_SEPARATOR);714 715 asprintf(& devmap_pathname, "%s/%s", DEVMAP_DEVICE_NAMESPACE,716 devmap_name);717 if ( devmap_pathname == NULL) {718 free( devmap_name);685 replace_char(loc_name, '/', LOC_SEPARATOR); 686 687 asprintf(&loc_pathname, "%s/%s", LOC_DEVICE_NAMESPACE, 688 loc_name); 689 if (loc_pathname == NULL) { 690 free(loc_name); 719 691 return; 720 692 } 721 693 722 devmap_device_register_with_iface(devmap_pathname,723 &fun-> devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);724 725 tree_add_ devmap_function(tree, fun);726 727 free( devmap_name);728 free( devmap_pathname);694 loc_service_register_with_iface(loc_pathname, 695 &fun->service_id, DEVMAN_CONNECT_FROM_LOC); 696 697 tree_add_loc_function(tree, fun); 698 699 free(loc_name); 700 free(loc_pathname); 729 701 } 730 702 … … 734 706 * @param node The device's node in the device tree. 735 707 */ 736 void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev, 737 dev_tree_t *tree) 708 void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree) 738 709 { 739 710 /* … … 752 723 } 753 724 754 async_exch_t *exch = async_exchange_begin( sess);725 async_exch_t *exch = async_exchange_begin(drv->sess); 755 726 756 727 ipc_call_t answer; … … 822 793 fibril_mutex_unlock(&drv->driver_mutex); 823 794 824 if (is_running) { 825 /* Notify the driver about the new device. */ 826 async_exch_t *exch = async_exchange_begin(drv->sess); 827 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch, 828 DRIVER_DEVMAN, 0, 0); 829 async_exchange_end(exch); 830 831 if (sess) { 832 add_device(sess, drv, dev, tree); 833 async_hangup(sess); 834 } 835 } 795 /* Notify the driver about the new device. */ 796 if (is_running) 797 add_device(drv, dev, tree); 836 798 837 799 return true; … … 856 818 hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1, 857 819 &devman_functions_ops); 858 hash_table_create(&tree-> devmap_functions, DEVICE_BUCKETS, 1,859 & devmap_devices_ops);820 hash_table_create(&tree->loc_functions, DEVICE_BUCKETS, 1, 821 &loc_devices_ops); 860 822 861 823 fibril_rwlock_initialize(&tree->rwlock); … … 936 898 } 937 899 900 /** Get list of device functions. */ 901 int dev_get_functions(dev_tree_t *tree, dev_node_t *dev, 902 devman_handle_t *hdl_buf, size_t buf_size, size_t *act_size) 903 { 904 size_t act_cnt; 905 size_t buf_cnt; 906 907 assert(fibril_rwlock_is_locked(&tree->rwlock)); 908 909 buf_cnt = buf_size / sizeof(devman_handle_t); 910 911 act_cnt = list_count(&dev->functions); 912 *act_size = act_cnt * sizeof(devman_handle_t); 913 914 if (buf_size % sizeof(devman_handle_t) != 0) 915 return EINVAL; 916 917 size_t pos = 0; 918 list_foreach(dev->functions, item) { 919 fun_node_t *fun = 920 list_get_instance(item, fun_node_t, dev_functions); 921 922 if (pos < buf_cnt) 923 hdl_buf[pos] = fun->handle; 924 pos++; 925 } 926 927 return EOK; 928 } 929 930 938 931 /* Function nodes */ 939 932 … … 950 943 link_initialize(&res->dev_functions); 951 944 list_initialize(&res->match_ids.ids); 952 list_initialize(&res->classes);953 945 link_initialize(&res->devman_fun); 954 link_initialize(&res-> devmap_fun);946 link_initialize(&res->loc_fun); 955 947 } 956 948 … … 1115 1107 1116 1108 return true; 1109 } 1110 1111 /** Remove function from device tree. 1112 * 1113 * @param tree Device tree 1114 * @param node Function node to remove 1115 */ 1116 void remove_fun_node(dev_tree_t *tree, fun_node_t *fun) 1117 { 1118 assert(tree != NULL); 1119 assert(fun != NULL); 1120 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 1121 1122 /* Remove the node from the handle-to-node map. */ 1123 unsigned long key = fun->handle; 1124 hash_table_remove(&tree->devman_functions, &key, 1); 1125 1126 /* Remove the node from the list of its parent's children. */ 1127 if (fun->dev != NULL) 1128 list_remove(&fun->dev_functions); 1117 1129 } 1118 1130 … … 1142 1154 char *rel_path = path; 1143 1155 char *next_path_elem = NULL; 1144 bool cont = true;1156 bool cont = (rel_path[1] != '\0'); 1145 1157 1146 1158 while (cont && fun != NULL) { … … 1193 1205 } 1194 1206 1195 /** Find function node by its class name and index. */1196 fun_node_t *find_fun_node_by_class(class_list_t *class_list,1197 const char *class_name, const char *dev_name)1198 {1199 assert(class_list != NULL);1200 assert(class_name != NULL);1201 assert(dev_name != NULL);1202 1203 fibril_rwlock_read_lock(&class_list->rwlock);1204 1205 dev_class_t *cl = find_dev_class_no_lock(class_list, class_name);1206 if (cl == NULL) {1207 fibril_rwlock_read_unlock(&class_list->rwlock);1208 return NULL;1209 }1210 1211 dev_class_info_t *dev = find_dev_in_class(cl, dev_name);1212 if (dev == NULL) {1213 fibril_rwlock_read_unlock(&class_list->rwlock);1214 return NULL;1215 }1216 1217 fun_node_t *fun = dev->fun;1218 1219 fibril_rwlock_read_unlock(&class_list->rwlock);1220 1221 return fun;1222 }1223 1224 1225 1207 /** Find child function node with a specified name. 1226 1208 * … … 1236 1218 } 1237 1219 1238 /* Device classes */ 1239 1240 /** Create device class. 1241 * 1242 * @return Device class. 1243 */ 1244 dev_class_t *create_dev_class(void) 1245 { 1246 dev_class_t *cl; 1247 1248 cl = (dev_class_t *) malloc(sizeof(dev_class_t)); 1249 if (cl != NULL) { 1250 memset(cl, 0, sizeof(dev_class_t)); 1251 list_initialize(&cl->devices); 1252 fibril_mutex_initialize(&cl->mutex); 1253 } 1254 1255 return cl; 1256 } 1257 1258 /** Create device class info. 1259 * 1260 * @return Device class info. 1261 */ 1262 dev_class_info_t *create_dev_class_info(void) 1263 { 1264 dev_class_info_t *info; 1265 1266 info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t)); 1267 if (info != NULL) { 1268 memset(info, 0, sizeof(dev_class_info_t)); 1269 link_initialize(&info->dev_classes); 1270 link_initialize(&info->devmap_link); 1271 link_initialize(&info->link); 1272 } 1273 1274 return info; 1275 } 1276 1277 size_t get_new_class_dev_idx(dev_class_t *cl) 1278 { 1279 size_t dev_idx; 1280 1281 fibril_mutex_lock(&cl->mutex); 1282 dev_idx = ++cl->curr_dev_idx; 1283 fibril_mutex_unlock(&cl->mutex); 1284 1285 return dev_idx; 1286 } 1287 1288 1289 /** Create unique device name within the class. 1290 * 1291 * @param cl The class. 1292 * @param base_dev_name Contains the base name for the device if it was 1293 * specified by the driver when it registered the device by 1294 * the class; NULL if driver specified no base name. 1295 * @return The unique name for the device within the class. 1296 */ 1297 char *create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name) 1298 { 1299 char *dev_name; 1300 const char *base_name; 1301 1302 if (base_dev_name != NULL) 1303 base_name = base_dev_name; 1304 else 1305 base_name = cl->base_dev_name; 1306 1307 size_t idx = get_new_class_dev_idx(cl); 1308 asprintf(&dev_name, "%s%zu", base_name, idx); 1309 1310 return dev_name; 1311 } 1312 1313 /** Add the device function to the class. 1314 * 1315 * The device may be added to multiple classes and a class may contain multiple 1316 * devices. The class and the device are associated with each other by the 1317 * dev_class_info_t structure. 1318 * 1319 * @param dev The device. 1320 * @param class The class. 1321 * @param base_dev_name The base name of the device within the class if 1322 * specified by the driver, NULL otherwise. 1323 * @return dev_class_info_t structure which associates the device 1324 * with the class. 1325 */ 1326 dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl, 1327 const char *base_dev_name) 1328 { 1329 dev_class_info_t *info; 1330 1331 assert(fun != NULL); 1332 assert(cl != NULL); 1333 1334 info = create_dev_class_info(); 1335 1336 1337 if (info != NULL) { 1338 info->dev_class = cl; 1339 info->fun = fun; 1340 1341 /* Add the device to the class. */ 1342 fibril_mutex_lock(&cl->mutex); 1343 list_append(&info->link, &cl->devices); 1344 fibril_mutex_unlock(&cl->mutex); 1345 1346 /* Add the class to the device. */ 1347 list_append(&info->dev_classes, &fun->classes); 1348 1349 /* Create unique name for the device within the class. */ 1350 info->dev_name = create_dev_name_for_class(cl, base_dev_name); 1351 } 1352 1353 return info; 1354 } 1355 1356 dev_class_t *get_dev_class(class_list_t *class_list, char *class_name) 1357 { 1358 dev_class_t *cl; 1359 1360 fibril_rwlock_write_lock(&class_list->rwlock); 1361 cl = find_dev_class_no_lock(class_list, class_name); 1362 if (cl == NULL) { 1363 cl = create_dev_class(); 1364 if (cl != NULL) { 1365 cl->name = class_name; 1366 cl->base_dev_name = ""; 1367 add_dev_class_no_lock(class_list, cl); 1368 } 1369 } 1370 1371 fibril_rwlock_write_unlock(&class_list->rwlock); 1372 return cl; 1373 } 1374 1375 dev_class_t *find_dev_class_no_lock(class_list_t *class_list, 1376 const char *class_name) 1377 { 1378 dev_class_t *cl; 1379 1380 list_foreach(class_list->classes, link) { 1381 cl = list_get_instance(link, dev_class_t, link); 1382 if (str_cmp(cl->name, class_name) == 0) { 1383 return cl; 1384 } 1385 } 1386 1387 return NULL; 1388 } 1389 1390 void add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl) 1391 { 1392 list_append(&cl->link, &class_list->classes); 1393 } 1394 1395 dev_class_info_t *find_dev_in_class(dev_class_t *dev_class, const char *dev_name) 1396 { 1397 assert(dev_class != NULL); 1398 assert(dev_name != NULL); 1399 1400 list_foreach(dev_class->devices, link) { 1401 dev_class_info_t *dev = list_get_instance(link, 1402 dev_class_info_t, link); 1403 1404 if (str_cmp(dev->dev_name, dev_name) == 0) { 1405 return dev; 1406 } 1407 } 1408 1409 return NULL; 1410 } 1411 1412 void init_class_list(class_list_t *class_list) 1413 { 1414 list_initialize(&class_list->classes); 1415 fibril_rwlock_initialize(&class_list->rwlock); 1416 hash_table_create(&class_list->devmap_functions, DEVICE_BUCKETS, 1, 1417 &devmap_devices_class_ops); 1418 } 1419 1420 1421 /* Devmap devices */ 1422 1423 fun_node_t *find_devmap_tree_function(dev_tree_t *tree, devmap_handle_t devmap_handle) 1220 /* loc devices */ 1221 1222 fun_node_t *find_loc_tree_function(dev_tree_t *tree, service_id_t service_id) 1424 1223 { 1425 1224 fun_node_t *fun = NULL; 1426 1225 link_t *link; 1427 unsigned long key = (unsigned long) devmap_handle;1226 unsigned long key = (unsigned long) service_id; 1428 1227 1429 1228 fibril_rwlock_read_lock(&tree->rwlock); 1430 link = hash_table_find(&tree-> devmap_functions, &key);1229 link = hash_table_find(&tree->loc_functions, &key); 1431 1230 if (link != NULL) 1432 fun = hash_table_get_instance(link, fun_node_t, devmap_fun);1231 fun = hash_table_get_instance(link, fun_node_t, loc_fun); 1433 1232 fibril_rwlock_read_unlock(&tree->rwlock); 1434 1233 … … 1436 1235 } 1437 1236 1438 fun_node_t *find_devmap_class_function(class_list_t *classes, 1439 devmap_handle_t devmap_handle) 1440 { 1441 fun_node_t *fun = NULL; 1442 dev_class_info_t *cli; 1443 link_t *link; 1444 unsigned long key = (unsigned long)devmap_handle; 1445 1446 fibril_rwlock_read_lock(&classes->rwlock); 1447 link = hash_table_find(&classes->devmap_functions, &key); 1448 if (link != NULL) { 1449 cli = hash_table_get_instance(link, dev_class_info_t, 1450 devmap_link); 1451 fun = cli->fun; 1452 } 1453 fibril_rwlock_read_unlock(&classes->rwlock); 1454 1455 return fun; 1456 } 1457 1458 void class_add_devmap_function(class_list_t *class_list, dev_class_info_t *cli) 1459 { 1460 unsigned long key = (unsigned long) cli->devmap_handle; 1461 1462 fibril_rwlock_write_lock(&class_list->rwlock); 1463 hash_table_insert(&class_list->devmap_functions, &key, &cli->devmap_link); 1464 fibril_rwlock_write_unlock(&class_list->rwlock); 1465 1466 assert(find_devmap_class_function(class_list, cli->devmap_handle) != NULL); 1467 } 1468 1469 void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun) 1470 { 1471 unsigned long key = (unsigned long) fun->devmap_handle; 1237 void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun) 1238 { 1239 unsigned long key = (unsigned long) fun->service_id; 1472 1240 fibril_rwlock_write_lock(&tree->rwlock); 1473 hash_table_insert(&tree-> devmap_functions, &key, &fun->devmap_fun);1241 hash_table_insert(&tree->loc_functions, &key, &fun->loc_fun); 1474 1242 fibril_rwlock_write_unlock(&tree->rwlock); 1475 1243 }
Note:
See TracChangeset
for help on using the changeset viewer.