Changes in / [4e6577c:e64df9a] in mainline
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r4e6577c re64df9a 1656 1656 1657 1657 return sess; 1658 } 1659 1660 /** Set arguments for new connections. 1661 * 1662 * FIXME This is an ugly hack to work around the problem that parallel 1663 * exchanges are implemented using parallel connections. When we create 1664 * a callback session, the framework does not know arguments for the new 1665 * connections. 1666 * 1667 * The proper solution seems to be to implement parallel exchanges using 1668 * tagging. 1669 */ 1670 void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2, 1671 sysarg_t arg3) 1672 { 1673 sess->arg1 = arg1; 1674 sess->arg2 = arg2; 1675 sess->arg3 = arg3; 1658 1676 } 1659 1677 -
uspace/lib/c/generic/devman.c
r4e6577c re64df9a 89 89 if (devman_driver_block_sess == NULL) 90 90 devman_driver_block_sess = 91 service_connect_blocking(EXCHANGE_ SERIALIZE,91 service_connect_blocking(EXCHANGE_PARALLEL, 92 92 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 93 93 } … … 138 138 if (devman_driver_sess == NULL) 139 139 devman_driver_sess = 140 service_connect(EXCHANGE_ SERIALIZE, SERVICE_DEVMAN,140 service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN, 141 141 DEVMAN_DRIVER, 0); 142 142 -
uspace/lib/c/generic/ns.c
r4e6577c re64df9a 56 56 async_exchange_end(exch); 57 57 58 /* 59 * FIXME Ugly hack to work around limitation of implementing 60 * parallel exchanges using multiple connections. Shift out 61 * first argument for non-initial connections. 62 */ 63 async_sess_args_set(sess, arg2, arg3, 0); 64 58 65 return sess; 59 66 } … … 66 73 async_connect_me_to_blocking(mgmt, exch, service, arg2, arg3); 67 74 async_exchange_end(exch); 75 76 /* 77 * FIXME Ugly hack to work around limitation of implementing 78 * parallel exchanges using multiple connections. Shift out 79 * first argument for non-initial connections. 80 */ 81 async_sess_args_set(sess, arg2, arg3, 0); 68 82 69 83 return sess; -
uspace/lib/c/include/async.h
r4e6577c re64df9a 337 337 338 338 /* 339 * FIXME These functions just work around problems with parallel exchange 340 * management. Proper solution needs to be implemented. 341 */ 342 void async_sess_args_set(async_sess_t *sess, sysarg_t, sysarg_t, sysarg_t); 343 344 /* 339 345 * User-friendly wrappers for async_share_in_start(). 340 346 */ -
uspace/srv/devman/devman.h
r4e6577c re64df9a 63 63 typedef struct fun_node fun_node_t; 64 64 65 typedef struct { 66 fibril_mutex_t mutex; 67 struct driver *driver; 68 } client_t; 69 65 70 typedef enum { 66 71 /** Driver has not been started. */ -
uspace/srv/devman/main.c
r4e6577c re64df9a 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); … … 814 836 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 815 837 { 816 /* Select interface. */838 /* Select port. */ 817 839 switch ((sysarg_t) (IPC_GET_ARG1(*icall))) { 818 840 case DEVMAN_DRIVER: … … 840 862 } 841 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 842 881 /** Initialize device manager internal structures. */ 843 882 static bool devman_init(void) … … 886 925 } 887 926 888 /* 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); 889 930 async_set_client_connection(devman_connection); 890 931
Note:
See TracChangeset
for help on using the changeset viewer.