Changeset 1a5b252 in mainline for uspace/lib


Ignore:
Timestamp:
2011-08-21T11:54:15Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8cc4ddb
Parents:
e64df9a
Message:

DDF support for function offlining and onlining. This allows
(anticipated) hot removal — support needs to be added in individual
drivers, currently there is support in test1 and partially in rootvirt.
Surprise removal is not supported. TODO synchronization.

Location:
uspace/lib
Files:
5 edited

Legend:

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

    re64df9a r1a5b252  
    327327}
    328328
     329int devman_drv_fun_online(devman_handle_t funh)
     330{
     331        async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
     332        if (exch == NULL)
     333                return ENOMEM;
     334       
     335        sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh);
     336       
     337        devman_exchange_end(exch);
     338        return (int) retval;
     339}
     340
     341int devman_drv_fun_offline(devman_handle_t funh)
     342{
     343        async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
     344        if (exch == NULL)
     345                return ENOMEM;
     346       
     347        sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh);
     348       
     349        devman_exchange_end(exch);
     350        return (int) retval;
     351}
     352
    329353async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    330354    devman_handle_t handle, unsigned int flags)
     
    430454}
    431455
     456int devman_fun_online(devman_handle_t funh)
     457{
     458        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     459        if (exch == NULL)
     460                return ENOMEM;
     461       
     462        sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh);
     463       
     464        devman_exchange_end(exch);
     465        return (int) retval;
     466}
     467
     468int devman_fun_offline(devman_handle_t funh)
     469{
     470        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     471        if (exch == NULL)
     472                return ENOMEM;
     473       
     474        sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh);
     475       
     476        devman_exchange_end(exch);
     477        return (int) retval;
     478}
     479
    432480static int devman_get_handles_once(sysarg_t method, sysarg_t arg1,
    433481    devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
  • uspace/lib/c/include/devman.h

    re64df9a r1a5b252  
    5050    devman_handle_t, devman_handle_t *);
    5151extern int devman_remove_function(devman_handle_t);
     52extern int devman_drv_fun_online(devman_handle_t);
     53extern int devman_drv_fun_offline(devman_handle_t);
    5254
    5355extern async_sess_t *devman_device_connect(exch_mgmt_t, devman_handle_t,
     
    6365extern int devman_fun_get_name(devman_handle_t, char *, size_t);
    6466extern int devman_fun_get_path(devman_handle_t, char *, size_t);
     67extern int devman_fun_online(devman_handle_t);
     68extern int devman_fun_offline(devman_handle_t);
    6569
    6670extern int devman_add_device_to_category(devman_handle_t, const char *);
  • uspace/lib/c/include/ipc/devman.h

    re64df9a r1a5b252  
    139139        DEVMAN_ADD_MATCH_ID,
    140140        DEVMAN_ADD_DEVICE_TO_CATEGORY,
     141        DEVMAN_DRV_FUN_ONLINE,
     142        DEVMAN_DRV_FUN_OFFLINE,
    141143        DEVMAN_REMOVE_FUNCTION
    142144} driver_to_devman_t;
    143145
    144146typedef enum {
    145         DRIVER_ADD_DEVICE = IPC_FIRST_USER_METHOD
     147        DRIVER_DEV_ADD = IPC_FIRST_USER_METHOD,
     148        DRIVER_DEV_REMOVE,
     149        DRIVER_FUN_ONLINE,
     150        DRIVER_FUN_OFFLINE,
    146151
    147152} devman_to_driver_t;
     
    152157        DEVMAN_FUN_GET_CHILD,
    153158        DEVMAN_FUN_GET_NAME,
     159        DEVMAN_FUN_ONLINE,
     160        DEVMAN_FUN_OFFLINE,
    154161        DEVMAN_FUN_GET_PATH,
    155162        DEVMAN_FUN_SID_TO_HANDLE
  • uspace/lib/drv/generic/driver.c

    re64df9a r1a5b252  
    6363
    6464/** Devices */
     65LIST_INITIALIZE(devices);
     66FIBRIL_MUTEX_INITIALIZE(devices_mutex);
     67
     68/** Functions */
    6569LIST_INITIALIZE(functions);
    6670FIBRIL_MUTEX_INITIALIZE(functions_mutex);
     
    227231}
    228232
    229 static ddf_fun_t *driver_get_function(list_t *functions, devman_handle_t handle)
     233static ddf_dev_t *driver_get_device(devman_handle_t handle)
     234{
     235        ddf_dev_t *dev = NULL;
     236       
     237        assert(fibril_mutex_is_locked(&devices_mutex));
     238       
     239        list_foreach(devices, link) {
     240                dev = list_get_instance(link, ddf_dev_t, link);
     241                if (dev->handle == handle)
     242                        return dev;
     243        }
     244       
     245        return NULL;
     246}
     247
     248static ddf_fun_t *driver_get_function(devman_handle_t handle)
    230249{
    231250        ddf_fun_t *fun = NULL;
    232251       
    233         fibril_mutex_lock(&functions_mutex);
    234        
    235         list_foreach(*functions, link) {
     252        assert(fibril_mutex_is_locked(&functions_mutex));
     253       
     254        list_foreach(functions, link) {
    236255                fun = list_get_instance(link, ddf_fun_t, link);
    237                 if (fun->handle == handle) {
    238                         fibril_mutex_unlock(&functions_mutex);
     256                if (fun->handle == handle)
    239257                        return fun;
    240                 }
    241         }
    242        
    243         fibril_mutex_unlock(&functions_mutex);
     258        }
    244259       
    245260        return NULL;
     
    270285                delete_device(dev);
    271286       
     287        fibril_mutex_lock(&devices_mutex);
     288        list_append(&dev->link, &devices);
     289        fibril_mutex_unlock(&devices_mutex);
     290       
    272291        async_answer_0(iid, res);
     292}
     293
     294static void driver_dev_remove(ipc_callid_t iid, ipc_call_t *icall)
     295{
     296        devman_handle_t devh;
     297        ddf_dev_t *dev;
     298        int rc;
     299       
     300        printf("libdrv: driver_dev_offline()\n");
     301        devh = IPC_GET_ARG1(*icall);
     302       
     303        fibril_mutex_lock(&devices_mutex);
     304        dev = driver_get_device(devh);
     305        fibril_mutex_unlock(&devices_mutex);
     306        /* XXX need lock on dev */
     307       
     308        if (dev == NULL) {
     309                async_answer_0(iid, ENOENT);
     310                return;
     311        }
     312       
     313        if (driver->driver_ops->dev_remove != NULL)
     314                rc = driver->driver_ops->dev_remove(dev);
     315        else
     316                rc = ENOTSUP;
     317       
     318        async_answer_0(iid, (sysarg_t) rc);
     319}
     320
     321static void driver_fun_online(ipc_callid_t iid, ipc_call_t *icall)
     322{
     323        devman_handle_t funh;
     324        ddf_fun_t *fun;
     325        int rc;
     326       
     327        funh = IPC_GET_ARG1(*icall);
     328        fibril_mutex_lock(&functions_mutex);
     329        fun = driver_get_function(funh);
     330        fibril_mutex_unlock(&functions_mutex);
     331        /* XXX Need lock on fun */
     332       
     333        if (fun == NULL) {
     334                async_answer_0(iid, ENOENT);
     335                return;
     336        }
     337       
     338        if (driver->driver_ops->fun_online != NULL)
     339                rc = driver->driver_ops->fun_online(fun);
     340        else
     341                rc = ENOTSUP;
     342       
     343        async_answer_0(iid, (sysarg_t) rc);
     344}
     345
     346static void driver_fun_offline(ipc_callid_t iid, ipc_call_t *icall)
     347{
     348        devman_handle_t funh;
     349        ddf_fun_t *fun;
     350        int rc;
     351       
     352        funh = IPC_GET_ARG1(*icall);
     353        fibril_mutex_lock(&functions_mutex);
     354        fun = driver_get_function(funh);
     355        fibril_mutex_unlock(&functions_mutex);
     356        /* XXX Need lock on fun */
     357       
     358        if (fun == NULL) {
     359                async_answer_0(iid, ENOENT);
     360                return;
     361        }
     362       
     363        if (driver->driver_ops->fun_offline != NULL)
     364                rc = driver->driver_ops->fun_offline(fun);
     365        else
     366                rc = ENOTSUP;
     367       
     368        async_answer_0(iid, (sysarg_t) rc);
    273369}
    274370
     
    286382               
    287383                switch (IPC_GET_IMETHOD(call)) {
    288                 case DRIVER_ADD_DEVICE:
     384                case DRIVER_DEV_ADD:
    289385                        driver_add_device(callid, &call);
    290386                        break;
     387                case DRIVER_DEV_REMOVE:
     388                        driver_dev_remove(callid, &call);
     389                        break;
     390                case DRIVER_FUN_ONLINE:
     391                        driver_fun_online(callid, &call);
     392                        break;
     393                case DRIVER_FUN_OFFLINE:
     394                        driver_fun_offline(callid, &call);
     395                        break;
    291396                default:
    292                         async_answer_0(callid, ENOENT);
     397                        async_answer_0(callid, ENOTSUP);
    293398                }
    294399        }
     
    308413         */
    309414        devman_handle_t handle = IPC_GET_ARG2(*icall);
    310         ddf_fun_t *fun = driver_get_function(&functions, handle);
     415
     416        fibril_mutex_lock(&functions_mutex);
     417        ddf_fun_t *fun = driver_get_function(handle);
     418        fibril_mutex_unlock(&functions_mutex);
     419        /* XXX Need a lock on fun */
    311420       
    312421        if (fun == NULL) {
     
    614723 * the function invisible to the system.
    615724 *
    616  * @param fun           Function to bind
     725 * @param fun           Function to unbind
    617726 * @return              EOK on success or negative error code
    618727 */
     
    623732        assert(fun->bound == true);
    624733       
    625         add_to_functions_list(fun);
    626734        res = devman_remove_function(fun->handle);
    627735        if (res != EOK)
     
    631739       
    632740        fun->bound = false;
     741        return EOK;
     742}
     743
     744/** Online function.
     745 *
     746 * @param fun           Function to online
     747 * @return              EOK on success or negative error code
     748 */
     749int ddf_fun_online(ddf_fun_t *fun)
     750{
     751        int res;
     752       
     753        assert(fun->bound == true);
     754       
     755        res = devman_drv_fun_online(fun->handle);
     756        if (res != EOK)
     757                return res;
     758       
     759        return EOK;
     760}
     761
     762/** Offline function.
     763 *
     764 * @param fun           Function to offline
     765 * @return              EOK on success or negative error code
     766 */
     767int ddf_fun_offline(ddf_fun_t *fun)
     768{
     769        int res;
     770       
     771        assert(fun->bound == true);
     772       
     773        res = devman_drv_fun_offline(fun->handle);
     774        if (res != EOK)
     775                return res;
     776       
    633777        return EOK;
    634778}
  • uspace/lib/drv/include/ddf/driver.h

    re64df9a r1a5b252  
    132132typedef struct driver_ops {
    133133        /** Callback method for passing a new device to the device driver */
    134         int (*add_device)(ddf_dev_t *dev);
    135         /* TODO: add other generic driver operations */
     134        int (*add_device)(ddf_dev_t *);
     135        /** Ask driver to remove a device */
     136        int (*dev_remove)(ddf_dev_t *);
     137        /** Ask driver to online a specific function */
     138        int (*fun_online)(ddf_fun_t *);
     139        /** Ask driver to offline a specific function */
     140        int (*fun_offline)(ddf_fun_t *);
    136141} driver_ops_t;
    137142
     
    150155extern int ddf_fun_bind(ddf_fun_t *);
    151156extern int ddf_fun_unbind(ddf_fun_t *);
     157extern int ddf_fun_online(ddf_fun_t *);
     158extern int ddf_fun_offline(ddf_fun_t *);
    152159extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
    153160
Note: See TracChangeset for help on using the changeset viewer.