Changeset 81685dd9 in mainline for uspace/lib/drv/generic/driver.c


Ignore:
Timestamp:
2017-10-20T07:18:57Z (7 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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.