Changeset bb70637 in mainline


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.

Location:
uspace
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/main.c

    r3e23316 rbb70637  
    8989         * This will create a separate fibril that will query the device
    9090         * for the data continuously. */
    91        rc = usb_device_auto_poll(dev,
     91        rc = usb_device_auto_poll_desc(dev,
    9292           /* Index of the polling pipe. */
    93            hid_dev->poll_pipe_index,
     93           hid_dev->poll_pipe_mapping->description,
    9494           /* Callback when data arrives. */
    9595           usb_hid_polling_callback,
    9696           /* How much data to request. */
    97            dev->pipes[hid_dev->poll_pipe_index].pipe.max_packet_size,
     97           hid_dev->poll_pipe_mapping->pipe.max_packet_size,
    9898           /* Delay */
    99            0,
     99           -1,
    100100           /* Callback when the polling ends. */
    101101           usb_hid_polling_ended_callback,
  • uspace/drv/bus/usb/usbhid/usbhid.c

    r3e23316 rbb70637  
    4141#include <usb/hid/hidreport.h>
    4242#include <usb/hid/request.h>
     43
    4344#include <errno.h>
     45#include <macros.h>
    4446#include <str_error.h>
    4547
     
    265267}
    266268
    267 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev)
     269static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    268270{
    269271        assert(hid_dev);
     
    271273
    272274        static const struct {
    273                 unsigned ep_number;
     275                const usb_endpoint_description_t *desc;
    274276                const char* description;
    275277        } endpoints[] = {
    276                 {USB_HID_KBD_POLL_EP_NO, "Keyboard endpoint"},
    277                 {USB_HID_MOUSE_POLL_EP_NO, "Mouse endpoint"},
    278                 {USB_HID_GENERIC_POLL_EP_NO, "Generic HID endpoint"},
     278                {&usb_hid_kbd_poll_endpoint_description, "Keyboard endpoint"},
     279                {&usb_hid_mouse_poll_endpoint_description, "Mouse endpoint"},
     280                {&usb_hid_generic_poll_endpoint_description, "Generic HID endpoint"},
    279281        };
    280282
    281         for (unsigned i = 0; i < sizeof(endpoints)/sizeof(endpoints[0]); ++i) {
    282                 if (endpoints[i].ep_number >= dev->pipes_count) {
    283                         return EINVAL;
    284                 }
    285                 if (dev->pipes[endpoints[i].ep_number].present) {
     283        for (unsigned i = 0; i < ARRAY_SIZE(endpoints); ++i) {
     284                usb_endpoint_mapping_t *epm =
     285                    usb_device_get_mapped_ep_desc(dev, endpoints[i].desc);
     286                if (epm && epm->present) {
    286287                        usb_log_debug("Found: %s.\n", endpoints[i].description);
    287                         hid_dev->poll_pipe_index = endpoints[i].ep_number;
     288                        hid_dev->poll_pipe_mapping = epm;
    288289                        return EOK;
    289290                }
     
    352353        /* The USB device should already be initialized, save it in structure */
    353354        hid_dev->usb_dev = dev;
    354         hid_dev->poll_pipe_index = -1;
     355        hid_dev->poll_pipe_mapping = NULL;
    355356
    356357        int rc = usb_hid_check_pipes(hid_dev, dev);
     
    382383                    "boot protocol.\n");
    383384
    384                 switch (hid_dev->poll_pipe_index) {
    385                 case USB_HID_KBD_POLL_EP_NO:
     385                switch (hid_dev->poll_pipe_mapping->interface->interface_protocol) {
     386                case USB_HID_PROTOCOL_KEYBOARD:
    386387                        usb_log_info("Falling back to kbd boot protocol.\n");
    387388                        rc = usb_kbd_set_boot_protocol(hid_dev);
     
    390391                        }
    391392                        break;
    392                 case USB_HID_MOUSE_POLL_EP_NO:
     393                case USB_HID_PROTOCOL_MOUSE:
    393394                        usb_log_info("Falling back to mouse boot protocol.\n");
    394395                        rc = usb_mouse_set_boot_protocol(hid_dev);
     
    398399                        break;
    399400                default:
    400                         assert(hid_dev->poll_pipe_index
    401                             == USB_HID_GENERIC_POLL_EP_NO);
    402401                        usb_log_info("Falling back to generic HID driver.\n");
    403402                        usb_hid_set_generic_hid_subdriver(hid_dev);
  • uspace/drv/bus/usb/usbhid/usbhid.h

    r3e23316 rbb70637  
    103103        usb_device_t *usb_dev;
    104104
    105         /** Index of the polling pipe in usb_hid_endpoints array. */
    106         unsigned poll_pipe_index;
     105        /** Endpont mapping of the polling pipe. */
     106        usb_endpoint_mapping_t *poll_pipe_mapping;
    107107
    108108        /** Subdrivers. */
     
    132132};
    133133
    134 
    135 
    136 enum {
    137         USB_HID_KBD_POLL_EP_NO = 0,
    138         USB_HID_MOUSE_POLL_EP_NO = 1,
    139         USB_HID_GENERIC_POLL_EP_NO = 2,
    140         USB_HID_POLL_EP_COUNT = 3
    141 };
    142 
    143134extern const usb_endpoint_description_t *usb_hid_endpoints[];
    144 
    145 
    146135
    147136int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev);
  • uspace/drv/bus/usb/usbhub/main.c

    r3e23316 rbb70637  
    4343#include "usbhub.h"
    4444
    45 /** Hub status-change endpoint description.
    46  *
    47  * For more information see section 11.15.1 of USB 1.1 specification.
    48  */
    49 static const usb_endpoint_description_t hub_status_change_endpoint_description =
    50 {
    51         .transfer_type = USB_TRANSFER_INTERRUPT,
    52         .direction = USB_DIRECTION_IN,
    53         .interface_class = USB_CLASS_HUB,
    54         .interface_subclass = 0,
    55         .interface_protocol = 0,
    56         .flags = 0
    57 };
    5845
    5946/** USB hub driver operations. */
  • uspace/drv/bus/usb/usbhub/usbhub.c

    r3e23316 rbb70637  
    5757
    5858#define HUB_FNC_NAME "hub"
     59/** Hub status-change endpoint description.
     60 *
     61 * For more information see section 11.15.1 of USB 1.1 specification.
     62 */
     63const usb_endpoint_description_t hub_status_change_endpoint_description =
     64{
     65        .transfer_type = USB_TRANSFER_INTERRUPT,
     66        .direction = USB_DIRECTION_IN,
     67        .interface_class = USB_CLASS_HUB,
     68        .interface_subclass = 0,
     69        .interface_protocol = 0,
     70        .flags = 0
     71};
    5972
    6073/** Standard get hub global status request */
     
    147160
    148161        /* Start hub operation. */
    149         opResult = usb_device_auto_poll(hub_dev->usb_device, 0,
     162        opResult = usb_device_auto_poll_desc(hub_dev->usb_device,
     163            &hub_status_change_endpoint_description,
    150164            hub_port_changes_callback, ((hub_dev->port_count + 1 + 7) / 8),
    151             255000,
    152             usb_hub_polling_terminated_callback, hub_dev);
     165            -1, usb_hub_polling_terminated_callback, hub_dev);
    153166        if (opResult != EOK) {
    154167                usb_pipe_end_long_transfer(control_pipe);
  • uspace/drv/bus/usb/usbhub/usbhub.h

    r3e23316 rbb70637  
    8080};
    8181
     82extern const usb_endpoint_description_t hub_status_change_endpoint_description;
     83
    8284int usb_hub_device_add(usb_device_t *usb_dev);
    8385int usb_hub_device_remove(usb_device_t *usb_dev);
  • uspace/lib/usbdev/include/usb/dev/poll.h

    r3e23316 rbb70637  
    8787} usb_device_auto_polling_t;
    8888
    89 int usb_device_auto_polling(usb_device_t *, size_t,
     89typedef bool (*usb_polling_callback_t)(usb_device_t *, uint8_t *, size_t, void *);
     90typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
     91
     92int usb_device_auto_polling(usb_device_t *, usb_endpoint_t,
    9093    const usb_device_auto_polling_t *, size_t);
    9194
    92 typedef bool (*usb_polling_callback_t)(usb_device_t *,
    93     uint8_t *, size_t, void *);
    94 typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
     95int usb_device_auto_poll(usb_device_t *, usb_endpoint_t,
     96    usb_polling_callback_t, size_t, int, usb_polling_terminted_callback_t, void *);
    9597
    96 int usb_device_auto_poll(usb_device_t *, size_t,
    97     usb_polling_callback_t, size_t, int, usb_polling_terminted_callback_t, void *);
     98int usb_device_auto_polling_desc(usb_device_t *,
     99    const usb_endpoint_description_t *, const usb_device_auto_polling_t *,
     100    size_t);
     101
     102int usb_device_auto_poll_desc(usb_device_t *,
     103    const usb_endpoint_description_t *, usb_polling_callback_t, size_t, int,
     104    usb_polling_terminted_callback_t, void *);
    98105
    99106#endif
  • 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.