Changeset 8a0c52a in mainline for uspace/lib/usbdev/src/devpoll.c


Ignore:
Timestamp:
2018-01-13T21:15:50Z (6 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
91173333
Parents:
71f211f
Message:

usbdev: add polling join mechanism

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbdev/src/devpoll.c

    r71f211f r8a0c52a  
    4747#include <errno.h>
    4848#include <fibril.h>
     49#include <fibril_synch.h>
    4950#include <stdbool.h>
    5051#include <stdlib.h>
     
    6263
    6364        /** Device enpoint mapping to use for polling. */
    64         usb_endpoint_mapping_t *polling_mapping;
     65        usb_endpoint_mapping_t *ep_mapping;
    6566
    6667        /** Size of the recieved data. */
     
    6970        /** Data buffer. */
    7071        uint8_t *buffer;
     72
     73        /** True if polling is currently in operation. */
     74        volatile bool running;
     75
     76        /** True if polling should terminate as soon as possible. */
     77        volatile bool joining;
     78
     79        /** Synchronization primitives for joining polling end. */
     80        fibril_mutex_t guard;
     81        fibril_condvar_t cv;
    7182};
     83
     84
     85static void polling_fini(usb_device_polling_t *polling)
     86{
     87        /* Free the allocated memory. */
     88        free(polling->buffer);
     89        free(polling);
     90}
    7291
    7392
     
    8099{
    81100        assert(arg);
    82         const usb_device_polling_t *data = arg;
     101        usb_device_polling_t *data = arg;
     102        data->running = true;
    83103
    84104        /* Helper to reduce typing. */
    85105        const usb_device_polling_config_t *params = &data->config;
    86106
    87         usb_pipe_t *pipe = &data->polling_mapping->pipe;
     107        usb_pipe_t *pipe = &data->ep_mapping->pipe;
    88108
    89109        if (params->debug > 0) {
    90110                const usb_endpoint_mapping_t *mapping =
    91                     data->polling_mapping;
     111                    data->ep_mapping;
    92112                usb_log_debug("Poll (%p): started polling of `%s' - " \
    93113                    "interface %d (%s,%d,%d), %zuB/%zu.\n",
     
    136156                        const bool cont = (params->on_error == NULL) ? true :
    137157                            params->on_error(data->dev, rc, params->arg);
    138                         if (!cont) {
     158                        if (!cont || data->joining) {
    139159                                /* This is user requested abort, erases failures. */
    140160                                failed_attempts = 0;
     
    184204        }
    185205
    186         /* Free the allocated memory. */
    187         free(data->buffer);
    188         free(data);
     206        data->running = false;
     207
     208        if (data->joining) {
     209                /* Notify joiners, if any. */
     210                fibril_mutex_lock(&data->guard);
     211                fibril_condvar_signal(&data->cv);
     212                fibril_mutex_unlock(&data->guard);
     213        } else {
     214                polling_fini(data);
     215        }
    189216
    190217        return EOK;
     
    235262        instance->request_size = req_size;
    236263        instance->dev = dev;
    237         instance->polling_mapping = epm;
     264        instance->ep_mapping = epm;
     265        instance->joining = false;
     266        fibril_mutex_initialize(&instance->guard);
     267        fibril_condvar_initialize(&instance->cv);
    238268
    239269        /* Copy provided settings. */
     
    265295}
    266296
     297int usb_device_poll_join(usb_device_polling_t *polling)
     298{
     299        int rc;
     300        if (!polling)
     301                return EBADMEM;
     302
     303        /* Set the flag */
     304        polling->joining = true;
     305
     306        /* Unregister the pipe. */
     307        if ((rc = usb_device_unmap_ep(polling->ep_mapping))) {
     308                return rc;
     309        }
     310
     311        /* Wait for the fibril to terminate. */
     312        fibril_mutex_lock(&polling->guard);
     313        while (polling->running)
     314                fibril_condvar_wait(&polling->cv, &polling->guard);
     315        fibril_mutex_unlock(&polling->guard);
     316
     317        /* Free the instance. */
     318        polling_fini(polling);
     319
     320        return EOK;
     321}
     322
    267323/**
    268324 * @}
Note: See TracChangeset for help on using the changeset viewer.