Changeset a1b7e80 in mainline for uspace/srv/devman/main.c
- Timestamp:
- 2011-09-02T16:54:18Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f480d7e
- Parents:
- 7a72ce1a (diff), 224c0e7 (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/main.c
r7a72ce1a ra1b7e80 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); 236 239 return EOK; 237 240 } 238 241 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) { 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) { 301 256 dev = create_dev_node(); 302 257 if (dev == NULL) { 303 fibril_rwlock_write_unlock(&tree->rwlock); 304 delete_fun_node(fun); 305 async_answer_0(callid, ENOMEM); 306 return; 258 fibril_rwlock_write_unlock(&device_tree.rwlock); 259 return ENOMEM; 307 260 } 308 261 309 insert_dev_node(tree, dev, fun); 310 } 311 312 fibril_rwlock_write_unlock(&tree->rwlock); 262 insert_dev_node(&device_tree, dev, fun); 263 dev_add_ref(dev); 264 } 313 265 314 266 log_msg(LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname); 315 267 316 devman_receive_match_ids(match_count, &fun->match_ids); 317 318 if (ftype == fun_inner) { 268 if (fun->ftype == fun_inner) { 269 dev = fun->child; 319 270 assert(dev != NULL); 271 272 /* Give one reference over to assign_driver_fibril(). */ 273 dev_add_ref(dev); 320 274 /* 321 275 * Try to find a suitable driver and assign it to the device. We do … … 327 281 fid_t assign_fibril = fibril_create(assign_driver_fibril, dev); 328 282 if (assign_fibril == 0) { 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); 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 319 dev_add_ref(dev); 320 fibril_rwlock_write_unlock(&device_tree.rwlock); 321 322 rc = driver_dev_remove(&device_tree, dev); 323 if (rc != EOK) { 324 dev_del_ref(dev); 325 return ENOTSUP; 326 } 327 328 detach_driver(&device_tree, dev); 329 330 fibril_rwlock_write_lock(&device_tree.rwlock); 331 remove_dev_node(&device_tree, dev); 332 333 /* Delete ref created when node was inserted */ 334 dev_del_ref(dev); 335 /* Delete ref created by dev_add_ref(dev) above */ 336 dev_del_ref(dev); 336 337 } 337 338 } else { 338 loc_register_tree_function(fun, tree); 339 /* Unregister from location service */ 340 rc = loc_service_unregister(fun->service_id); 341 if (rc != EOK) { 342 fibril_rwlock_write_unlock(&device_tree.rwlock); 343 log_msg(LVL_ERROR, "Failed unregistering tree service."); 344 return EIO; 345 } 346 347 fun->service_id = 0; 348 } 349 350 fun->state = FUN_OFF_LINE; 351 fibril_rwlock_write_unlock(&device_tree.rwlock); 352 353 return EOK; 354 } 355 356 /** Handle function registration. 357 * 358 * Child devices are registered by their parent's device driver. 359 */ 360 static void devman_add_function(ipc_callid_t callid, ipc_call_t *call) 361 { 362 fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call); 363 devman_handle_t dev_handle = IPC_GET_ARG2(*call); 364 sysarg_t match_count = IPC_GET_ARG3(*call); 365 dev_tree_t *tree = &device_tree; 366 367 dev_node_t *pdev = find_dev_node(&device_tree, dev_handle); 368 if (pdev == NULL) { 369 async_answer_0(callid, ENOENT); 370 return; 371 } 372 373 if (ftype != fun_inner && ftype != fun_exposed) { 374 /* Unknown function type */ 375 log_msg(LVL_ERROR, 376 "Unknown function type %d provided by driver.", 377 (int) ftype); 378 379 dev_del_ref(pdev); 380 async_answer_0(callid, EINVAL); 381 return; 382 } 383 384 char *fun_name = NULL; 385 int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0); 386 if (rc != EOK) { 387 dev_del_ref(pdev); 388 async_answer_0(callid, rc); 389 return; 390 } 391 392 fibril_rwlock_write_lock(&tree->rwlock); 393 394 /* Check device state */ 395 if (pdev->state == DEVICE_REMOVED) { 396 fibril_rwlock_write_unlock(&tree->rwlock); 397 dev_del_ref(pdev); 398 async_answer_0(callid, ENOENT); 399 return; 400 } 401 402 /* Check that function with same name is not there already. */ 403 if (find_fun_node_in_device(tree, pdev, fun_name) != NULL) { 404 fibril_rwlock_write_unlock(&tree->rwlock); 405 dev_del_ref(pdev); 406 async_answer_0(callid, EEXISTS); 407 printf(NAME ": Warning, driver tried to register `%s' twice.\n", 408 fun_name); 409 free(fun_name); 410 return; 411 } 412 413 fun_node_t *fun = create_fun_node(); 414 fun_add_ref(fun); 415 fun->ftype = ftype; 416 417 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 418 fibril_rwlock_write_unlock(&tree->rwlock); 419 dev_del_ref(pdev); 420 delete_fun_node(fun); 421 async_answer_0(callid, ENOMEM); 422 return; 423 } 424 425 fibril_rwlock_write_unlock(&tree->rwlock); 426 dev_del_ref(pdev); 427 428 devman_receive_match_ids(match_count, &fun->match_ids); 429 430 rc = online_function(fun); 431 if (rc != EOK) { 432 /* XXX clean up */ 433 async_answer_0(callid, rc); 434 return; 339 435 } 340 436 … … 356 452 async_answer_0(callid, rc); 357 453 return; 358 } 454 } 359 455 360 456 fun_node_t *fun = find_fun_node(&device_tree, handle); 361 457 if (fun == NULL) { 458 async_answer_0(callid, ENOENT); 459 return; 460 } 461 462 fibril_rwlock_read_lock(&device_tree.rwlock); 463 464 /* Check function state */ 465 if (fun->state == FUN_REMOVED) { 466 fibril_rwlock_read_unlock(&device_tree.rwlock); 362 467 async_answer_0(callid, ENOENT); 363 468 return; … … 375 480 fun->pathname, cat_name); 376 481 482 fibril_rwlock_read_unlock(&device_tree.rwlock); 483 fun_del_ref(fun); 484 377 485 async_answer_0(callid, EOK); 486 } 487 488 /** Online function by driver request. 489 * 490 */ 491 static void devman_drv_fun_online(ipc_callid_t iid, ipc_call_t *icall, 492 driver_t *drv) 493 { 494 fun_node_t *fun; 495 int rc; 496 497 printf("devman_drv_fun_online()\n"); 498 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 499 if (fun == NULL) { 500 async_answer_0(iid, ENOENT); 501 return; 502 } 503 504 fibril_rwlock_read_lock(&device_tree.rwlock); 505 if (fun->dev == NULL || fun->dev->drv != drv) { 506 fibril_rwlock_read_unlock(&device_tree.rwlock); 507 fun_del_ref(fun); 508 async_answer_0(iid, ENOENT); 509 return; 510 } 511 fibril_rwlock_read_unlock(&device_tree.rwlock); 512 513 rc = online_function(fun); 514 if (rc != EOK) { 515 printf("devman_drv_fun_online() online_fun->ERROR\n"); 516 fun_del_ref(fun); 517 async_answer_0(iid, (sysarg_t) rc); 518 return; 519 } 520 521 fun_del_ref(fun); 522 printf("devman_drv_fun_online() online_fun->OK\n"); 523 524 async_answer_0(iid, (sysarg_t) EOK); 525 } 526 527 528 /** Offline function by driver request. 529 * 530 */ 531 static void devman_drv_fun_offline(ipc_callid_t iid, ipc_call_t *icall, 532 driver_t *drv) 533 { 534 fun_node_t *fun; 535 int rc; 536 537 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 538 if (fun == NULL) { 539 async_answer_0(iid, ENOENT); 540 return; 541 } 542 543 fibril_rwlock_write_lock(&device_tree.rwlock); 544 if (fun->dev == NULL || fun->dev->drv != drv) { 545 fun_del_ref(fun); 546 async_answer_0(iid, ENOENT); 547 return; 548 } 549 fibril_rwlock_write_unlock(&device_tree.rwlock); 550 551 rc = offline_function(fun); 552 if (rc != EOK) { 553 fun_del_ref(fun); 554 async_answer_0(iid, (sysarg_t) rc); 555 return; 556 } 557 558 fun_del_ref(fun); 559 async_answer_0(iid, (sysarg_t) EOK); 378 560 } 379 561 … … 385 567 int rc; 386 568 569 570 fun_node_t *fun = find_fun_node(&device_tree, fun_handle); 571 if (fun == NULL) { 572 async_answer_0(callid, ENOENT); 573 return; 574 } 575 387 576 fibril_rwlock_write_lock(&tree->rwlock); 388 577 389 fun_node_t *fun = find_fun_node_no_lock(&device_tree, fun_handle); 390 if (fun == NULL) { 578 log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname); 579 580 /* Check function state */ 581 if (fun->state == FUN_REMOVED) { 391 582 fibril_rwlock_write_unlock(&tree->rwlock); 392 583 async_answer_0(callid, ENOENT); … … 394 585 } 395 586 396 log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname);397 398 587 if (fun->ftype == fun_inner) { 399 588 /* Handle possible descendants */ 400 /* TODO */ 401 log_msg(LVL_WARN, "devman_remove_function(): not handling " 402 "descendants\n"); 589 /* TODO - This is a surprise removal */ 590 if (fun->child != NULL) { 591 log_msg(LVL_WARN, "devman_remove_function(): not handling " 592 "descendants\n"); 593 } 403 594 } else { 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; 595 if (fun->service_id != 0) { 596 /* Unregister from location service */ 597 rc = loc_service_unregister(fun->service_id); 598 if (rc != EOK) { 599 log_msg(LVL_ERROR, "Failed unregistering tree " 600 "service."); 601 fibril_rwlock_write_unlock(&tree->rwlock); 602 fun_del_ref(fun); 603 async_answer_0(callid, EIO); 604 return; 605 } 411 606 } 412 607 } … … 414 609 remove_fun_node(&device_tree, fun); 415 610 fibril_rwlock_write_unlock(&tree->rwlock); 416 delete_fun_node(fun); 611 612 /* Delete ref added when inserting function into tree */ 613 fun_del_ref(fun); 614 /* Delete ref added above when looking up function */ 615 fun_del_ref(fun); 417 616 418 617 log_msg(LVL_DEBUG, "devman_remove_function() succeeded."); … … 485 684 devman_add_function_to_cat(callid, &call); 486 685 break; 686 case DEVMAN_DRV_FUN_ONLINE: 687 devman_drv_fun_online(callid, &call, driver); 688 break; 689 case DEVMAN_DRV_FUN_OFFLINE: 690 devman_drv_fun_offline(callid, &call, driver); 691 break; 487 692 case DEVMAN_REMOVE_FUNCTION: 488 693 devman_remove_function(callid, &call); 489 694 break; 490 695 default: 491 async_answer_0(callid, EINVAL); 696 async_answer_0(callid, EINVAL); 492 697 break; 493 698 } … … 500 705 { 501 706 char *pathname; 707 devman_handle_t handle; 502 708 503 709 int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0); … … 516 722 } 517 723 518 async_answer_1(iid, EOK, fun->handle); 724 fibril_rwlock_read_lock(&device_tree.rwlock); 725 726 /* Check function state */ 727 if (fun->state == FUN_REMOVED) { 728 fibril_rwlock_read_unlock(&device_tree.rwlock); 729 async_answer_0(iid, ENOENT); 730 return; 731 } 732 handle = fun->handle; 733 734 fibril_rwlock_read_unlock(&device_tree.rwlock); 735 736 /* Delete reference created above by find_fun_node_by_path() */ 737 fun_del_ref(fun); 738 739 async_answer_1(iid, EOK, handle); 519 740 } 520 741 … … 534 755 if (!async_data_read_receive(&data_callid, &data_len)) { 535 756 async_answer_0(iid, EINVAL); 757 fun_del_ref(fun); 536 758 return; 537 759 } … … 541 763 async_answer_0(data_callid, ENOMEM); 542 764 async_answer_0(iid, ENOMEM); 765 fun_del_ref(fun); 766 return; 767 } 768 769 fibril_rwlock_read_lock(&device_tree.rwlock); 770 771 /* Check function state */ 772 if (fun->state == FUN_REMOVED) { 773 fibril_rwlock_read_unlock(&device_tree.rwlock); 774 free(buffer); 775 776 async_answer_0(data_callid, ENOENT); 777 async_answer_0(iid, ENOENT); 778 fun_del_ref(fun); 543 779 return; 544 780 } … … 552 788 async_answer_0(iid, EOK); 553 789 790 fibril_rwlock_read_unlock(&device_tree.rwlock); 791 fun_del_ref(fun); 554 792 free(buffer); 555 793 } … … 571 809 if (!async_data_read_receive(&data_callid, &data_len)) { 572 810 async_answer_0(iid, EINVAL); 811 fun_del_ref(fun); 573 812 return; 574 813 } … … 578 817 async_answer_0(data_callid, ENOMEM); 579 818 async_answer_0(iid, ENOMEM); 580 return; 581 } 582 819 fun_del_ref(fun); 820 return; 821 } 822 823 fibril_rwlock_read_lock(&device_tree.rwlock); 824 825 /* Check function state */ 826 if (fun->state == FUN_REMOVED) { 827 fibril_rwlock_read_unlock(&device_tree.rwlock); 828 free(buffer); 829 830 async_answer_0(data_callid, ENOENT); 831 async_answer_0(iid, ENOENT); 832 fun_del_ref(fun); 833 return; 834 } 835 583 836 size_t sent_length = str_size(fun->pathname); 584 837 if (sent_length > data_len) { … … 589 842 async_answer_0(iid, EOK); 590 843 844 fibril_rwlock_read_unlock(&device_tree.rwlock); 845 fun_del_ref(fun); 591 846 free(buffer); 592 847 } … … 609 864 dev_node_t *dev = find_dev_node_no_lock(&device_tree, 610 865 IPC_GET_ARG1(*icall)); 611 if (dev == NULL ) {866 if (dev == NULL || dev->state == DEVICE_REMOVED) { 612 867 fibril_rwlock_read_unlock(&device_tree.rwlock); 613 868 async_answer_0(callid, ENOENT); … … 648 903 fibril_rwlock_read_lock(&device_tree.rwlock); 649 904 905 fun = find_fun_node_no_lock(&device_tree, IPC_GET_ARG1(*icall)); 906 if (fun == NULL || fun->state == FUN_REMOVED) { 907 fibril_rwlock_read_unlock(&device_tree.rwlock); 908 async_answer_0(iid, ENOENT); 909 return; 910 } 911 912 if (fun->child == NULL) { 913 fibril_rwlock_read_unlock(&device_tree.rwlock); 914 async_answer_0(iid, ENOENT); 915 return; 916 } 917 918 async_answer_1(iid, EOK, fun->child->handle); 919 920 fibril_rwlock_read_unlock(&device_tree.rwlock); 921 } 922 923 /** Online function. 924 * 925 * Send a request to online a function to the responsible driver. 926 * The driver may offline other functions if necessary (i.e. if the state 927 * of this function is linked to state of another function somehow). 928 */ 929 static void devman_fun_online(ipc_callid_t iid, ipc_call_t *icall) 930 { 931 fun_node_t *fun; 932 int rc; 933 650 934 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 651 935 if (fun == NULL) { 652 fibril_rwlock_read_unlock(&device_tree.rwlock); 653 async_answer_0(iid, ENOENT); 654 return; 655 } 656 657 if (fun->child == NULL) { 658 fibril_rwlock_read_unlock(&device_tree.rwlock); 659 async_answer_0(iid, ENOENT); 660 return; 661 } 662 663 async_answer_1(iid, EOK, fun->child->handle); 664 665 fibril_rwlock_read_unlock(&device_tree.rwlock); 936 async_answer_0(iid, ENOENT); 937 return; 938 } 939 940 rc = driver_fun_online(&device_tree, fun); 941 fun_del_ref(fun); 942 943 async_answer_0(iid, (sysarg_t) rc); 944 } 945 946 /** Offline function. 947 * 948 * Send a request to offline a function to the responsible driver. As 949 * a result the subtree rooted at that function should be cleanly 950 * detatched. The driver may offline other functions if necessary 951 * (i.e. if the state of this function is linked to state of another 952 * function somehow). 953 */ 954 static void devman_fun_offline(ipc_callid_t iid, ipc_call_t *icall) 955 { 956 fun_node_t *fun; 957 int rc; 958 959 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 960 if (fun == NULL) { 961 async_answer_0(iid, ENOENT); 962 return; 963 } 964 965 rc = driver_fun_offline(&device_tree, fun); 966 fun_del_ref(fun); 967 968 async_answer_0(iid, (sysarg_t) rc); 666 969 } 667 970 … … 678 981 } 679 982 983 fibril_rwlock_read_lock(&device_tree.rwlock); 984 985 /* Check function state */ 986 if (fun->state == FUN_REMOVED) { 987 fibril_rwlock_read_unlock(&device_tree.rwlock); 988 async_answer_0(iid, ENOENT); 989 return; 990 } 991 680 992 async_answer_1(iid, EOK, fun->handle); 993 fibril_rwlock_read_unlock(&device_tree.rwlock); 994 fun_del_ref(fun); 681 995 } 682 996 … … 710 1024 devman_fun_get_path(callid, &call); 711 1025 break; 1026 case DEVMAN_FUN_ONLINE: 1027 devman_fun_online(callid, &call); 1028 break; 1029 case DEVMAN_FUN_OFFLINE: 1030 devman_fun_offline(callid, &call); 1031 break; 712 1032 case DEVMAN_FUN_SID_TO_HANDLE: 713 1033 devman_fun_sid_to_handle(callid, &call); … … 730 1050 if (fun == NULL) 731 1051 dev = find_dev_node(&device_tree, handle); 732 else 1052 else { 1053 fibril_rwlock_read_lock(&device_tree.rwlock); 733 1054 dev = fun->dev; 1055 if (dev != NULL) 1056 dev_add_ref(dev); 1057 fibril_rwlock_read_unlock(&device_tree.rwlock); 1058 } 734 1059 735 1060 /* … … 743 1068 "function with handle %" PRIun " was found.", handle); 744 1069 async_answer_0(iid, ENOENT); 745 return;1070 goto cleanup; 746 1071 } 747 1072 … … 751 1076 handle); 752 1077 async_answer_0(iid, ENOENT); 753 return;1078 goto cleanup; 754 1079 } 755 1080 756 1081 driver_t *driver = NULL; 1082 1083 fibril_rwlock_read_lock(&device_tree.rwlock); 757 1084 758 1085 if (drv_to_parent) { … … 769 1096 } 770 1097 1098 fibril_rwlock_read_unlock(&device_tree.rwlock); 1099 771 1100 if (driver == NULL) { 772 1101 log_msg(LVL_ERROR, "IPC forwarding refused - " \ 773 1102 "the device %" PRIun " is not in usable state.", handle); 774 1103 async_answer_0(iid, ENOENT); 775 return;1104 goto cleanup; 776 1105 } 777 1106 … … 786 1115 "Could not forward to driver `%s'.", driver->name); 787 1116 async_answer_0(iid, EINVAL); 788 return;1117 goto cleanup; 789 1118 } 790 1119 … … 802 1131 async_forward_fast(iid, exch, method, fwd_h, 0, IPC_FF_NONE); 803 1132 async_exchange_end(exch); 1133 1134 cleanup: 1135 if (dev != NULL) 1136 dev_del_ref(dev); 1137 if (fun != NULL) 1138 fun_del_ref(fun); 804 1139 } 805 1140 … … 811 1146 fun_node_t *fun; 812 1147 dev_node_t *dev; 1148 devman_handle_t handle; 1149 driver_t *driver; 813 1150 814 1151 fun = find_loc_tree_function(&device_tree, service_id); 815 1152 816 if (fun == NULL || fun->dev->drv == NULL) { 1153 fibril_rwlock_read_lock(&device_tree.rwlock); 1154 1155 if (fun == NULL || fun->dev == NULL || fun->dev->drv == NULL) { 817 1156 log_msg(LVL_WARN, "devman_connection_loc(): function " 818 1157 "not found.\n"); 1158 fibril_rwlock_read_unlock(&device_tree.rwlock); 819 1159 async_answer_0(iid, ENOENT); 820 1160 return; … … 822 1162 823 1163 dev = fun->dev; 824 825 async_exch_t *exch = async_exchange_begin(dev->drv->sess); 826 async_forward_fast(iid, exch, DRIVER_CLIENT, fun->handle, 0, 1164 driver = dev->drv; 1165 handle = fun->handle; 1166 1167 fibril_rwlock_read_unlock(&device_tree.rwlock); 1168 1169 async_exch_t *exch = async_exchange_begin(driver->sess); 1170 async_forward_fast(iid, exch, DRIVER_CLIENT, handle, 0, 827 1171 IPC_FF_NONE); 828 1172 async_exchange_end(exch); … … 830 1174 log_msg(LVL_DEBUG, 831 1175 "Forwarding loc service request for `%s' function to driver `%s'.", 832 fun->pathname, dev->drv->name); 1176 fun->pathname, driver->name); 1177 1178 fun_del_ref(fun); 833 1179 } 834 1180
Note:
See TracChangeset
for help on using the changeset viewer.