Ignore:
File:
1 edited

Legend:

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

    r4125b7d r4ede178  
    3333 * USB device driver framework - automatic interrupt polling.
    3434 */
    35 #include <usb/devpoll.h>
     35#include <usb/devdrv.h>
    3636#include <usb/request.h>
    3737#include <usb/debug.h>
    38 #include <usb/classes/classes.h>
    3938#include <errno.h>
    4039#include <str_error.h>
     
    4645/** Data needed for polling. */
    4746typedef struct {
    48         int debug;
    49         size_t max_failures;
    50         useconds_t delay;
    51         bool auto_clear_halt;
    52         bool (*on_data)(usb_device_t *, uint8_t *, size_t, void *);
    53         void (*on_polling_end)(usb_device_t *, bool, void *);
    54         bool (*on_error)(usb_device_t *, int, void *);
    55 
    5647        usb_device_t *dev;
    5748        size_t pipe_index;
     49        usb_polling_callback_t callback;
     50        usb_polling_terminted_callback_t terminated_callback;
    5851        size_t request_size;
    5952        uint8_t *buffer;
    6053        void *custom_arg;
    6154} polling_data_t;
    62 
    6355
    6456/** Polling fibril.
     
    7567            = polling_data->dev->pipes[polling_data->pipe_index].pipe;
    7668       
    77         if (polling_data->debug > 0) {
    78                 usb_endpoint_mapping_t *mapping
    79                     = &polling_data->dev->pipes[polling_data->pipe_index];
    80                 usb_log_debug("Poll%p: started polling of `%s' - " \
    81                     "interface %d (%s,%d,%d), %zuB/%zu.\n",
    82                     polling_data,
    83                     polling_data->dev->ddf_dev->name,
    84                     (int) mapping->interface->interface_number,
    85                     usb_str_class(mapping->interface->interface_class),
    86                     (int) mapping->interface->interface_subclass,
    87                     (int) mapping->interface->interface_protocol,
    88                     polling_data->request_size, pipe->max_packet_size);
    89         }
     69        usb_log_debug("Pipe interface number: %d, protocol: %d, subclass: %d, max packet size: %d\n",
     70            polling_data->dev->pipes[polling_data->pipe_index].interface_no,
     71            polling_data->dev->pipes[polling_data->pipe_index].description->interface_protocol,
     72            polling_data->dev->pipes[polling_data->pipe_index].description->interface_subclass,
     73            pipe->max_packet_size);
    9074
    9175        size_t failed_attempts = 0;
    92         while (failed_attempts <= polling_data->max_failures) {
     76        while (failed_attempts < MAX_FAILED_ATTEMPTS) {
    9377                int rc;
    9478
     
    9781                    polling_data->request_size, &actual_size);
    9882
    99                 if (polling_data->debug > 1) {
    100                         if (rc == EOK) {
    101                                 usb_log_debug(
    102                                     "Poll%p: received: '%s' (%zuB).\n",
    103                                     polling_data,
    104                                     usb_debug_str_buffer(polling_data->buffer,
    105                                         actual_size, 16),
    106                                     actual_size);
    107                         } else {
    108                                 usb_log_debug(
    109                                     "Poll%p: polling failed: %s.\n",
    110                                     polling_data, str_error(rc));
    111                         }
    112                 }
    113 
    114                 /* If the pipe stalled, we can try to reset the stall. */
    115                 if ((rc == ESTALL) && (polling_data->auto_clear_halt)) {
    116                         /*
    117                          * We ignore error here as this is usually a futile
    118                          * attempt anyway.
    119                          */
    120                         usb_request_clear_endpoint_halt(
    121                             &polling_data->dev->ctrl_pipe,
    122                             pipe->endpoint_no);
    123                 }
     83               
     84//              if (rc == ESTALL) {
     85//                      usb_log_debug("Seding clear feature...\n");
     86//                      usb_request_clear_feature(pipe, USB_REQUEST_TYPE_STANDARD,
     87//                        USB_REQUEST_RECIPIENT_ENDPOINT, 0, pipe->endpoint_no);
     88//                      continue;
     89//              }
    12490
    12591                if (rc != EOK) {
    126                         if (polling_data->on_error != NULL) {
    127                                 bool cont = polling_data->on_error(
    128                                     polling_data->dev, rc,
    129                                     polling_data->custom_arg);
    130                                 if (!cont) {
    131                                         failed_attempts
    132                                             = polling_data->max_failures;
    133                                 }
    134                         }
    13592                        failed_attempts++;
    13693                        continue;
     
    13895
    13996                /* We have the data, execute the callback now. */
    140                 bool carry_on = polling_data->on_data(polling_data->dev,
     97                bool carry_on = polling_data->callback(polling_data->dev,
    14198                    polling_data->buffer, actual_size,
    14299                    polling_data->custom_arg);
     
    149106                /* Reset as something might be only a temporary problem. */
    150107                failed_attempts = 0;
    151 
    152                 /* Take a rest before next request. */
    153                 async_usleep(polling_data->delay);
    154108        }
    155109
    156         if (polling_data->on_polling_end != NULL) {
    157                 polling_data->on_polling_end(polling_data->dev,
    158                     failed_attempts > 0, polling_data->custom_arg);
     110        if (failed_attempts > 0) {
     111                usb_log_error(
     112                    "Polling of device `%s' terminated: recurring failures.\n",
     113                    polling_data->dev->ddf_dev->name);
    159114        }
    160115
    161         if (polling_data->debug > 0) {
    162                 if (failed_attempts > 0) {
    163                         usb_log_error(
    164                             "Polling of device `%s' terminated: %s.\n",
    165                             polling_data->dev->ddf_dev->name,
    166                             "recurring failures");
    167                 } else {
    168                         usb_log_debug(
    169                             "Polling of device `%s' terminated by user.\n",
    170                             polling_data->dev->ddf_dev->name
    171                         );
    172                 }
     116        if (polling_data->terminated_callback != NULL) {
     117                polling_data->terminated_callback(polling_data->dev,
     118                    failed_attempts > 0, polling_data->custom_arg);
    173119        }
    174120
     
    213159        }
    214160
    215         usb_device_auto_polling_t *auto_polling
    216             = malloc(sizeof(usb_device_auto_polling_t));
    217         if (auto_polling == NULL) {
    218                 return ENOMEM;
    219         }
    220 
    221         auto_polling->debug = 1;
    222         auto_polling->auto_clear_halt = true;
    223         auto_polling->delay = 0;
    224         auto_polling->max_failures = MAX_FAILED_ATTEMPTS;
    225         auto_polling->on_data = callback;
    226         auto_polling->on_polling_end = terminated_callback;
    227         auto_polling->on_error = NULL;
    228 
    229         int rc = usb_device_auto_polling(dev, pipe_index, auto_polling,
    230            request_size, arg);
    231 
    232         free(auto_polling);
    233 
    234         return rc;
    235 }
    236 
    237 /** Start automatic device polling over interrupt in pipe.
    238  *
    239  * The polling settings is copied thus it is okay to destroy the structure
    240  * after this function returns.
    241  *
    242  * @warning There is no guarantee when the request to the device
    243  * will be sent for the first time (it is possible that this
    244  * first request would be executed prior to return from this function).
    245  *
    246  * @param dev Device to be periodically polled.
    247  * @param pipe_index Index of the endpoint pipe used for polling.
    248  * @param polling Polling settings.
    249  * @param request_size How many bytes to ask for in each request.
    250  * @param arg Custom argument (passed as is to the callbacks).
    251  * @return Error code.
    252  * @retval EOK New fibril polling the device was already started.
    253  */
    254 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
    255     usb_device_auto_polling_t *polling,
    256     size_t request_size, void *arg)
    257 {
    258         if (dev == NULL) {
    259                 return EBADMEM;
    260         }
    261         if (pipe_index >= dev->pipes_count) {
    262                 return EINVAL;
    263         }
    264         if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
    265             || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
    266                 return EINVAL;
    267         }
    268         if ((polling == NULL) || (polling->on_data == NULL)) {
    269                 return EBADMEM;
    270         }
    271 
    272161        polling_data_t *polling_data = malloc(sizeof(polling_data_t));
    273162        if (polling_data == NULL) {
     
    275164        }
    276165
    277         /* Fill-in the data. */
    278         polling_data->buffer = malloc(sizeof(request_size));
     166        /* Allocate now to prevent immediate failure in the polling fibril. */
     167        polling_data->buffer = malloc(request_size);
    279168        if (polling_data->buffer == NULL) {
    280169                free(polling_data);
    281170                return ENOMEM;
    282171        }
    283         polling_data->request_size = request_size;
    284172        polling_data->dev = dev;
    285173        polling_data->pipe_index = pipe_index;
     174        polling_data->callback = callback;
     175        polling_data->terminated_callback = terminated_callback;
     176        polling_data->request_size = request_size;
    286177        polling_data->custom_arg = arg;
    287 
    288         polling_data->debug = polling->debug;
    289         polling_data->max_failures = polling->max_failures;
    290         if (polling->delay >= 0) {
    291                 polling_data->delay = (useconds_t) polling->delay;
    292         } else {
    293                 polling_data->delay = (useconds_t) dev->pipes[pipe_index]
    294                     .descriptor->poll_interval;
    295         }
    296         polling_data->auto_clear_halt = polling->auto_clear_halt;
    297 
    298         polling_data->on_data = polling->on_data;
    299         polling_data->on_polling_end = polling->on_polling_end;
    300         polling_data->on_error = polling->on_error;
    301178
    302179        fid_t fibril = fibril_create(polling_fibril, polling_data);
     
    304181                free(polling_data->buffer);
    305182                free(polling_data);
     183                /* FIXME: better error code. */
    306184                return ENOMEM;
    307185        }
    308186        fibril_add_ready(fibril);
    309187
    310         /* Fibril launched. That fibril will free the allocated data. */
     188        /* The allocated buffer etc. will be freed by the fibril. */
    311189
    312190        return EOK;
Note: See TracChangeset for help on using the changeset viewer.