Ignore:
File:
1 edited

Legend:

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

    rd93f5afb r56fd7cf  
    5151        /** USB device to poll. */
    5252        usb_device_t *dev;
    53         /** Device enpoint mapping to use for polling. */
    54         usb_endpoint_mapping_t *polling_mapping;
     53        /** Device pipe to use for polling. */
     54        size_t pipe_index;
    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 = &data->polling_mapping->pipe;
     74        usb_pipe_t *pipe
     75            = &data->dev->pipes[data->pipe_index].pipe;
    7576
    7677        if (params->debug > 0) {
    7778                const usb_endpoint_mapping_t *mapping
    78                     = data->polling_mapping;
     79                    = &data->dev->pipes[data->pipe_index];
    7980                usb_log_debug("Poll%p: started polling of `%s' - " \
    8081                    "interface %d (%s,%d,%d), %zuB/%zu.\n",
    81                     data, usb_device_get_name(data->dev),
     82                    data, ddf_dev_get_name(data->dev->ddf_dev),
    8283                    (int) mapping->interface->interface_number,
    8384                    usb_str_class(mapping->interface->interface_class),
     
    8788        }
    8889
     90        usb_pipe_start_long_transfer(pipe);
    8991        size_t failed_attempts = 0;
    9092        while (failed_attempts <= params->max_failures) {
     
    115117                         */
    116118                        usb_request_clear_endpoint_halt(
    117                             usb_device_get_default_pipe(data->dev),
    118                             pipe->endpoint_no);
     119                            &data->dev->ctrl_pipe, pipe->endpoint_no);
    119120                }
    120121
     
    147148        }
    148149
     150        usb_pipe_end_long_transfer(pipe);
     151
    149152        const bool failed = failed_attempts > 0;
    150153
     
    156159                if (failed) {
    157160                        usb_log_error("Polling of device `%s' terminated: "
    158                             "recurring failures.\n",
    159                             usb_device_get_name(data->dev));
     161                            "recurring failures.\n", ddf_dev_get_name(
     162                            data->dev->ddf_dev));
    160163                } else {
    161164                        usb_log_debug("Polling of device `%s' terminated: "
    162                             "driver request.\n",
    163                             usb_device_get_name(data->dev));
     165                            "driver request.\n", ddf_dev_get_name(
     166                            data->dev->ddf_dev));
    164167                }
    165168        }
     
    172175}
    173176
    174 
    175177/** Start automatic device polling over interrupt in pipe.
    176178 *
    177  * The polling settings is copied thus it is okay to destroy the structure
    178  * after this function returns.
     179 * @warning It is up to the callback to produce delays between individual
     180 * requests.
    179181 *
    180182 * @warning There is no guarantee when the request to the device
     
    183185 *
    184186 * @param dev Device to be periodically polled.
    185  * @param epm Endpoint mapping to use.
    186  * @param polling Polling settings.
    187  * @param request_size How many bytes to ask for in each request.
    188  * @param arg Custom argument (passed as is to the callbacks).
    189  * @return Error code.
    190  * @retval EOK New fibril polling the device was already started.
    191  */
    192 static int usb_device_auto_polling_internal(usb_device_t *dev,
    193     usb_endpoint_mapping_t *epm, const usb_device_auto_polling_t *polling,
    194     size_t request_size)
    195 {
    196         if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
    197                 return EBADMEM;
    198         }
    199 
    200         if (request_size == 0)
    201                 return EINVAL;
    202 
    203         if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
    204             (epm->pipe.direction != USB_DIRECTION_IN))
    205                 return EINVAL;
    206 
    207 
    208         polling_data_t *polling_data = malloc(sizeof(polling_data_t));
    209         if (polling_data == NULL) {
    210                 return ENOMEM;
    211         }
    212 
    213         /* Fill-in the data. */
    214         polling_data->buffer = malloc(sizeof(request_size));
    215         if (polling_data->buffer == NULL) {
    216                 free(polling_data);
    217                 return ENOMEM;
    218         }
    219         polling_data->request_size = request_size;
    220         polling_data->dev = dev;
    221         polling_data->polling_mapping = epm;
    222 
    223         /* Copy provided settings. */
    224         polling_data->auto_polling = *polling;
    225 
    226         /* Negative value means use descriptor provided value. */
    227         if (polling->delay < 0) {
    228                 polling_data->auto_polling.delay =
    229                     epm->descriptor->poll_interval;
    230         }
    231 
    232         fid_t fibril = fibril_create(polling_fibril, polling_data);
    233         if (fibril == 0) {
    234                 free(polling_data->buffer);
    235                 free(polling_data);
    236                 return ENOMEM;
    237         }
    238         fibril_add_ready(fibril);
    239 
    240         /* Fibril launched. That fibril will free the allocated data. */
    241 
    242         return EOK;
    243 }
    244 /** Start automatic device polling over interrupt in pipe.
    245  *
    246  * The polling settings is copied thus it is okay to destroy the structure
    247  * after this function returns.
    248  *
    249  * @warning There is no guarantee when the request to the device
    250  * will be sent for the first time (it is possible that this
    251  * first request would be executed prior to return from this function).
    252  *
    253  * @param dev Device to be periodically polled.
    254187 * @param pipe_index Index of the endpoint pipe used for polling.
    255  * @param polling Polling settings.
    256  * @param req_size How many bytes to ask for in each request.
    257  * @param arg Custom argument (passed as is to the callbacks).
    258  * @return Error code.
    259  * @retval EOK New fibril polling the device was already started.
    260  */
    261 int usb_device_auto_polling(usb_device_t *usb_dev, usb_endpoint_t ep,
    262     const usb_device_auto_polling_t *polling, size_t req_size)
    263 {
    264         usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(usb_dev, ep);
    265         return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
    266 }
    267 
    268 /** Start automatic device polling over interrupt in pipe.
    269  *
    270  * @warning It is up to the callback to produce delays between individual
    271  * requests.
    272  *
    273  * @warning There is no guarantee when the request to the device
    274  * will be sent for the first time (it is possible that this
    275  * first request would be executed prior to return from this function).
    276  *
    277  * @param dev Device to be periodically polled.
    278  * @param ep Endpoint  used for polling.
    279188 * @param callback Callback when data are available.
    280189 * @param request_size How many bytes to ask for in each request.
    281  * @param delay NUmber of ms to wait between queries, -1 to use descriptor val.
    282190 * @param terminated_callback Callback when polling is terminated.
    283191 * @param arg Custom argument (passed as is to the callbacks).
     
    285193 * @retval EOK New fibril polling the device was already started.
    286194 */
    287 int usb_device_auto_poll(usb_device_t *dev, usb_endpoint_t ep,
    288     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,
    289197    usb_polling_terminted_callback_t terminated_callback, void *arg)
    290198{
     
    292200                .debug = 1,
    293201                .auto_clear_halt = true,
    294                 .delay = delay,
     202                .delay = 0,
    295203                .max_failures = MAX_FAILED_ATTEMPTS,
    296204                .on_data = callback,
     
    300208        };
    301209
    302         usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(dev, ep);
    303         return usb_device_auto_polling_internal(
    304             dev, epm, &auto_polling, request_size);
     210        return usb_device_auto_polling(dev, pipe_index, &auto_polling,
     211           request_size);
    305212}
    306213
    307 int usb_device_auto_polling_desc(usb_device_t *usb_dev,
    308     const usb_endpoint_description_t *desc,
    309     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)
    310234{
    311         usb_endpoint_mapping_t *epm =
    312             usb_device_get_mapped_ep_desc(usb_dev, desc);
    313         return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
    314 }
    315 
    316 int usb_device_auto_poll_desc(usb_device_t * usb_dev,
    317     const usb_endpoint_description_t *desc, usb_polling_callback_t callback,
    318     size_t req_size, int delay,
    319     usb_polling_terminted_callback_t terminated_callback, void *arg)
    320 {
    321         const usb_device_auto_polling_t auto_polling = {
    322                 .debug = 1,
    323                 .auto_clear_halt = true,
    324                 .delay = delay,
    325                 .max_failures = MAX_FAILED_ATTEMPTS,
    326                 .on_data = callback,
    327                 .on_polling_end = terminated_callback,
    328                 .on_error = NULL,
    329                 .arg = arg,
    330         };
    331 
    332         usb_endpoint_mapping_t *epm =
    333             usb_device_get_mapped_ep_desc(usb_dev, desc);
    334         return usb_device_auto_polling_internal(
    335             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;
    336282}
    337283
Note: See TracChangeset for help on using the changeset viewer.