Changes in uspace/srv/devman/main.c [422722e:d0dd7b5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/main.c
r422722e rd0dd7b5 65 65 static dev_tree_t device_tree; 66 66 67 static int init_running_drv(void *drv);68 69 67 /** Register running driver. */ 70 static driver_t *devman_driver_register(ipc_callid_t callid, ipc_call_t *call) 71 { 68 static driver_t *devman_driver_register(void) 69 { 70 ipc_call_t icall; 71 ipc_callid_t iid; 72 72 driver_t *driver = NULL; 73 74 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 73 82 char *drv_name = NULL; 74 75 log_msg(LVL_DEBUG, "devman_driver_register");76 83 77 84 /* Get driver name. */ 78 85 int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0); 79 86 if (rc != EOK) { 80 async_answer_0( callid, rc);87 async_answer_0(iid, rc); 81 88 return NULL; 82 89 } … … 91 98 free(drv_name); 92 99 drv_name = NULL; 93 async_answer_0( callid, ENOENT);100 async_answer_0(iid, ENOENT); 94 101 return NULL; 95 102 } … … 105 112 driver->name); 106 113 fibril_mutex_unlock(&driver->driver_mutex); 107 async_answer_0( callid, EEXISTS);114 async_answer_0(iid, EEXISTS); 108 115 return NULL; 109 116 } … … 127 134 log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.", 128 135 driver->name); 129 driver->sess = async_callback_receive(EXCHANGE_ PARALLEL);136 driver->sess = async_callback_receive(EXCHANGE_SERIALIZE); 130 137 if (!driver->sess) { 131 138 fibril_mutex_unlock(&driver->driver_mutex); 132 async_answer_0( callid, ENOTSUP);139 async_answer_0(iid, ENOTSUP); 133 140 return NULL; 134 141 } 135 /* FIXME: Work around problem with callback sessions */136 async_sess_args_set(driver->sess, DRIVER_DEVMAN, 0, 0);142 143 fibril_mutex_unlock(&driver->driver_mutex); 137 144 138 145 log_msg(LVL_NOTE, … … 140 147 driver->name); 141 148 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); 149 async_answer_0(iid, EOK); 150 160 151 return driver; 161 152 } … … 438 429 static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall) 439 430 { 440 client_t *client;441 driver_t *driver;442 443 431 /* Accept the connection. */ 444 432 async_answer_0(iid, EOK); 445 433 446 client = async_get_client_data(); 447 if (client == NULL) { 448 log_msg(LVL_ERROR, "Failed to allocate client data."); 449 return; 450 } 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); 451 450 452 451 while (true) { … … 457 456 break; 458 457 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 470 458 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;481 459 case DEVMAN_ADD_FUNCTION: 482 460 devman_add_function(callid, &call); … … 519 497 } 520 498 521 /** Get device name. */ 522 static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall) 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) 523 502 { 524 503 devman_handle_t handle = IPC_GET_ARG1(*icall); … … 544 523 } 545 524 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 583 525 size_t sent_length = str_size(fun->pathname); 584 526 if (sent_length > data_len) { … … 590 532 591 533 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);666 534 } 667 535 … … 698 566 devman_function_get_handle(callid, &call); 699 567 break; 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); 568 case DEVMAN_DEVICE_GET_DEVICE_PATH: 569 devman_get_device_path_by_handle(callid, &call); 711 570 break; 712 571 case DEVMAN_FUN_SID_TO_HANDLE: … … 836 695 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 837 696 { 838 /* Select port. */697 /* Select interface. */ 839 698 switch ((sysarg_t) (IPC_GET_ARG1(*icall))) { 840 699 case DEVMAN_DRIVER: … … 862 721 } 863 722 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 881 723 /** Initialize device manager internal structures. */ 882 724 static bool devman_init(void) … … 925 767 } 926 768 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); 769 /* Set a handler of incomming connections. */ 930 770 async_set_client_connection(devman_connection); 931 771
Note:
See TracChangeset
for help on using the changeset viewer.