Changeset f401312 in mainline for uspace/lib/usb


Ignore:
Timestamp:
2011-01-14T12:34:42Z (15 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
45019865
Parents:
b2a6fcfe (diff), 6610565b (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 development into lelian/hidd

Location:
uspace/lib/usb
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/devreq.h

    rb2a6fcfe rf401312  
    8585} __attribute__ ((packed)) usb_device_request_setup_packet_t;
    8686
     87
     88int usb_drv_req_get_status(int, usb_address_t, usb_request_recipient_t,
     89    uint16_t, uint16_t *);
     90int usb_drv_req_clear_feature(int, usb_address_t, usb_request_recipient_t,
     91    uint16_t, uint16_t);
     92int usb_drv_req_set_feature(int, usb_address_t, usb_request_recipient_t,
     93    uint16_t, uint16_t);
    8794int usb_drv_req_set_address(int, usb_address_t, usb_address_t);
     95int usb_drv_req_get_descriptor(int, usb_address_t, usb_request_type_t,
     96    uint8_t, uint8_t, uint16_t, void *, size_t, size_t *);
    8897int usb_drv_req_get_device_descriptor(int, usb_address_t,
    8998    usb_standard_device_descriptor_t *);
     
    92101int usb_drv_req_get_full_configuration_descriptor(int, usb_address_t, int,
    93102    void *, size_t, size_t *);
    94 
     103int usb_drv_req_set_descriptor(int, usb_address_t, uint8_t, uint8_t, uint16_t,
     104    void *, size_t);
     105int usb_drv_req_get_configuration(int, usb_address_t, uint8_t *);
     106int usb_drv_req_set_configuration(int, usb_address_t, uint8_t);
     107int usb_drv_req_get_interface(int, usb_address_t, uint16_t, uint8_t *);
     108int usb_drv_req_set_interface(int, usb_address_t, uint16_t, uint8_t);
    95109
    96110#endif
  • uspace/lib/usb/include/usb/usb.h

    rb2a6fcfe rf401312  
    5454        USB_DIRECTION_OUT
    5555} usb_direction_t;
     56
     57/** USB request type target. */
     58typedef enum {
     59        USB_REQUEST_TYPE_STANDARD = 0,
     60        USB_REQUEST_TYPE_CLASS = 1,
     61        USB_REQUEST_TYPE_VENDOR = 2
     62} usb_request_type_t;
     63
     64/** USB request recipient. */
     65typedef enum {
     66        USB_REQUEST_RECIPIENT_DEVICE = 0,
     67        USB_REQUEST_RECIPIENT_INTERFACE = 1,
     68        USB_REQUEST_RECIPIENT_ENDPOINT = 2
     69} usb_request_recipient_t;
    5670
    5771/** USB transaction outcome. */
  • uspace/lib/usb/include/usb/usbdrv.h

    rb2a6fcfe rf401312  
    9696int usb_drv_async_wait_for(usb_handle_t);
    9797
     98int usb_drv_create_match_ids_from_device_descriptor(match_id_list_t *,
     99    const usb_standard_device_descriptor_t *);
     100int usb_drv_create_match_ids_from_configuration_descriptor(match_id_list_t *,
     101    const void *, size_t);
     102
    98103int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t);
    99104int usb_drv_register_child_in_devman(int, device_t *, usb_address_t,
  • uspace/lib/usb/src/addrkeep.c

    rb2a6fcfe rf401312  
    187187                new_address_position = addresses->used_addresses.next;
    188188        } else {
     189                usb_address_keeping_used_t *first
     190                    = used_address_get_instance(addresses->used_addresses.next);
     191                previous_address = first->address;
     192               
    189193                for_all_used_addresses(new_address_position, addresses) {
    190194                        usb_address_keeping_used_t *info
     
    194198                                break;
    195199                        }
     200                        previous_address = info->address;
    196201                }
    197202
  • uspace/lib/usb/src/recognise.c

    rb2a6fcfe rf401312  
    129129}
    130130
     131/** Create DDF match ids from USB device descriptor.
     132 *
     133 * @param matches List of match ids to extend.
     134 * @param device_descriptor Device descriptor returned by given device.
     135 * @return Error code.
     136 */
     137int usb_drv_create_match_ids_from_device_descriptor(
     138    match_id_list_t *matches,
     139    const usb_standard_device_descriptor_t *device_descriptor)
     140{
     141        int rc;
     142       
     143        /*
     144         * Unless the vendor id is 0, the pair idVendor-idProduct
     145         * quite uniquely describes the device.
     146         */
     147        if (device_descriptor->vendor_id != 0) {
     148                /* First, with release number. */
     149                rc = usb_add_match_id(matches, 100,
     150                    "usb&vendor=%d&product=%d&release=" BCD_FMT,
     151                    (int) device_descriptor->vendor_id,
     152                    (int) device_descriptor->product_id,
     153                    BCD_ARGS(device_descriptor->device_version));
     154                if (rc != EOK) {
     155                        return rc;
     156                }
     157               
     158                /* Next, without release number. */
     159                rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
     160                    (int) device_descriptor->vendor_id,
     161                    (int) device_descriptor->product_id);
     162                if (rc != EOK) {
     163                        return rc;
     164                }
     165        }       
     166
     167        /*
     168         * If the device class points to interface we skip adding
     169         * class directly.
     170         */
     171        if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
     172                rc = usb_add_match_id(matches, 50, "usb&class=%s",
     173                    usb_str_class(device_descriptor->device_class));
     174                if (rc != EOK) {
     175                        return rc;
     176                }
     177        }
     178       
     179        return EOK;
     180}
     181
     182/** Create DDF match ids from USB configuration descriptor.
     183 * The configuration descriptor is expected to be in the complete form,
     184 * i.e. including interface, endpoint etc. descriptors.
     185 *
     186 * @param matches List of match ids to extend.
     187 * @param config_descriptor Configuration descriptor returned by given device.
     188 * @param total_size Size of the @p config_descriptor.
     189 * @return Error code.
     190 */
     191int usb_drv_create_match_ids_from_configuration_descriptor(
     192    match_id_list_t *matches,
     193    const void *config_descriptor, size_t total_size)
     194{
     195        /*
     196         * Iterate through config descriptor to find the interface
     197         * descriptors.
     198         */
     199        size_t position = sizeof(usb_standard_configuration_descriptor_t);
     200        while (position + 1 < total_size) {
     201                uint8_t *current_descriptor
     202                    = ((uint8_t *) config_descriptor) + position;
     203                uint8_t cur_descr_len = current_descriptor[0];
     204                uint8_t cur_descr_type = current_descriptor[1];
     205               
     206                position += cur_descr_len;
     207               
     208                if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
     209                        continue;
     210                }
     211               
     212                /*
     213                 * Finally, we found an interface descriptor.
     214                 */
     215                usb_standard_interface_descriptor_t *interface
     216                    = (usb_standard_interface_descriptor_t *)
     217                    current_descriptor;
     218               
     219                int rc = usb_add_match_id(matches, 50,
     220                    "usb&interface&class=%s",
     221                    usb_str_class(interface->interface_class));
     222                if (rc != EOK) {
     223                        return rc;
     224                }
     225        }
     226       
     227        return EOK;
     228}
     229
    131230/** Add match ids based on configuration descriptor.
    132231 *
     
    169268                        continue;
    170269                }
    171 
    172                 /*
    173                  * Iterate through config descriptor to find the interface
    174                  * descriptors.
    175                  */
    176                 size_t position = sizeof(config_descriptor);
    177                 while (position + 1 < full_config_descriptor_size) {
    178                         uint8_t *current_descriptor
    179                             = ((uint8_t *) full_config_descriptor) + position;
    180                         uint8_t cur_descr_len = current_descriptor[0];
    181                         uint8_t cur_descr_type = current_descriptor[1];
    182                        
    183                         position += cur_descr_len;
    184                        
    185                         if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
    186                                 continue;
    187                         }
    188                         /*
    189                          * Finally, we found an interface descriptor.
    190                          */
    191                         usb_standard_interface_descriptor_t *interface
    192                             = (usb_standard_interface_descriptor_t *)
    193                             current_descriptor;
    194                        
    195                         rc = usb_add_match_id(matches, 50,
    196                             "usb&interface&class=%s",
    197                             usb_str_class(interface->interface_class));
    198                         if (rc != EOK) {
    199                                 final_rc = rc;
    200                                 break;
    201                         }
    202                 }
     270               
     271                rc = usb_drv_create_match_ids_from_configuration_descriptor(
     272                    matches,
     273                    full_config_descriptor, full_config_descriptor_size);
     274                if (rc != EOK) {
     275                        final_rc = rc;
     276                        continue;
     277                }
     278               
    203279        }
    204280       
     
    220296{
    221297        int rc;
     298       
     299        /*
     300         * Retrieve device descriptor and add matches from it.
     301         */
    222302        usb_standard_device_descriptor_t device_descriptor;
    223303
     
    227307                return rc;
    228308        }
    229 
    230         /*
    231          * Unless the vendor id is 0, the pair idVendor-idProduct
    232          * quite uniquely describes the device.
    233          */
    234         if (device_descriptor.vendor_id != 0) {
    235                 /* First, with release number. */
    236                 rc = usb_add_match_id(matches, 100,
    237                     "usb&vendor=%d&product=%d&release=" BCD_FMT,
    238                     (int) device_descriptor.vendor_id,
    239                     (int) device_descriptor.product_id,
    240                     BCD_ARGS(device_descriptor.device_version));
    241                 if (rc != EOK) {
    242                         return rc;
    243                 }
    244                
    245                 /* Next, without release number. */
    246                 rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
    247                     (int) device_descriptor.vendor_id,
    248                     (int) device_descriptor.product_id);
    249                 if (rc != EOK) {
    250                         return rc;
    251                 }
    252 
    253         }       
    254 
    255         /*
    256          * If the device class points to interface we skip adding
    257          * class directly.
    258          */
    259         if (device_descriptor.device_class != USB_CLASS_USE_INTERFACE) {
    260                 rc = usb_add_match_id(matches, 50, "usb&class=%s",
    261                     usb_str_class(device_descriptor.device_class));
    262                 if (rc != EOK) {
    263                         return rc;
    264                 }
    265         }
     309       
     310        rc = usb_drv_create_match_ids_from_device_descriptor(matches,
     311            &device_descriptor);
     312        if (rc != EOK) {
     313                return rc;
     314        }
     315       
    266316        /*
    267317         * Go through all configurations and add matches
  • uspace/lib/usb/src/usbdrvreq.c

    rb2a6fcfe rf401312  
    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,
     
    73206}
    74207
     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 */
     221int 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
    75250/** Retrieve device descriptor of connected USB device.
    76251 *
    77252 * @param[in] phone Open phone to HC driver.
    78  * @param[in] address Device USB address.
     253 * @param[in] address Device address.
    79254 * @param[out] descriptor Storage for the device descriptor.
    80255 * @return Error code.
     
    87262                return EBADMEM;
    88263        }
    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. */
     264       
    107265        size_t actually_transferred = 0;
    108266        usb_standard_device_descriptor_t descriptor_tmp;
    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);
     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);
    114273
    115274        if (rc != EOK) {
     
    137296 *
    138297 * @param[in] phone Open phone to HC driver.
    139  * @param[in] address Device USB address.
     298 * @param[in] address Device address.
    140299 * @param[in] index Configuration descriptor index.
    141300 * @param[out] descriptor Storage for the configuration descriptor.
     
    150309                return EBADMEM;
    151310        }
    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. */
     311       
    170312        size_t actually_transferred = 0;
    171313        usb_standard_configuration_descriptor_t descriptor_tmp;
    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);
     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);
    177320
    178321        if (rc != EOK) {
     
    195338 *
    196339 * @warning The @p buffer might be touched (i.e. its contents changed)
    197  * even when error occurres.
     340 * even when error occurs.
    198341 *
    199342 * @param[in] phone Open phone to HC driver.
    200  * @param[in] address Device USB address.
     343 * @param[in] address Device address.
    201344 * @param[in] index Configuration descriptor index.
    202345 * @param[out] buffer Buffer for the whole configuration descriptor.
     
    210353    void *buffer, size_t buffer_size, size_t *actual_buffer_size)
    211354{
    212         if (buffer == NULL) {
     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);
     361
     362        return rc;
     363}
     364
     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) {
    213408                return EBADMEM;
    214409        }
    215410
    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);
    236 
    237         return rc;
    238 }
    239 
     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}
    240520
    241521/**
Note: See TracChangeset for help on using the changeset viewer.