Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/drv_conn.c

    rfafb8e5 r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    34 * All rights reserved.
     
    360361        rc = loc_category_get_id(cat_name, &cat_id, IPC_FLAG_BLOCKING);
    361362        if (rc == EOK)
    362                 rc = loc_service_add_to_cat(fun->service_id, cat_id);
     363                rc = loc_service_add_to_cat(devman_srv, fun->service_id, cat_id);
    363364        if (rc == EOK) {
    364365                log_msg(LOG_DEFAULT, LVL_NOTE, "Function `%s' added to category `%s'.",
     
    452453        fun_busy_unlock(fun);
    453454        fun_del_ref(fun);
     455        async_answer_0(icall, EOK);
     456}
     457
     458/** Quiesce function by driver request.
     459 *
     460 */
     461static void devman_drv_fun_quiesce(ipc_call_t *icall, driver_t *drv)
     462{
     463        fun_node_t *fun;
     464        errno_t rc;
     465
     466        fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
     467        if (fun == NULL) {
     468                async_answer_0(icall, ENOENT);
     469                return;
     470        }
     471
     472        fun_busy_lock(fun);
     473
     474        fibril_rwlock_write_lock(&device_tree.rwlock);
     475        if (fun->dev == NULL || fun->dev->drv != drv) {
     476                fun_busy_unlock(fun);
     477                fun_del_ref(fun);
     478                async_answer_0(icall, ENOENT);
     479                return;
     480        }
     481        fibril_rwlock_write_unlock(&device_tree.rwlock);
     482
     483        rc = fun_quiesce(fun);
     484        if (rc != EOK) {
     485                fun_busy_unlock(fun);
     486                fun_del_ref(fun);
     487                async_answer_0(icall, rc);
     488                return;
     489        }
     490
     491        fun_busy_unlock(fun);
     492        fun_del_ref(fun);
     493        async_answer_0(icall, EOK);
     494}
     495
     496/** Wait for function to become stable.
     497 *
     498 */
     499static void devman_drv_fun_wait_stable(ipc_call_t *icall, driver_t *drv)
     500{
     501        fun_node_t *fun;
     502        dev_node_t *dev;
     503
     504        fibril_rwlock_read_lock(&device_tree.rwlock);
     505
     506        fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
     507        if (fun == NULL) {
     508                fibril_rwlock_read_unlock(&device_tree.rwlock);
     509                async_answer_0(icall, ENOENT);
     510                return;
     511        }
     512
     513        if (fun->child == NULL) {
     514                fibril_rwlock_read_unlock(&device_tree.rwlock);
     515                fun_del_ref(fun);
     516                async_answer_0(icall, EOK);
     517                return;
     518        }
     519
     520        dev = fun->child;
     521        dev_add_ref(dev);
     522
     523        fibril_rwlock_read_unlock(&device_tree.rwlock);
     524
     525        dev_wait_stable(dev);
     526        dev_del_ref(dev);
     527
    454528        async_answer_0(icall, EOK);
    455529}
     
    641715                        devman_drv_fun_offline(&call, driver);
    642716                        break;
     717                case DEVMAN_DRV_FUN_QUIESCE:
     718                        devman_drv_fun_quiesce(&call, driver);
     719                        break;
     720                case DEVMAN_DRV_FUN_WAIT_STABLE:
     721                        devman_drv_fun_wait_stable(&call, driver);
     722                        break;
    643723                case DEVMAN_REMOVE_FUNCTION:
    644724                        devman_remove_function(&call);
Note: See TracChangeset for help on using the changeset viewer.