Changeset 81685dd9 in mainline
- Timestamp:
- 2017-10-20T07:18:57Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- feab36ae
- Parents:
- 04efacc
- Location:
- uspace
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/devctl/devctl.c
r04efacc r81685dd9 337 337 } 338 338 339 static int drv_unload(const char *drvname) 340 { 341 int rc; 342 devman_handle_t drvh; 343 344 rc = devman_driver_get_handle(drvname, &drvh); 345 if (rc != EOK) { 346 printf("Failed resolving driver '%s' (%d).\n", drvname, rc); 347 return rc; 348 } 349 350 rc = devman_driver_unload(drvh); 351 if (rc != EOK) { 352 printf("Failed unloading driver '%s' (%d).\n", drvname, rc); 353 return rc; 354 } 355 356 return EOK; 357 } 358 339 359 static void print_syntax(void) 340 360 { … … 346 366 printf("\tdevctl show-drv <driver-name>\n"); 347 367 printf("\tdevctl load-drv <driver-name>\n"); 368 printf("\tdevctl unload-drv <driver-name>\n"); 348 369 } 349 370 … … 412 433 if (rc != EOK) 413 434 return 2; 435 } else if (str_cmp(argv[1], "unload-drv") == 0) { 436 if (argc < 3) { 437 printf(NAME ": Argument missing.\n"); 438 print_syntax(); 439 return 1; 440 } 441 442 rc = drv_unload(argv[2]); 443 if (rc != EOK) 444 return 2; 414 445 } else { 415 446 printf(NAME ": Invalid argument '%s'.\n", argv[1]); -
uspace/lib/c/generic/devman.c
r04efacc r81685dd9 719 719 } 720 720 721 int devman_driver_unload(devman_handle_t drvh) 722 { 723 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT); 724 if (exch == NULL) 725 return ENOMEM; 726 727 int rc = async_req_1_0(exch, DEVMAN_DRIVER_UNLOAD, drvh); 728 729 devman_exchange_end(exch); 730 return rc; 731 } 732 721 733 /** @} 722 734 */ -
uspace/lib/c/include/devman.h
r04efacc r81685dd9 82 82 extern int devman_driver_get_state(devman_handle_t, driver_state_t *); 83 83 extern int devman_driver_load(devman_handle_t); 84 extern int devman_driver_unload(devman_handle_t); 84 85 85 86 #endif -
uspace/lib/c/include/ipc/devman.h
r04efacc r81685dd9 156 156 DRIVER_FUN_ONLINE, 157 157 DRIVER_FUN_OFFLINE, 158 DRIVER_STOP 158 159 } devman_to_driver_t; 159 160 … … 176 177 DEVMAN_DRIVER_GET_NAME, 177 178 DEVMAN_DRIVER_GET_STATE, 178 DEVMAN_DRIVER_LOAD 179 DEVMAN_DRIVER_LOAD, 180 DEVMAN_DRIVER_UNLOAD 179 181 } client_to_devman_t; 180 182 -
uspace/lib/drv/generic/driver.c
r04efacc r81685dd9 68 68 FIBRIL_MUTEX_INITIALIZE(functions_mutex); 69 69 70 FIBRIL_RWLOCK_INITIALIZE(stopping_lock); 71 static bool stopping = false; 72 70 73 static ddf_dev_t *create_device(void); 71 74 static void delete_device(ddf_dev_t *); … … 127 130 } 128 131 132 fibril_rwlock_read_lock(&stopping_lock); 133 134 if (stopping) { 135 fibril_rwlock_read_unlock(&stopping_lock); 136 async_answer_0(iid, EIO); 137 return; 138 } 139 129 140 ddf_dev_t *dev = create_device(); 130 141 if (!dev) { 142 fibril_rwlock_read_unlock(&stopping_lock); 131 143 free(dev_name); 132 144 async_answer_0(iid, ENOMEM); … … 148 160 149 161 if (res != EOK) { 162 fibril_rwlock_read_unlock(&stopping_lock); 150 163 dev_del_ref(dev); 151 164 async_answer_0(iid, res); … … 156 169 list_append(&dev->link, &devices); 157 170 fibril_mutex_unlock(&devices_mutex); 171 fibril_rwlock_read_unlock(&stopping_lock); 158 172 159 173 async_answer_0(iid, res); … … 282 296 283 297 async_answer_0(iid, (sysarg_t) rc); 298 } 299 300 static void driver_stop(ipc_callid_t iid, ipc_call_t *icall) 301 { 302 /* Prevent new devices from being added */ 303 fibril_rwlock_write_lock(&stopping_lock); 304 stopping = true; 305 306 /* Check if there are any devices */ 307 fibril_mutex_lock(&devices_mutex); 308 if (list_first(&devices) != NULL) { 309 /* Devices exist, roll back */ 310 fibril_mutex_unlock(&devices_mutex); 311 stopping = false; 312 fibril_rwlock_write_unlock(&stopping_lock); 313 async_answer_0(iid, EBUSY); 314 return; 315 } 316 317 fibril_rwlock_write_unlock(&stopping_lock); 318 319 /* There should be no functions at this point */ 320 fibril_mutex_lock(&functions_mutex); 321 assert(list_first(&functions) == NULL); 322 fibril_mutex_unlock(&functions_mutex); 323 324 /* Reply with success and terminate */ 325 async_answer_0(iid, EOK); 326 exit(0); 284 327 } 285 328 … … 312 355 case DRIVER_FUN_OFFLINE: 313 356 driver_fun_offline(callid, &call); 357 break; 358 case DRIVER_STOP: 359 driver_stop(callid, &call); 314 360 break; 315 361 default: -
uspace/srv/devman/client_conn.c
r04efacc r81685dd9 726 726 } 727 727 728 /** Unload a driver by user request. */ 729 static void devman_driver_unload(ipc_callid_t iid, ipc_call_t *icall) 730 { 731 driver_t *drv; 732 int rc; 733 734 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall)); 735 if (drv == NULL) { 736 async_answer_0(iid, ENOENT); 737 return; 738 } 739 740 fibril_mutex_lock(&drv->driver_mutex); 741 rc = stop_driver(drv); 742 fibril_mutex_unlock(&drv->driver_mutex); 743 744 async_answer_0(iid, rc); 745 } 746 728 747 /** Function for handling connections from a client to the device manager. */ 729 748 void devman_connection_client(ipc_callid_t iid, ipc_call_t *icall, void *arg) … … 794 813 devman_driver_load(callid, &call); 795 814 break; 815 case DEVMAN_DRIVER_UNLOAD: 816 devman_driver_unload(callid, &call); 817 break; 796 818 default: 797 819 async_answer_0(callid, ENOENT); -
uspace/srv/devman/driver.c
r04efacc r81685dd9 298 298 drv->state = DRIVER_STARTING; 299 299 return true; 300 } 301 302 /** Stop a driver 303 * 304 * @param drv The driver's structure. 305 * @return True if the driver's task is successfully spawned, false 306 * otherwise. 307 */ 308 int stop_driver(driver_t *drv) 309 { 310 async_exch_t *exch; 311 sysarg_t retval; 312 313 log_msg(LOG_DEFAULT, LVL_DEBUG, "stop_driver(drv=\"%s\")", drv->name); 314 315 exch = async_exchange_begin(drv->sess); 316 retval = async_req_0_0(exch, DRIVER_STOP); 317 loc_exchange_end(exch); 318 319 if (retval != EOK) 320 return retval; 321 322 drv->state = DRIVER_NOT_STARTED; 323 async_hangup(drv->sess); 324 drv->sess = NULL; 325 return EOK; 300 326 } 301 327 -
uspace/srv/devman/driver.h
r04efacc r81685dd9 50 50 extern void detach_driver(dev_tree_t *, dev_node_t *); 51 51 extern bool start_driver(driver_t *); 52 extern int stop_driver(driver_t *); 52 53 extern void add_device(driver_t *, dev_node_t *, dev_tree_t *); 53 54 extern int driver_dev_remove(dev_tree_t *, dev_node_t *);
Note:
See TracChangeset
for help on using the changeset viewer.