Changes in uspace/lib/drv/generic/driver.c [58563585:3e6a98c5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r58563585 r3e6a98c5 36 36 /** @file 37 37 */ 38 39 #define _DDF_DATA_IMPLANT 38 40 39 41 #include <assert.h> … … 49 51 #include <str_error.h> 50 52 #include <ctype.h> 53 #include <errno.h> 51 54 #include <inttypes.h> 52 55 #include <devman.h> 56 57 #include <ipc/driver.h> 53 58 54 59 #include "dev_iface.h" … … 58 63 59 64 /** Driver structure */ 60 static constdriver_t *driver;65 static driver_t *driver; 61 66 62 67 /** Devices */ … … 93 98 static ddf_dev_t *driver_get_device(devman_handle_t handle) 94 99 { 100 ddf_dev_t *dev = NULL; 101 95 102 assert(fibril_mutex_is_locked(&devices_mutex)); 96 103 97 list_foreach(devices, link, ddf_dev_t, dev) { 104 list_foreach(devices, link) { 105 dev = list_get_instance(link, ddf_dev_t, link); 98 106 if (dev->handle == handle) 99 107 return dev; … … 105 113 static ddf_fun_t *driver_get_function(devman_handle_t handle) 106 114 { 115 ddf_fun_t *fun = NULL; 116 107 117 assert(fibril_mutex_is_locked(&functions_mutex)); 108 118 109 list_foreach(functions, link, ddf_fun_t, fun) { 119 list_foreach(functions, link) { 120 fun = list_get_instance(link, ddf_fun_t, link); 110 121 if (fun->handle == handle) 111 122 return fun; … … 120 131 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall); 121 132 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 129 133 ddf_dev_t *dev = create_device(); 130 if (!dev) {131 free(dev_name);132 async_answer_0(iid, ENOMEM);133 return;134 }135 134 136 135 /* Add one reference that will be dropped by driver_dev_remove() */ 137 136 dev_add_ref(dev); 138 137 dev->handle = dev_handle; 138 139 char *dev_name = NULL; 140 async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0); 139 141 dev->name = dev_name; 140 142 … … 284 286 } 285 287 286 static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall, 287 void *arg) 288 static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall) 288 289 { 289 290 /* Accept connection */ … … 335 336 fibril_mutex_lock(&functions_mutex); 336 337 ddf_fun_t *fun = driver_get_function(handle); 337 if (fun != NULL)338 fun_add_ref(fun);339 338 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);352 351 return; 353 352 } … … 364 363 365 364 async_answer_0(iid, ret); 366 if (ret != EOK) { 367 fun_del_ref(fun); 365 if (ret != EOK) 368 366 return; 369 }370 367 371 368 while (true) { … … 380 377 (*fun->ops->close)(fun); 381 378 async_answer_0(callid, EOK); 382 fun_del_ref(fun);383 379 return; 384 380 } … … 423 419 * handling ("remote interface"). 424 420 */ 425 constremote_iface_t *rem_iface = get_remote_iface(iface_idx);421 remote_iface_t *rem_iface = get_remote_iface(iface_idx); 426 422 assert(rem_iface != NULL); 427 423 … … 448 444 } 449 445 450 static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall, 451 void *arg) 446 static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall) 452 447 { 453 448 driver_connection_gen(iid, icall, true); 454 449 } 455 450 456 static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall, 457 void *arg) 451 static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall) 458 452 { 459 453 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 } 460 487 } 461 488 … … 503 530 if (dev->driver_data != NULL) 504 531 free(dev->driver_data); 505 if (dev->name)506 free(dev->name);507 532 free(dev); 508 533 } … … 577 602 } 578 603 604 /** Implant foreign driver-specific device data. 605 * 606 * XXX This is used to transition USB to new interface. Do not use 607 * 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 579 615 /** Return driver-specific device data. */ 580 616 void *ddf_dev_data_get(ddf_dev_t *dev) … … 603 639 * The session will be automatically closed when @a dev is destroyed. 604 640 * 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) 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) 611 646 { 612 647 assert(dev->parent_sess == NULL); 613 dev->parent_sess = devman_parent_device_connect( dev->handle,648 dev->parent_sess = devman_parent_device_connect(mgmt, dev->handle, 614 649 IPC_FLAG_BLOCKING); 615 650 … … 786 821 assert(fun->bound == false); 787 822 assert(fun->name != NULL); 788 assert(fun->dev != NULL);789 823 790 824 add_to_functions_list(fun); … … 891 925 892 926 /** Set function ops. */ 893 void ddf_fun_set_ops(ddf_fun_t *fun, constddf_dev_ops_t *dev_ops)927 void ddf_fun_set_ops(ddf_fun_t *fun, ddf_dev_ops_t *dev_ops) 894 928 { 895 929 assert(fun->conn_handler == NULL); … … 901 935 * This allows handling connections the non-devman way. 902 936 */ 903 void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_ port_handler_t conn)937 void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_client_conn_t conn) 904 938 { 905 939 assert(fun->ops == NULL); … … 928 962 } 929 963 930 int ddf_driver_main( constdriver_t *drv)964 int ddf_driver_main(driver_t *drv) 931 965 { 932 966 /* … … 936 970 driver = drv; 937 971 972 /* Initialize interrupt module */ 973 interrupt_init(); 974 938 975 /* 939 976 * Register driver with device manager using generic handler for 940 977 * incoming connections. 941 978 */ 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); 979 async_set_client_connection(driver_connection); 980 int rc = devman_driver_register(driver->name); 956 981 if (rc != EOK) { 957 982 printf("Error: Failed to register driver with device manager " 958 "(%s).\n", (rc == EEXIST ) ? "driver already started" :983 "(%s).\n", (rc == EEXISTS) ? "driver already started" : 959 984 str_error(rc)); 960 985
Note:
See TracChangeset
for help on using the changeset viewer.