Changeset bd5f3b7 in mainline for uspace/srv/devman/devman.c
- Timestamp:
- 2011-08-21T13:07:35Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 00aece0, f1a9e87
- Parents:
- 86a34d3e (diff), a6480d5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r86a34d3e rbd5f3b7 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 }; … … 270 254 } 271 255 272 ssize_t read_bytes = safe_read(fd, buf, len);256 ssize_t read_bytes = read_all(fd, buf, len); 273 257 if (read_bytes <= 0) { 274 log_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path); 258 log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path, 259 read_bytes); 275 260 goto cleanup; 276 261 } … … 421 406 } 422 407 423 insert_fun_node(tree, fun, clone_string(""), NULL);408 insert_fun_node(tree, fun, str_dup(""), NULL); 424 409 match_id_t *id = create_match_id(); 425 id->id = clone_string("root");410 id->id = str_dup("root"); 426 411 id->score = 100; 427 412 add_match_id(&fun->match_ids, id); … … 563 548 564 549 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 }575 550 576 551 /* … … 598 573 fibril_mutex_unlock(&driver->driver_mutex); 599 574 600 add_device( sess,driver, dev, tree);575 add_device(driver, dev, tree); 601 576 602 577 /* … … 618 593 link = driver->devices.head.next; 619 594 } 620 621 async_hangup(sess);622 595 623 596 /* … … 700 673 } 701 674 702 /** Create devmappath 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)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) 710 683 return; 711 684 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);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); 718 691 return; 719 692 } 720 693 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);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); 728 701 } 729 702 … … 733 706 * @param node The device's node in the device tree. 734 707 */ 735 void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev, 736 dev_tree_t *tree) 708 void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree) 737 709 { 738 710 /* … … 751 723 } 752 724 753 async_exch_t *exch = async_exchange_begin( sess);725 async_exch_t *exch = async_exchange_begin(drv->sess); 754 726 755 727 ipc_call_t answer; … … 821 793 fibril_mutex_unlock(&drv->driver_mutex); 822 794 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 } 795 /* Notify the driver about the new device. */ 796 if (is_running) 797 add_device(drv, dev, tree); 835 798 836 799 return true; … … 855 818 hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1, 856 819 &devman_functions_ops); 857 hash_table_create(&tree-> devmap_functions, DEVICE_BUCKETS, 1,858 & devmap_devices_ops);820 hash_table_create(&tree->loc_functions, DEVICE_BUCKETS, 1, 821 &loc_devices_ops); 859 822 860 823 fibril_rwlock_initialize(&tree->rwlock); … … 935 898 } 936 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 937 931 /* Function nodes */ 938 932 … … 949 943 link_initialize(&res->dev_functions); 950 944 list_initialize(&res->match_ids.ids); 951 list_initialize(&res->classes);952 945 link_initialize(&res->devman_fun); 953 link_initialize(&res-> devmap_fun);946 link_initialize(&res->loc_fun); 954 947 } 955 948 … … 1114 1107 1115 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); 1116 1129 } 1117 1130 … … 1141 1154 char *rel_path = path; 1142 1155 char *next_path_elem = NULL; 1143 bool cont = true;1156 bool cont = (rel_path[1] != '\0'); 1144 1157 1145 1158 while (cont && fun != NULL) { … … 1192 1205 } 1193 1206 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 1224 1207 /** Find child function node with a specified name. 1225 1208 * … … 1235 1218 } 1236 1219 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) 1220 /* loc devices */ 1221 1222 fun_node_t *find_loc_tree_function(dev_tree_t *tree, service_id_t service_id) 1423 1223 { 1424 1224 fun_node_t *fun = NULL; 1425 1225 link_t *link; 1426 unsigned long key = (unsigned long) devmap_handle;1226 unsigned long key = (unsigned long) service_id; 1427 1227 1428 1228 fibril_rwlock_read_lock(&tree->rwlock); 1429 link = hash_table_find(&tree-> devmap_functions, &key);1229 link = hash_table_find(&tree->loc_functions, &key); 1430 1230 if (link != NULL) 1431 fun = hash_table_get_instance(link, fun_node_t, devmap_fun);1231 fun = hash_table_get_instance(link, fun_node_t, loc_fun); 1432 1232 fibril_rwlock_read_unlock(&tree->rwlock); 1433 1233 … … 1435 1235 } 1436 1236 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; 1237 void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun) 1238 { 1239 unsigned long key = (unsigned long) fun->service_id; 1471 1240 fibril_rwlock_write_lock(&tree->rwlock); 1472 hash_table_insert(&tree-> devmap_functions, &key, &fun->devmap_fun);1241 hash_table_insert(&tree->loc_functions, &key, &fun->loc_fun); 1473 1242 fibril_rwlock_write_unlock(&tree->rwlock); 1474 1243 }
Note:
See TracChangeset
for help on using the changeset viewer.