Changes in uspace/srv/devman/devman.c [45059d6b:b72efe8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r45059d6b rb72efe8 37 37 #include <ipc/driver.h> 38 38 #include <ipc/devman.h> 39 #include < loc.h>39 #include <devmap.h> 40 40 #include <str_error.h> 41 41 #include <stdio.h> … … 66 66 } 67 67 68 static int loc_functions_compare(unsigned long key[], hash_count_t keys,68 static int devmap_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, loc_fun); 72 return (fun->service_id == (service_id_t) key[0]); 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]); 73 83 } 74 84 … … 89 99 }; 90 100 91 static hash_table_operations_t loc_devices_ops = {101 static hash_table_operations_t devmap_devices_ops = { 92 102 .hash = devices_hash, 93 .compare = loc_functions_compare, 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, 94 110 .remove_callback = devices_remove_callback 95 111 }; … … 254 270 } 255 271 256 ssize_t read_bytes = read_all(fd, buf, len);272 ssize_t read_bytes = safe_read(fd, buf, len); 257 273 if (read_bytes <= 0) { 258 log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path, 259 read_bytes); 274 log_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path); 260 275 goto cleanup; 261 276 } … … 406 421 } 407 422 408 insert_fun_node(tree, fun, str_dup(""), NULL);423 insert_fun_node(tree, fun, clone_string(""), NULL); 409 424 match_id_t *id = create_match_id(); 410 id->id = str_dup("root");425 id->id = clone_string("root"); 411 426 id->score = 100; 412 427 add_match_id(&fun->match_ids, id); … … 548 563 549 564 fibril_mutex_lock(&driver->driver_mutex); 565 566 async_exch_t *exch = async_exchange_begin(driver->sess); 567 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch, 568 DRIVER_DEVMAN, 0, 0); 569 async_exchange_end(exch); 570 571 if (!sess) { 572 fibril_mutex_unlock(&driver->driver_mutex); 573 return; 574 } 550 575 551 576 /* … … 573 598 fibril_mutex_unlock(&driver->driver_mutex); 574 599 575 add_device( driver, dev, tree);600 add_device(sess, driver, dev, tree); 576 601 577 602 /* … … 593 618 link = driver->devices.head.next; 594 619 } 620 621 async_hangup(sess); 595 622 596 623 /* … … 673 700 } 674 701 675 /** Create locpath 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)702 /** Create devmap path and name for the function. */ 703 void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree) 704 { 705 char *devmap_pathname = NULL; 706 char *devmap_name = NULL; 707 708 asprintf(&devmap_name, "%s", fun->pathname); 709 if (devmap_name == NULL) 683 710 return; 684 711 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);712 replace_char(devmap_name, '/', DEVMAP_SEPARATOR); 713 714 asprintf(&devmap_pathname, "%s/%s", DEVMAP_DEVICE_NAMESPACE, 715 devmap_name); 716 if (devmap_pathname == NULL) { 717 free(devmap_name); 691 718 return; 692 719 } 693 720 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);721 devmap_device_register_with_iface(devmap_pathname, 722 &fun->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP); 723 724 tree_add_devmap_function(tree, fun); 725 726 free(devmap_name); 727 free(devmap_pathname); 701 728 } 702 729 … … 706 733 * @param node The device's node in the device tree. 707 734 */ 708 void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree) 735 void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev, 736 dev_tree_t *tree) 709 737 { 710 738 /* … … 723 751 } 724 752 725 async_exch_t *exch = async_exchange_begin( drv->sess);753 async_exch_t *exch = async_exchange_begin(sess); 726 754 727 755 ipc_call_t answer; … … 793 821 fibril_mutex_unlock(&drv->driver_mutex); 794 822 795 /* Notify the driver about the new device. */ 796 if (is_running) 797 add_device(drv, dev, tree); 823 if (is_running) { 824 /* Notify the driver about the new device. */ 825 async_exch_t *exch = async_exchange_begin(drv->sess); 826 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch, 827 DRIVER_DEVMAN, 0, 0); 828 async_exchange_end(exch); 829 830 if (sess) { 831 add_device(sess, drv, dev, tree); 832 async_hangup(sess); 833 } 834 } 798 835 799 836 return true; … … 818 855 hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1, 819 856 &devman_functions_ops); 820 hash_table_create(&tree-> loc_functions, DEVICE_BUCKETS, 1,821 & loc_devices_ops);857 hash_table_create(&tree->devmap_functions, DEVICE_BUCKETS, 1, 858 &devmap_devices_ops); 822 859 823 860 fibril_rwlock_initialize(&tree->rwlock); … … 898 935 } 899 936 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 931 937 /* Function nodes */ 932 938 … … 943 949 link_initialize(&res->dev_functions); 944 950 list_initialize(&res->match_ids.ids); 951 list_initialize(&res->classes); 945 952 link_initialize(&res->devman_fun); 946 link_initialize(&res-> loc_fun);953 link_initialize(&res->devmap_fun); 947 954 } 948 955 … … 1107 1114 1108 1115 return true; 1109 }1110 1111 /** Remove function from device tree.1112 *1113 * @param tree Device tree1114 * @param node Function node to remove1115 */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);1129 1116 } 1130 1117 … … 1154 1141 char *rel_path = path; 1155 1142 char *next_path_elem = NULL; 1156 bool cont = (rel_path[1] != '\0');1143 bool cont = true; 1157 1144 1158 1145 while (cont && fun != NULL) { … … 1205 1192 } 1206 1193 1194 /** Find function node by its class name and index. */ 1195 fun_node_t *find_fun_node_by_class(class_list_t *class_list, 1196 const char *class_name, const char *dev_name) 1197 { 1198 assert(class_list != NULL); 1199 assert(class_name != NULL); 1200 assert(dev_name != NULL); 1201 1202 fibril_rwlock_read_lock(&class_list->rwlock); 1203 1204 dev_class_t *cl = find_dev_class_no_lock(class_list, class_name); 1205 if (cl == NULL) { 1206 fibril_rwlock_read_unlock(&class_list->rwlock); 1207 return NULL; 1208 } 1209 1210 dev_class_info_t *dev = find_dev_in_class(cl, dev_name); 1211 if (dev == NULL) { 1212 fibril_rwlock_read_unlock(&class_list->rwlock); 1213 return NULL; 1214 } 1215 1216 fun_node_t *fun = dev->fun; 1217 1218 fibril_rwlock_read_unlock(&class_list->rwlock); 1219 1220 return fun; 1221 } 1222 1223 1207 1224 /** Find child function node with a specified name. 1208 1225 * … … 1218 1235 } 1219 1236 1220 /* loc devices */ 1221 1222 fun_node_t *find_loc_tree_function(dev_tree_t *tree, service_id_t service_id) 1237 /* Device classes */ 1238 1239 /** Create device class. 1240 * 1241 * @return Device class. 1242 */ 1243 dev_class_t *create_dev_class(void) 1244 { 1245 dev_class_t *cl; 1246 1247 cl = (dev_class_t *) malloc(sizeof(dev_class_t)); 1248 if (cl != NULL) { 1249 memset(cl, 0, sizeof(dev_class_t)); 1250 list_initialize(&cl->devices); 1251 fibril_mutex_initialize(&cl->mutex); 1252 } 1253 1254 return cl; 1255 } 1256 1257 /** Create device class info. 1258 * 1259 * @return Device class info. 1260 */ 1261 dev_class_info_t *create_dev_class_info(void) 1262 { 1263 dev_class_info_t *info; 1264 1265 info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t)); 1266 if (info != NULL) { 1267 memset(info, 0, sizeof(dev_class_info_t)); 1268 link_initialize(&info->dev_classes); 1269 link_initialize(&info->devmap_link); 1270 link_initialize(&info->link); 1271 } 1272 1273 return info; 1274 } 1275 1276 size_t get_new_class_dev_idx(dev_class_t *cl) 1277 { 1278 size_t dev_idx; 1279 1280 fibril_mutex_lock(&cl->mutex); 1281 dev_idx = ++cl->curr_dev_idx; 1282 fibril_mutex_unlock(&cl->mutex); 1283 1284 return dev_idx; 1285 } 1286 1287 1288 /** Create unique device name within the class. 1289 * 1290 * @param cl The class. 1291 * @param base_dev_name Contains the base name for the device if it was 1292 * specified by the driver when it registered the device by 1293 * the class; NULL if driver specified no base name. 1294 * @return The unique name for the device within the class. 1295 */ 1296 char *create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name) 1297 { 1298 char *dev_name; 1299 const char *base_name; 1300 1301 if (base_dev_name != NULL) 1302 base_name = base_dev_name; 1303 else 1304 base_name = cl->base_dev_name; 1305 1306 size_t idx = get_new_class_dev_idx(cl); 1307 asprintf(&dev_name, "%s%zu", base_name, idx); 1308 1309 return dev_name; 1310 } 1311 1312 /** Add the device function to the class. 1313 * 1314 * The device may be added to multiple classes and a class may contain multiple 1315 * devices. The class and the device are associated with each other by the 1316 * dev_class_info_t structure. 1317 * 1318 * @param dev The device. 1319 * @param class The class. 1320 * @param base_dev_name The base name of the device within the class if 1321 * specified by the driver, NULL otherwise. 1322 * @return dev_class_info_t structure which associates the device 1323 * with the class. 1324 */ 1325 dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl, 1326 const char *base_dev_name) 1327 { 1328 dev_class_info_t *info; 1329 1330 assert(fun != NULL); 1331 assert(cl != NULL); 1332 1333 info = create_dev_class_info(); 1334 1335 1336 if (info != NULL) { 1337 info->dev_class = cl; 1338 info->fun = fun; 1339 1340 /* Add the device to the class. */ 1341 fibril_mutex_lock(&cl->mutex); 1342 list_append(&info->link, &cl->devices); 1343 fibril_mutex_unlock(&cl->mutex); 1344 1345 /* Add the class to the device. */ 1346 list_append(&info->dev_classes, &fun->classes); 1347 1348 /* Create unique name for the device within the class. */ 1349 info->dev_name = create_dev_name_for_class(cl, base_dev_name); 1350 } 1351 1352 return info; 1353 } 1354 1355 dev_class_t *get_dev_class(class_list_t *class_list, char *class_name) 1356 { 1357 dev_class_t *cl; 1358 1359 fibril_rwlock_write_lock(&class_list->rwlock); 1360 cl = find_dev_class_no_lock(class_list, class_name); 1361 if (cl == NULL) { 1362 cl = create_dev_class(); 1363 if (cl != NULL) { 1364 cl->name = class_name; 1365 cl->base_dev_name = ""; 1366 add_dev_class_no_lock(class_list, cl); 1367 } 1368 } 1369 1370 fibril_rwlock_write_unlock(&class_list->rwlock); 1371 return cl; 1372 } 1373 1374 dev_class_t *find_dev_class_no_lock(class_list_t *class_list, 1375 const char *class_name) 1376 { 1377 dev_class_t *cl; 1378 1379 list_foreach(class_list->classes, link) { 1380 cl = list_get_instance(link, dev_class_t, link); 1381 if (str_cmp(cl->name, class_name) == 0) { 1382 return cl; 1383 } 1384 } 1385 1386 return NULL; 1387 } 1388 1389 void add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl) 1390 { 1391 list_append(&cl->link, &class_list->classes); 1392 } 1393 1394 dev_class_info_t *find_dev_in_class(dev_class_t *dev_class, const char *dev_name) 1395 { 1396 assert(dev_class != NULL); 1397 assert(dev_name != NULL); 1398 1399 list_foreach(dev_class->devices, link) { 1400 dev_class_info_t *dev = list_get_instance(link, 1401 dev_class_info_t, link); 1402 1403 if (str_cmp(dev->dev_name, dev_name) == 0) { 1404 return dev; 1405 } 1406 } 1407 1408 return NULL; 1409 } 1410 1411 void init_class_list(class_list_t *class_list) 1412 { 1413 list_initialize(&class_list->classes); 1414 fibril_rwlock_initialize(&class_list->rwlock); 1415 hash_table_create(&class_list->devmap_functions, DEVICE_BUCKETS, 1, 1416 &devmap_devices_class_ops); 1417 } 1418 1419 1420 /* Devmap devices */ 1421 1422 fun_node_t *find_devmap_tree_function(dev_tree_t *tree, devmap_handle_t devmap_handle) 1223 1423 { 1224 1424 fun_node_t *fun = NULL; 1225 1425 link_t *link; 1226 unsigned long key = (unsigned long) service_id;1426 unsigned long key = (unsigned long) devmap_handle; 1227 1427 1228 1428 fibril_rwlock_read_lock(&tree->rwlock); 1229 link = hash_table_find(&tree-> loc_functions, &key);1429 link = hash_table_find(&tree->devmap_functions, &key); 1230 1430 if (link != NULL) 1231 fun = hash_table_get_instance(link, fun_node_t, loc_fun);1431 fun = hash_table_get_instance(link, fun_node_t, devmap_fun); 1232 1432 fibril_rwlock_read_unlock(&tree->rwlock); 1233 1433 … … 1235 1435 } 1236 1436 1237 void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun) 1238 { 1239 unsigned long key = (unsigned long) fun->service_id; 1437 fun_node_t *find_devmap_class_function(class_list_t *classes, 1438 devmap_handle_t devmap_handle) 1439 { 1440 fun_node_t *fun = NULL; 1441 dev_class_info_t *cli; 1442 link_t *link; 1443 unsigned long key = (unsigned long)devmap_handle; 1444 1445 fibril_rwlock_read_lock(&classes->rwlock); 1446 link = hash_table_find(&classes->devmap_functions, &key); 1447 if (link != NULL) { 1448 cli = hash_table_get_instance(link, dev_class_info_t, 1449 devmap_link); 1450 fun = cli->fun; 1451 } 1452 fibril_rwlock_read_unlock(&classes->rwlock); 1453 1454 return fun; 1455 } 1456 1457 void class_add_devmap_function(class_list_t *class_list, dev_class_info_t *cli) 1458 { 1459 unsigned long key = (unsigned long) cli->devmap_handle; 1460 1461 fibril_rwlock_write_lock(&class_list->rwlock); 1462 hash_table_insert(&class_list->devmap_functions, &key, &cli->devmap_link); 1463 fibril_rwlock_write_unlock(&class_list->rwlock); 1464 1465 assert(find_devmap_class_function(class_list, cli->devmap_handle) != NULL); 1466 } 1467 1468 void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun) 1469 { 1470 unsigned long key = (unsigned long) fun->devmap_handle; 1240 1471 fibril_rwlock_write_lock(&tree->rwlock); 1241 hash_table_insert(&tree-> loc_functions, &key, &fun->loc_fun);1472 hash_table_insert(&tree->devmap_functions, &key, &fun->devmap_fun); 1242 1473 fibril_rwlock_write_unlock(&tree->rwlock); 1243 1474 }
Note:
See TracChangeset
for help on using the changeset viewer.