Changeset 07b39338 in mainline for uspace/srv
- Timestamp:
- 2011-08-20T18:21:49Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6ab014d
- Parents:
- 0cf27ee (diff), f00af83 (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. - Location:
- uspace/srv
- Files:
-
- 17 edited
-
devman/devman.c (modified) (15 diffs)
-
devman/devman.h (modified) (10 diffs)
-
devman/main.c (modified) (13 diffs)
-
hid/input/generic/input.c (modified) (4 diffs)
-
hid/input/port/adb_mouse.c (modified) (1 diff)
-
hw/irc/apic/apic.c (modified) (1 diff)
-
loader/main.c (modified) (4 diffs)
-
loc/category.c (modified) (4 diffs)
-
loc/category.h (modified) (3 diffs)
-
loc/loc.c (modified) (13 diffs)
-
loc/loc.h (modified) (3 diffs)
-
vfs/vfs.c (modified) (6 diffs)
-
vfs/vfs.h (modified) (6 diffs)
-
vfs/vfs_file.c (modified) (14 diffs)
-
vfs/vfs_lookup.c (modified) (1 diff)
-
vfs/vfs_node.c (modified) (1 diff)
-
vfs/vfs_ops.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r0cf27ee r07b39338 73 73 } 74 74 75 static int loc_devices_class_compare(unsigned long key[], hash_count_t keys,76 link_t *item)77 {78 dev_class_info_t *class_info79 = hash_table_get_instance(item, dev_class_info_t, loc_link);80 assert(class_info != NULL);81 82 return (class_info->service_id == (service_id_t) key[0]);83 }84 85 75 static void devices_remove_callback(link_t *item) 86 76 { … … 102 92 .hash = devices_hash, 103 93 .compare = loc_functions_compare, 104 .remove_callback = devices_remove_callback105 };106 107 static hash_table_operations_t loc_devices_class_ops = {108 .hash = devices_hash,109 .compare = loc_devices_class_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 /* … … 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; … … 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 946 link_initialize(&res->loc_fun); … … 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 * … … 1235 1217 return find_fun_node_in_device(pfun->child, name); 1236 1218 } 1237 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->loc_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 was1293 * specified by the driver when it registered the device by1294 * 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 else1305 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 multiple1316 * devices. The class and the device are associated with each other by the1317 * 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 if1322 * specified by the driver, NULL otherwise.1323 * @return dev_class_info_t structure which associates the device1324 * 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->loc_functions, DEVICE_BUCKETS, 1,1417 &loc_devices_class_ops);1418 }1419 1420 1219 1421 1220 /* loc devices */ … … 1436 1235 } 1437 1236 1438 fun_node_t *find_loc_class_function(class_list_t *classes,1439 service_id_t service_id)1440 {1441 fun_node_t *fun = NULL;1442 dev_class_info_t *cli;1443 link_t *link;1444 unsigned long key = (unsigned long)service_id;1445 1446 fibril_rwlock_read_lock(&classes->rwlock);1447 link = hash_table_find(&classes->loc_functions, &key);1448 if (link != NULL) {1449 cli = hash_table_get_instance(link, dev_class_info_t,1450 loc_link);1451 fun = cli->fun;1452 }1453 fibril_rwlock_read_unlock(&classes->rwlock);1454 1455 return fun;1456 }1457 1458 void class_add_loc_function(class_list_t *class_list, dev_class_info_t *cli)1459 {1460 unsigned long key = (unsigned long) cli->service_id;1461 1462 fibril_rwlock_write_lock(&class_list->rwlock);1463 hash_table_insert(&class_list->loc_functions, &key, &cli->loc_link);1464 fibril_rwlock_write_unlock(&class_list->rwlock);1465 1466 assert(find_loc_class_function(class_list, cli->service_id) != NULL);1467 }1468 1469 1237 void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun) 1470 1238 { -
uspace/srv/devman/devman.h
r0cf27ee r07b39338 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 53 54 #define DEVICE_BUCKETS 256 54 55 55 #define LOC_CLASS_NAMESPACE "class"56 56 #define LOC_DEVICE_NAMESPACE "devices" 57 57 #define LOC_SEPARATOR '\\' … … 155 155 /** Name of the function, assigned by the device driver */ 156 156 char *name; 157 /** Function type */ 158 fun_type_t ftype; 157 159 158 160 /** Full path and name of the device in device hierarchy */ … … 170 172 match_id_list_t match_ids; 171 173 172 /** List of device classes to which this device function belongs. */173 list_t classes;174 174 /** Service ID if the device function is registered with loc. */ 175 175 service_id_t service_id; … … 214 214 } dev_tree_t; 215 215 216 typedef struct dev_class {217 /** The name of the class. */218 const char *name;219 220 /**221 * Pointer to the previous and next class in the list of registered222 * classes.223 */224 link_t link;225 226 /**227 * List of dev_class_info structures - one for each device registered by228 * this class.229 */230 list_t devices;231 232 /**233 * Default base name for the device within the class, might be overrided234 * by the driver.235 */236 const char *base_dev_name;237 238 /** Unique numerical identifier of the newly added device. */239 size_t curr_dev_idx;240 /** Synchronize access to the list of devices in this class. */241 fibril_mutex_t mutex;242 } dev_class_t;243 244 /**245 * Provides n-to-m mapping between function nodes and classes - each function246 * can register in an arbitrary number of classes and each class can contain247 * an arbitrary number of device functions.248 */249 typedef struct dev_class_info {250 /** The class. */251 dev_class_t *dev_class;252 /** The device. */253 fun_node_t *fun;254 255 /**256 * Pointer to the previous and next class info in the list of devices257 * registered by the class.258 */259 link_t link;260 261 /**262 * Pointer to the previous and next class info in the list of classes263 * by which the device is registered.264 */265 link_t dev_classes;266 267 /** The name of the device function within the class. */268 char *dev_name;269 /** Service ID in the class namespace. */270 service_id_t service_id;271 272 /**273 * Link to hash table of services registered with location service using274 * their class names.275 */276 link_t loc_link;277 } dev_class_info_t;278 279 /** The list of device classes. */280 typedef struct class_list {281 /** List of classes. */282 list_t classes;283 284 /**285 * Hash table of services registered with location service using their286 * class name, indexed by service IDs.287 */288 hash_table_t loc_functions;289 290 /** Fibril mutex for list of classes. */291 fibril_rwlock_t rwlock;292 } class_list_t;293 294 216 /* Match ids and scores */ 295 217 … … 313 235 extern void add_driver(driver_list_t *, driver_t *); 314 236 extern void attach_driver(dev_node_t *, driver_t *); 315 extern void add_device( async_sess_t *,driver_t *, dev_node_t *, dev_tree_t *);237 extern void add_device(driver_t *, dev_node_t *, dev_tree_t *); 316 238 extern bool start_driver(driver_t *); 317 239 … … 331 253 extern dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle); 332 254 extern dev_node_t *find_dev_function(dev_node_t *, const char *); 255 extern int dev_get_functions(dev_tree_t *tree, dev_node_t *, devman_handle_t *, 256 size_t, size_t *); 333 257 334 258 extern fun_node_t *create_fun_node(void); … … 339 263 extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *); 340 264 extern fun_node_t *find_fun_node_in_device(dev_node_t *, const char *); 341 extern fun_node_t *find_fun_node_by_class(class_list_t *, const char *, const char *);342 265 343 266 /* Device tree */ … … 347 270 extern bool insert_dev_node(dev_tree_t *, dev_node_t *, fun_node_t *); 348 271 extern bool insert_fun_node(dev_tree_t *, fun_node_t *, char *, dev_node_t *); 349 350 /* Device classes */ 351 352 extern dev_class_t *create_dev_class(void); 353 extern dev_class_info_t *create_dev_class_info(void); 354 extern size_t get_new_class_dev_idx(dev_class_t *); 355 extern char *create_dev_name_for_class(dev_class_t *, const char *); 356 extern dev_class_info_t *add_function_to_class(fun_node_t *, dev_class_t *, 357 const char *); 358 359 extern void init_class_list(class_list_t *); 360 361 extern dev_class_t *get_dev_class(class_list_t *, char *); 362 extern dev_class_t *find_dev_class_no_lock(class_list_t *, const char *); 363 extern dev_class_info_t *find_dev_in_class(dev_class_t *, const char *); 364 extern void add_dev_class_no_lock(class_list_t *, dev_class_t *); 272 extern void remove_fun_node(dev_tree_t *, fun_node_t *); 365 273 366 274 /* Loc services */ … … 369 277 370 278 extern fun_node_t *find_loc_tree_function(dev_tree_t *, service_id_t); 371 extern fun_node_t *find_loc_class_function(class_list_t *, service_id_t); 372 373 extern void class_add_loc_function(class_list_t *, dev_class_info_t *); 279 374 280 extern void tree_add_loc_function(dev_tree_t *, fun_node_t *); 375 281 -
uspace/srv/devman/main.c
r0cf27ee r07b39338 64 64 static driver_list_t drivers_list; 65 65 static dev_tree_t device_tree; 66 static class_list_t class_list;67 66 68 67 /** Register running driver. */ … … 279 278 return; 280 279 } 281 280 282 281 fun_node_t *fun = create_fun_node(); 282 fun->ftype = ftype; 283 283 284 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 284 285 fibril_rwlock_write_unlock(&tree->rwlock); … … 333 334 } 334 335 335 static void loc_register_class_dev(dev_class_info_t *cli) 336 { 337 /* Create loc path and name for the service. */ 338 char *loc_pathname = NULL; 339 340 asprintf(&loc_pathname, "%s/%s%c%s", LOC_CLASS_NAMESPACE, 341 cli->dev_class->name, LOC_SEPARATOR, cli->dev_name); 342 if (loc_pathname == NULL) 343 return; 344 345 /* 346 * Register the device with location service and remember its 347 * service ID. 348 */ 349 loc_service_register_with_iface(loc_pathname, 350 &cli->service_id, DEVMAN_CONNECT_FROM_LOC); 351 352 /* 353 * Add device to the hash map of class devices registered with 354 * location service. 355 */ 356 class_add_loc_function(&class_list, cli); 357 358 free(loc_pathname); 359 } 360 361 static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call) 336 static void devman_add_function_to_cat(ipc_callid_t callid, ipc_call_t *call) 362 337 { 363 338 devman_handle_t handle = IPC_GET_ARG1(*call); … … 365 340 int rc; 366 341 367 /* Get c lassname. */368 char *c lass_name;369 rc = async_data_write_accept((void **) &c lass_name, true,342 /* Get category name. */ 343 char *cat_name; 344 rc = async_data_write_accept((void **) &cat_name, true, 370 345 0, 0, 0, 0); 371 346 if (rc != EOK) { … … 380 355 } 381 356 382 dev_class_t *cl = get_dev_class(&class_list, class_name); 383 dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL); 384 385 /* Register the device's class alias with location service. */ 386 loc_register_class_dev(class_info); 387 388 rc = loc_category_get_id(class_name, &cat_id, IPC_FLAG_BLOCKING); 357 rc = loc_category_get_id(cat_name, &cat_id, IPC_FLAG_BLOCKING); 389 358 if (rc == EOK) { 390 359 loc_service_add_to_cat(fun->service_id, cat_id); 391 360 } else { 392 361 log_msg(LVL_ERROR, "Failed adding function `%s' to category " 393 "`%s'.", fun->pathname, class_name); 394 } 395 396 log_msg(LVL_NOTE, "Function `%s' added to class `%s' as `%s'.", 397 fun->pathname, class_name, class_info->dev_name); 398 362 "`%s'.", fun->pathname, cat_name); 363 } 364 365 log_msg(LVL_NOTE, "Function `%s' added to category `%s'.", 366 fun->pathname, cat_name); 367 368 async_answer_0(callid, EOK); 369 } 370 371 /** Remove function. */ 372 static void devman_remove_function(ipc_callid_t callid, ipc_call_t *call) 373 { 374 devman_handle_t fun_handle = IPC_GET_ARG1(*call); 375 dev_tree_t *tree = &device_tree; 376 int rc; 377 378 fibril_rwlock_write_lock(&tree->rwlock); 379 380 fun_node_t *fun = find_fun_node_no_lock(&device_tree, fun_handle); 381 if (fun == NULL) { 382 fibril_rwlock_write_unlock(&tree->rwlock); 383 async_answer_0(callid, ENOENT); 384 return; 385 } 386 387 log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname); 388 389 if (fun->ftype == fun_inner) { 390 /* Handle possible descendants */ 391 /* TODO */ 392 log_msg(LVL_WARN, "devman_remove_function(): not handling " 393 "descendants\n"); 394 } else { 395 /* Unregister from location service */ 396 rc = loc_service_unregister(fun->service_id); 397 if (rc != EOK) { 398 log_msg(LVL_ERROR, "Failed unregistering tree service."); 399 fibril_rwlock_write_unlock(&tree->rwlock); 400 async_answer_0(callid, EIO); 401 return; 402 } 403 } 404 405 remove_fun_node(&device_tree, fun); 406 fibril_rwlock_write_unlock(&tree->rwlock); 407 delete_fun_node(fun); 408 409 log_msg(LVL_DEBUG, "devman_remove_function() succeeded."); 399 410 async_answer_0(callid, EOK); 400 411 } … … 449 460 devman_add_function(callid, &call); 450 461 break; 451 case DEVMAN_ADD_DEVICE_TO_CLASS: 452 devman_add_function_to_class(callid, &call); 462 case DEVMAN_ADD_DEVICE_TO_CATEGORY: 463 devman_add_function_to_cat(callid, &call); 464 break; 465 case DEVMAN_REMOVE_FUNCTION: 466 devman_remove_function(callid, &call); 453 467 break; 454 468 default: … … 483 497 } 484 498 485 /** Find handle for the device instance identified by device class name. */ 486 static void devman_function_get_handle_by_class(ipc_callid_t iid, 487 ipc_call_t *icall) 488 { 489 char *classname; 490 char *devname; 491 492 int rc = async_data_write_accept((void **) &classname, true, 0, 0, 0, 0); 493 if (rc != EOK) { 494 async_answer_0(iid, rc); 495 return; 496 } 497 rc = async_data_write_accept((void **) &devname, true, 0, 0, 0, 0); 498 if (rc != EOK) { 499 free(classname); 500 async_answer_0(iid, rc); 501 return; 502 } 503 504 505 fun_node_t *fun = find_fun_node_by_class(&class_list, 506 classname, devname); 507 508 free(classname); 509 free(devname); 510 511 if (fun == NULL) { 512 async_answer_0(iid, ENOENT); 513 return; 514 } 515 516 async_answer_1(iid, EOK, fun->handle); 517 } 518 519 /** Find device path by its handle. */ 520 static void devman_get_device_path_by_handle(ipc_callid_t iid, 521 ipc_call_t *icall) 499 /** Get device name. */ 500 static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall) 522 501 { 523 502 devman_handle_t handle = IPC_GET_ARG1(*icall); … … 543 522 } 544 523 524 size_t sent_length = str_size(fun->name); 525 if (sent_length > data_len) { 526 sent_length = data_len; 527 } 528 529 async_data_read_finalize(data_callid, fun->name, sent_length); 530 async_answer_0(iid, EOK); 531 532 free(buffer); 533 } 534 535 536 /** Get device path. */ 537 static void devman_fun_get_path(ipc_callid_t iid, ipc_call_t *icall) 538 { 539 devman_handle_t handle = IPC_GET_ARG1(*icall); 540 541 fun_node_t *fun = find_fun_node(&device_tree, handle); 542 if (fun == NULL) { 543 async_answer_0(iid, ENOMEM); 544 return; 545 } 546 547 ipc_callid_t data_callid; 548 size_t data_len; 549 if (!async_data_read_receive(&data_callid, &data_len)) { 550 async_answer_0(iid, EINVAL); 551 return; 552 } 553 554 void *buffer = malloc(data_len); 555 if (buffer == NULL) { 556 async_answer_0(data_callid, ENOMEM); 557 async_answer_0(iid, ENOMEM); 558 return; 559 } 560 545 561 size_t sent_length = str_size(fun->pathname); 546 562 if (sent_length > data_len) { … … 554 570 } 555 571 572 static void devman_dev_get_functions(ipc_callid_t iid, ipc_call_t *icall) 573 { 574 ipc_callid_t callid; 575 size_t size; 576 size_t act_size; 577 int rc; 578 579 if (!async_data_read_receive(&callid, &size)) { 580 async_answer_0(callid, EREFUSED); 581 async_answer_0(iid, EREFUSED); 582 return; 583 } 584 585 fibril_rwlock_read_lock(&device_tree.rwlock); 586 587 dev_node_t *dev = find_dev_node_no_lock(&device_tree, 588 IPC_GET_ARG1(*icall)); 589 if (dev == NULL) { 590 fibril_rwlock_read_unlock(&device_tree.rwlock); 591 async_answer_0(callid, ENOENT); 592 async_answer_0(iid, ENOENT); 593 return; 594 } 595 596 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size); 597 if (hdl_buf == NULL) { 598 fibril_rwlock_read_unlock(&device_tree.rwlock); 599 async_answer_0(callid, ENOMEM); 600 async_answer_0(iid, ENOMEM); 601 return; 602 } 603 604 rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size); 605 if (rc != EOK) { 606 fibril_rwlock_read_unlock(&device_tree.rwlock); 607 async_answer_0(callid, rc); 608 async_answer_0(iid, rc); 609 return; 610 } 611 612 fibril_rwlock_read_unlock(&device_tree.rwlock); 613 614 sysarg_t retval = async_data_read_finalize(callid, hdl_buf, size); 615 free(hdl_buf); 616 617 async_answer_1(iid, retval, act_size); 618 } 619 620 621 /** Get handle for child device of a function. */ 622 static void devman_fun_get_child(ipc_callid_t iid, ipc_call_t *icall) 623 { 624 fun_node_t *fun; 625 626 fibril_rwlock_read_lock(&device_tree.rwlock); 627 628 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 629 if (fun == NULL) { 630 fibril_rwlock_read_unlock(&device_tree.rwlock); 631 async_answer_0(iid, ENOENT); 632 return; 633 } 634 635 if (fun->child == NULL) { 636 fibril_rwlock_read_unlock(&device_tree.rwlock); 637 async_answer_0(iid, ENOENT); 638 return; 639 } 640 641 async_answer_1(iid, EOK, fun->child->handle); 642 643 fibril_rwlock_read_unlock(&device_tree.rwlock); 644 } 645 646 /** Find handle for the function instance identified by its service ID. */ 647 static void devman_fun_sid_to_handle(ipc_callid_t iid, ipc_call_t *icall) 648 { 649 fun_node_t *fun; 650 651 fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall)); 652 653 if (fun == NULL) { 654 async_answer_0(iid, ENOENT); 655 return; 656 } 657 658 async_answer_1(iid, EOK, fun->handle); 659 } 556 660 557 661 /** Function for handling connections from a client to the device manager. */ … … 572 676 devman_function_get_handle(callid, &call); 573 677 break; 574 case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS: 575 devman_function_get_handle_by_class(callid, &call); 576 break; 577 case DEVMAN_DEVICE_GET_DEVICE_PATH: 578 devman_get_device_path_by_handle(callid, &call); 678 case DEVMAN_DEV_GET_FUNCTIONS: 679 devman_dev_get_functions(callid, &call); 680 break; 681 case DEVMAN_FUN_GET_CHILD: 682 devman_fun_get_child(callid, &call); 683 break; 684 case DEVMAN_FUN_GET_NAME: 685 devman_fun_get_name(callid, &call); 686 break; 687 case DEVMAN_FUN_GET_PATH: 688 devman_fun_get_path(callid, &call); 689 break; 690 case DEVMAN_FUN_SID_TO_HANDLE: 691 devman_fun_sid_to_handle(callid, &call); 579 692 break; 580 693 default: … … 678 791 679 792 fun = find_loc_tree_function(&device_tree, service_id); 680 if (fun == NULL)681 fun = find_loc_class_function(&class_list, service_id);682 793 683 794 if (fun == NULL || fun->dev->drv == NULL) { 795 log_msg(LVL_WARN, "devman_connection_loc(): function " 796 "not found.\n"); 684 797 async_answer_0(iid, ENOENT); 685 798 return; … … 687 800 688 801 dev = fun->dev; 689 690 if ((dev->state != DEVICE_USABLE) || (!dev->drv->sess)) {691 async_answer_0(iid, EINVAL);692 return;693 }694 802 695 803 async_exch_t *exch = async_exchange_begin(dev->drv->sess); … … 753 861 } 754 862 755 init_class_list(&class_list);756 757 863 /* 758 864 * !!! devman_connection ... as the device manager is not a real loc -
uspace/srv/hid/input/generic/input.c
r0cf27ee r07b39338 66 66 #include <abi/ipc/methods.h> 67 67 68 /* In microseconds */69 #define DISCOVERY_POLL_INTERVAL (10 * 1000 * 1000)70 71 68 #define NUM_LAYOUTS 3 72 69 … … 497 494 } 498 495 499 /** Periodically check for new input devices. 500 * 501 * Looks under /loc/class/keyboard and /loc/class/mouse. 502 * 503 * @param arg Ignored 504 * 505 */ 506 static int dev_discovery_fibril(void *arg) 507 { 508 category_id_t keyboard_cat, mouse_cat; 496 static int dev_check_new_kbdevs(void) 497 { 498 category_id_t keyboard_cat; 509 499 service_id_t *svcs; 510 500 size_t count, i; … … 518 508 } 519 509 510 /* 511 * Check for new keyboard devices 512 */ 513 rc = loc_category_get_svcs(keyboard_cat, &svcs, &count); 514 if (rc != EOK) { 515 printf("%s: Failed getting list of keyboard devices.\n", 516 NAME); 517 return EIO; 518 } 519 520 for (i = 0; i < count; i++) { 521 already_known = false; 522 523 /* Determine whether we already know this device. */ 524 list_foreach(kbd_devs, kdev_link) { 525 kbd_dev_t *kdev = list_get_instance(kdev_link, 526 kbd_dev_t, kbd_devs); 527 if (kdev->svc_id == svcs[i]) { 528 already_known = true; 529 break; 530 } 531 } 532 533 if (!already_known) { 534 kbd_dev_t *kdev; 535 if (kbd_add_kbdev(svcs[i], &kdev) == EOK) { 536 printf("%s: Connected keyboard device '%s'\n", 537 NAME, kdev->svc_name); 538 } 539 } 540 } 541 542 free(svcs); 543 544 /* XXX Handle device removal */ 545 546 return EOK; 547 } 548 549 static int dev_check_new_mousedevs(void) 550 { 551 category_id_t mouse_cat; 552 service_id_t *svcs; 553 size_t count, i; 554 bool already_known; 555 int rc; 556 520 557 rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING); 521 558 if (rc != EOK) { … … 524 561 } 525 562 526 while (true) { 527 async_usleep(DISCOVERY_POLL_INTERVAL); 528 529 /* 530 * Check for new keyboard devices 531 */ 532 rc = loc_category_get_svcs(keyboard_cat, &svcs, &count); 533 if (rc != EOK) { 534 printf("%s: Failed getting list of keyboard devices.\n", 535 NAME); 536 continue; 537 } 538 539 for (i = 0; i < count; i++) { 540 already_known = false; 541 542 /* Determine whether we already know this device. */ 543 list_foreach(kbd_devs, kdev_link) { 544 kbd_dev_t *kdev = list_get_instance(kdev_link, 545 kbd_dev_t, kbd_devs); 546 if (kdev->svc_id == svcs[i]) { 547 already_known = true; 548 break; 549 } 550 } 551 552 if (!already_known) { 553 kbd_dev_t *kdev; 554 if (kbd_add_kbdev(svcs[i], &kdev) == EOK) { 555 printf("%s: Connected keyboard device '%s'\n", 556 NAME, kdev->svc_name); 557 } 563 /* 564 * Check for new mouse devices 565 */ 566 rc = loc_category_get_svcs(mouse_cat, &svcs, &count); 567 if (rc != EOK) { 568 printf("%s: Failed getting list of mouse devices.\n", 569 NAME); 570 return EIO; 571 } 572 573 for (i = 0; i < count; i++) { 574 already_known = false; 575 576 /* Determine whether we already know this device. */ 577 list_foreach(mouse_devs, mdev_link) { 578 mouse_dev_t *mdev = list_get_instance(mdev_link, 579 mouse_dev_t, mouse_devs); 580 if (mdev->svc_id == svcs[i]) { 581 already_known = true; 582 break; 558 583 } 559 584 } 560 585 561 /* XXX Handle device removal */ 562 563 /* 564 * Check for new mouse devices 565 */ 566 rc = loc_category_get_svcs(mouse_cat, &svcs, &count); 567 if (rc != EOK) { 568 printf("%s: Failed getting list of mouse devices.\n", 569 NAME); 570 continue; 571 } 572 573 for (i = 0; i < count; i++) { 574 already_known = false; 575 576 /* Determine whether we already know this device. */ 577 list_foreach(mouse_devs, mdev_link) { 578 mouse_dev_t *mdev = list_get_instance(mdev_link, 579 mouse_dev_t, mouse_devs); 580 if (mdev->svc_id == svcs[i]) { 581 already_known = true; 582 break; 583 } 584 } 585 586 if (!already_known) { 587 mouse_dev_t *mdev; 588 if (mouse_add_mousedev(svcs[i], &mdev) == EOK) { 589 printf("%s: Connected mouse device '%s'\n", 590 NAME, mdev->svc_name); 591 } 586 if (!already_known) { 587 mouse_dev_t *mdev; 588 if (mouse_add_mousedev(svcs[i], &mdev) == EOK) { 589 printf("%s: Connected mouse device '%s'\n", 590 NAME, mdev->svc_name); 592 591 } 593 592 } 594 595 /* XXX Handle device removal */ 596 } 593 } 594 595 free(svcs); 596 597 /* XXX Handle device removal */ 597 598 598 599 return EOK; 599 600 } 600 601 601 /** Start a fibril for discovering new devices. */ 602 static void input_start_dev_discovery(void) 603 { 604 fid_t fid = fibril_create(dev_discovery_fibril, NULL); 605 if (!fid) { 606 printf("%s: Failed to create device discovery fibril.\n", 607 NAME); 608 return; 609 } 610 611 fibril_add_ready(fid); 602 static int dev_check_new(void) 603 { 604 int rc; 605 606 rc = dev_check_new_kbdevs(); 607 if (rc != EOK) 608 return rc; 609 610 rc = dev_check_new_mousedevs(); 611 if (rc != EOK) 612 return rc; 613 614 return EOK; 615 } 616 617 static void cat_change_cb(void) 618 { 619 dev_check_new(); 620 } 621 622 /** Start listening for new devices. */ 623 static int input_start_dev_discovery(void) 624 { 625 int rc; 626 627 rc = loc_register_cat_change_cb(cat_change_cb); 628 if (rc != EOK) { 629 printf("%s: Failed registering callback for device discovery. " 630 "(%d)\n", NAME, rc); 631 return rc; 632 } 633 634 return dev_check_new(); 612 635 } 613 636 -
uspace/srv/hid/input/port/adb_mouse.c
r0cf27ee r07b39338 42 42 #include <errno.h> 43 43 #include <loc.h> 44 #include <stdio.h> 44 45 45 46 static mouse_dev_t *mouse_dev; -
uspace/srv/hw/irc/apic/apic.c
r0cf27ee r07b39338 45 45 #include <errno.h> 46 46 #include <async.h> 47 #include <stdio.h> 47 48 48 49 #define NAME "apic" -
uspace/srv/loader/main.c
r0cf27ee r07b39338 61 61 #include <elf/elf.h> 62 62 #include <elf/elf_load.h> 63 #include <vfs/vfs.h> 63 64 64 65 #ifdef CONFIG_RTLD … … 89 90 90 91 /** Number of preset files */ 91 static int filc = 0; 92 /** Preset files vector */ 93 static fdi_node_t **filv = NULL; 94 /** Buffer holding all preset files */ 95 static fdi_node_t *fil_buf = NULL; 92 static unsigned int filc = 0; 96 93 97 94 static elf_info_t prog_info; … … 239 236 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 240 237 { 241 fdi_node_t *buf; 242 size_t buf_size; 243 int rc = async_data_write_accept((void **) &buf, false, 0, 0, 244 sizeof(fdi_node_t), &buf_size); 245 246 if (rc == EOK) { 247 int count = buf_size / sizeof(fdi_node_t); 248 249 /* 250 * Allocate new filv 251 */ 252 fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *)); 253 if (_filv == NULL) { 254 free(buf); 255 async_answer_0(rid, ENOMEM); 256 return; 238 size_t count = IPC_GET_ARG1(*request); 239 240 async_exch_t *vfs_exch = vfs_exchange_begin(); 241 242 for (filc = 0; filc < count; filc++) { 243 ipc_callid_t callid; 244 int fd; 245 246 if (!async_state_change_receive(&callid, NULL, NULL, NULL)) { 247 async_answer_0(callid, EINVAL); 248 break; 257 249 } 258 259 /* 260 * Fill the new filv with argument pointers 261 */ 262 int i; 263 for (i = 0; i < count; i++) 264 _filv[i] = &buf[i]; 265 266 _filv[count] = NULL; 267 268 /* 269 * Copy temporary data to global variables 270 */ 271 if (fil_buf != NULL) 272 free(fil_buf); 273 274 if (filv != NULL) 275 free(filv); 276 277 filc = count; 278 fil_buf = buf; 279 filv = _filv; 280 } 281 250 async_state_change_finalize(callid, vfs_exch); 251 fd = fd_wait(); 252 assert(fd == (int) filc); 253 } 254 255 vfs_exchange_end(vfs_exch); 256 282 257 async_answer_0(rid, EOK); 283 258 } … … 308 283 309 284 pcb.filc = filc; 310 pcb.filv = filv;311 285 312 286 if (prog_info.interp == NULL) { -
uspace/srv/loc/category.c
r0cf27ee r07b39338 93 93 cat->id = loc_create_id(); 94 94 link_initialize(&cat->cat_list); 95 list_initialize(&cat->s ervices);95 list_initialize(&cat->svc_memb); 96 96 } 97 97 … … 113 113 { 114 114 assert(fibril_mutex_is_locked(&cat->mutex)); 115 assert(fibril_mutex_is_locked(&services_list_mutex)); 115 116 116 117 /* Verify that category does not contain this service yet. */ 117 list_foreach(cat->services, item) { 118 119 loc_service_t *csvc = list_get_instance(item, loc_service_t, 120 cat_services); 121 if (csvc == svc) { 118 list_foreach(cat->svc_memb, item) { 119 svc_categ_t *memb = list_get_instance(item, svc_categ_t, 120 cat_link); 121 if (memb->svc == svc) { 122 122 return EEXIST; 123 123 } 124 124 } 125 125 126 list_append(&svc->cat_services, &cat->services); 126 svc_categ_t *nmemb = malloc(sizeof(svc_categ_t)); 127 if (nmemb == NULL) 128 return ENOMEM; 129 130 nmemb->svc = svc; 131 nmemb->cat = cat; 132 133 list_append(&nmemb->cat_link, &cat->svc_memb); 134 list_append(&nmemb->svc_link, &svc->cat_memb); 135 127 136 return EOK; 137 } 138 139 /** Remove service from category. */ 140 void category_remove_service(svc_categ_t *memb) 141 { 142 assert(fibril_mutex_is_locked(&memb->cat->mutex)); 143 assert(fibril_mutex_is_locked(&services_list_mutex)); 144 145 list_remove(&memb->cat_link); 146 list_remove(&memb->svc_link); 147 148 free(memb); 128 149 } 129 150 … … 169 190 buf_cnt = buf_size / sizeof(service_id_t); 170 191 171 act_cnt = list_count(&cat->s ervices);192 act_cnt = list_count(&cat->svc_memb); 172 193 *act_size = act_cnt * sizeof(service_id_t); 173 194 … … 176 197 177 198 size_t pos = 0; 178 list_foreach(cat->s ervices, item) {179 loc_service_t *svc=180 list_get_instance(item, loc_service_t, cat_services);199 list_foreach(cat->svc_memb, item) { 200 svc_categ_t *memb = 201 list_get_instance(item, svc_categ_t, cat_link); 181 202 182 203 if (pos < buf_cnt) 183 id_buf[pos] = svc->id;204 id_buf[pos] = memb->svc->id; 184 205 pos++; 185 206 } -
uspace/srv/loc/category.h
r0cf27ee r07b39338 55 55 link_t cat_list; 56 56 57 /** List of service s in this category (loc_service_t) */58 list_t s ervices;57 /** List of service memberships in this category (svc_categ_t) */ 58 list_t svc_memb; 59 59 } category_t; 60 60 … … 67 67 } categ_dir_t; 68 68 69 /** Service in category membership. */ 70 typedef struct { 71 /** Link to category_t.svc_memb list */ 72 link_t cat_link; 73 /** Link to loc_service_t.cat_memb list */ 74 link_t svc_link; 75 76 /** Category */ 77 category_t *cat; 78 /** Service */ 79 loc_service_t *svc; 80 } svc_categ_t; 81 69 82 extern void categ_dir_init(categ_dir_t *); 70 83 extern void categ_dir_add_cat(categ_dir_t *, category_t *); … … 73 86 extern category_t *category_new(const char *); 74 87 extern int category_add_service(category_t *, loc_service_t *); 88 extern void category_remove_service(svc_categ_t *); 75 89 extern category_t *category_get(categ_dir_t *, catid_t); 76 90 extern category_t *category_find_by_name(categ_dir_t *, const char *); -
uspace/srv/loc/loc.c
r0cf27ee r07b39338 67 67 **/ 68 68 69 staticFIBRIL_MUTEX_INITIALIZE(services_list_mutex);69 FIBRIL_MUTEX_INITIALIZE(services_list_mutex); 70 70 static FIBRIL_CONDVAR_INITIALIZE(services_list_cv); 71 71 static FIBRIL_MUTEX_INITIALIZE(servers_list_mutex); … … 84 84 /** Service directory ogranized by categories (yellow pages) */ 85 85 static categ_dir_t cdir; 86 87 static FIBRIL_MUTEX_INITIALIZE(callback_sess_mutex); 88 static async_sess_t *callback_sess = NULL; 86 89 87 90 service_id_t loc_create_id(void) … … 308 311 { 309 312 assert(fibril_mutex_is_locked(&services_list_mutex)); 310 313 assert(fibril_mutex_is_locked(&cdir.mutex)); 314 311 315 loc_namespace_delref(service->namespace); 312 316 list_remove(&(service->services)); 313 317 list_remove(&(service->server_services)); 318 319 /* Remove service from all categories. */ 320 while (!list_empty(&service->cat_memb)) { 321 link_t *link = list_first(&service->cat_memb); 322 svc_categ_t *memb = list_get_instance(link, svc_categ_t, 323 svc_link); 324 fibril_mutex_lock(&memb->cat->mutex); 325 category_remove_service(memb); 326 fibril_mutex_unlock(&memb->cat->mutex); 327 } 314 328 315 329 free(service->name); … … 412 426 fibril_mutex_lock(&services_list_mutex); 413 427 fibril_mutex_lock(&server->services_mutex); 428 fibril_mutex_lock(&cdir.mutex); 414 429 415 430 while (!list_empty(&server->services)) { … … 420 435 } 421 436 437 fibril_mutex_unlock(&cdir.mutex); 422 438 fibril_mutex_unlock(&server->services_mutex); 423 439 fibril_mutex_unlock(&services_list_mutex); … … 489 505 link_initialize(&service->services); 490 506 link_initialize(&service->server_services); 507 list_initialize(&service->cat_memb); 491 508 492 509 /* Check that service is not already registered */ … … 526 543 * 527 544 */ 528 static intloc_service_unregister(ipc_callid_t iid, ipc_call_t *icall,545 static void loc_service_unregister(ipc_callid_t iid, ipc_call_t *icall, 529 546 loc_server_t *server) 530 547 { 531 /* TODO */ 532 return EOK; 548 loc_service_t *svc; 549 550 fibril_mutex_lock(&services_list_mutex); 551 svc = loc_service_find_id(IPC_GET_ARG1(*icall)); 552 if (svc == NULL) { 553 fibril_mutex_unlock(&services_list_mutex); 554 async_answer_0(iid, ENOENT); 555 return; 556 } 557 558 fibril_mutex_lock(&cdir.mutex); 559 loc_service_unregister_core(svc); 560 fibril_mutex_unlock(&cdir.mutex); 561 fibril_mutex_unlock(&services_list_mutex); 562 async_answer_0(iid, EOK); 563 } 564 565 static void loc_category_get_name(ipc_callid_t iid, ipc_call_t *icall) 566 { 567 ipc_callid_t callid; 568 size_t size; 569 size_t act_size; 570 category_t *cat; 571 572 if (!async_data_read_receive(&callid, &size)) { 573 async_answer_0(callid, EREFUSED); 574 async_answer_0(iid, EREFUSED); 575 return; 576 } 577 578 fibril_mutex_lock(&cdir.mutex); 579 580 cat = category_get(&cdir, IPC_GET_ARG1(*icall)); 581 if (cat == NULL) { 582 fibril_mutex_unlock(&cdir.mutex); 583 async_answer_0(callid, ENOENT); 584 async_answer_0(iid, ENOENT); 585 return; 586 } 587 588 act_size = str_size(cat->name); 589 if (act_size > size) { 590 fibril_mutex_unlock(&cdir.mutex); 591 async_answer_0(callid, EOVERFLOW); 592 async_answer_0(iid, EOVERFLOW); 593 return; 594 } 595 596 sysarg_t retval = async_data_read_finalize(callid, cat->name, 597 min(size, act_size)); 598 599 fibril_mutex_unlock(&cdir.mutex); 600 601 async_answer_0(iid, retval); 533 602 } 534 603 … … 571 640 async_answer_0(iid, retval); 572 641 } 573 574 642 575 643 /** Connect client to the service. … … 728 796 * 729 797 */ 798 static void loc_callback_create(ipc_callid_t iid, ipc_call_t *icall) 799 { 800 async_sess_t *cb_sess = async_callback_receive(EXCHANGE_SERIALIZE); 801 if (cb_sess == NULL) { 802 async_answer_0(iid, ENOMEM); 803 return; 804 } 805 806 fibril_mutex_lock(&callback_sess_mutex); 807 if (callback_sess != NULL) { 808 fibril_mutex_unlock(&callback_sess_mutex); 809 async_answer_0(iid, EEXIST); 810 return; 811 } 812 813 callback_sess = cb_sess; 814 fibril_mutex_unlock(&callback_sess_mutex); 815 816 async_answer_0(iid, EOK); 817 } 818 819 void loc_category_change_event(void) 820 { 821 fibril_mutex_lock(&callback_sess_mutex); 822 823 if (callback_sess != NULL) { 824 async_exch_t *exch = async_exchange_begin(callback_sess); 825 async_msg_0(exch, LOC_EVENT_CAT_CHANGE); 826 async_exchange_end(exch); 827 } 828 829 fibril_mutex_unlock(&callback_sess_mutex); 830 } 831 832 /** Find ID for category specified by name. 833 * 834 * On success, answer will contain EOK int retval and service ID in arg1. 835 * On failure, error code will be sent in retval. 836 * 837 */ 730 838 static void loc_category_get_id(ipc_callid_t iid, ipc_call_t *icall) 731 839 { … … 1095 1203 1096 1204 fibril_mutex_lock(&services_list_mutex); 1205 fibril_mutex_lock(&cdir.mutex); 1097 1206 loc_service_unregister_core(null_services[i]); 1207 fibril_mutex_unlock(&cdir.mutex); 1098 1208 fibril_mutex_unlock(&services_list_mutex); 1099 1209 … … 1129 1239 1130 1240 async_answer_0(iid, retval); 1241 1242 loc_category_change_event(); 1131 1243 } 1132 1244 … … 1156 1268 1157 1269 cat = category_new("serial"); 1270 categ_dir_add_cat(&cdir, cat); 1271 1272 cat = category_new("usbhc"); 1273 categ_dir_add_cat(&cdir, cat); 1274 1275 cat = category_new("virtual"); 1158 1276 categ_dir_add_cat(&cdir, cat); 1159 1277 … … 1244 1362 loc_namespace_get_id(callid, &call); 1245 1363 break; 1364 case LOC_CALLBACK_CREATE: 1365 loc_callback_create(callid, &call); 1366 break; 1246 1367 case LOC_CATEGORY_GET_ID: 1247 1368 loc_category_get_id(callid, &call); 1369 break; 1370 case LOC_CATEGORY_GET_NAME: 1371 loc_category_get_name(callid, &call); 1248 1372 break; 1249 1373 case LOC_CATEGORY_GET_SVCS: -
uspace/srv/loc/loc.h
r0cf27ee r07b39338 36 36 #define LOC_H_ 37 37 38 #include <ipc/loc.h> 38 39 #include <async.h> 39 40 #include <fibril_synch.h> … … 89 90 /** Link to list of services in category (category_t.services) */ 90 91 link_t cat_services; 92 /** List of category memberships (svc_categ_t) */ 93 list_t cat_memb; 91 94 /** Unique service identifier */ 92 95 service_id_t id; … … 101 104 } loc_service_t; 102 105 106 extern fibril_mutex_t services_list_mutex; 107 103 108 extern service_id_t loc_create_id(void); 109 extern void loc_category_change_event(void); 104 110 105 111 #endif -
uspace/srv/vfs/vfs.c
r0cf27ee r07b39338 36 36 */ 37 37 38 #include <vfs/vfs.h> 38 39 #include <ipc/services.h> 40 #include <abi/ipc/event.h> 41 #include <event.h> 39 42 #include <ns.h> 40 43 #include <async.h> … … 45 48 #include <as.h> 46 49 #include <atomic.h> 50 #include <macros.h> 47 51 #include "vfs.h" 48 52 49 53 #define NAME "vfs" 54 55 enum { 56 VFS_TASK_STATE_CHANGE 57 }; 50 58 51 59 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) … … 80 88 vfs_open(callid, &call); 81 89 break; 82 case VFS_IN_OPEN_NODE:83 vfs_open_node(callid, &call);84 break;85 90 case VFS_IN_CLOSE: 86 91 vfs_close(callid, &call); … … 118 123 case VFS_IN_DUP: 119 124 vfs_dup(callid, &call); 125 break; 126 case VFS_IN_WAIT_HANDLE: 127 vfs_wait_handle(callid, &call); 128 break; 120 129 default: 121 130 async_answer_0(callid, ENOTSUP); … … 128 137 * connection fibril terminates. 129 138 */ 139 } 140 141 static void notification_received(ipc_callid_t callid, ipc_call_t *call) 142 { 143 switch (IPC_GET_IMETHOD(*call)) { 144 case VFS_TASK_STATE_CHANGE: 145 if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE) 146 vfs_pass_handle( 147 (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call), 148 IPC_GET_ARG5(*call)), call->in_task_id, 149 (int) IPC_GET_ARG2(*call)); 150 break; 151 default: 152 break; 153 } 130 154 } 131 155 … … 170 194 171 195 /* 196 * Set notification handler and subscribe to notifications. 197 */ 198 async_set_interrupt_received(notification_received); 199 event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE); 200 201 /* 172 202 * Register at the naming service. 173 203 */ -
uspace/srv/vfs/vfs.h
r0cf27ee r07b39338 41 41 #include <bool.h> 42 42 #include <ipc/vfs.h> 43 #include <task.h> 43 44 44 45 #ifndef dprintf … … 175 176 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, 176 177 vfs_pair_t *, ...); 177 extern int vfs_open_node_internal(vfs_lookup_res_t *);178 178 179 179 extern bool vfs_nodes_init(void); … … 189 189 extern void vfs_client_data_destroy(void *); 190 190 191 extern void vfs_pass_handle(task_id_t, task_id_t, int); 192 extern int vfs_wait_handle_internal(void); 193 191 194 extern vfs_file_t *vfs_file_get(int); 192 195 extern void vfs_file_put(vfs_file_t *); … … 197 200 extern void vfs_node_addref(vfs_node_t *); 198 201 extern void vfs_node_delref(vfs_node_t *); 202 extern int vfs_open_node_remote(vfs_node_t *); 199 203 200 204 extern void vfs_register(ipc_callid_t, ipc_call_t *); … … 202 206 extern void vfs_unmount(ipc_callid_t, ipc_call_t *); 203 207 extern void vfs_open(ipc_callid_t, ipc_call_t *); 204 extern void vfs_open_node(ipc_callid_t, ipc_call_t *);205 208 extern void vfs_sync(ipc_callid_t, ipc_call_t *); 206 209 extern void vfs_dup(ipc_callid_t, ipc_call_t *); … … 215 218 extern void vfs_unlink(ipc_callid_t, ipc_call_t *); 216 219 extern void vfs_rename(ipc_callid_t, ipc_call_t *); 220 extern void vfs_wait_handle(ipc_callid_t, ipc_call_t *); 217 221 218 222 #endif -
uspace/srv/vfs/vfs_file.c
r0cf27ee r07b39338 43 43 #include <fibril.h> 44 44 #include <fibril_synch.h> 45 #include <adt/list.h> 46 #include <task.h> 45 47 #include "vfs.h" 46 48 … … 50 52 typedef struct { 51 53 fibril_mutex_t lock; 54 fibril_condvar_t cv; 55 list_t passed_handles; 52 56 vfs_file_t **files; 53 57 } vfs_client_data_t; 54 58 59 typedef struct { 60 link_t link; 61 int handle; 62 } vfs_boxed_handle_t; 63 64 static int _vfs_fd_free(vfs_client_data_t *, int); 65 55 66 /** Initialize the table of open files. */ 56 static bool vfs_files_init(v oid)57 { 58 fibril_mutex_lock(& VFS_DATA->lock);59 if (! FILES) {60 FILES= malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));61 if (! FILES) {62 fibril_mutex_unlock(& VFS_DATA->lock);67 static bool vfs_files_init(vfs_client_data_t *vfs_data) 68 { 69 fibril_mutex_lock(&vfs_data->lock); 70 if (!vfs_data->files) { 71 vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *)); 72 if (!vfs_data->files) { 73 fibril_mutex_unlock(&vfs_data->lock); 63 74 return false; 64 75 } 65 memset( FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));66 } 67 fibril_mutex_unlock(& VFS_DATA->lock);76 memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *)); 77 } 78 fibril_mutex_unlock(&vfs_data->lock); 68 79 return true; 69 80 } 70 81 71 82 /** Cleanup the table of open files. */ 72 static void vfs_files_done(v oid)83 static void vfs_files_done(vfs_client_data_t *vfs_data) 73 84 { 74 85 int i; 75 86 76 if (! FILES)87 if (!vfs_data->files) 77 88 return; 78 89 79 90 for (i = 0; i < MAX_OPEN_FILES; i++) { 80 if (FILES[i]) { 81 (void) vfs_fd_free(i); 82 } 83 } 84 85 free(FILES); 91 if (vfs_data->files[i]) 92 (void) _vfs_fd_free(vfs_data, i); 93 } 94 95 free(vfs_data->files); 96 97 while (!list_empty(&vfs_data->passed_handles)) { 98 link_t *lnk; 99 vfs_boxed_handle_t *bh; 100 101 lnk = list_first(&vfs_data->passed_handles); 102 list_remove(lnk); 103 104 bh = list_get_instance(lnk, vfs_boxed_handle_t, link); 105 free(bh); 106 } 86 107 } 87 108 … … 93 114 if (vfs_data) { 94 115 fibril_mutex_initialize(&vfs_data->lock); 116 fibril_condvar_initialize(&vfs_data->cv); 117 list_initialize(&vfs_data->passed_handles); 95 118 vfs_data->files = NULL; 96 119 } … … 103 126 vfs_client_data_t *vfs_data = (vfs_client_data_t *) data; 104 127 105 vfs_files_done( );128 vfs_files_done(vfs_data); 106 129 free(vfs_data); 107 130 } … … 131 154 * incremented. 132 155 */ 133 static void vfs_file_addref(vfs_ file_t *file)134 { 135 assert(fibril_mutex_is_locked(& VFS_DATA->lock));156 static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file) 157 { 158 assert(fibril_mutex_is_locked(&vfs_data->lock)); 136 159 137 160 file->refcnt++; … … 143 166 * decremented. 144 167 */ 145 static int vfs_file_delref(vfs_ file_t *file)168 static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file) 146 169 { 147 170 int rc = EOK; 148 171 149 assert(fibril_mutex_is_locked(& VFS_DATA->lock));172 assert(fibril_mutex_is_locked(&vfs_data->lock)); 150 173 151 174 if (file->refcnt-- == 1) { … … 162 185 } 163 186 164 165 /** Allocate a file descriptor. 166 * 167 * @param desc If true, look for an available file descriptor 168 * in a descending order. 169 * 170 * @return First available file descriptor or a negative error 171 * code. 172 */ 173 int vfs_fd_alloc(bool desc) 174 { 175 if (!vfs_files_init()) 187 static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc) 188 { 189 if (!vfs_files_init(vfs_data)) 176 190 return ENOMEM; 177 191 … … 182 196 i = 0; 183 197 184 fibril_mutex_lock(& VFS_DATA->lock);198 fibril_mutex_lock(&vfs_data->lock); 185 199 while (true) { 186 if (! FILES[i]) {187 FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));188 if (! FILES[i]) {189 fibril_mutex_unlock(& VFS_DATA->lock);200 if (!vfs_data->files[i]) { 201 vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t)); 202 if (!vfs_data->files[i]) { 203 fibril_mutex_unlock(&vfs_data->lock); 190 204 return ENOMEM; 191 205 } 192 206 193 memset( FILES[i], 0, sizeof(vfs_file_t));194 fibril_mutex_initialize(& FILES[i]->lock);195 vfs_file_addref( FILES[i]);196 fibril_mutex_unlock(& VFS_DATA->lock);207 memset(vfs_data->files[i], 0, sizeof(vfs_file_t)); 208 fibril_mutex_initialize(&vfs_data->files[i]->lock); 209 vfs_file_addref(vfs_data, vfs_data->files[i]); 210 fibril_mutex_unlock(&vfs_data->lock); 197 211 return (int) i; 198 212 } … … 210 224 } 211 225 } 212 fibril_mutex_unlock(& VFS_DATA->lock);226 fibril_mutex_unlock(&vfs_data->lock); 213 227 214 228 return EMFILE; 229 } 230 231 /** Allocate a file descriptor. 232 * 233 * @param desc If true, look for an available file descriptor 234 * in a descending order. 235 * 236 * @return First available file descriptor or a negative error 237 * code. 238 */ 239 int vfs_fd_alloc(bool desc) 240 { 241 return _vfs_fd_alloc(VFS_DATA, desc); 242 } 243 244 static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd) 245 { 246 int rc; 247 248 if (!vfs_files_init(vfs_data)) 249 return ENOMEM; 250 251 fibril_mutex_lock(&vfs_data->lock); 252 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) { 253 fibril_mutex_unlock(&vfs_data->lock); 254 return EBADF; 255 } 256 257 rc = vfs_file_delref(vfs_data, vfs_data->files[fd]); 258 vfs_data->files[fd] = NULL; 259 fibril_mutex_unlock(&vfs_data->lock); 260 261 return rc; 215 262 } 216 263 … … 224 271 int vfs_fd_free(int fd) 225 272 { 226 int rc; 227 228 if (!vfs_files_init()) 229 return ENOMEM; 230 231 fibril_mutex_lock(&VFS_DATA->lock); 232 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) { 233 fibril_mutex_unlock(&VFS_DATA->lock); 234 return EBADF; 235 } 236 237 rc = vfs_file_delref(FILES[fd]); 238 FILES[fd] = NULL; 239 fibril_mutex_unlock(&VFS_DATA->lock); 240 241 return rc; 273 return _vfs_fd_free(VFS_DATA, fd); 242 274 } 243 275 … … 253 285 int vfs_fd_assign(vfs_file_t *file, int fd) 254 286 { 255 if (!vfs_files_init( ))287 if (!vfs_files_init(VFS_DATA)) 256 288 return ENOMEM; 257 289 … … 263 295 264 296 FILES[fd] = file; 265 vfs_file_addref( FILES[fd]);297 vfs_file_addref(VFS_DATA, FILES[fd]); 266 298 fibril_mutex_unlock(&VFS_DATA->lock); 267 299 … … 269 301 } 270 302 271 /** Find VFS file structure for a given file descriptor. 272 * 273 * @param fd File descriptor. 274 * 275 * @return VFS file structure corresponding to fd. 276 */ 277 vfs_file_t *vfs_file_get(int fd) 278 { 279 if (!vfs_files_init()) 303 static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd) 304 { 305 if (!vfs_files_init(vfs_data)) 280 306 return NULL; 281 307 282 fibril_mutex_lock(& VFS_DATA->lock);308 fibril_mutex_lock(&vfs_data->lock); 283 309 if ((fd >= 0) && (fd < MAX_OPEN_FILES)) { 284 vfs_file_t *file = FILES[fd];310 vfs_file_t *file = vfs_data->files[fd]; 285 311 if (file != NULL) { 286 vfs_file_addref( file);287 fibril_mutex_unlock(& VFS_DATA->lock);312 vfs_file_addref(vfs_data, file); 313 fibril_mutex_unlock(&vfs_data->lock); 288 314 return file; 289 315 } 290 316 } 291 fibril_mutex_unlock(& VFS_DATA->lock);317 fibril_mutex_unlock(&vfs_data->lock); 292 318 293 319 return NULL; 294 320 } 295 321 322 /** Find VFS file structure for a given file descriptor. 323 * 324 * @param fd File descriptor. 325 * 326 * @return VFS file structure corresponding to fd. 327 */ 328 vfs_file_t *vfs_file_get(int fd) 329 { 330 return _vfs_file_get(VFS_DATA, fd); 331 } 332 333 static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file) 334 { 335 fibril_mutex_lock(&vfs_data->lock); 336 vfs_file_delref(vfs_data, file); 337 fibril_mutex_unlock(&vfs_data->lock); 338 } 339 296 340 /** Stop using a file structure. 297 341 * … … 300 344 void vfs_file_put(vfs_file_t *file) 301 345 { 302 fibril_mutex_lock(&VFS_DATA->lock); 303 vfs_file_delref(file); 304 fibril_mutex_unlock(&VFS_DATA->lock); 346 _vfs_file_put(VFS_DATA, file); 347 } 348 349 void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd) 350 { 351 vfs_client_data_t *donor_data = NULL; 352 vfs_client_data_t *acceptor_data = NULL; 353 vfs_file_t *donor_file = NULL; 354 vfs_file_t *acceptor_file = NULL; 355 vfs_boxed_handle_t *bh; 356 int acceptor_fd; 357 358 acceptor_data = async_get_client_data_by_id(acceptor_id); 359 if (!acceptor_data) 360 return; 361 362 bh = malloc(sizeof(vfs_boxed_handle_t)); 363 assert(bh); 364 365 link_initialize(&bh->link); 366 bh->handle = -1; 367 368 donor_data = async_get_client_data_by_id(donor_id); 369 if (!donor_data) 370 goto out; 371 372 donor_file = _vfs_file_get(donor_data, donor_fd); 373 if (!donor_file) 374 goto out; 375 376 acceptor_fd = _vfs_fd_alloc(acceptor_data, false); 377 if (acceptor_fd < 0) 378 goto out; 379 380 bh->handle = acceptor_fd; 381 382 /* 383 * Add a new reference to the underlying VFS node. 384 */ 385 vfs_node_addref(donor_file->node); 386 (void) vfs_open_node_remote(donor_file->node); 387 388 acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd); 389 assert(acceptor_file); 390 391 /* 392 * Inherit attributes from the donor. 393 */ 394 acceptor_file->node = donor_file->node; 395 acceptor_file->append = donor_file->append; 396 acceptor_file->pos = donor_file->pos; 397 398 out: 399 fibril_mutex_lock(&acceptor_data->lock); 400 list_append(&bh->link, &acceptor_data->passed_handles); 401 fibril_condvar_broadcast(&acceptor_data->cv); 402 fibril_mutex_unlock(&acceptor_data->lock); 403 404 if (donor_data) 405 async_put_client_data_by_id(donor_id); 406 if (acceptor_data) 407 async_put_client_data_by_id(acceptor_id); 408 if (donor_file) 409 _vfs_file_put(donor_data, donor_file); 410 if (acceptor_file) 411 _vfs_file_put(acceptor_data, acceptor_file); 412 413 } 414 415 int vfs_wait_handle_internal(void) 416 { 417 vfs_client_data_t *vfs_data = VFS_DATA; 418 int fd; 419 420 fibril_mutex_lock(&vfs_data->lock); 421 while (list_empty(&vfs_data->passed_handles)) 422 fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock); 423 link_t *lnk = list_first(&vfs_data->passed_handles); 424 list_remove(lnk); 425 fibril_mutex_unlock(&vfs_data->lock); 426 427 vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link); 428 fd = bh->handle; 429 free(bh); 430 431 return fd; 305 432 } 306 433 -
uspace/srv/vfs/vfs_lookup.c
r0cf27ee r07b39338 201 201 } 202 202 203 /** Perform a node open operation.204 *205 * @return EOK on success or an error code from errno.h.206 *207 */208 int vfs_open_node_internal(vfs_lookup_res_t *result)209 {210 async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);211 212 ipc_call_t answer;213 aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,214 (sysarg_t) result->triplet.service_id,215 (sysarg_t) result->triplet.index, &answer);216 217 sysarg_t rc;218 async_wait_for(req, &rc);219 vfs_exchange_release(exch);220 221 if (rc == EOK) {222 result->size =223 MERGE_LOUP32(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer));224 result->lnkcnt = (unsigned int) IPC_GET_ARG3(answer);225 if (IPC_GET_ARG4(answer) & L_FILE)226 result->type = VFS_NODE_FILE;227 else if (IPC_GET_ARG4(answer) & L_DIRECTORY)228 result->type = VFS_NODE_DIRECTORY;229 else230 result->type = VFS_NODE_UNKNOWN;231 }232 233 return rc;234 }235 236 203 /** 237 204 * @} -
uspace/srv/vfs/vfs_node.c
r0cf27ee r07b39338 293 293 } 294 294 295 296 /** Perform a remote node open operation. 297 * 298 * @return EOK on success or an error code from errno.h. 299 * 300 */ 301 int vfs_open_node_remote(vfs_node_t *node) 302 { 303 async_exch_t *exch = vfs_exchange_grab(node->fs_handle); 304 305 ipc_call_t answer; 306 aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE, 307 (sysarg_t) node->service_id, (sysarg_t) node->index, &answer); 308 309 vfs_exchange_release(exch); 310 311 sysarg_t rc; 312 async_wait_for(req, &rc); 313 314 return rc; 315 } 316 295 317 /** 296 318 * @} -
uspace/srv/vfs/vfs_ops.c
r0cf27ee r07b39338 618 618 } 619 619 620 void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)621 {622 // FIXME: check for sanity of the supplied fs, dev and index623 624 /*625 * The interface is open_node(fs, dev, index, oflag).626 */627 vfs_lookup_res_t lr;628 629 lr.triplet.fs_handle = IPC_GET_ARG1(*request);630 lr.triplet.service_id = IPC_GET_ARG2(*request);631 lr.triplet.index = IPC_GET_ARG3(*request);632 int oflag = IPC_GET_ARG4(*request);633 634 fibril_rwlock_read_lock(&namespace_rwlock);635 636 int rc = vfs_open_node_internal(&lr);637 if (rc != EOK) {638 fibril_rwlock_read_unlock(&namespace_rwlock);639 async_answer_0(rid, rc);640 return;641 }642 643 vfs_node_t *node = vfs_node_get(&lr);644 fibril_rwlock_read_unlock(&namespace_rwlock);645 646 /* Truncate the file if requested and if necessary. */647 if (oflag & O_TRUNC) {648 fibril_rwlock_write_lock(&node->contents_rwlock);649 if (node->size) {650 rc = vfs_truncate_internal(node->fs_handle,651 node->service_id, node->index, 0);652 if (rc) {653 fibril_rwlock_write_unlock(&node->contents_rwlock);654 vfs_node_put(node);655 async_answer_0(rid, rc);656 return;657 }658 node->size = 0;659 }660 fibril_rwlock_write_unlock(&node->contents_rwlock);661 }662 663 /*664 * Get ourselves a file descriptor and the corresponding vfs_file_t665 * structure.666 */667 int fd = vfs_fd_alloc((oflag & O_DESC) != 0);668 if (fd < 0) {669 vfs_node_put(node);670 async_answer_0(rid, fd);671 return;672 }673 vfs_file_t *file = vfs_file_get(fd);674 file->node = node;675 if (oflag & O_APPEND)676 file->append = true;677 678 /*679 * The following increase in reference count is for the fact that the680 * file is being opened and that a file structure is pointing to it.681 * It is necessary so that the file will not disappear when682 * vfs_node_put() is called. The reference will be dropped by the683 * respective VFS_IN_CLOSE.684 */685 vfs_node_addref(node);686 vfs_node_put(node);687 vfs_file_put(file);688 689 /* Success! Return the new file descriptor to the client. */690 async_answer_1(rid, EOK, fd);691 }692 693 620 void vfs_sync(ipc_callid_t rid, ipc_call_t *request) 694 621 { … … 1349 1276 } 1350 1277 1278 void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request) 1279 { 1280 int fd = vfs_wait_handle_internal(); 1281 async_answer_1(rid, EOK, fd); 1282 } 1283 1351 1284 /** 1352 1285 * @}
Note:
See TracChangeset
for help on using the changeset viewer.
