Changes in uspace/lib/drv/generic/driver.c [3e6a98c5:58563585] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r3e6a98c5 r58563585 36 36 /** @file 37 37 */ 38 39 #define _DDF_DATA_IMPLANT40 38 41 39 #include <assert.h> … … 51 49 #include <str_error.h> 52 50 #include <ctype.h> 53 #include <errno.h>54 51 #include <inttypes.h> 55 52 #include <devman.h> 56 57 #include <ipc/driver.h>58 53 59 54 #include "dev_iface.h" … … 63 58 64 59 /** Driver structure */ 65 static driver_t *driver;60 static const driver_t *driver; 66 61 67 62 /** Devices */ … … 98 93 static ddf_dev_t *driver_get_device(devman_handle_t handle) 99 94 { 100 ddf_dev_t *dev = NULL;101 102 95 assert(fibril_mutex_is_locked(&devices_mutex)); 103 96 104 list_foreach(devices, link) { 105 dev = list_get_instance(link, ddf_dev_t, link); 97 list_foreach(devices, link, ddf_dev_t, dev) { 106 98 if (dev->handle == handle) 107 99 return dev; … … 113 105 static ddf_fun_t *driver_get_function(devman_handle_t handle) 114 106 { 115 ddf_fun_t *fun = NULL;116 117 107 assert(fibril_mutex_is_locked(&functions_mutex)); 118 108 119 list_foreach(functions, link) { 120 fun = list_get_instance(link, ddf_fun_t, link); 109 list_foreach(functions, link, ddf_fun_t, fun) { 121 110 if (fun->handle == handle) 122 111 return fun; … … 131 120 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall); 132 121 122 char *dev_name = NULL; 123 int rc = async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0); 124 if (rc != EOK) { 125 async_answer_0(iid, rc); 126 return; 127 } 128 133 129 ddf_dev_t *dev = create_device(); 130 if (!dev) { 131 free(dev_name); 132 async_answer_0(iid, ENOMEM); 133 return; 134 } 134 135 135 136 /* Add one reference that will be dropped by driver_dev_remove() */ 136 137 dev_add_ref(dev); 137 138 dev->handle = dev_handle; 138 139 char *dev_name = NULL;140 async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);141 139 dev->name = dev_name; 142 140 … … 286 284 } 287 285 288 static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall) 286 static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall, 287 void *arg) 289 288 { 290 289 /* Accept connection */ … … 336 335 fibril_mutex_lock(&functions_mutex); 337 336 ddf_fun_t *fun = driver_get_function(handle); 337 if (fun != NULL) 338 fun_add_ref(fun); 338 339 fibril_mutex_unlock(&functions_mutex); 339 /* XXX Need a lock on fun */340 340 341 341 if (fun == NULL) { … … 349 349 /* Driver has a custom connection handler. */ 350 350 (*fun->conn_handler)(iid, icall, (void *)fun); 351 fun_del_ref(fun); 351 352 return; 352 353 } … … 363 364 364 365 async_answer_0(iid, ret); 365 if (ret != EOK) 366 if (ret != EOK) { 367 fun_del_ref(fun); 366 368 return; 369 } 367 370 368 371 while (true) { … … 377 380 (*fun->ops->close)(fun); 378 381 async_answer_0(callid, EOK); 382 fun_del_ref(fun); 379 383 return; 380 384 } … … 419 423 * handling ("remote interface"). 420 424 */ 421 remote_iface_t *rem_iface = get_remote_iface(iface_idx);425 const remote_iface_t *rem_iface = get_remote_iface(iface_idx); 422 426 assert(rem_iface != NULL); 423 427 … … 444 448 } 445 449 446 static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall) 450 static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall, 451 void *arg) 447 452 { 448 453 driver_connection_gen(iid, icall, true); 449 454 } 450 455 451 static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall) 456 static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall, 457 void *arg) 452 458 { 453 459 driver_connection_gen(iid, icall, false); 454 }455 456 /** Function for handling connections to device driver. */457 static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)458 {459 sysarg_t conn_type;460 461 if (iid == 0) {462 /* Callback connection from devman */463 /* XXX Use separate handler for this type of connection */464 conn_type = DRIVER_DEVMAN;465 } else {466 conn_type = IPC_GET_ARG1(*icall);467 }468 469 /* Select interface */470 switch (conn_type) {471 case DRIVER_DEVMAN:472 /* Handle request from device manager */473 driver_connection_devman(iid, icall);474 break;475 case DRIVER_DRIVER:476 /* Handle request from drivers of child devices */477 driver_connection_driver(iid, icall);478 break;479 case DRIVER_CLIENT:480 /* Handle request from client applications */481 driver_connection_client(iid, icall);482 break;483 default:484 /* No such interface */485 async_answer_0(iid, ENOENT);486 }487 460 } 488 461 … … 530 503 if (dev->driver_data != NULL) 531 504 free(dev->driver_data); 505 if (dev->name) 506 free(dev->name); 532 507 free(dev); 533 508 } … … 602 577 } 603 578 604 /** Implant foreign driver-specific device data.605 *606 * XXX This is used to transition USB to new interface. Do not use607 * in new code. Use of this function must be removed.608 */609 void ddf_fun_data_implant(ddf_fun_t *fun, void *data)610 {611 assert(fun->driver_data == NULL);612 fun->driver_data = data;613 }614 615 579 /** Return driver-specific device data. */ 616 580 void *ddf_dev_data_get(ddf_dev_t *dev) … … 639 603 * The session will be automatically closed when @a dev is destroyed. 640 604 * 641 * @param dev Device 642 * @param mgmt Exchange management style 643 * @return New session or NULL if session could not be created 644 */ 645 async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev, exch_mgmt_t mgmt) 605 * @param dev Device 606 * 607 * @return New session or NULL if session could not be created 608 * 609 */ 610 async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev) 646 611 { 647 612 assert(dev->parent_sess == NULL); 648 dev->parent_sess = devman_parent_device_connect( mgmt,dev->handle,613 dev->parent_sess = devman_parent_device_connect(dev->handle, 649 614 IPC_FLAG_BLOCKING); 650 615 … … 821 786 assert(fun->bound == false); 822 787 assert(fun->name != NULL); 788 assert(fun->dev != NULL); 823 789 824 790 add_to_functions_list(fun); … … 925 891 926 892 /** Set function ops. */ 927 void ddf_fun_set_ops(ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)893 void ddf_fun_set_ops(ddf_fun_t *fun, const ddf_dev_ops_t *dev_ops) 928 894 { 929 895 assert(fun->conn_handler == NULL); … … 935 901 * This allows handling connections the non-devman way. 936 902 */ 937 void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_ client_conn_t conn)903 void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_port_handler_t conn) 938 904 { 939 905 assert(fun->ops == NULL); … … 962 928 } 963 929 964 int ddf_driver_main( driver_t *drv)930 int ddf_driver_main(const driver_t *drv) 965 931 { 966 932 /* … … 970 936 driver = drv; 971 937 972 /* Initialize interrupt module */973 interrupt_init();974 975 938 /* 976 939 * Register driver with device manager using generic handler for 977 940 * incoming connections. 978 941 */ 979 async_set_client_connection(driver_connection); 980 int rc = devman_driver_register(driver->name); 942 port_id_t port; 943 int rc = async_create_port(INTERFACE_DDF_DRIVER, driver_connection_driver, 944 NULL, &port); 945 if (rc != EOK) 946 return rc; 947 948 rc = async_create_port(INTERFACE_DDF_DEVMAN, driver_connection_devman, 949 NULL, &port); 950 if (rc != EOK) 951 return rc; 952 953 async_set_fallback_port_handler(driver_connection_client, NULL); 954 955 rc = devman_driver_register(driver->name); 981 956 if (rc != EOK) { 982 957 printf("Error: Failed to register driver with device manager " 983 "(%s).\n", (rc == EEXIST S) ? "driver already started" :958 "(%s).\n", (rc == EEXIST) ? "driver already started" : 984 959 str_error(rc)); 985 960
Note:
See TracChangeset
for help on using the changeset viewer.