Changes in uspace/srv/devman/main.c [d0dd7b5:422722e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/main.c
rd0dd7b5 r422722e 65 65 static dev_tree_t device_tree; 66 66 67 static int init_running_drv(void *drv); 68 67 69 /** Register running driver. */ 68 static driver_t *devman_driver_register(void) 69 { 70 ipc_call_t icall; 71 ipc_callid_t iid; 70 static driver_t *devman_driver_register(ipc_callid_t callid, ipc_call_t *call) 71 { 72 72 driver_t *driver = NULL; 73 char *drv_name = NULL; 73 74 74 75 log_msg(LVL_DEBUG, "devman_driver_register"); 75 76 iid = async_get_call(&icall);77 if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) {78 async_answer_0(iid, EREFUSED);79 return NULL;80 }81 82 char *drv_name = NULL;83 76 84 77 /* Get driver name. */ 85 78 int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0); 86 79 if (rc != EOK) { 87 async_answer_0( iid, rc);80 async_answer_0(callid, rc); 88 81 return NULL; 89 82 } … … 98 91 free(drv_name); 99 92 drv_name = NULL; 100 async_answer_0( iid, ENOENT);93 async_answer_0(callid, ENOENT); 101 94 return NULL; 102 95 } … … 112 105 driver->name); 113 106 fibril_mutex_unlock(&driver->driver_mutex); 114 async_answer_0( iid, EEXISTS);107 async_answer_0(callid, EEXISTS); 115 108 return NULL; 116 109 } … … 134 127 log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.", 135 128 driver->name); 136 driver->sess = async_callback_receive(EXCHANGE_ SERIALIZE);129 driver->sess = async_callback_receive(EXCHANGE_PARALLEL); 137 130 if (!driver->sess) { 138 131 fibril_mutex_unlock(&driver->driver_mutex); 139 async_answer_0( iid, ENOTSUP);132 async_answer_0(callid, ENOTSUP); 140 133 return NULL; 141 134 } 142 143 fibril_mutex_unlock(&driver->driver_mutex);135 /* FIXME: Work around problem with callback sessions */ 136 async_sess_args_set(driver->sess, DRIVER_DEVMAN, 0, 0); 144 137 145 138 log_msg(LVL_NOTE, … … 147 140 driver->name); 148 141 149 async_answer_0(iid, EOK); 150 142 /* 143 * Initialize the driver as running (e.g. pass assigned devices to it) 144 * in a separate fibril; the separate fibril is used to enable the 145 * driver to use devman service during the driver's initialization. 146 */ 147 fid_t fid = fibril_create(init_running_drv, driver); 148 if (fid == 0) { 149 log_msg(LVL_ERROR, "Failed to create initialization fibril " \ 150 "for driver `%s'.", driver->name); 151 fibril_mutex_unlock(&driver->driver_mutex); 152 async_answer_0(callid, ENOMEM); 153 return NULL; 154 } 155 156 fibril_add_ready(fid); 157 fibril_mutex_unlock(&driver->driver_mutex); 158 159 async_answer_0(callid, EOK); 151 160 return driver; 152 161 } … … 429 438 static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall) 430 439 { 440 client_t *client; 441 driver_t *driver; 442 431 443 /* Accept the connection. */ 432 444 async_answer_0(iid, EOK); 433 445 434 driver_t *driver = devman_driver_register(); 435 if (driver == NULL) 436 return; 437 438 /* 439 * Initialize the driver as running (e.g. pass assigned devices to it) 440 * in a separate fibril; the separate fibril is used to enable the 441 * driver to use devman service during the driver's initialization. 442 */ 443 fid_t fid = fibril_create(init_running_drv, driver); 444 if (fid == 0) { 445 log_msg(LVL_ERROR, "Failed to create initialization fibril " \ 446 "for driver `%s'.", driver->name); 447 return; 448 } 449 fibril_add_ready(fid); 446 client = async_get_client_data(); 447 if (client == NULL) { 448 log_msg(LVL_ERROR, "Failed to allocate client data."); 449 return; 450 } 450 451 451 452 while (true) { … … 456 457 break; 457 458 459 if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) { 460 fibril_mutex_lock(&client->mutex); 461 driver = client->driver; 462 fibril_mutex_unlock(&client->mutex); 463 if (driver == NULL) { 464 /* First call must be to DEVMAN_DRIVER_REGISTER */ 465 async_answer_0(callid, ENOTSUP); 466 continue; 467 } 468 } 469 458 470 switch (IPC_GET_IMETHOD(call)) { 471 case DEVMAN_DRIVER_REGISTER: 472 fibril_mutex_lock(&client->mutex); 473 if (client->driver != NULL) { 474 fibril_mutex_unlock(&client->mutex); 475 async_answer_0(callid, EINVAL); 476 continue; 477 } 478 client->driver = devman_driver_register(callid, &call); 479 fibril_mutex_unlock(&client->mutex); 480 break; 459 481 case DEVMAN_ADD_FUNCTION: 460 482 devman_add_function(callid, &call); … … 497 519 } 498 520 499 /** Find device path by its handle. */ 500 static void devman_get_device_path_by_handle(ipc_callid_t iid, 501 ipc_call_t *icall) 521 /** Get device name. */ 522 static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall) 502 523 { 503 524 devman_handle_t handle = IPC_GET_ARG1(*icall); … … 523 544 } 524 545 546 size_t sent_length = str_size(fun->name); 547 if (sent_length > data_len) { 548 sent_length = data_len; 549 } 550 551 async_data_read_finalize(data_callid, fun->name, sent_length); 552 async_answer_0(iid, EOK); 553 554 free(buffer); 555 } 556 557 558 /** Get device path. */ 559 static void devman_fun_get_path(ipc_callid_t iid, ipc_call_t *icall) 560 { 561 devman_handle_t handle = IPC_GET_ARG1(*icall); 562 563 fun_node_t *fun = find_fun_node(&device_tree, handle); 564 if (fun == NULL) { 565 async_answer_0(iid, ENOMEM); 566 return; 567 } 568 569 ipc_callid_t data_callid; 570 size_t data_len; 571 if (!async_data_read_receive(&data_callid, &data_len)) { 572 async_answer_0(iid, EINVAL); 573 return; 574 } 575 576 void *buffer = malloc(data_len); 577 if (buffer == NULL) { 578 async_answer_0(data_callid, ENOMEM); 579 async_answer_0(iid, ENOMEM); 580 return; 581 } 582 525 583 size_t sent_length = str_size(fun->pathname); 526 584 if (sent_length > data_len) { … … 532 590 533 591 free(buffer); 592 } 593 594 static void devman_dev_get_functions(ipc_callid_t iid, ipc_call_t *icall) 595 { 596 ipc_callid_t callid; 597 size_t size; 598 size_t act_size; 599 int rc; 600 601 if (!async_data_read_receive(&callid, &size)) { 602 async_answer_0(callid, EREFUSED); 603 async_answer_0(iid, EREFUSED); 604 return; 605 } 606 607 fibril_rwlock_read_lock(&device_tree.rwlock); 608 609 dev_node_t *dev = find_dev_node_no_lock(&device_tree, 610 IPC_GET_ARG1(*icall)); 611 if (dev == NULL) { 612 fibril_rwlock_read_unlock(&device_tree.rwlock); 613 async_answer_0(callid, ENOENT); 614 async_answer_0(iid, ENOENT); 615 return; 616 } 617 618 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size); 619 if (hdl_buf == NULL) { 620 fibril_rwlock_read_unlock(&device_tree.rwlock); 621 async_answer_0(callid, ENOMEM); 622 async_answer_0(iid, ENOMEM); 623 return; 624 } 625 626 rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size); 627 if (rc != EOK) { 628 fibril_rwlock_read_unlock(&device_tree.rwlock); 629 async_answer_0(callid, rc); 630 async_answer_0(iid, rc); 631 return; 632 } 633 634 fibril_rwlock_read_unlock(&device_tree.rwlock); 635 636 sysarg_t retval = async_data_read_finalize(callid, hdl_buf, size); 637 free(hdl_buf); 638 639 async_answer_1(iid, retval, act_size); 640 } 641 642 643 /** Get handle for child device of a function. */ 644 static void devman_fun_get_child(ipc_callid_t iid, ipc_call_t *icall) 645 { 646 fun_node_t *fun; 647 648 fibril_rwlock_read_lock(&device_tree.rwlock); 649 650 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 651 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); 534 666 } 535 667 … … 566 698 devman_function_get_handle(callid, &call); 567 699 break; 568 case DEVMAN_DEVICE_GET_DEVICE_PATH: 569 devman_get_device_path_by_handle(callid, &call); 700 case DEVMAN_DEV_GET_FUNCTIONS: 701 devman_dev_get_functions(callid, &call); 702 break; 703 case DEVMAN_FUN_GET_CHILD: 704 devman_fun_get_child(callid, &call); 705 break; 706 case DEVMAN_FUN_GET_NAME: 707 devman_fun_get_name(callid, &call); 708 break; 709 case DEVMAN_FUN_GET_PATH: 710 devman_fun_get_path(callid, &call); 570 711 break; 571 712 case DEVMAN_FUN_SID_TO_HANDLE: … … 695 836 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 696 837 { 697 /* Select interface. */838 /* Select port. */ 698 839 switch ((sysarg_t) (IPC_GET_ARG1(*icall))) { 699 840 case DEVMAN_DRIVER: … … 721 862 } 722 863 864 static void *devman_client_data_create(void) 865 { 866 client_t *client; 867 868 client = calloc(1, sizeof(client_t)); 869 if (client == NULL) 870 return NULL; 871 872 fibril_mutex_initialize(&client->mutex); 873 return client; 874 } 875 876 static void devman_client_data_destroy(void *data) 877 { 878 free(data); 879 } 880 723 881 /** Initialize device manager internal structures. */ 724 882 static bool devman_init(void) … … 767 925 } 768 926 769 /* Set a handler of incomming connections. */ 927 /* Set handlers for incoming connections. */ 928 async_set_client_data_constructor(devman_client_data_create); 929 async_set_client_data_destructor(devman_client_data_destroy); 770 930 async_set_client_connection(devman_connection); 771 931
Note:
See TracChangeset
for help on using the changeset viewer.