Changeset 8300c72 in mainline


Ignore:
Timestamp:
2025-03-03T22:58:05Z (11 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.

Location:
uspace
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/devctl/devctl.c

    rf35749e r8300c72  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    198198}
    199199
     200static errno_t fun_quiesce(const char *path)
     201{
     202        devman_handle_t funh;
     203        errno_t rc;
     204
     205        rc = devman_fun_get_handle(path, &funh, 0);
     206        if (rc != EOK) {
     207                printf(NAME ": Error resolving device function '%s' (%s)\n",
     208                    path, str_error(rc));
     209                return rc;
     210        }
     211
     212        rc = devman_fun_quiesce(funh);
     213        if (rc != EOK) {
     214                printf(NAME ": Failed to offline function '%s' (%s)\n", path,
     215                    str_error(rc));
     216                return rc;
     217        }
     218
     219        return EOK;
     220}
     221
    200222static errno_t drv_list(void)
    201223{
     
    409431                        return 2;
    410432                }
     433        } else if (str_cmp(argv[1], "quiesce") == 0) {
     434                if (argc < 3) {
     435                        printf(NAME ": Argument missing.\n");
     436                        print_syntax();
     437                        return 1;
     438                }
     439
     440                rc = fun_quiesce(argv[2]);
     441                if (rc != EOK) {
     442                        return 2;
     443                }
    411444        } else if (str_cmp(argv[1], "list-drv") == 0) {
    412445                rc = drv_list();
  • uspace/drv/bus/usb/uhci/hc.c

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2011 Jan Vesely
    34 * Copyright (c) 2018 Ondrej Hlavaty, Petr Manek
     
    267268}
    268269
     270/** Quiesce host controller.
     271 *
     272 * @param[in] instance Host controller structure to use.
     273 */
     274int hc_quiesce(hc_device_t *hcd)
     275{
     276        hc_t *instance = hcd_to_hc(hcd);
     277        uhci_regs_t *registers = instance->registers;
     278
     279        /* Reset everything, who knows what touched it before us */
     280        pio_write_16(&registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
     281        fibril_usleep(50000); /* 50ms according to USB spec(root hub reset) */
     282        pio_write_16(&registers->usbcmd, 0);
     283
     284        /* Reset hc, all states and counters. Hope that hw is not broken */
     285        pio_write_16(&registers->usbcmd, UHCI_CMD_HCRESET);
     286        do {
     287                fibril_usleep(10);
     288        } while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
     289
     290        return EOK;
     291}
     292
    269293/** Initialize UHCI hc hw resources.
    270294 *
  • uspace/drv/bus/usb/uhci/hc.h

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2011 Jan Vesely
    34 * Copyright (c) 2018 Ondrej Hlavaty
     
    164165extern errno_t hc_setup_roothub(hc_device_t *);
    165166extern errno_t hc_gone(hc_device_t *);
     167extern errno_t hc_quiesce(hc_device_t *);
    166168
    167169#endif
  • uspace/drv/bus/usb/uhci/main.c

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2011 Vojtech Horky, Jan Vesely
    34 * Copyright (c) 2018 Ondrej Hlavaty, Petr Manek
     
    6162        .setup_root_hub = hc_setup_roothub,
    6263        .hc_gone = hc_gone,
     64        .hc_quiesce = hc_quiesce
    6365};
    6466
  • uspace/drv/bus/usb/xhci/hc.c

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2018 Ondrej Hlavaty, Petr Manek, Jaroslav Jindrak, Jan Hrach, Michal Staruch
    34 * All rights reserved.
     
    746747}
    747748
     749/**
     750 * Quiesce host controller.
     751 */
     752errno_t hc_quiesce(xhci_hc_t *hc)
     753{
     754        hc_stop(hc);
     755        usb_log_info("HC quiesced.");
     756        return EOK;
     757}
     758
    748759unsigned hc_speed_to_psiv(usb_speed_t speed)
    749760{
  • uspace/drv/bus/usb/xhci/hc.h

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2018 Ondrej Hlavaty, Jan Hrach, Jaroslav Jindrak, Petr Manek
    34 * All rights reserved.
     
    119120extern errno_t hc_start(xhci_hc_t *);
    120121extern void hc_fini(xhci_hc_t *);
     122extern errno_t hc_quiesce(xhci_hc_t *);
    121123
    122124extern void hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned);
  • uspace/drv/bus/usb/xhci/main.c

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2018 Ondrej Hlavaty, Petr Manek
    34 * All rights reserved.
     
    9495}
    9596
     97static errno_t hcd_hc_quiesce(hc_device_t *hcd)
     98{
     99        xhci_hc_t *hc = hcd_to_hc(hcd);
     100        hc_quiesce(hc);
     101        return EOK;
     102}
     103
    96104static const hc_driver_t xhci_driver = {
    97105        .name = NAME,
     
    103111        .start = hcd_start,
    104112        .hc_gone = hcd_hc_gone,
     113        .hc_quiesce = hcd_hc_quiesce
    105114};
    106115
  • uspace/drv/nic/e1k/e1k.c

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2011 Zdenek Bouska
    34 * All rights reserved.
     
    220221
    221222static errno_t e1000_dev_add(ddf_dev_t *);
     223static errno_t e1000_dev_quiesce(ddf_dev_t *);
    222224
    223225/** Basic driver operations for E1000 driver */
    224226static driver_ops_t e1000_driver_ops = {
    225         .dev_add = e1000_dev_add
     227        .dev_add = e1000_dev_add,
     228        .dev_quiesce = e1000_dev_quiesce
    226229};
    227230
     
    22232226}
    22242227
     2228/** Quiesce E1000 device.
     2229 *
     2230 * @param dev E1000 device.
     2231 *
     2232 */
     2233errno_t e1000_dev_quiesce(ddf_dev_t *dev)
     2234{
     2235        nic_t *nic = ddf_dev_data_get(dev);
     2236        e1000_t *e1000 = DRIVER_DATA_NIC(nic);
     2237        errno_t rc;
     2238
     2239        ddf_msg(LVL_DEBUG, "e1000_dev_quiesce()");
     2240
     2241        e1000_disable_interrupts(e1000);
     2242        rc = e1000_reset(nic);
     2243        if (rc != EOK)
     2244                ddf_msg(LVL_ERROR, "e1000_dev_quiesce failed");
     2245        return rc;
     2246}
     2247
    22252248/** Read 16-bit value from EEPROM of E1000 adapter
    22262249 *
  • uspace/lib/device/include/devman.h

    rf35749e r8300c72  
    5252extern errno_t devman_drv_fun_online(devman_handle_t);
    5353extern errno_t devman_drv_fun_offline(devman_handle_t);
     54extern errno_t devman_drv_fun_quiesce(devman_handle_t);
    5455extern errno_t devman_drv_fun_wait_stable(devman_handle_t);
    5556
     
    7172extern errno_t devman_fun_online(devman_handle_t);
    7273extern errno_t devman_fun_offline(devman_handle_t);
     74extern errno_t devman_fun_quiesce(devman_handle_t);
    7375
    7476extern errno_t devman_add_device_to_category(devman_handle_t, const char *);
    7577extern errno_t devman_fun_sid_to_handle(service_id_t, devman_handle_t *);
     78extern errno_t devman_quiesce_devices(const char *);
    7679extern errno_t devman_get_drivers(devman_handle_t **, size_t *);
    7780extern errno_t devman_driver_get_devices(devman_handle_t, devman_handle_t **,
  • uspace/lib/device/include/ipc/devman.h

    rf35749e r8300c72  
    148148        DEVMAN_DRV_FUN_ONLINE,
    149149        DEVMAN_DRV_FUN_OFFLINE,
     150        DEVMAN_DRV_FUN_QUIESCE,
    150151        DEVMAN_DRV_FUN_WAIT_STABLE,
    151152        DEVMAN_REMOVE_FUNCTION
     
    156157        DRIVER_DEV_REMOVE,
    157158        DRIVER_DEV_GONE,
     159        DRIVER_DEV_QUIESCE,
    158160        DRIVER_FUN_ONLINE,
    159161        DRIVER_FUN_OFFLINE,
     
    171173        DEVMAN_FUN_ONLINE,
    172174        DEVMAN_FUN_OFFLINE,
     175        DEVMAN_FUN_QUIESCE,
    173176        DEVMAN_FUN_GET_PATH,
    174177        DEVMAN_FUN_SID_TO_HANDLE,
  • uspace/lib/device/src/devman.c

    rf35749e r8300c72  
    343343}
    344344
     345errno_t devman_drv_fun_quiesce(devman_handle_t funh)
     346{
     347        async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
     348        if (exch == NULL)
     349                return ENOMEM;
     350
     351        errno_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_QUIESCE, funh);
     352
     353        devman_exchange_end(exch);
     354        return retval;
     355}
     356
    345357errno_t devman_drv_fun_wait_stable(devman_handle_t funh)
    346358{
     
    506518}
    507519
     520errno_t devman_fun_quiesce(devman_handle_t funh)
     521{
     522        async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
     523        if (exch == NULL)
     524                return ENOMEM;
     525
     526        errno_t retval = async_req_1_0(exch, DEVMAN_FUN_QUIESCE, funh);
     527
     528        devman_exchange_end(exch);
     529        return retval;
     530}
     531
    508532static errno_t devman_get_handles_once(sysarg_t method, sysarg_t arg1,
    509533    devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
     
    632656}
    633657
     658errno_t devman_quiesce_devices(const char *path)
     659{
     660        devman_handle_t funh;
     661        errno_t rc;
     662
     663        funh = 0;
     664        rc = devman_fun_get_handle(path, &funh, 0);
     665        if (rc != EOK)
     666                return rc;
     667
     668        return devman_fun_quiesce(funh);
     669}
     670
    634671errno_t devman_get_drivers(devman_handle_t **drvs,
    635672    size_t *count)
  • uspace/lib/drv/generic/driver.c

    rf35749e r8300c72  
    237237}
    238238
     239static void driver_dev_quiesce(ipc_call_t *icall)
     240{
     241        devman_handle_t devh = ipc_get_arg1(icall);
     242        ddf_fun_t *fun;
     243        link_t *link;
     244
     245        fibril_mutex_lock(&devices_mutex);
     246        ddf_dev_t *dev = driver_get_device(devh);
     247        if (dev != NULL)
     248                dev_add_ref(dev);
     249        fibril_mutex_unlock(&devices_mutex);
     250
     251        if (dev == NULL) {
     252                async_answer_0(icall, ENOENT);
     253                return;
     254        }
     255
     256        errno_t rc;
     257
     258        if (driver->driver_ops->dev_quiesce != NULL) {
     259                rc = driver->driver_ops->dev_quiesce(dev);
     260        } else {
     261                /*
     262                 * If the driver does not implement quiesce, we will
     263                 * simply request all subordinate functions to quiesce.
     264                 */
     265                fibril_mutex_lock(&functions_mutex);
     266                link = list_first(&functions);
     267                while (link != NULL) {
     268                        fun = list_get_instance(link, ddf_fun_t, link);
     269                        if (fun->dev == dev)
     270                                ddf_fun_quiesce(fun);
     271                        link = list_next(link, &functions);
     272                }
     273                fibril_mutex_unlock(&functions_mutex);
     274                rc = EOK;
     275        }
     276
     277        dev_del_ref(dev);
     278        async_answer_0(icall, rc);
     279}
     280
    239281static void driver_fun_online(ipc_call_t *icall)
    240282{
     
    357399                case DRIVER_DEV_GONE:
    358400                        driver_dev_gone(&call);
     401                        break;
     402                case DRIVER_DEV_QUIESCE:
     403                        driver_dev_quiesce(&call);
    359404                        break;
    360405                case DRIVER_FUN_ONLINE:
     
    903948}
    904949
     950/** Quiesce function.
     951 *
     952 * @param fun Function to quiesce
     953 *
     954 * @return EOK on success or an error code
     955 *
     956 */
     957errno_t ddf_fun_quiesce(ddf_fun_t *fun)
     958{
     959        assert(fun->bound == true);
     960
     961        errno_t res = devman_drv_fun_quiesce(fun->handle);
     962        if (res != EOK)
     963                return res;
     964
     965        return EOK;
     966}
     967
    905968/** Add single match ID to inner function.
    906969 *
  • uspace/lib/drv/include/ddf/driver.h

    rf35749e r8300c72  
    8686/** Generic device driver operations */
    8787typedef struct driver_ops {
    88         /** Callback method for passing a new device to the device driver */
     88        /** Ask driver to add a new device */
    8989        errno_t (*dev_add)(ddf_dev_t *);
    9090
     
    9494        /** Inform driver a device disappeared */
    9595        errno_t (*dev_gone)(ddf_dev_t *);
     96
     97        /** Ask driver to quiesce device (disable interrupts and DMA) */
     98        errno_t (*dev_quiesce)(ddf_dev_t *);
    9699
    97100        /** Ask driver to online a specific function */
     
    129132extern errno_t ddf_fun_online(ddf_fun_t *);
    130133extern errno_t ddf_fun_offline(ddf_fun_t *);
     134extern errno_t ddf_fun_quiesce(ddf_fun_t *);
    131135extern errno_t ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
    132136extern void ddf_fun_set_ops(ddf_fun_t *, const ddf_dev_ops_t *);
  • uspace/lib/usbhost/include/usb/host/hcd.h

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2011 Jan Vesely
    34 * Copyright (c) 2018 Ondrej Hlavaty
     
    101102        /** HC is gone. */
    102103        int (*hc_gone)(hc_device_t *);
     104
     105        /** Quiesce HC. */
     106        int (*hc_quiesce)(hc_device_t *);
    103107} hc_driver_t;
    104108
  • uspace/lib/usbhost/src/hcd.c

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2011 Jan Vesely
    34 * Copyright (c) 2018 Ondrej Hlavaty
     
    5859int hc_dev_remove(ddf_dev_t *);
    5960int hc_dev_gone(ddf_dev_t *);
     61int hc_dev_quiesce(ddf_dev_t *);
    6062int hc_fun_online(ddf_fun_t *);
    6163int hc_fun_offline(ddf_fun_t *);
     
    6567        .dev_remove = hc_dev_remove,
    6668        .dev_gone = hc_dev_gone,
     69        .dev_quiesce = hc_dev_quiesce,
    6770        .fun_online = hc_fun_online,
    6871        .fun_offline = hc_fun_offline,
     
    358361}
    359362
     363errno_t hc_dev_quiesce(ddf_dev_t *dev)
     364{
     365        errno_t err = ENOTSUP;
     366        hc_device_t *hcd = dev_to_hcd(dev);
     367
     368        if (hc_driver->hc_quiesce)
     369                err = hc_driver->hc_quiesce(hcd);
     370
     371        return err;
     372}
     373
    360374errno_t hc_fun_online(ddf_fun_t *fun)
    361375{
  • uspace/srv/devman/client_conn.c

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2013 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    479479}
    480480
     481/** Quiesce function.
     482 *
     483 * Send a request to quiesce a function to the responsible driver.
     484 */
     485static void devman_fun_quiesce(ipc_call_t *icall)
     486{
     487        fun_node_t *fun;
     488        dev_node_t *child;
     489        errno_t rc;
     490
     491        fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
     492        if (fun == NULL) {
     493                async_answer_0(icall, ENOENT);
     494                return;
     495        }
     496
     497        fibril_rwlock_read_lock(&device_tree.rwlock);
     498
     499        /* Check function state */
     500        if (fun->state == FUN_REMOVED) {
     501                fibril_rwlock_read_unlock(&device_tree.rwlock);
     502                async_answer_0(icall, ENOENT);
     503                return;
     504        }
     505
     506        child = fun->child;
     507        dev_add_ref(child);
     508        fibril_rwlock_read_unlock(&device_tree.rwlock);
     509
     510        rc = driver_dev_quiesce(&device_tree, child);
     511        fun_del_ref(fun);
     512
     513        async_answer_0(icall, rc);
     514}
     515
    481516/** Find handle for the function instance identified by its service ID. */
    482517static void devman_fun_sid_to_handle(ipc_call_t *icall)
     
    790825                        devman_fun_offline(&call);
    791826                        break;
     827                case DEVMAN_FUN_QUIESCE:
     828                        devman_fun_quiesce(&call);
     829                        break;
    792830                case DEVMAN_FUN_SID_TO_HANDLE:
    793831                        devman_fun_sid_to_handle(&call);
  • uspace/srv/devman/driver.c

    rf35749e r8300c72  
    741741}
    742742
     743errno_t driver_dev_quiesce(dev_tree_t *tree, dev_node_t *dev)
     744{
     745        async_exch_t *exch;
     746        errno_t retval;
     747        driver_t *drv;
     748        devman_handle_t handle;
     749
     750        assert(dev != NULL);
     751
     752        log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_dev_quiesce(%p)", dev);
     753
     754        fibril_rwlock_read_lock(&tree->rwlock);
     755        drv = dev->drv;
     756        handle = dev->handle;
     757        fibril_rwlock_read_unlock(&tree->rwlock);
     758
     759        exch = async_exchange_begin(drv->sess);
     760        retval = async_req_1_0(exch, DRIVER_DEV_QUIESCE, handle);
     761        async_exchange_end(exch);
     762
     763        return retval;
     764}
     765
    743766errno_t driver_dev_gone(dev_tree_t *tree, dev_node_t *dev)
    744767{
  • uspace/srv/devman/driver.h

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2013 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    5353extern void add_device(driver_t *, dev_node_t *, dev_tree_t *);
    5454extern errno_t driver_dev_remove(dev_tree_t *, dev_node_t *);
     55extern errno_t driver_dev_quiesce(dev_tree_t *, dev_node_t *);
    5556extern errno_t driver_dev_gone(dev_tree_t *, dev_node_t *);
    5657extern errno_t driver_fun_online(dev_tree_t *, fun_node_t *);
  • uspace/srv/devman/drv_conn.c

    rf35749e r8300c72  
    444444
    445445        rc = fun_offline(fun);
     446        if (rc != EOK) {
     447                fun_busy_unlock(fun);
     448                fun_del_ref(fun);
     449                async_answer_0(icall, rc);
     450                return;
     451        }
     452
     453        fun_busy_unlock(fun);
     454        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);
    446484        if (rc != EOK) {
    447485                fun_busy_unlock(fun);
     
    677715                        devman_drv_fun_offline(&call, driver);
    678716                        break;
     717                case DEVMAN_DRV_FUN_QUIESCE:
     718                        devman_drv_fun_quiesce(&call, driver);
     719                        break;
    679720                case DEVMAN_DRV_FUN_WAIT_STABLE:
    680721                        devman_drv_fun_wait_stable(&call, driver);
  • 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 */
  • uspace/srv/devman/fun.h

    rf35749e r8300c72  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2013 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    5151extern errno_t fun_online(fun_node_t *);
    5252extern errno_t fun_offline(fun_node_t *);
     53extern errno_t fun_quiesce(fun_node_t *);
    5354
    5455#endif
  • uspace/srv/system/system.c

    rf35749e r8300c72  
    3535 */
    3636
     37#include <devman.h>
    3738#include <fibril.h>
    3839#include <futil.h>
     
    522523        /* Eject all volumes. */
    523524
     525        log_msg(LOG_DEFAULT, LVL_NOTE, "Ejecting volumes.");
     526
    524527        rc = vol_create(&vol);
    525528        if (rc != EOK) {
     
    545548
    546549        free(part_ids);
     550        part_ids = NULL;
    547551        vol_destroy(vol);
     552        vol = NULL;
     553
     554        /* Quiesce the device tree. */
     555
     556        log_msg(LOG_DEFAULT, LVL_NOTE, "Quiescing devices.");
     557
     558        rc = devman_quiesce_devices("/hw");
     559        if (rc != EOK) {
     560                log_msg(LOG_DEFAULT, LVL_ERROR,
     561                    "Failed to quiesce device tree.");
     562                goto error;
     563        }
     564
    548565        return EOK;
    549566error:
Note: See TracChangeset for help on using the changeset viewer.