Changeset 0b90f49 in mainline


Ignore:
Timestamp:
2018-01-12T11:32:53Z (6 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b233821
Parents:
46c5dc2
Message:

usbhub: joining polling fibril

Location:
uspace/drv/bus/usb/usbhub
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhub/usbhub.c

    r46c5dc2 r0b90f49  
    8989    bool was_error, void *data);
    9090
     91static bool usb_hub_polling_error_callback(usb_device_t *dev, int err_code, void *arg)
     92{
     93        assert(dev);
     94        assert(arg);
     95        usb_hub_dev_t *hub = arg;
     96
     97        usb_log_error("Device %s polling error: %s", usb_device_get_name(dev),
     98            str_error(err_code));
     99
     100        /* Continue polling until the device is about to be removed. */
     101        return hub->running && !hub->poll_stop;
     102}
     103
    91104/**
    92105 * Initialize hub device driver structure.
     
    110123        hub_dev->pending_ops_count = 0;
    111124        hub_dev->running = false;
     125        hub_dev->poll_stop = false;
    112126        fibril_mutex_initialize(&hub_dev->pending_ops_mutex);
     127        fibril_mutex_initialize(&hub_dev->poll_guard);
    113128        fibril_condvar_initialize(&hub_dev->pending_ops_cv);
     129        fibril_condvar_initialize(&hub_dev->poll_cv);
    114130
    115131        /* Set hub's first configuration. (There should be only one) */
     
    151167            &hub_status_change_endpoint_description,
    152168            hub_port_changes_callback, ((hub_dev->port_count + 1 + 7) / 8),
    153             -1, NULL, usb_hub_polling_terminated_callback, hub_dev);
     169            -1, usb_hub_polling_error_callback,
     170            usb_hub_polling_terminated_callback, hub_dev);
    154171        if (opResult != EOK) {
    155172                /* Function is already bound */
     
    176193int usb_hub_device_remove(usb_device_t *usb_dev)
    177194{
    178         /* TODO: Implement me! */
     195        assert(usb_dev);
     196        usb_hub_dev_t *hub = usb_device_data_get(usb_dev);
     197        assert(hub);
     198
     199        usb_log_info("(%p) USB hub will be removed.", hub);
     200
     201        /* Instruct the hub to stop once endpoints are unregistered. */
     202        hub->poll_stop = true;
    179203        return EOK;
    180204}
    181205
     206static int usb_hub_cleanup(usb_hub_dev_t *hub)
     207{
     208        assert(!hub->running);
     209
     210        for (size_t port = 0; port < hub->port_count; ++port) {
     211                const int ret = usb_hub_port_fini(&hub->ports[port], hub);
     212                if (ret != EOK)
     213                        return ret;
     214        }
     215        free(hub->ports);
     216
     217        const int ret = ddf_fun_unbind(hub->hub_fun);
     218        if (ret != EOK) {
     219                usb_log_error("(%p) Failed to unbind '%s' function: %s.",
     220                   hub, HUB_FNC_NAME, str_error(ret));
     221                return ret;
     222        }
     223        ddf_fun_destroy(hub->hub_fun);
     224
     225        usb_log_info("(%p) USB hub driver stopped and cleaned.", hub);
     226
     227        /* Device data (usb_hub_dev_t) will be freed by usbdev. */
     228        return EOK;
     229}
     230
    182231int usb_hub_device_removed(usb_device_t *usb_dev)
    183232{
    184         /* TODO: Implement me! */
    185         return EOK;
     233        assert(usb_dev);
     234        usb_hub_dev_t *hub = usb_device_data_get(usb_dev);
     235        assert(hub);
     236
     237        usb_log_info("(%p) USB hub was removed, joining polling fibril.", hub);
     238
     239        /* Join polling fibril. */
     240        fibril_mutex_lock(&hub->poll_guard);
     241        while (hub->running)
     242                fibril_condvar_wait(&hub->poll_cv, &hub->poll_guard);
     243        fibril_mutex_unlock(&hub->poll_guard);
     244
     245        usb_log_info("(%p) USB hub polling stopped, freeing memory.", hub);
     246
     247        /* Destroy hub. */
     248        return usb_hub_cleanup(hub);
    186249}
    187250
     
    196259        usb_hub_dev_t *hub = usb_device_data_get(usb_dev);
    197260        assert(hub);
     261
     262        hub->poll_stop = true;
     263        usb_log_info("(%p) USB hub gone, joining polling fibril.", hub);
     264
     265        // TODO: Join the polling fibril in a better way?
    198266        unsigned tries = 10;
    199267        while (hub->running) {
     
    206274        }
    207275
    208         assert(!hub->running);
    209 
    210         for (size_t port = 0; port < hub->port_count; ++port) {
    211                 const int ret = usb_hub_port_fini(&hub->ports[port], hub);
    212                 if (ret != EOK)
    213                         return ret;
    214         }
    215         free(hub->ports);
    216 
    217         const int ret = ddf_fun_unbind(hub->hub_fun);
    218         if (ret != EOK) {
    219                 usb_log_error("(%p) Failed to unbind '%s' function: %s.",
    220                    hub, HUB_FNC_NAME, str_error(ret));
    221                 return ret;
    222         }
    223         ddf_fun_destroy(hub->hub_fun);
    224 
    225         usb_log_info("(%p) USB hub driver stopped and cleaned.", hub);
    226         return EOK;
     276        return usb_hub_cleanup(hub);
    227277}
    228278
     
    534584        fibril_mutex_unlock(&hub->pending_ops_mutex);
    535585        hub->running = false;
     586
     587        /* Signal polling end to joining thread. */
     588        fibril_mutex_lock(&hub->poll_guard);
     589        fibril_condvar_signal(&hub->poll_cv);
     590        fibril_mutex_unlock(&hub->poll_guard);
    536591}
    537592/**
  • uspace/drv/bus/usb/usbhub/usbhub.h

    r46c5dc2 r0b90f49  
    7474        ddf_fun_t *hub_fun;
    7575        /** Status indicator */
    76         bool running;
     76        volatile bool running;
    7777        /** Hub supports port power switching. */
    7878        bool power_switched;
    7979        /** Each port is switched individually. */
    8080        bool per_port_power;
     81        /** True if the device should stop running as soon as possible. */
     82        volatile bool poll_stop;
     83        fibril_mutex_t poll_guard;
     84        fibril_condvar_t poll_cv;
    8185};
    8286
Note: See TracChangeset for help on using the changeset viewer.