Ignore:
File:
1 edited

Legend:

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

    rc01987c r56fd7cf  
    3333 * USB device driver framework - automatic interrupt polling.
    3434 */
    35 #include <usb/dev/device.h>
    36 #include <usb/dev/pipes.h>
    3735#include <usb/dev/poll.h>
    3836#include <usb/dev/request.h>
     37#include <usb/debug.h>
    3938#include <usb/classes/classes.h>
    40 #include <usb/debug.h>
    41 #include <usb/descriptor.h>
    42 #include <usb/usb.h>
    43 
     39#include <errno.h>
     40#include <str_error.h>
    4441#include <assert.h>
    45 #include <async.h>
    46 #include <errno.h>
    47 #include <fibril.h>
    48 #include <stdbool.h>
    49 #include <stdlib.h>
    50 #include <str_error.h>
    51 #include <sys/types.h>
    5242
    5343/** Maximum number of failed consecutive requests before announcing failure. */
     
    6151        /** USB device to poll. */
    6252        usb_device_t *dev;
    63         /** Device enpoint mapping to use for polling. */
    64         usb_endpoint_mapping_t *polling_mapping;
     53        /** Device pipe to use for polling. */
     54        size_t pipe_index;
    6555        /** Size of the recieved data. */
    6656        size_t request_size;
     
    8272        const usb_device_auto_polling_t *params = &data->auto_polling;
    8373
    84         usb_pipe_t *pipe = &data->polling_mapping->pipe;
     74        usb_pipe_t *pipe
     75            = &data->dev->pipes[data->pipe_index].pipe;
    8576
    8677        if (params->debug > 0) {
    8778                const usb_endpoint_mapping_t *mapping
    88                     = data->polling_mapping;
     79                    = &data->dev->pipes[data->pipe_index];
    8980                usb_log_debug("Poll%p: started polling of `%s' - " \
    9081                    "interface %d (%s,%d,%d), %zuB/%zu.\n",
    91                     data, usb_device_get_name(data->dev),
     82                    data, ddf_dev_get_name(data->dev->ddf_dev),
    9283                    (int) mapping->interface->interface_number,
    9384                    usb_str_class(mapping->interface->interface_class),
     
    9788        }
    9889
     90        usb_pipe_start_long_transfer(pipe);
    9991        size_t failed_attempts = 0;
    10092        while (failed_attempts <= params->max_failures) {
     
    125117                         */
    126118                        usb_request_clear_endpoint_halt(
    127                             usb_device_get_default_pipe(data->dev),
    128                             pipe->endpoint_no);
     119                            &data->dev->ctrl_pipe, pipe->endpoint_no);
    129120                }
    130121
     
    157148        }
    158149
     150        usb_pipe_end_long_transfer(pipe);
     151
    159152        const bool failed = failed_attempts > 0;
    160153
     
    166159                if (failed) {
    167160                        usb_log_error("Polling of device `%s' terminated: "
    168                             "recurring failures.\n",
    169                             usb_device_get_name(data->dev));
     161                            "recurring failures.\n", ddf_dev_get_name(
     162                            data->dev->ddf_dev));
    170163                } else {
    171164                        usb_log_debug("Polling of device `%s' terminated: "
    172                             "driver request.\n",
    173                             usb_device_get_name(data->dev));
     165                            "driver request.\n", ddf_dev_get_name(
     166                            data->dev->ddf_dev));
    174167                }
    175168        }
     
    182175}
    183176
    184 
    185177/** Start automatic device polling over interrupt in pipe.
    186178 *
    187  * The polling settings is copied thus it is okay to destroy the structure
    188  * after this function returns.
     179 * @warning It is up to the callback to produce delays between individual
     180 * requests.
    189181 *
    190182 * @warning There is no guarantee when the request to the device
     
    193185 *
    194186 * @param dev Device to be periodically polled.
    195  * @param epm Endpoint mapping to use.
    196  * @param polling Polling settings.
    197  * @param request_size How many bytes to ask for in each request.
    198  * @param arg Custom argument (passed as is to the callbacks).
    199  * @return Error code.
    200  * @retval EOK New fibril polling the device was already started.
    201  */
    202 static int usb_device_auto_polling_internal(usb_device_t *dev,
    203     usb_endpoint_mapping_t *epm, const usb_device_auto_polling_t *polling,
    204     size_t request_size)
    205 {
    206         if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
    207                 return EBADMEM;
    208         }
    209 
    210         if (request_size == 0)
    211                 return EINVAL;
    212 
    213         if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
    214             (epm->pipe.direction != USB_DIRECTION_IN))
    215                 return EINVAL;
    216 
    217 
    218         polling_data_t *polling_data = malloc(sizeof(polling_data_t));
    219         if (polling_data == NULL) {
    220                 return ENOMEM;
    221         }
    222 
    223         /* Fill-in the data. */
    224         polling_data->buffer = malloc(sizeof(request_size));
    225         if (polling_data->buffer == NULL) {
    226                 free(polling_data);
    227                 return ENOMEM;
    228         }
    229         polling_data->request_size = request_size;
    230         polling_data->dev = dev;
    231         polling_data->polling_mapping = epm;
    232 
    233         /* Copy provided settings. */
    234         polling_data->auto_polling = *polling;
    235 
    236         /* Negative value means use descriptor provided value. */
    237         if (polling->delay < 0) {
    238                 polling_data->auto_polling.delay =
    239                     epm->descriptor->poll_interval;
    240         }
    241 
    242         fid_t fibril = fibril_create(polling_fibril, polling_data);
    243         if (fibril == 0) {
    244                 free(polling_data->buffer);
    245                 free(polling_data);
    246                 return ENOMEM;
    247         }
    248         fibril_add_ready(fibril);
    249 
    250         /* Fibril launched. That fibril will free the allocated data. */
    251 
    252         return EOK;
    253 }
    254 /** Start automatic device polling over interrupt in pipe.
    255  *
    256  * The polling settings is copied thus it is okay to destroy the structure
    257  * after this function returns.
    258  *
    259  * @warning There is no guarantee when the request to the device
    260  * will be sent for the first time (it is possible that this
    261  * first request would be executed prior to return from this function).
    262  *
    263  * @param dev Device to be periodically polled.
    264187 * @param pipe_index Index of the endpoint pipe used for polling.
    265  * @param polling Polling settings.
    266  * @param req_size How many bytes to ask for in each request.
    267  * @param arg Custom argument (passed as is to the callbacks).
    268  * @return Error code.
    269  * @retval EOK New fibril polling the device was already started.
    270  */
    271 int usb_device_auto_polling(usb_device_t *usb_dev, usb_endpoint_t ep,
    272     const usb_device_auto_polling_t *polling, size_t req_size)
    273 {
    274         usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(usb_dev, ep);
    275         return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
    276 }
    277 
    278 /** Start automatic device polling over interrupt in pipe.
    279  *
    280  * @warning It is up to the callback to produce delays between individual
    281  * requests.
    282  *
    283  * @warning There is no guarantee when the request to the device
    284  * will be sent for the first time (it is possible that this
    285  * first request would be executed prior to return from this function).
    286  *
    287  * @param dev Device to be periodically polled.
    288  * @param ep Endpoint  used for polling.
    289188 * @param callback Callback when data are available.
    290189 * @param request_size How many bytes to ask for in each request.
    291  * @param delay NUmber of ms to wait between queries, -1 to use descriptor val.
    292190 * @param terminated_callback Callback when polling is terminated.
    293191 * @param arg Custom argument (passed as is to the callbacks).
     
    295193 * @retval EOK New fibril polling the device was already started.
    296194 */
    297 int usb_device_auto_poll(usb_device_t *dev, usb_endpoint_t ep,
    298     usb_polling_callback_t callback, size_t request_size, int delay,
     195int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index,
     196    usb_polling_callback_t callback, size_t request_size,
    299197    usb_polling_terminted_callback_t terminated_callback, void *arg)
    300198{
     
    302200                .debug = 1,
    303201                .auto_clear_halt = true,
    304                 .delay = delay,
     202                .delay = 0,
    305203                .max_failures = MAX_FAILED_ATTEMPTS,
    306204                .on_data = callback,
     
    310208        };
    311209
    312         usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(dev, ep);
    313         return usb_device_auto_polling_internal(
    314             dev, epm, &auto_polling, request_size);
     210        return usb_device_auto_polling(dev, pipe_index, &auto_polling,
     211           request_size);
    315212}
    316213
    317 int usb_device_auto_polling_desc(usb_device_t *usb_dev,
    318     const usb_endpoint_description_t *desc,
    319     const usb_device_auto_polling_t *polling, size_t req_size)
     214/** Start automatic device polling over interrupt in pipe.
     215 *
     216 * The polling settings is copied thus it is okay to destroy the structure
     217 * after this function returns.
     218 *
     219 * @warning There is no guarantee when the request to the device
     220 * will be sent for the first time (it is possible that this
     221 * first request would be executed prior to return from this function).
     222 *
     223 * @param dev Device to be periodically polled.
     224 * @param pipe_index Index of the endpoint pipe used for polling.
     225 * @param polling Polling settings.
     226 * @param request_size How many bytes to ask for in each request.
     227 * @param arg Custom argument (passed as is to the callbacks).
     228 * @return Error code.
     229 * @retval EOK New fibril polling the device was already started.
     230 */
     231int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
     232    const usb_device_auto_polling_t *polling,
     233    size_t request_size)
    320234{
    321         usb_endpoint_mapping_t *epm =
    322             usb_device_get_mapped_ep_desc(usb_dev, desc);
    323         return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
    324 }
    325 
    326 int usb_device_auto_poll_desc(usb_device_t * usb_dev,
    327     const usb_endpoint_description_t *desc, usb_polling_callback_t callback,
    328     size_t req_size, int delay,
    329     usb_polling_terminted_callback_t terminated_callback, void *arg)
    330 {
    331         const usb_device_auto_polling_t auto_polling = {
    332                 .debug = 1,
    333                 .auto_clear_halt = true,
    334                 .delay = delay,
    335                 .max_failures = MAX_FAILED_ATTEMPTS,
    336                 .on_data = callback,
    337                 .on_polling_end = terminated_callback,
    338                 .on_error = NULL,
    339                 .arg = arg,
    340         };
    341 
    342         usb_endpoint_mapping_t *epm =
    343             usb_device_get_mapped_ep_desc(usb_dev, desc);
    344         return usb_device_auto_polling_internal(
    345             usb_dev, epm, &auto_polling, req_size);
     235        if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
     236                return EBADMEM;
     237        }
     238
     239        if (pipe_index >= dev->pipes_count || request_size == 0) {
     240                return EINVAL;
     241        }
     242        if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT)
     243            || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) {
     244                return EINVAL;
     245        }
     246
     247        polling_data_t *polling_data = malloc(sizeof(polling_data_t));
     248        if (polling_data == NULL) {
     249                return ENOMEM;
     250        }
     251
     252        /* Fill-in the data. */
     253        polling_data->buffer = malloc(sizeof(request_size));
     254        if (polling_data->buffer == NULL) {
     255                free(polling_data);
     256                return ENOMEM;
     257        }
     258        polling_data->request_size = request_size;
     259        polling_data->dev = dev;
     260        polling_data->pipe_index = pipe_index;
     261
     262        /* Copy provided settings. */
     263        polling_data->auto_polling = *polling;
     264
     265        /* Negative value means use descriptor provided value. */
     266        if (polling->delay < 0) {
     267                polling_data->auto_polling.delay =
     268                    (int) dev->pipes[pipe_index].descriptor->poll_interval;
     269        }
     270
     271        fid_t fibril = fibril_create(polling_fibril, polling_data);
     272        if (fibril == 0) {
     273                free(polling_data->buffer);
     274                free(polling_data);
     275                return ENOMEM;
     276        }
     277        fibril_add_ready(fibril);
     278
     279        /* Fibril launched. That fibril will free the allocated data. */
     280
     281        return EOK;
    346282}
    347283
Note: See TracChangeset for help on using the changeset viewer.