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


Ignore:
Timestamp:
2013-01-26T23:35:12Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
35bc430
Parents:
3e23316
Message:

usb: Rework polling to accept either ep numbers or descriptions.

Switch usbhub and usbhid to new polling.

File:
1 edited

Legend:

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

    r3e23316 rbb70637  
    5151        /** USB device to poll. */
    5252        usb_device_t *dev;
    53         /** Device pipe to use for polling. */
    54         size_t pipe_index;
     53        /** Device enpoint mapping to use for polling. */
     54        usb_endpoint_mapping_t *polling_mapping;
    5555        /** Size of the recieved data. */
    5656        size_t request_size;
     
    7272        const usb_device_auto_polling_t *params = &data->auto_polling;
    7373
    74         usb_pipe_t *pipe
    75             = &data->dev->pipes[data->pipe_index].pipe;
     74        usb_pipe_t *pipe = &data->polling_mapping->pipe;
    7675
    7776        if (params->debug > 0) {
    7877                const usb_endpoint_mapping_t *mapping
    79                     = &data->dev->pipes[data->pipe_index];
     78                    = data->polling_mapping;
    8079                usb_log_debug("Poll%p: started polling of `%s' - " \
    8180                    "interface %d (%s,%d,%d), %zuB/%zu.\n",
     
    117116                         */
    118117                        usb_request_clear_endpoint_halt(
    119                             &data->dev->ctrl_pipe, pipe->endpoint_no);
     118                            usb_device_get_default_pipe(data->dev),
     119                            pipe->endpoint_no);
    120120                }
    121121
     
    175175}
    176176
     177
    177178/** Start automatic device polling over interrupt in pipe.
    178179 *
    179  * @warning It is up to the callback to produce delays between individual
    180  * requests.
     180 * The polling settings is copied thus it is okay to destroy the structure
     181 * after this function returns.
    181182 *
    182183 * @warning There is no guarantee when the request to the device
     
    185186 *
    186187 * @param dev Device to be periodically polled.
     188 * @param epm Endpoint mapping to use.
     189 * @param polling Polling settings.
     190 * @param request_size How many bytes to ask for in each request.
     191 * @param arg Custom argument (passed as is to the callbacks).
     192 * @return Error code.
     193 * @retval EOK New fibril polling the device was already started.
     194 */
     195static int usb_device_auto_polling_internal(usb_device_t *dev,
     196    usb_endpoint_mapping_t *epm, const usb_device_auto_polling_t *polling,
     197    size_t request_size)
     198{
     199        if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
     200                return EBADMEM;
     201        }
     202
     203        if (request_size == 0)
     204                return EINVAL;
     205
     206        if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
     207            (epm->pipe.direction != USB_DIRECTION_IN))
     208                return EINVAL;
     209
     210
     211        polling_data_t *polling_data = malloc(sizeof(polling_data_t));
     212        if (polling_data == NULL) {
     213                return ENOMEM;
     214        }
     215
     216        /* Fill-in the data. */
     217        polling_data->buffer = malloc(sizeof(request_size));
     218        if (polling_data->buffer == NULL) {
     219                free(polling_data);
     220                return ENOMEM;
     221        }
     222        polling_data->request_size = request_size;
     223        polling_data->dev = dev;
     224        polling_data->polling_mapping = epm;
     225
     226        /* Copy provided settings. */
     227        polling_data->auto_polling = *polling;
     228
     229        /* Negative value means use descriptor provided value. */
     230        if (polling->delay < 0) {
     231                polling_data->auto_polling.delay =
     232                    epm->descriptor->poll_interval;
     233        }
     234
     235        fid_t fibril = fibril_create(polling_fibril, polling_data);
     236        if (fibril == 0) {
     237                free(polling_data->buffer);
     238                free(polling_data);
     239                return ENOMEM;
     240        }
     241        fibril_add_ready(fibril);
     242
     243        /* Fibril launched. That fibril will free the allocated data. */
     244
     245        return EOK;
     246}
     247/** Start automatic device polling over interrupt in pipe.
     248 *
     249 * The polling settings is copied thus it is okay to destroy the structure
     250 * after this function returns.
     251 *
     252 * @warning There is no guarantee when the request to the device
     253 * will be sent for the first time (it is possible that this
     254 * first request would be executed prior to return from this function).
     255 *
     256 * @param dev Device to be periodically polled.
    187257 * @param pipe_index Index of the endpoint pipe used for polling.
     258 * @param polling Polling settings.
     259 * @param req_size How many bytes to ask for in each request.
     260 * @param arg Custom argument (passed as is to the callbacks).
     261 * @return Error code.
     262 * @retval EOK New fibril polling the device was already started.
     263 */
     264int usb_device_auto_polling(usb_device_t *usb_dev, usb_endpoint_t ep,
     265    const usb_device_auto_polling_t *polling, size_t req_size)
     266{
     267        usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(usb_dev, ep);
     268        return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
     269}
     270
     271/** Start automatic device polling over interrupt in pipe.
     272 *
     273 * @warning It is up to the callback to produce delays between individual
     274 * requests.
     275 *
     276 * @warning There is no guarantee when the request to the device
     277 * will be sent for the first time (it is possible that this
     278 * first request would be executed prior to return from this function).
     279 *
     280 * @param dev Device to be periodically polled.
     281 * @param ep Endpoint  used for polling.
    188282 * @param callback Callback when data are available.
    189283 * @param request_size How many bytes to ask for in each request.
     284 * @param delay NUmber of ms to wait between queries, -1 to use descriptor val.
    190285 * @param terminated_callback Callback when polling is terminated.
    191286 * @param arg Custom argument (passed as is to the callbacks).
     
    193288 * @retval EOK New fibril polling the device was already started.
    194289 */
    195 int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index,
     290int usb_device_auto_poll(usb_device_t *dev, usb_endpoint_t ep,
    196291    usb_polling_callback_t callback, size_t request_size, int delay,
    197292    usb_polling_terminted_callback_t terminated_callback, void *arg)
     
    208303        };
    209304
    210         return usb_device_auto_polling(dev, pipe_index, &auto_polling,
    211            request_size);
    212 }
    213 
    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  */
    231 int 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)
    234 {
    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;
     305        usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(dev, ep);
     306        return usb_device_auto_polling_internal(
     307            dev, epm, &auto_polling, request_size);
     308}
     309
     310int usb_device_auto_polling_desc(usb_device_t *usb_dev,
     311    const usb_endpoint_description_t *desc,
     312    const usb_device_auto_polling_t *polling, size_t req_size)
     313{
     314        usb_endpoint_mapping_t *epm =
     315            usb_device_get_mapped_ep_desc(usb_dev, desc);
     316        return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
     317}
     318
     319int usb_device_auto_poll_desc(usb_device_t * usb_dev,
     320    const usb_endpoint_description_t *desc, usb_polling_callback_t callback,
     321    size_t req_size, int delay,
     322    usb_polling_terminted_callback_t terminated_callback, void *arg)
     323{
     324        const usb_device_auto_polling_t auto_polling = {
     325                .debug = 1,
     326                .auto_clear_halt = true,
     327                .delay = delay,
     328                .max_failures = MAX_FAILED_ATTEMPTS,
     329                .on_data = callback,
     330                .on_polling_end = terminated_callback,
     331                .on_error = NULL,
     332                .arg = arg,
     333        };
     334
     335        usb_endpoint_mapping_t *epm =
     336            usb_device_get_mapped_ep_desc(usb_dev, desc);
     337        return usb_device_auto_polling_internal(
     338            usb_dev, epm, &auto_polling, req_size);
    282339}
    283340
Note: See TracChangeset for help on using the changeset viewer.