Ignore:
File:
1 edited

Legend:

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

    rff0258f 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;
    89                 usb_log_debug("Poll (%p): started polling of `%s' - " \
     79                    = &data->dev->pipes[data->pipe_index];
     80                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) {
     
    10395                    data->request_size, &actual_size);
    10496
    105                 if (rc == EOK) {
    106                         if (params->debug > 1) {
     97                if (params->debug > 1) {
     98                        if (rc == EOK) {
    10799                                usb_log_debug(
    108100                                    "Poll%p: received: '%s' (%zuB).\n",
     
    111103                                        actual_size, 16),
    112104                                    actual_size);
    113                         }
    114                 } else {
     105                        } else {
    115106                                usb_log_debug(
    116107                                    "Poll%p: polling failed: %s.\n",
    117108                                    data, str_error(rc));
     109                        }
    118110                }
    119111
     
    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
     
    154145
    155146                /* Take a rest before next request. */
    156                 //TODO: This is broken, the time is in ms not us.
    157                 // but first we need to fix drivers to actually stop using this,
    158                 // since polling dealy should be implemented in HC schedule
    159147                async_usleep(params->delay);
    160148        }
     149
     150        usb_pipe_end_long_transfer(pipe);
    161151
    162152        const bool failed = failed_attempts > 0;
     
    169159                if (failed) {
    170160                        usb_log_error("Polling of device `%s' terminated: "
    171                             "recurring failures.\n",
    172                             usb_device_get_name(data->dev));
     161                            "recurring failures.\n", ddf_dev_get_name(
     162                            data->dev->ddf_dev));
    173163                } else {
    174164                        usb_log_debug("Polling of device `%s' terminated: "
    175                             "driver request.\n",
    176                             usb_device_get_name(data->dev));
     165                            "driver request.\n", ddf_dev_get_name(
     166                            data->dev->ddf_dev));
    177167                }
    178168        }
     
    185175}
    186176
    187 
    188177/** Start automatic device polling over interrupt in pipe.
    189178 *
    190  * The polling settings is copied thus it is okay to destroy the structure
    191  * after this function returns.
     179 * @warning It is up to the callback to produce delays between individual
     180 * requests.
    192181 *
    193182 * @warning There is no guarantee when the request to the device
     
    196185 *
    197186 * @param dev Device to be periodically polled.
    198  * @param epm Endpoint mapping to use.
    199  * @param polling Polling settings.
    200  * @param request_size How many bytes to ask for in each request.
    201  * @param arg Custom argument (passed as is to the callbacks).
    202  * @return Error code.
    203  * @retval EOK New fibril polling the device was already started.
    204  */
    205 static int usb_device_auto_polling_internal(usb_device_t *dev,
    206     usb_endpoint_mapping_t *epm, const usb_device_auto_polling_t *polling,
    207     size_t request_size)
    208 {
    209         if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
    210                 return EBADMEM;
    211         }
    212 
    213         if (request_size == 0)
    214                 return EINVAL;
    215 
    216         if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
    217             (epm->pipe.direction != USB_DIRECTION_IN))
    218                 return EINVAL;
    219 
    220 
    221         polling_data_t *polling_data = malloc(sizeof(polling_data_t));
    222         if (polling_data == NULL) {
    223                 return ENOMEM;
    224         }
    225 
    226         /* Fill-in the data. */
    227         polling_data->buffer = malloc(sizeof(request_size));
    228         if (polling_data->buffer == NULL) {
    229                 free(polling_data);
    230                 return ENOMEM;
    231         }
    232         polling_data->request_size = request_size;
    233         polling_data->dev = dev;
    234         polling_data->polling_mapping = epm;
    235 
    236         /* Copy provided settings. */
    237         polling_data->auto_polling = *polling;
    238 
    239         /* Negative value means use descriptor provided value. */
    240         if (polling->delay < 0) {
    241                 polling_data->auto_polling.delay =
    242                     epm->descriptor->poll_interval;
    243         }
    244 
    245         fid_t fibril = fibril_create(polling_fibril, polling_data);
    246         if (fibril == 0) {
    247                 free(polling_data->buffer);
    248                 free(polling_data);
    249                 return ENOMEM;
    250         }
    251         fibril_add_ready(fibril);
    252 
    253         /* Fibril launched. That fibril will free the allocated data. */
    254 
    255         return EOK;
    256 }
    257 /** Start automatic device polling over interrupt in pipe.
    258  *
    259  * The polling settings is copied thus it is okay to destroy the structure
    260  * after this function returns.
    261  *
    262  * @warning There is no guarantee when the request to the device
    263  * will be sent for the first time (it is possible that this
    264  * first request would be executed prior to return from this function).
    265  *
    266  * @param dev Device to be periodically polled.
    267187 * @param pipe_index Index of the endpoint pipe used for polling.
    268  * @param polling Polling settings.
    269  * @param req_size How many bytes to ask for in each request.
    270  * @param arg Custom argument (passed as is to the callbacks).
    271  * @return Error code.
    272  * @retval EOK New fibril polling the device was already started.
    273  */
    274 int usb_device_auto_polling(usb_device_t *usb_dev, usb_endpoint_t ep,
    275     const usb_device_auto_polling_t *polling, size_t req_size)
    276 {
    277         usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(usb_dev, ep);
    278         return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
    279 }
    280 
    281 /** Start automatic device polling over interrupt in pipe.
    282  *
    283  * @warning It is up to the callback to produce delays between individual
    284  * requests.
    285  *
    286  * @warning There is no guarantee when the request to the device
    287  * will be sent for the first time (it is possible that this
    288  * first request would be executed prior to return from this function).
    289  *
    290  * @param dev Device to be periodically polled.
    291  * @param ep Endpoint  used for polling.
    292188 * @param callback Callback when data are available.
    293189 * @param request_size How many bytes to ask for in each request.
    294  * @param delay NUmber of ms to wait between queries, -1 to use descriptor val.
    295190 * @param terminated_callback Callback when polling is terminated.
    296191 * @param arg Custom argument (passed as is to the callbacks).
     
    298193 * @retval EOK New fibril polling the device was already started.
    299194 */
    300 int usb_device_auto_poll(usb_device_t *dev, usb_endpoint_t ep,
    301     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,
    302197    usb_polling_terminted_callback_t terminated_callback, void *arg)
    303198{
     
    305200                .debug = 1,
    306201                .auto_clear_halt = true,
    307                 .delay = delay,
     202                .delay = 0,
    308203                .max_failures = MAX_FAILED_ATTEMPTS,
    309204                .on_data = callback,
     
    313208        };
    314209
    315         usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(dev, ep);
    316         return usb_device_auto_polling_internal(
    317             dev, epm, &auto_polling, request_size);
     210        return usb_device_auto_polling(dev, pipe_index, &auto_polling,
     211           request_size);
    318212}
    319213
    320 int usb_device_auto_polling_desc(usb_device_t *usb_dev,
    321     const usb_endpoint_description_t *desc,
    322     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)
    323234{
    324         usb_endpoint_mapping_t *epm =
    325             usb_device_get_mapped_ep_desc(usb_dev, desc);
    326         return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
    327 }
    328 
    329 int usb_device_auto_poll_desc(usb_device_t * usb_dev,
    330     const usb_endpoint_description_t *desc, usb_polling_callback_t callback,
    331     size_t req_size, int delay,
    332     usb_polling_terminted_callback_t terminated_callback, void *arg)
    333 {
    334         const usb_device_auto_polling_t auto_polling = {
    335                 .debug = 1,
    336                 .auto_clear_halt = true,
    337                 .delay = delay,
    338                 .max_failures = MAX_FAILED_ATTEMPTS,
    339                 .on_data = callback,
    340                 .on_polling_end = terminated_callback,
    341                 .on_error = NULL,
    342                 .arg = arg,
    343         };
    344 
    345         usb_endpoint_mapping_t *epm =
    346             usb_device_get_mapped_ep_desc(usb_dev, desc);
    347         return usb_device_auto_polling_internal(
    348             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;
    349282}
    350283
Note: See TracChangeset for help on using the changeset viewer.