Changeset 81685dd9 in mainline for uspace/lib


Ignore:
Timestamp:
2017-10-20T07:18:57Z (8 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
feab36ae
Parents:
04efacc
Message:

Add devctl unload-drv subcommand to manually unload a driver that is not in use.

Location:
uspace/lib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/devman.c

    r04efacc r81685dd9  
    719719}
    720720
     721int 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
    721733/** @}
    722734 */
  • uspace/lib/c/include/devman.h

    r04efacc r81685dd9  
    8282extern int devman_driver_get_state(devman_handle_t, driver_state_t *);
    8383extern int devman_driver_load(devman_handle_t);
     84extern int devman_driver_unload(devman_handle_t);
    8485
    8586#endif
  • uspace/lib/c/include/ipc/devman.h

    r04efacc r81685dd9  
    156156        DRIVER_FUN_ONLINE,
    157157        DRIVER_FUN_OFFLINE,
     158        DRIVER_STOP
    158159} devman_to_driver_t;
    159160
     
    176177        DEVMAN_DRIVER_GET_NAME,
    177178        DEVMAN_DRIVER_GET_STATE,
    178         DEVMAN_DRIVER_LOAD
     179        DEVMAN_DRIVER_LOAD,
     180        DEVMAN_DRIVER_UNLOAD
    179181} client_to_devman_t;
    180182
  • uspace/lib/drv/generic/driver.c

    r04efacc r81685dd9  
    6868FIBRIL_MUTEX_INITIALIZE(functions_mutex);
    6969
     70FIBRIL_RWLOCK_INITIALIZE(stopping_lock);
     71static bool stopping = false;
     72
    7073static ddf_dev_t *create_device(void);
    7174static void delete_device(ddf_dev_t *);
     
    127130        }
    128131       
     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       
    129140        ddf_dev_t *dev = create_device();
    130141        if (!dev) {
     142                fibril_rwlock_read_unlock(&stopping_lock);
    131143                free(dev_name);
    132144                async_answer_0(iid, ENOMEM);
     
    148160       
    149161        if (res != EOK) {
     162                fibril_rwlock_read_unlock(&stopping_lock);
    150163                dev_del_ref(dev);
    151164                async_answer_0(iid, res);
     
    156169        list_append(&dev->link, &devices);
    157170        fibril_mutex_unlock(&devices_mutex);
     171        fibril_rwlock_read_unlock(&stopping_lock);
    158172       
    159173        async_answer_0(iid, res);
     
    282296       
    283297        async_answer_0(iid, (sysarg_t) rc);
     298}
     299
     300static 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);
    284327}
    285328
     
    312355                case DRIVER_FUN_OFFLINE:
    313356                        driver_fun_offline(callid, &call);
     357                        break;
     358                case DRIVER_STOP:
     359                        driver_stop(callid, &call);
    314360                        break;
    315361                default:
Note: See TracChangeset for help on using the changeset viewer.