Changes in uspace/srv/devman/main.c [80a96d2:422722e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/main.c
r80a96d2 r422722e 234 234 dev_node_t *dev_node = (dev_node_t *) arg; 235 235 assign_driver(dev_node, &drivers_list, &device_tree); 236 237 /* Delete one reference we got from the caller. */238 dev_del_ref(dev_node);239 236 return EOK; 240 237 } 241 238 242 static int online_function(fun_node_t *fun) 243 { 244 dev_node_t *dev; 245 246 fibril_rwlock_write_lock(&device_tree.rwlock); 247 248 if (fun->state == FUN_ON_LINE) { 249 fibril_rwlock_write_unlock(&device_tree.rwlock); 250 log_msg(LVL_WARN, "Function %s is already on line.", 251 fun->pathname); 252 return EOK; 253 } 254 255 if (fun->ftype == fun_inner) { 239 /** Handle function registration. 240 * 241 * Child devices are registered by their parent's device driver. 242 */ 243 static void devman_add_function(ipc_callid_t callid, ipc_call_t *call) 244 { 245 fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call); 246 devman_handle_t dev_handle = IPC_GET_ARG2(*call); 247 sysarg_t match_count = IPC_GET_ARG3(*call); 248 dev_tree_t *tree = &device_tree; 249 250 fibril_rwlock_write_lock(&tree->rwlock); 251 252 dev_node_t *dev = NULL; 253 dev_node_t *pdev = find_dev_node_no_lock(&device_tree, dev_handle); 254 255 if (pdev == NULL) { 256 fibril_rwlock_write_unlock(&tree->rwlock); 257 async_answer_0(callid, ENOENT); 258 return; 259 } 260 261 if (ftype != fun_inner && ftype != fun_exposed) { 262 /* Unknown function type */ 263 log_msg(LVL_ERROR, 264 "Unknown function type %d provided by driver.", 265 (int) ftype); 266 267 fibril_rwlock_write_unlock(&tree->rwlock); 268 async_answer_0(callid, EINVAL); 269 return; 270 } 271 272 char *fun_name = NULL; 273 int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0); 274 if (rc != EOK) { 275 fibril_rwlock_write_unlock(&tree->rwlock); 276 async_answer_0(callid, rc); 277 return; 278 } 279 280 /* Check that function with same name is not there already. */ 281 if (find_fun_node_in_device(pdev, fun_name) != NULL) { 282 fibril_rwlock_write_unlock(&tree->rwlock); 283 async_answer_0(callid, EEXISTS); 284 printf(NAME ": Warning, driver tried to register `%s' twice.\n", 285 fun_name); 286 free(fun_name); 287 return; 288 } 289 290 fun_node_t *fun = create_fun_node(); 291 fun->ftype = ftype; 292 293 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 294 fibril_rwlock_write_unlock(&tree->rwlock); 295 delete_fun_node(fun); 296 async_answer_0(callid, ENOMEM); 297 return; 298 } 299 300 if (ftype == fun_inner) { 256 301 dev = create_dev_node(); 257 302 if (dev == NULL) { 258 fibril_rwlock_write_unlock(&device_tree.rwlock); 259 return ENOMEM; 303 fibril_rwlock_write_unlock(&tree->rwlock); 304 delete_fun_node(fun); 305 async_answer_0(callid, ENOMEM); 306 return; 260 307 } 261 308 262 insert_dev_node(&device_tree, dev, fun); 263 dev_add_ref(dev); 264 } 309 insert_dev_node(tree, dev, fun); 310 } 311 312 fibril_rwlock_write_unlock(&tree->rwlock); 265 313 266 314 log_msg(LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname); 267 315 268 if (fun->ftype == fun_inner) { 269 dev = fun->child; 316 devman_receive_match_ids(match_count, &fun->match_ids); 317 318 if (ftype == fun_inner) { 270 319 assert(dev != NULL); 271 272 /* Give one reference over to assign_driver_fibril(). */273 dev_add_ref(dev);274 320 /* 275 321 * Try to find a suitable driver and assign it to the device. We do … … 281 327 fid_t assign_fibril = fibril_create(assign_driver_fibril, dev); 282 328 if (assign_fibril == 0) { 283 log_msg(LVL_ERROR, "Failed to create fibril for " 284 "assigning driver."); 285 /* XXX Cleanup */ 286 fibril_rwlock_write_unlock(&device_tree.rwlock); 287 return ENOMEM; 288 } 289 fibril_add_ready(assign_fibril); 290 } else { 291 loc_register_tree_function(fun, &device_tree); 292 } 293 294 fibril_rwlock_write_unlock(&device_tree.rwlock); 295 296 return EOK; 297 } 298 299 static int offline_function(fun_node_t *fun) 300 { 301 int rc; 302 303 fibril_rwlock_write_lock(&device_tree.rwlock); 304 305 if (fun->state == FUN_OFF_LINE) { 306 fibril_rwlock_write_unlock(&device_tree.rwlock); 307 log_msg(LVL_WARN, "Function %s is already off line.", 308 fun->pathname); 309 return EOK; 310 } 311 312 if (fun->ftype == fun_inner) { 313 log_msg(LVL_DEBUG, "Offlining inner function %s.", 314 fun->pathname); 315 316 if (fun->child != NULL) { 317 dev_node_t *dev = fun->child; 318 device_state_t dev_state; 319 320 dev_add_ref(dev); 321 dev_state = dev->state; 322 323 fibril_rwlock_write_unlock(&device_tree.rwlock); 324 325 /* If device is owned by driver, ask driver to give it up. */ 326 if (dev_state == DEVICE_USABLE) { 327 rc = driver_dev_remove(&device_tree, dev); 328 if (rc != EOK) { 329 dev_del_ref(dev); 330 return ENOTSUP; 331 } 332 } 333 334 /* Verify that driver removed all functions */ 335 fibril_rwlock_read_lock(&device_tree.rwlock); 336 if (!list_empty(&dev->functions)) { 337 fibril_rwlock_read_unlock(&device_tree.rwlock); 338 dev_del_ref(dev); 339 return EIO; 340 } 341 342 driver_t *driver = dev->drv; 343 fibril_rwlock_read_unlock(&device_tree.rwlock); 344 345 if (driver) 346 detach_driver(&device_tree, dev); 347 348 fibril_rwlock_write_lock(&device_tree.rwlock); 349 remove_dev_node(&device_tree, dev); 350 351 /* Delete ref created when node was inserted */ 352 dev_del_ref(dev); 353 /* Delete ref created by dev_add_ref(dev) above */ 354 dev_del_ref(dev); 329 /* 330 * Fallback in case we are out of memory. 331 * Probably not needed as we will die soon anyway ;-). 332 */ 333 (void) assign_driver_fibril(fun); 334 } else { 335 fibril_add_ready(assign_fibril); 355 336 } 356 337 } else { 357 /* Unregister from location service */ 358 rc = loc_service_unregister(fun->service_id); 359 if (rc != EOK) { 360 fibril_rwlock_write_unlock(&device_tree.rwlock); 361 log_msg(LVL_ERROR, "Failed unregistering tree service."); 362 return EIO; 363 } 364 365 fun->service_id = 0; 366 } 367 368 fun->state = FUN_OFF_LINE; 369 fibril_rwlock_write_unlock(&device_tree.rwlock); 370 371 return EOK; 372 } 373 374 /** Handle function registration. 375 * 376 * Child devices are registered by their parent's device driver. 377 */ 378 static void devman_add_function(ipc_callid_t callid, ipc_call_t *call) 379 { 380 fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call); 381 devman_handle_t dev_handle = IPC_GET_ARG2(*call); 382 sysarg_t match_count = IPC_GET_ARG3(*call); 383 dev_tree_t *tree = &device_tree; 384 385 dev_node_t *pdev = find_dev_node(&device_tree, dev_handle); 386 if (pdev == NULL) { 387 async_answer_0(callid, ENOENT); 388 return; 389 } 390 391 if (ftype != fun_inner && ftype != fun_exposed) { 392 /* Unknown function type */ 393 log_msg(LVL_ERROR, 394 "Unknown function type %d provided by driver.", 395 (int) ftype); 396 397 dev_del_ref(pdev); 398 async_answer_0(callid, EINVAL); 399 return; 400 } 401 402 char *fun_name = NULL; 403 int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0); 404 if (rc != EOK) { 405 dev_del_ref(pdev); 406 async_answer_0(callid, rc); 407 return; 408 } 409 410 fibril_rwlock_write_lock(&tree->rwlock); 411 412 /* Check device state */ 413 if (pdev->state == DEVICE_REMOVED) { 414 fibril_rwlock_write_unlock(&tree->rwlock); 415 dev_del_ref(pdev); 416 async_answer_0(callid, ENOENT); 417 return; 418 } 419 420 /* Check that function with same name is not there already. */ 421 if (find_fun_node_in_device(tree, pdev, fun_name) != NULL) { 422 fibril_rwlock_write_unlock(&tree->rwlock); 423 dev_del_ref(pdev); 424 async_answer_0(callid, EEXISTS); 425 printf(NAME ": Warning, driver tried to register `%s' twice.\n", 426 fun_name); 427 free(fun_name); 428 return; 429 } 430 431 fun_node_t *fun = create_fun_node(); 432 fun_add_ref(fun); 433 fun->ftype = ftype; 434 435 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 436 fibril_rwlock_write_unlock(&tree->rwlock); 437 dev_del_ref(pdev); 438 delete_fun_node(fun); 439 async_answer_0(callid, ENOMEM); 440 return; 441 } 442 443 fibril_rwlock_write_unlock(&tree->rwlock); 444 dev_del_ref(pdev); 445 446 devman_receive_match_ids(match_count, &fun->match_ids); 447 448 rc = online_function(fun); 449 if (rc != EOK) { 450 /* XXX clean up */ 451 async_answer_0(callid, rc); 452 return; 338 loc_register_tree_function(fun, tree); 453 339 } 454 340 … … 470 356 async_answer_0(callid, rc); 471 357 return; 472 } 358 } 473 359 474 360 fun_node_t *fun = find_fun_node(&device_tree, handle); 475 361 if (fun == NULL) { 476 async_answer_0(callid, ENOENT);477 return;478 }479 480 fibril_rwlock_read_lock(&device_tree.rwlock);481 482 /* Check function state */483 if (fun->state == FUN_REMOVED) {484 fibril_rwlock_read_unlock(&device_tree.rwlock);485 362 async_answer_0(callid, ENOENT); 486 363 return; … … 498 375 fun->pathname, cat_name); 499 376 500 fibril_rwlock_read_unlock(&device_tree.rwlock);501 fun_del_ref(fun);502 503 377 async_answer_0(callid, EOK); 504 }505 506 /** Online function by driver request.507 *508 */509 static void devman_drv_fun_online(ipc_callid_t iid, ipc_call_t *icall,510 driver_t *drv)511 {512 fun_node_t *fun;513 int rc;514 515 log_msg(LVL_DEBUG, "devman_drv_fun_online()");516 517 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));518 if (fun == NULL) {519 async_answer_0(iid, ENOENT);520 return;521 }522 523 fibril_rwlock_read_lock(&device_tree.rwlock);524 if (fun->dev == NULL || fun->dev->drv != drv) {525 fibril_rwlock_read_unlock(&device_tree.rwlock);526 fun_del_ref(fun);527 async_answer_0(iid, ENOENT);528 return;529 }530 fibril_rwlock_read_unlock(&device_tree.rwlock);531 532 rc = online_function(fun);533 if (rc != EOK) {534 fun_del_ref(fun);535 async_answer_0(iid, (sysarg_t) rc);536 return;537 }538 539 fun_del_ref(fun);540 541 async_answer_0(iid, (sysarg_t) EOK);542 }543 544 545 /** Offline function by driver request.546 *547 */548 static void devman_drv_fun_offline(ipc_callid_t iid, ipc_call_t *icall,549 driver_t *drv)550 {551 fun_node_t *fun;552 int rc;553 554 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));555 if (fun == NULL) {556 async_answer_0(iid, ENOENT);557 return;558 }559 560 fibril_rwlock_write_lock(&device_tree.rwlock);561 if (fun->dev == NULL || fun->dev->drv != drv) {562 fun_del_ref(fun);563 async_answer_0(iid, ENOENT);564 return;565 }566 fibril_rwlock_write_unlock(&device_tree.rwlock);567 568 rc = offline_function(fun);569 if (rc != EOK) {570 fun_del_ref(fun);571 async_answer_0(iid, (sysarg_t) rc);572 return;573 }574 575 fun_del_ref(fun);576 async_answer_0(iid, (sysarg_t) EOK);577 378 } 578 379 … … 584 385 int rc; 585 386 586 fun_node_t *fun = find_fun_node(&device_tree, fun_handle); 387 fibril_rwlock_write_lock(&tree->rwlock); 388 389 fun_node_t *fun = find_fun_node_no_lock(&device_tree, fun_handle); 587 390 if (fun == NULL) { 588 async_answer_0(callid, ENOENT);589 return;590 }591 592 fibril_rwlock_write_lock(&tree->rwlock);593 594 log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname);595 596 /* Check function state */597 if (fun->state == FUN_REMOVED) {598 391 fibril_rwlock_write_unlock(&tree->rwlock); 599 392 async_answer_0(callid, ENOENT); … … 601 394 } 602 395 396 log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname); 397 603 398 if (fun->ftype == fun_inner) { 604 /* This is a surprise removal. Handle possible descendants */ 605 if (fun->child != NULL) { 606 dev_node_t *dev = fun->child; 607 device_state_t dev_state; 608 int gone_rc; 609 610 dev_add_ref(dev); 611 dev_state = dev->state; 612 613 fibril_rwlock_write_unlock(&device_tree.rwlock); 614 615 /* If device is owned by driver, inform driver it is gone. */ 616 if (dev_state == DEVICE_USABLE) 617 gone_rc = driver_dev_gone(&device_tree, dev); 618 else 619 gone_rc = EOK; 620 621 fibril_rwlock_read_lock(&device_tree.rwlock); 622 623 /* Verify that driver succeeded and removed all functions */ 624 if (gone_rc != EOK || !list_empty(&dev->functions)) { 625 log_msg(LVL_ERROR, "Driver did not remove " 626 "functions for device that is gone. " 627 "Device node is now defunct."); 628 629 /* 630 * Not much we can do but mark the device 631 * node as having invalid state. This 632 * is a driver bug. 633 */ 634 dev->state = DEVICE_INVALID; 635 fibril_rwlock_read_unlock(&device_tree.rwlock); 636 dev_del_ref(dev); 637 return; 638 } 639 640 driver_t *driver = dev->drv; 641 fibril_rwlock_read_unlock(&device_tree.rwlock); 642 643 if (driver) 644 detach_driver(&device_tree, dev); 645 646 fibril_rwlock_write_lock(&device_tree.rwlock); 647 remove_dev_node(&device_tree, dev); 648 649 /* Delete ref created when node was inserted */ 650 dev_del_ref(dev); 651 /* Delete ref created by dev_add_ref(dev) above */ 652 dev_del_ref(dev); 653 } 399 /* Handle possible descendants */ 400 /* TODO */ 401 log_msg(LVL_WARN, "devman_remove_function(): not handling " 402 "descendants\n"); 654 403 } else { 655 if (fun->service_id != 0) { 656 /* Unregister from location service */ 657 rc = loc_service_unregister(fun->service_id); 658 if (rc != EOK) { 659 log_msg(LVL_ERROR, "Failed unregistering tree " 660 "service."); 661 fibril_rwlock_write_unlock(&tree->rwlock); 662 fun_del_ref(fun); 663 async_answer_0(callid, EIO); 664 return; 665 } 404 /* Unregister from location service */ 405 rc = loc_service_unregister(fun->service_id); 406 if (rc != EOK) { 407 log_msg(LVL_ERROR, "Failed unregistering tree service."); 408 fibril_rwlock_write_unlock(&tree->rwlock); 409 async_answer_0(callid, EIO); 410 return; 666 411 } 667 412 } … … 669 414 remove_fun_node(&device_tree, fun); 670 415 fibril_rwlock_write_unlock(&tree->rwlock); 671 672 /* Delete ref added when inserting function into tree */ 673 fun_del_ref(fun); 674 /* Delete ref added above when looking up function */ 675 fun_del_ref(fun); 416 delete_fun_node(fun); 676 417 677 418 log_msg(LVL_DEBUG, "devman_remove_function() succeeded."); … … 744 485 devman_add_function_to_cat(callid, &call); 745 486 break; 746 case DEVMAN_DRV_FUN_ONLINE:747 devman_drv_fun_online(callid, &call, driver);748 break;749 case DEVMAN_DRV_FUN_OFFLINE:750 devman_drv_fun_offline(callid, &call, driver);751 break;752 487 case DEVMAN_REMOVE_FUNCTION: 753 488 devman_remove_function(callid, &call); 754 489 break; 755 490 default: 756 async_answer_0(callid, EINVAL); 491 async_answer_0(callid, EINVAL); 757 492 break; 758 493 } … … 765 500 { 766 501 char *pathname; 767 devman_handle_t handle;768 502 769 503 int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0); … … 782 516 } 783 517 784 fibril_rwlock_read_lock(&device_tree.rwlock); 785 786 /* Check function state */ 787 if (fun->state == FUN_REMOVED) { 788 fibril_rwlock_read_unlock(&device_tree.rwlock); 789 async_answer_0(iid, ENOENT); 790 return; 791 } 792 handle = fun->handle; 793 794 fibril_rwlock_read_unlock(&device_tree.rwlock); 795 796 /* Delete reference created above by find_fun_node_by_path() */ 797 fun_del_ref(fun); 798 799 async_answer_1(iid, EOK, handle); 518 async_answer_1(iid, EOK, fun->handle); 800 519 } 801 520 … … 815 534 if (!async_data_read_receive(&data_callid, &data_len)) { 816 535 async_answer_0(iid, EINVAL); 817 fun_del_ref(fun);818 536 return; 819 537 } … … 823 541 async_answer_0(data_callid, ENOMEM); 824 542 async_answer_0(iid, ENOMEM); 825 fun_del_ref(fun);826 return;827 }828 829 fibril_rwlock_read_lock(&device_tree.rwlock);830 831 /* Check function state */832 if (fun->state == FUN_REMOVED) {833 fibril_rwlock_read_unlock(&device_tree.rwlock);834 free(buffer);835 836 async_answer_0(data_callid, ENOENT);837 async_answer_0(iid, ENOENT);838 fun_del_ref(fun);839 543 return; 840 544 } … … 848 552 async_answer_0(iid, EOK); 849 553 850 fibril_rwlock_read_unlock(&device_tree.rwlock);851 fun_del_ref(fun);852 554 free(buffer); 853 555 } … … 869 571 if (!async_data_read_receive(&data_callid, &data_len)) { 870 572 async_answer_0(iid, EINVAL); 871 fun_del_ref(fun);872 573 return; 873 574 } … … 877 578 async_answer_0(data_callid, ENOMEM); 878 579 async_answer_0(iid, ENOMEM); 879 fun_del_ref(fun); 880 return; 881 } 882 883 fibril_rwlock_read_lock(&device_tree.rwlock); 884 885 /* Check function state */ 886 if (fun->state == FUN_REMOVED) { 887 fibril_rwlock_read_unlock(&device_tree.rwlock); 888 free(buffer); 889 890 async_answer_0(data_callid, ENOENT); 891 async_answer_0(iid, ENOENT); 892 fun_del_ref(fun); 893 return; 894 } 895 580 return; 581 } 582 896 583 size_t sent_length = str_size(fun->pathname); 897 584 if (sent_length > data_len) { … … 902 589 async_answer_0(iid, EOK); 903 590 904 fibril_rwlock_read_unlock(&device_tree.rwlock);905 fun_del_ref(fun);906 591 free(buffer); 907 592 } … … 924 609 dev_node_t *dev = find_dev_node_no_lock(&device_tree, 925 610 IPC_GET_ARG1(*icall)); 926 if (dev == NULL || dev->state == DEVICE_REMOVED) {611 if (dev == NULL) { 927 612 fibril_rwlock_read_unlock(&device_tree.rwlock); 928 613 async_answer_0(callid, ENOENT); … … 963 648 fibril_rwlock_read_lock(&device_tree.rwlock); 964 649 965 fun = find_fun_node _no_lock(&device_tree, IPC_GET_ARG1(*icall));966 if (fun == NULL || fun->state == FUN_REMOVED) {650 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 651 if (fun == NULL) { 967 652 fibril_rwlock_read_unlock(&device_tree.rwlock); 968 653 async_answer_0(iid, ENOENT); … … 981 666 } 982 667 983 /** Online function. 984 * 985 * Send a request to online a function to the responsible driver. 986 * The driver may offline other functions if necessary (i.e. if the state 987 * of this function is linked to state of another function somehow). 988 */ 989 static void devman_fun_online(ipc_callid_t iid, ipc_call_t *icall) 668 /** Find handle for the function instance identified by its service ID. */ 669 static void devman_fun_sid_to_handle(ipc_callid_t iid, ipc_call_t *icall) 990 670 { 991 671 fun_node_t *fun; 992 int rc; 993 994 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));672 673 fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall)); 674 995 675 if (fun == NULL) { 996 676 async_answer_0(iid, ENOENT); 997 677 return; 998 678 } 999 1000 rc = driver_fun_online(&device_tree, fun);1001 fun_del_ref(fun);1002 1003 async_answer_0(iid, (sysarg_t) rc);1004 }1005 1006 /** Offline function.1007 *1008 * Send a request to offline a function to the responsible driver. As1009 * a result the subtree rooted at that function should be cleanly1010 * detatched. The driver may offline other functions if necessary1011 * (i.e. if the state of this function is linked to state of another1012 * function somehow).1013 */1014 static void devman_fun_offline(ipc_callid_t iid, ipc_call_t *icall)1015 {1016 fun_node_t *fun;1017 int rc;1018 1019 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));1020 if (fun == NULL) {1021 async_answer_0(iid, ENOENT);1022 return;1023 }1024 1025 rc = driver_fun_offline(&device_tree, fun);1026 fun_del_ref(fun);1027 1028 async_answer_0(iid, (sysarg_t) rc);1029 }1030 1031 /** Find handle for the function instance identified by its service ID. */1032 static void devman_fun_sid_to_handle(ipc_callid_t iid, ipc_call_t *icall)1033 {1034 fun_node_t *fun;1035 1036 fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));1037 1038 if (fun == NULL) {1039 async_answer_0(iid, ENOENT);1040 return;1041 }1042 1043 fibril_rwlock_read_lock(&device_tree.rwlock);1044 1045 /* Check function state */1046 if (fun->state == FUN_REMOVED) {1047 fibril_rwlock_read_unlock(&device_tree.rwlock);1048 async_answer_0(iid, ENOENT);1049 return;1050 }1051 679 1052 680 async_answer_1(iid, EOK, fun->handle); 1053 fibril_rwlock_read_unlock(&device_tree.rwlock);1054 fun_del_ref(fun);1055 681 } 1056 682 … … 1084 710 devman_fun_get_path(callid, &call); 1085 711 break; 1086 case DEVMAN_FUN_ONLINE:1087 devman_fun_online(callid, &call);1088 break;1089 case DEVMAN_FUN_OFFLINE:1090 devman_fun_offline(callid, &call);1091 break;1092 712 case DEVMAN_FUN_SID_TO_HANDLE: 1093 713 devman_fun_sid_to_handle(callid, &call); … … 1110 730 if (fun == NULL) 1111 731 dev = find_dev_node(&device_tree, handle); 1112 else { 1113 fibril_rwlock_read_lock(&device_tree.rwlock); 732 else 1114 733 dev = fun->dev; 1115 if (dev != NULL)1116 dev_add_ref(dev);1117 fibril_rwlock_read_unlock(&device_tree.rwlock);1118 }1119 734 1120 735 /* … … 1128 743 "function with handle %" PRIun " was found.", handle); 1129 744 async_answer_0(iid, ENOENT); 1130 goto cleanup;745 return; 1131 746 } 1132 747 … … 1136 751 handle); 1137 752 async_answer_0(iid, ENOENT); 1138 goto cleanup;753 return; 1139 754 } 1140 755 1141 756 driver_t *driver = NULL; 1142 1143 fibril_rwlock_read_lock(&device_tree.rwlock);1144 757 1145 758 if (drv_to_parent) { … … 1156 769 } 1157 770 1158 fibril_rwlock_read_unlock(&device_tree.rwlock);1159 1160 771 if (driver == NULL) { 1161 772 log_msg(LVL_ERROR, "IPC forwarding refused - " \ 1162 773 "the device %" PRIun " is not in usable state.", handle); 1163 774 async_answer_0(iid, ENOENT); 1164 goto cleanup;775 return; 1165 776 } 1166 777 … … 1175 786 "Could not forward to driver `%s'.", driver->name); 1176 787 async_answer_0(iid, EINVAL); 1177 goto cleanup;788 return; 1178 789 } 1179 790 … … 1191 802 async_forward_fast(iid, exch, method, fwd_h, 0, IPC_FF_NONE); 1192 803 async_exchange_end(exch); 1193 1194 cleanup:1195 if (dev != NULL)1196 dev_del_ref(dev);1197 if (fun != NULL)1198 fun_del_ref(fun);1199 804 } 1200 805 … … 1206 811 fun_node_t *fun; 1207 812 dev_node_t *dev; 1208 devman_handle_t handle;1209 driver_t *driver;1210 813 1211 814 fun = find_loc_tree_function(&device_tree, service_id); 1212 815 1213 fibril_rwlock_read_lock(&device_tree.rwlock); 1214 1215 if (fun == NULL || fun->dev == NULL || fun->dev->drv == NULL) { 816 if (fun == NULL || fun->dev->drv == NULL) { 1216 817 log_msg(LVL_WARN, "devman_connection_loc(): function " 1217 818 "not found.\n"); 1218 fibril_rwlock_read_unlock(&device_tree.rwlock);1219 819 async_answer_0(iid, ENOENT); 1220 820 return; … … 1222 822 1223 823 dev = fun->dev; 1224 driver = dev->drv; 1225 handle = fun->handle; 1226 1227 fibril_rwlock_read_unlock(&device_tree.rwlock); 1228 1229 async_exch_t *exch = async_exchange_begin(driver->sess); 1230 async_forward_fast(iid, exch, DRIVER_CLIENT, handle, 0, 824 825 async_exch_t *exch = async_exchange_begin(dev->drv->sess); 826 async_forward_fast(iid, exch, DRIVER_CLIENT, fun->handle, 0, 1231 827 IPC_FF_NONE); 1232 828 async_exchange_end(exch); … … 1234 830 log_msg(LVL_DEBUG, 1235 831 "Forwarding loc service request for `%s' function to driver `%s'.", 1236 fun->pathname, driver->name); 1237 1238 fun_del_ref(fun); 832 fun->pathname, dev->drv->name); 1239 833 } 1240 834
Note:
See TracChangeset
for help on using the changeset viewer.