Changeset 8300c72 in mainline for uspace/srv/devman/fun.c


Ignore:
Timestamp:
2025-03-03T22:58:05Z (13 hours ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
77a0119
Parents:
f35749e
Message:

Quiesce devices before proceeding with shutdown.

Only implemented for e1k, uhci and xhci.

File:
1 edited

Legend:

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

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    34 * All rights reserved.
     
    428429}
    429430
     431errno_t fun_quiesce(fun_node_t *fun)
     432{
     433        errno_t rc;
     434
     435        log_msg(LOG_DEFAULT, LVL_DEBUG, "fun_quiesce(%s)", fun->pathname);
     436        fibril_rwlock_read_lock(&device_tree.rwlock);
     437
     438        if (fun->state == FUN_OFF_LINE) {
     439                fibril_rwlock_read_unlock(&device_tree.rwlock);
     440                log_msg(LOG_DEFAULT, LVL_DEBUG, "Function %s is off line.",
     441                    fun->pathname);
     442                return EOK;
     443        }
     444
     445        if (fun->ftype != fun_inner) {
     446                /* Nothing to do */
     447                log_msg(LOG_DEFAULT, LVL_DEBUG, "Nothing to do for external "
     448                    "function %s\n", fun->pathname);
     449                fibril_rwlock_read_unlock(&device_tree.rwlock);
     450                return EOK;
     451        }
     452
     453        log_msg(LOG_DEFAULT, LVL_DEBUG, "Quiescing inner function %s.",
     454            fun->pathname);
     455
     456        if (fun->child == NULL) {
     457                log_msg(LOG_DEFAULT, LVL_DEBUG, "Function %s child is NULL.",
     458                    fun->pathname);
     459                fibril_rwlock_read_unlock(&device_tree.rwlock);
     460                return EOK;
     461        }
     462
     463        dev_node_t *dev = fun->child;
     464        device_state_t dev_state;
     465
     466        dev_add_ref(dev);
     467        dev_state = dev->state;
     468
     469        fibril_rwlock_read_unlock(&device_tree.rwlock);
     470
     471        /* If device is owned by driver, ask driver to quiesce it. */
     472        if (dev_state == DEVICE_USABLE) {
     473                log_msg(LOG_DEFAULT, LVL_DEBUG, "Call driver_dev_quiesce() "
     474                    "for %s.", fun->pathname);
     475                rc = driver_dev_quiesce(&device_tree, dev);
     476                if (rc != EOK) {
     477                        log_msg(LOG_DEFAULT, LVL_ERROR,
     478                            "driver_dev_quiesce() -> %d", (int)rc);
     479                        dev_del_ref(dev);
     480                        return ENOTSUP;
     481                }
     482        }
     483
     484        dev_del_ref(dev);
     485        return EOK;
     486}
     487
    430488/** @}
    431489 */
Note: See TracChangeset for help on using the changeset viewer.