Changeset 8300c72 in mainline for uspace/lib


Ignore:
Timestamp:
2025-03-03T22:58:05Z (7 months 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/lib
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • 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{
Note: See TracChangeset for help on using the changeset viewer.