Changeset a97ea0f in mainline for uspace/lib/usb/src/usbdrvreq.c


Ignore:
Timestamp:
2011-01-10T11:58:21Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6610565b
Parents:
a523af4 (diff), 863d45e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merged vojtechhorky/ - wrappers for standard requests

File:
1 edited

Legend:

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

    ra523af4 ra97ea0f  
    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 */
     100int 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 */
     139int 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 */
     164int 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
    38180/** Change address of connected device.
    39181 *
     
    44186 * @see usb_drv_bind_address
    45187 *
    46  * @param phone Open phone to HC driver.
    47  * @param old_address Current address.
    48  * @param address Address to be set.
     188 * @param[in] phone Open phone to HC driver.
     189 * @param[in] old_address Current address.
     190 * @param[in] address Address to be set.
    49191 * @return Error code.
    50192 */
     
    52194    usb_address_t new_address)
    53195{
    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;
     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);
    68201
    69202        int rc = usb_drv_psync_control_write(phone, target,
     
    76209 *
    77210 * @param[in] hc_phone Open phone to HC driver.
    78  * @param[in] address Device USB address.
     211 * @param[in] address Device address.
    79212 * @param[in] request_type Request type (standard/class/vendor).
    80213 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
    81214 * @param[in] descriptor_index Descriptor index.
    82  * @param[in] langauge Language index.
     215 * @param[in] language Language index.
    83216 * @param[out] buffer Buffer where to store the retrieved descriptor.
    84217 * @param[in] size Size of the @p buffer.
     
    92225    void *buffer, size_t size, size_t *actual_size)
    93226{
    94         /* Prepare the target. */
    95         usb_target_t target = {
    96                 .address = address,
    97                 .endpoint = 0
    98         };
    99 
    100         /* Prepare the setup packet. */
    101         usb_device_request_setup_packet_t setup_packet = {
    102                 .request_type = 128 | (request_type << 5),
    103                 .request = USB_DEVREQ_GET_DESCRIPTOR,
    104                 .index = language,
    105                 .length = (uint16_t) size,
    106         };
    107         setup_packet.value_high = descriptor_type;
    108         setup_packet.value_low = descriptor_index;
    109        
    110         /* Perform CONTROL READ */
     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
    111243        int rc = usb_drv_psync_control_read(hc_phone, target,
    112244            &setup_packet, sizeof(setup_packet),
     
    119251 *
    120252 * @param[in] phone Open phone to HC driver.
    121  * @param[in] address Device USB address.
     253 * @param[in] address Device address.
    122254 * @param[out] descriptor Storage for the device descriptor.
    123255 * @return Error code.
     
    164296 *
    165297 * @param[in] phone Open phone to HC driver.
    166  * @param[in] address Device USB address.
     298 * @param[in] address Device address.
    167299 * @param[in] index Configuration descriptor index.
    168300 * @param[out] descriptor Storage for the configuration descriptor.
     
    206338 *
    207339 * @warning The @p buffer might be touched (i.e. its contents changed)
    208  * even when error occurres.
     340 * even when error occurs.
    209341 *
    210342 * @param[in] phone Open phone to HC driver.
    211  * @param[in] address Device USB address.
     343 * @param[in] address Device address.
    212344 * @param[in] index Configuration descriptor index.
    213345 * @param[out] buffer Buffer for the whole configuration descriptor.
     
    221353    void *buffer, size_t buffer_size, size_t *actual_buffer_size)
    222354{
    223         if (buffer == NULL) {
    224                 return EBADMEM;
    225         }
    226 
    227355        int rc = usb_drv_req_get_descriptor(phone, address,
    228356            USB_REQUEST_TYPE_STANDARD,
     
    235363}
    236364
     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 */
     376int 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 */
     404int 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 */
     442int 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 */
     466int 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 */
     505int 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}
    237520
    238521/**
Note: See TracChangeset for help on using the changeset viewer.