Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/usbdrvreq.c

    r863d45e r82783b0  
    3636#include <errno.h>
    3737
    38 /**  Prepare USB target for control endpoint.
    39  *
    40  * @param name Variable name with the USB target.
    41  * @param target_address Target USB address.
    42  */
    43 #define PREPARE_TARGET(name, target_address) \
    44         usb_target_t name = { \
    45                 .address = target_address, \
    46                 .endpoint = 0 \
    47         }
    48 
    49 /** Prepare setup packet.
    50  *
    51  * @param name Variable name with the setup packet.
    52  * @param p_direction Data transfer direction.
    53  * @param p_type Request type (standard/class/vendor)
    54  * @param p_recipient Recipient of the request.
    55  * @param p_request Request.
    56  * @param p_value wValue field of setup packet.
    57  * @param p_index wIndex field of setup packet.
    58  * @param p_length Length of extra data.
    59  */
    60 #define PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \
    61     p_request, p_value, p_index, p_length) \
    62         usb_device_request_setup_packet_t setup_packet = { \
    63                 .request_type = \
    64                         ((p_direction) == USB_DIRECTION_IN ? 128 : 0) \
    65                         | ((p_type) << 5) \
    66                         | (p_recipient), \
    67                 .request = (p_request), \
    68                 { .value = (p_value) }, \
    69                 .index = (p_index), \
    70                 .length = (p_length) \
    71         }
    72 
    73 /** Prepare setup packet.
    74  *
    75  * @param name Variable name with the setup packet.
    76  * @param p_direction Data transfer direction.
    77  * @param p_type Request type (standard/class/vendor)
    78  * @param p_recipient Recipient of the request.
    79  * @param p_request Request.
    80  * @param p_value_low wValue field of setup packet (low byte).
    81  * @param p_value_high wValue field of setup packet (high byte).
    82  * @param p_index wIndex field of setup packet.
    83  * @param p_length Length of extra data.
    84  */
    85 #define PREPARE_SETUP_PACKET_LOHI(name, p_direction, p_type, p_recipient, \
    86     p_request, p_value_low, p_value_high, p_index, p_length) \
    87         PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \
    88             p_request, (p_value_low) | ((p_value_high) << 8), \
    89             p_index, p_length)
    90 
    91 /** Retrieve status of a USB device.
    92  *
    93  * @param[in] hc_phone Open phone to HC driver.
    94  * @param[in] address Device address.
    95  * @param[in] recipient Recipient of the request.
    96  * @param[in] recipient_index Index of @p recipient.
    97  * @param[out] status Status (see figure 9-4 in USB 1.1 specification).
    98  * @return Error code.
    99  */
    100 int usb_drv_req_get_status(int hc_phone, usb_address_t address,
    101     usb_request_recipient_t recipient, uint16_t recipient_index,
    102     uint16_t *status)
    103 {
    104         if (status == NULL) {
    105                 return EBADMEM;
    106         }
    107 
    108         PREPARE_TARGET(target, address);
    109 
    110         PREPARE_SETUP_PACKET(setup_packet,
    111             USB_DIRECTION_IN, USB_REQUEST_TYPE_STANDARD,
    112             recipient, USB_DEVREQ_GET_STATUS, 0, recipient_index, 2);
    113 
    114         size_t transfered;
    115         uint16_t tmp_status;
    116         int rc = usb_drv_psync_control_read(hc_phone, target,
    117             &setup_packet, sizeof(setup_packet), &tmp_status, 2, &transfered);
    118         if (rc != EOK) {
    119                 return rc;
    120         }
    121         if (transfered != 2) {
    122                 return ERANGE;
    123         }
    124 
    125         *status = tmp_status;
    126 
    127         return EOK;
    128 }
    129 
    130 /** Clear or disable USB device feature.
    131  *
    132  * @param[in] hc_phone Open phone to HC driver.
    133  * @param[in] address Device address.
    134  * @param[in] recipient Recipient of the request.
    135  * @param[in] selector Feature selector.
    136  * @param[in] index Index of @p recipient.
    137  * @return Error code.
    138  */
    139 int usb_drv_req_clear_feature(int hc_phone, usb_address_t address,
    140     usb_request_recipient_t recipient,
    141     uint16_t selector, uint16_t index)
    142 {
    143         PREPARE_TARGET(target, address);
    144 
    145         PREPARE_SETUP_PACKET(setup_packet,
    146             USB_DIRECTION_OUT, USB_REQUEST_TYPE_STANDARD,
    147             recipient, USB_DEVREQ_CLEAR_FEATURE, selector, index, 0);
    148 
    149         int rc = usb_drv_psync_control_write(hc_phone, target,
    150             &setup_packet, sizeof(setup_packet), NULL, 0);
    151 
    152         return rc;
    153 }
    154 
    155 /** Set or enable USB device feature.
    156  *
    157  * @param[in] hc_phone Open phone to HC driver.
    158  * @param[in] address Device address.
    159  * @param[in] recipient Recipient of the request.
    160  * @param[in] selector Feature selector.
    161  * @param[in] index Index of @p recipient.
    162  * @return Error code.
    163  */
    164 int usb_drv_req_set_feature(int hc_phone, usb_address_t address,
    165     usb_request_recipient_t recipient,
    166     uint16_t selector, uint16_t index)
    167 {
    168         PREPARE_TARGET(target, address);
    169 
    170         PREPARE_SETUP_PACKET(setup_packet,
    171             USB_DIRECTION_OUT, USB_REQUEST_TYPE_STANDARD,
    172             recipient, USB_DEVREQ_SET_FEATURE, selector, index, 0);
    173 
    174         int rc = usb_drv_psync_control_write(hc_phone, target,
    175             &setup_packet, sizeof(setup_packet), NULL, 0);
    176 
    177         return rc;
    178 }
    179 
    18038/** Change address of connected device.
    18139 *
     
    18644 * @see usb_drv_bind_address
    18745 *
    188  * @param[in] phone Open phone to HC driver.
    189  * @param[in] old_address Current address.
    190  * @param[in] address Address to be set.
     46 * @param phone Open phone to HC driver.
     47 * @param old_address Current address.
     48 * @param address Address to be set.
    19149 * @return Error code.
    19250 */
     
    19452    usb_address_t new_address)
    19553{
    196         PREPARE_TARGET(target, old_address);
    197 
    198         PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_OUT,
    199             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    200             USB_DEVREQ_SET_ADDRESS, new_address, 0, 0);
     54        /* Prepare the target. */
     55        usb_target_t target = {
     56                .address = old_address,
     57                .endpoint = 0
     58        };
     59
     60        /* Prepare the setup packet. */
     61        usb_device_request_setup_packet_t setup_packet = {
     62                .request_type = 0,
     63                .request = USB_DEVREQ_SET_ADDRESS,
     64                .index = 0,
     65                .length = 0,
     66        };
     67        setup_packet.value = new_address;
    20168
    20269        int rc = usb_drv_psync_control_write(phone, target,
     
    20673}
    20774
    208 /** Retrieve USB descriptor of connected USB device.
    209  *
    210  * @param[in] hc_phone Open phone to HC driver.
    211  * @param[in] address Device address.
    212  * @param[in] request_type Request type (standard/class/vendor).
    213  * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
    214  * @param[in] descriptor_index Descriptor index.
    215  * @param[in] language Language index.
    216  * @param[out] buffer Buffer where to store the retrieved descriptor.
    217  * @param[in] size Size of the @p buffer.
    218  * @param[out] actual_size Number of bytes actually transferred.
    219  * @return Error code.
    220  */
    221 int usb_drv_req_get_descriptor(int hc_phone, usb_address_t address,
    222     usb_request_type_t request_type,
    223     uint8_t descriptor_type, uint8_t descriptor_index,
    224     uint16_t language,
    225     void *buffer, size_t size, size_t *actual_size)
    226 {
    227         if (buffer == NULL) {
    228                 return EBADMEM;
    229         }
    230         if (size == 0) {
    231                 return EINVAL;
    232         }
    233 
    234         // FIXME: check that size is not too big
    235 
    236         PREPARE_TARGET(target, address);
    237 
    238         PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_IN,
    239             request_type, USB_REQUEST_RECIPIENT_DEVICE,
    240             USB_DEVREQ_GET_DESCRIPTOR, descriptor_index, descriptor_type,
    241             language, size);
    242 
    243         int rc = usb_drv_psync_control_read(hc_phone, target,
    244             &setup_packet, sizeof(setup_packet),
    245             buffer, size, actual_size);
    246        
    247         return rc;
    248 }
    249 
    25075/** Retrieve device descriptor of connected USB device.
    25176 *
    25277 * @param[in] phone Open phone to HC driver.
    253  * @param[in] address Device address.
     78 * @param[in] address Device USB address.
    25479 * @param[out] descriptor Storage for the device descriptor.
    25580 * @return Error code.
     
    26287                return EBADMEM;
    26388        }
    264        
     89
     90        /* Prepare the target. */
     91        usb_target_t target = {
     92                .address = address,
     93                .endpoint = 0
     94        };
     95
     96        /* Prepare the setup packet. */
     97        usb_device_request_setup_packet_t setup_packet = {
     98                .request_type = 128,
     99                .request = USB_DEVREQ_GET_DESCRIPTOR,
     100                .index = 0,
     101                .length = sizeof(usb_standard_device_descriptor_t)
     102        };
     103        setup_packet.value_high = USB_DESCTYPE_DEVICE;
     104        setup_packet.value_low = 0;
     105
     106        /* Prepare local descriptor. */
    265107        size_t actually_transferred = 0;
    266108        usb_standard_device_descriptor_t descriptor_tmp;
    267         int rc = usb_drv_req_get_descriptor(phone, address,
    268             USB_REQUEST_TYPE_STANDARD,
    269             USB_DESCTYPE_DEVICE, 0,
    270             0,
    271             &descriptor_tmp, sizeof(descriptor_tmp),
    272             &actually_transferred);
     109
     110        /* Perform the control read transaction. */
     111        int rc = usb_drv_psync_control_read(phone, target,
     112            &setup_packet, sizeof(setup_packet),
     113            &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
    273114
    274115        if (rc != EOK) {
     
    296137 *
    297138 * @param[in] phone Open phone to HC driver.
    298  * @param[in] address Device address.
     139 * @param[in] address Device USB address.
    299140 * @param[in] index Configuration descriptor index.
    300141 * @param[out] descriptor Storage for the configuration descriptor.
     
    309150                return EBADMEM;
    310151        }
    311        
     152
     153        /* Prepare the target. */
     154        usb_target_t target = {
     155                .address = address,
     156                .endpoint = 0
     157        };
     158
     159        /* Prepare the setup packet. */
     160        usb_device_request_setup_packet_t setup_packet = {
     161                .request_type = 128,
     162                .request = USB_DEVREQ_GET_DESCRIPTOR,
     163                .index = 0,
     164                .length = sizeof(usb_standard_configuration_descriptor_t)
     165        };
     166        setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
     167        setup_packet.value_low = index;
     168
     169        /* Prepare local descriptor. */
    312170        size_t actually_transferred = 0;
    313171        usb_standard_configuration_descriptor_t descriptor_tmp;
    314         int rc = usb_drv_req_get_descriptor(phone, address,
    315             USB_REQUEST_TYPE_STANDARD,
    316             USB_DESCTYPE_CONFIGURATION, 0,
    317             0,
    318             &descriptor_tmp, sizeof(descriptor_tmp),
    319             &actually_transferred);
     172
     173        /* Perform the control read transaction. */
     174        int rc = usb_drv_psync_control_read(phone, target,
     175            &setup_packet, sizeof(setup_packet),
     176            &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
    320177
    321178        if (rc != EOK) {
     
    338195 *
    339196 * @warning The @p buffer might be touched (i.e. its contents changed)
    340  * even when error occurs.
     197 * even when error occurres.
    341198 *
    342199 * @param[in] phone Open phone to HC driver.
    343  * @param[in] address Device address.
     200 * @param[in] address Device USB address.
    344201 * @param[in] index Configuration descriptor index.
    345202 * @param[out] buffer Buffer for the whole configuration descriptor.
     
    353210    void *buffer, size_t buffer_size, size_t *actual_buffer_size)
    354211{
    355         int rc = usb_drv_req_get_descriptor(phone, address,
    356             USB_REQUEST_TYPE_STANDARD,
    357             USB_DESCTYPE_CONFIGURATION, 0,
    358             0,
    359             buffer, buffer_size,
    360             actual_buffer_size);
     212        if (buffer == NULL) {
     213                return EBADMEM;
     214        }
     215
     216        /* Prepare the target. */
     217        usb_target_t target = {
     218                .address = address,
     219                .endpoint = 0
     220        };
     221
     222        /* Prepare the setup packet. */
     223        usb_device_request_setup_packet_t setup_packet = {
     224                .request_type = 128,
     225                .request = USB_DEVREQ_GET_DESCRIPTOR,
     226                .index = 0,
     227                .length = buffer_size
     228        };
     229        setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
     230        setup_packet.value_low = index;
     231
     232        /* Perform the control read transaction. */
     233        int rc = usb_drv_psync_control_read(phone, target,
     234            &setup_packet, sizeof(setup_packet),
     235            buffer, buffer_size, actual_buffer_size);
    361236
    362237        return rc;
    363238}
    364239
    365 /** Update existing descriptor of a USB device.
    366  *
    367  * @param[in] hc_phone Open phone to HC driver.
    368  * @param[in] address Device address.
    369  * @param[in] descriptor_type Descriptor type (device/configuration/...).
    370  * @param[in] descriptor_index Descriptor index.
    371  * @param[in] language Language index.
    372  * @param[in] descriptor Actual descriptor data.
    373  * @param[in] descriptor_size Descriptor size.
    374  * @return Error code.
    375  */
    376 int usb_drv_req_set_descriptor(int hc_phone, usb_address_t address,
    377     uint8_t descriptor_type, uint8_t descriptor_index,
    378     uint16_t language,
    379     void *descriptor, size_t descriptor_size)
    380 {
    381         // FIXME: check that descriptor is not too big
    382 
    383         PREPARE_TARGET(target, address);
    384 
    385         PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT,
    386             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    387             USB_DEVREQ_SET_DESCRIPTOR, descriptor_index, descriptor_type,
    388             language, descriptor_size);
    389 
    390         int rc = usb_drv_psync_control_write(hc_phone, target,
    391             &setup_packet, sizeof(setup_packet),
    392             descriptor, descriptor_size);
    393 
    394         return rc;
    395 }
    396 
    397 /** Determine current configuration value of USB device.
    398  *
    399  * @param[in] hc_phone Open phone to HC driver.
    400  * @param[in] address Device address.
    401  * @param[out] configuration_value Current configuration value.
    402  * @return Error code.
    403  */
    404 int usb_drv_req_get_configuration(int hc_phone, usb_address_t address,
    405     uint8_t *configuration_value)
    406 {
    407         if (configuration_value == NULL) {
    408                 return EBADMEM;
    409         }
    410 
    411         PREPARE_TARGET(target, address);
    412 
    413         PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_IN,
    414             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    415             USB_DEVREQ_GET_CONFIGURATION, 0, 0, 1);
    416 
    417         uint8_t value;
    418         size_t transfered;
    419         int rc = usb_drv_psync_control_read(hc_phone, target,
    420             &setup_packet, sizeof(setup_packet), &value, 1, &transfered);
    421 
    422         if (rc != EOK) {
    423                 return rc;
    424         }
    425 
    426         if (transfered != 1) {
    427                 return ERANGE;
    428         }
    429 
    430         *configuration_value = value;
    431 
    432         return EOK;
    433 }
    434 
    435 /** Set configuration of USB device.
    436  *
    437  * @param[in] hc_phone Open phone to HC driver.
    438  * @param[in] address Device address.
    439  * @param[in] configuration_value New configuration value.
    440  * @return Error code.
    441  */
    442 int usb_drv_req_set_configuration(int hc_phone, usb_address_t address,
    443     uint8_t configuration_value)
    444 {
    445         PREPARE_TARGET(target, address);
    446 
    447         PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT,
    448             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    449             USB_DEVREQ_SET_CONFIGURATION, configuration_value, 0,
    450             0, 0);
    451 
    452         int rc = usb_drv_psync_control_write(hc_phone, target,
    453             &setup_packet, sizeof(setup_packet), NULL, 0);
    454 
    455         return rc;
    456 }
    457 
    458 /** Determine alternate setting of USB device interface.
    459  *
    460  * @param[in] hc_phone Open phone to HC driver.
    461  * @param[in] address Device address.
    462  * @param[in] interface_index Interface index.
    463  * @param[out] alternate_setting Value of alternate setting.
    464  * @return Error code.
    465  */
    466 int usb_drv_req_get_interface(int hc_phone, usb_address_t address,
    467     uint16_t interface_index, uint8_t *alternate_setting)
    468 {
    469         if (alternate_setting == NULL) {
    470                 return EBADMEM;
    471         }
    472 
    473         PREPARE_TARGET(target, address);
    474 
    475         PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_IN,
    476             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
    477             USB_DEVREQ_GET_INTERFACE, 0, interface_index, 1);
    478 
    479         uint8_t alternate;
    480         size_t transfered;
    481         int rc = usb_drv_psync_control_read(hc_phone, target,
    482             &setup_packet, sizeof(setup_packet), &alternate, 1, &transfered);
    483 
    484         if (rc != EOK) {
    485                 return rc;
    486         }
    487 
    488         if (transfered != 1) {
    489                 return ERANGE;
    490         }
    491 
    492         *alternate_setting = alternate;
    493 
    494         return EOK;
    495 }
    496 
    497 /** Select an alternate setting of USB device interface.
    498  *
    499  * @param[in] hc_phone Open phone to HC driver.
    500  * @param[in] address Device address.
    501  * @param[in] interface_index Interface index.
    502  * @param[in] alternate_setting Value of alternate setting.
    503  * @return Error code.
    504  */
    505 int usb_drv_req_set_interface(int hc_phone, usb_address_t address,
    506     uint16_t interface_index, uint8_t alternate_setting)
    507 {
    508         PREPARE_TARGET(target, address);
    509 
    510         PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT,
    511             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
    512             USB_DEVREQ_SET_INTERFACE, alternate_setting, 0,
    513             0, 0);
    514 
    515         int rc = usb_drv_psync_control_write(hc_phone, target,
    516             &setup_packet, sizeof(setup_packet), NULL, 0);
    517 
    518         return rc;
    519 }
    520240
    521241/**
Note: See TracChangeset for help on using the changeset viewer.