Ignore:
File:
1 edited

Legend:

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

    r9d58539 r58563585  
    3434 */
    3535#include <usb/dev/request.h>
     36#include <usb/request.h>
     37#include <usb/usb.h>
     38
    3639#include <errno.h>
    37 #include <assert.h>
    38 #include <usb/debug.h>
     40#include <mem.h>
     41#include <stdlib.h>
     42#include <str.h>
    3943
    4044#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
    4145
     46static_assert(sizeof(usb_device_request_setup_packet_t) == 8);
     47
    4248/** Generic wrapper for SET requests using standard control request format.
    4349 *
    4450 * @see usb_pipe_control_write
    4551 *
    46  * @param pipe Pipe used for the communication.
     52 * @param pipe         Pipe used for the communication.
    4753 * @param request_type Request type (standard/class/vendor).
    48  * @param recipient Request recipient (e.g. device or endpoint).
    49  * @param request Actual request (e.g. GET_DESCRIPTOR).
    50  * @param value Value of @c wValue field of setup packet
    51  *      (must be in USB endianness).
    52  * @param index Value of @c wIndex field of setup packet
    53  *      (must be in USB endianness).
    54  * @param data Data to be sent during DATA stage
    55  *      (expected to be in USB endianness).
    56  * @param data_size Size of the @p data buffer (in native endianness).
     54 * @param recipient    Request recipient (e.g. device or endpoint).
     55 * @param request      Actual request (e.g. GET_DESCRIPTOR).
     56 * @param value        Value of @c wValue field of setup packet
     57 *                     (must be in USB endianness).
     58 * @param index        Value of @c wIndex field of setup packet
     59 *                     (must be in USB endianness).
     60 * @param data         Data to be sent during DATA stage
     61 *                     (expected to be in USB endianness).
     62 * @param data_size     Size of the @p data buffer (in native endianness).
     63 *
    5764 * @return Error code.
    5865 * @retval EBADMEM @p pipe is NULL.
    5966 * @retval EBADMEM @p data is NULL and @p data_size is not zero.
    6067 * @retval ERANGE Data buffer too large.
     68 *
    6169 */
    6270int usb_control_request_set(usb_pipe_t *pipe,
    6371    usb_request_type_t request_type, usb_request_recipient_t recipient,
    64     uint8_t request,
    65     uint16_t value, uint16_t index,
    66     void *data, size_t data_size)
     72    uint8_t request, uint16_t value, uint16_t index,
     73    const void *data, size_t data_size)
    6774{
    6875        if (pipe == NULL) {
     
    8390         */
    8491
    85         usb_device_request_setup_packet_t setup_packet;
    86         setup_packet.request_type = (request_type << 5) | recipient;
    87         setup_packet.request = request;
    88         setup_packet.value = value;
    89         setup_packet.index = index;
    90         setup_packet.length = (uint16_t) data_size;
    91 
    92         int rc = usb_pipe_control_write(pipe,
    93             &setup_packet, sizeof(setup_packet),
    94             data, data_size);
    95 
    96         return rc;
    97 }
    98 
    99  /** Generic wrapper for GET requests using standard control request format.
    100   *
    101   * @see usb_pipe_control_read
    102   *
    103   * @param pipe Pipe used for the communication.
    104   * @param request_type Request type (standard/class/vendor).
    105   * @param recipient Request recipient (e.g. device or endpoint).
    106   * @param request Actual request (e.g. GET_DESCRIPTOR).
    107   * @param value Value of @c wValue field of setup packet
    108   *     (must be in USB endianness).
    109   * @param index Value of @c wIndex field of setup packet
    110   *     (must be in USB endianness).
    111   * @param data Buffer where to store data accepted during the DATA stage.
    112   *     (they will come in USB endianness).
    113   * @param data_size Size of the @p data buffer
    114   *     (in native endianness).
    115   * @param actual_data_size Actual size of transfered data
    116   *     (in native endianness).
    117   * @return Error code.
    118   * @retval EBADMEM @p pipe is NULL.
    119   * @retval EBADMEM @p data is NULL and @p data_size is not zero.
    120   * @retval ERANGE Data buffer too large.
    121   */
    122 int usb_control_request_get(usb_pipe_t *pipe,
    123     usb_request_type_t request_type, usb_request_recipient_t recipient,
    124     uint8_t request,
    125     uint16_t value, uint16_t index,
    126     void *data, size_t data_size, size_t *actual_data_size)
    127 {
    128         if (pipe == NULL) {
    129                 return EBADMEM;
    130         }
    131 
    132         if (data_size > MAX_DATA_LENGTH) {
    133                 return ERANGE;
    134         }
    135 
    136         if ((data_size > 0) && (data == NULL)) {
    137                 return EBADMEM;
    138         }
    139 
    140         /*
    141          * TODO: check that @p request_type and @p recipient are
    142          * within ranges.
    143          */
    144 
    14592        const usb_device_request_setup_packet_t setup_packet = {
    146                 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST
    147                     | (request_type << 5) | recipient,
     93                .request_type = (request_type << 5) | recipient,
    14894                .request = request,
    14995                .value = value,
     
    15298        };
    15399
     100        return usb_pipe_control_write(pipe,
     101            &setup_packet, sizeof(setup_packet), data, data_size);
     102}
     103
     104/** Generic wrapper for GET requests using standard control request format.
     105 *
     106 * @see usb_pipe_control_read
     107 *
     108 * @param pipe             Pipe used for the communication.
     109 * @param request_type     Request type (standard/class/vendor).
     110 * @param recipient        Request recipient (e.g. device or endpoint).
     111 * @param request          Actual request (e.g. GET_DESCRIPTOR).
     112 * @param value            Value of @c wValue field of setup packet
     113 *                         (must be in USB endianness).
     114 * @param index            Value of @c wIndex field of setup packet
     115 *                         (must be in USB endianness).
     116 * @param data             Buffer where to store data accepted during
     117 *                         the DATA stage (they will come in USB endianness).
     118 * @param data_size        Size of the @p data buffer
     119 *                         (in native endianness).
     120 * @param actual_data_size Actual size of transfered data
     121 *                         (in native endianness).
     122 *
     123 * @return Error code.
     124 * @retval EBADMEM @p pipe is NULL.
     125 * @retval EBADMEM @p data is NULL and @p data_size is not zero.
     126 * @retval ERANGE Data buffer too large.
     127 *
     128 */
     129int usb_control_request_get(usb_pipe_t *pipe,
     130    usb_request_type_t request_type, usb_request_recipient_t recipient,
     131    uint8_t request, uint16_t value, uint16_t index,
     132    void *data, size_t data_size, size_t *actual_data_size)
     133{
     134        if (pipe == NULL) {
     135                return EBADMEM;
     136        }
     137
     138        if (data_size > MAX_DATA_LENGTH) {
     139                return ERANGE;
     140        }
     141
     142        if ((data_size > 0) && (data == NULL)) {
     143                return EBADMEM;
     144        }
     145
     146        /*
     147         * TODO: check that @p request_type and @p recipient are
     148         * within ranges.
     149         */
     150
     151        const usb_device_request_setup_packet_t setup_packet = {
     152                .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST
     153                    | (request_type << 5) | recipient,
     154                .request = request,
     155                .value = uint16_host2usb(value),
     156                .index = uint16_host2usb(index),
     157                .length = uint16_host2usb(data_size),
     158        };
     159
    154160        return usb_pipe_control_read(pipe, &setup_packet, sizeof(setup_packet),
    155161            data, data_size, actual_data_size);
     
    207213{
    208214        if (request_type == USB_REQUEST_TYPE_STANDARD) {
    209                 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
    210                     && (index != 0)) {
     215                if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) {
    211216                        return EINVAL;
    212217                }
    213218        }
    214219
    215         int rc = usb_control_request_set(pipe, request_type, recipient,
    216             USB_DEVREQ_CLEAR_FEATURE,
    217             uint16_host2usb(feature_selector), uint16_host2usb(index),
    218             NULL, 0);
    219 
    220         return rc;
     220        return usb_control_request_set(pipe,
     221            request_type, recipient, USB_DEVREQ_CLEAR_FEATURE,
     222            uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0);
    221223}
    222224
     
    235237{
    236238        if (request_type == USB_REQUEST_TYPE_STANDARD) {
    237                 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
    238                     && (index != 0)) {
     239                if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) {
    239240                        return EINVAL;
    240241                }
    241242        }
    242243
    243         int rc = usb_control_request_set(pipe, request_type, recipient,
    244             USB_DEVREQ_SET_FEATURE,
    245             uint16_host2usb(feature_selector), uint16_host2usb(index),
    246             NULL, 0);
    247 
    248         return rc;
     244        return usb_control_request_set(pipe,
     245            request_type, recipient, USB_DEVREQ_SET_FEATURE,
     246            uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0);
    249247}
    250248
     
    275273        }
    276274
     275        /*
     276         * The wValue field specifies the descriptor type in the high byte
     277         * and the descriptor index in the low byte. USB 1.1 spec p. 189
     278         */
    277279        const uint16_t wValue = descriptor_index | (descriptor_type << 8);
    278280
     
    311313         * Get only first byte to retrieve descriptor length.
    312314         */
    313         uint8_t tmp_buffer[1];
     315        uint8_t tmp_buffer;
    314316        size_t bytes_transfered;
    315317        rc = usb_request_get_descriptor(pipe, request_type, recipient,
    316318            descriptor_type, descriptor_index, language,
    317             &tmp_buffer, 1, &bytes_transfered);
     319            &tmp_buffer, sizeof(tmp_buffer), &bytes_transfered);
    318320        if (rc != EOK) {
    319321                return rc;
    320322        }
    321323        if (bytes_transfered != 1) {
    322                 /* FIXME: some better error code? */
    323                 return ESTALL;
    324         }
    325 
    326         size_t size = tmp_buffer[0];
     324                return ELIMIT;
     325        }
     326
     327        const size_t size = tmp_buffer;
    327328        if (size == 0) {
    328                 /* FIXME: some better error code? */
    329                 return ESTALL;
     329                return ELIMIT;
    330330        }
    331331
     
    347347        if (bytes_transfered != size) {
    348348                free(buffer);
    349                 /* FIXME: some better error code? */
    350                 return ESTALL;
     349                return ELIMIT;
    351350        }
    352351
     
    375374        usb_standard_device_descriptor_t descriptor_tmp;
    376375        int rc = usb_request_get_descriptor(pipe,
    377             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    378             USB_DESCTYPE_DEVICE, 0, 0,
    379             &descriptor_tmp, sizeof(descriptor_tmp),
     376            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     377            USB_DESCTYPE_DEVICE, 0, 0, &descriptor_tmp, sizeof(descriptor_tmp),
    380378            &actually_transferred);
    381379
     
    419417        size_t actually_transferred = 0;
    420418        usb_standard_configuration_descriptor_t descriptor_tmp;
    421         int rc = usb_request_get_descriptor(pipe,
     419        const int rc = usb_request_get_descriptor(pipe,
    422420            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    423421            USB_DESCTYPE_CONFIGURATION, index, 0,
     
    435433        /* Everything is okay, copy the descriptor. */
    436434        memcpy(descriptor, &descriptor_tmp, sizeof(descriptor_tmp));
    437 
    438435        return EOK;
    439436}
     
    478475int usb_request_get_full_configuration_descriptor_alloc(
    479476    usb_pipe_t *pipe, int index,
    480     void **descriptor_ptr, size_t *descriptor_size)
     477    const void **descriptor_ptr, size_t *descriptor_size)
    481478{
    482479        int rc;
     
    495492                return ENOENT;
    496493        }
    497         if (bare_config.total_length < sizeof(bare_config)) {
    498                 return ELIMIT;
    499         }
    500 
    501         void *buffer = malloc(bare_config.total_length);
     494
     495        const size_t total_length = uint16_usb2host(bare_config.total_length);
     496        if (total_length < sizeof(bare_config)) {
     497                return ELIMIT;
     498        }
     499
     500        void *buffer = malloc(total_length);
    502501        if (buffer == NULL) {
    503502                return ENOMEM;
     
    506505        size_t transferred = 0;
    507506        rc = usb_request_get_full_configuration_descriptor(pipe, index,
    508             buffer, bare_config.total_length, &transferred);
     507            buffer, total_length, &transferred);
    509508        if (rc != EOK) {
    510509                free(buffer);
     
    512511        }
    513512
    514         if (transferred != bare_config.total_length) {
     513        if (transferred != total_length) {
    515514                free(buffer);
    516515                return ELIMIT;
     
    522521
    523522        if (descriptor_size != NULL) {
    524                 *descriptor_size = bare_config.total_length;
     523                *descriptor_size = total_length;
    525524        }
    526525
     
    543542    usb_request_type_t request_type, usb_request_recipient_t recipient,
    544543    uint8_t descriptor_type, uint8_t descriptor_index,
    545     uint16_t language,
    546     void *buffer, size_t size)
     544    uint16_t language, const void *buffer, size_t size)
    547545{
    548546        if (buffer == NULL) {
     
    557555
    558556        return usb_control_request_set(pipe,
    559             request_type, recipient,
    560             USB_DEVREQ_SET_DESCRIPTOR,
    561             wValue, language,
    562             buffer, size);
     557            request_type, recipient, USB_DEVREQ_SET_DESCRIPTOR,
     558            wValue, language, buffer, size);
    563559}
    564560
     
    575571        size_t actual_size;
    576572
    577         int rc = usb_control_request_get(pipe,
     573        const int rc = usb_control_request_get(pipe,
    578574            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    579             USB_DEVREQ_GET_CONFIGURATION,
    580             0, 0,
    581             &value, 1, &actual_size);
     575            USB_DEVREQ_GET_CONFIGURATION, 0, 0, &value, 1, &actual_size);
    582576
    583577        if (rc != EOK) {
     
    604598    uint8_t configuration_value)
    605599{
    606         uint16_t config_value
     600        const uint16_t config_value
    607601            = uint16_host2usb((uint16_t) configuration_value);
    608602
     
    626620        size_t actual_size;
    627621
    628         int rc = usb_control_request_get(pipe,
     622        const int rc = usb_control_request_get(pipe,
    629623            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
    630624            USB_DEVREQ_GET_INTERFACE,
    631625            0, uint16_host2usb((uint16_t) interface_index),
    632             &value, 1, &actual_size);
     626            &value, sizeof(value), &actual_size);
    633627
    634628        if (rc != EOK) {
     
    675669    l18_win_locales_t **languages_ptr, size_t *languages_count)
    676670{
    677         int rc;
    678 
    679         if (languages_ptr == NULL) {
    680                 return EBADMEM;
    681         }
    682         if (languages_count == NULL) {
     671        if (languages_ptr == NULL || languages_count == NULL) {
    683672                return EBADMEM;
    684673        }
     
    686675        uint8_t *string_descriptor = NULL;
    687676        size_t string_descriptor_size = 0;
    688         rc = usb_request_get_descriptor_alloc(pipe,
     677        const int rc = usb_request_get_descriptor_alloc(pipe,
    689678            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    690679            USB_DESCTYPE_STRING, 0, 0,
     
    707696        }
    708697
    709         size_t langs_count = string_descriptor_size / 2;
    710         l18_win_locales_t *langs
    711             = malloc(sizeof(l18_win_locales_t) * langs_count);
     698        const size_t langs_count = string_descriptor_size / 2;
     699        l18_win_locales_t *langs =
     700            calloc(langs_count, sizeof(l18_win_locales_t));
    712701        if (langs == NULL) {
    713702                free(string_descriptor);
     
    715704        }
    716705
    717         size_t i;
    718         for (i = 0; i < langs_count; i++) {
     706        for (size_t i = 0; i < langs_count; i++) {
    719707                /* Language code from the descriptor is in USB endianness. */
    720708                /* FIXME: is this really correct? */
    721                 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
     709                const uint16_t lang_code =
     710                    (string_descriptor[2 + 2 * i + 1] << 8)
    722711                    + string_descriptor[2 + 2 * i];
    723712                langs[i] = uint16_usb2host(lang_code);
     
    758747        }
    759748        /* Language is actually two byte value. */
    760         if (lang > 0xFFFF) {
     749        if (lang > L18N_WIN_LOCALE_MAX) {
    761750                return ERANGE;
    762751        }
     
    792781        }
    793782
    794         size_t string_char_count = string_size / 2;
     783        const size_t string_char_count = string_size / 2;
    795784        string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
    796785        if (string_chars == NULL) {
     
    804793         * do not have them).
    805794         */
    806         size_t i;
    807         for (i = 0; i < string_char_count; i++) {
    808                 uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
     795        for (size_t i = 0; i < string_char_count; i++) {
     796                const uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
    809797                    + string[2 + 2 * i];
    810798                string_chars[i] = uni_char;
     
    824812
    825813leave:
    826         if (string != NULL) {
    827                 free(string);
    828         }
    829         if (string_chars != NULL) {
    830                 free(string_chars);
    831         }
     814        free(string);
     815        free(string_chars);
    832816
    833817        return rc;
     
    844828        return usb_request_clear_feature(pipe,
    845829            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,
    846             uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),
     830            uint16_host2usb(USB_FEATURE_ENDPOINT_HALT),
    847831            uint16_host2usb(ep_index));
    848832}
Note: See TracChangeset for help on using the changeset viewer.