Changeset a97ea0f in mainline


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

Location:
uspace
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/Makefile

    ra523af4 ra97ea0f  
    3535SOURCES = \
    3636        dump.c \
     37        info.c \
    3738        main.c
    3839
  • uspace/app/usbinfo/main.c

    ra523af4 ra97ea0f  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2010-2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    4040#include <str_error.h>
    4141#include <bool.h>
     42#include <getopt.h>
    4243#include <devman.h>
     44#include <devmap.h>
    4345#include <usb/usbdrv.h>
    4446#include "usbinfo.h"
    4547
    46 #define DEFAULT_HOST_CONTROLLER_PATH "/virt/usbhc"
     48enum {
     49        ACTION_HELP = 256,
     50        ACTION_DEVICE_ADDRESS,
     51        ACTION_HOST_CONTROLLER,
     52        ACTION_DEVICE,
     53};
     54
     55static struct option long_options[] = {
     56        {"help", no_argument, NULL, ACTION_HELP},
     57        {"address", required_argument, NULL, ACTION_DEVICE_ADDRESS},
     58        {"host-controller", required_argument, NULL, ACTION_HOST_CONTROLLER},
     59        {"device", required_argument, NULL, ACTION_DEVICE},
     60        {0, 0, NULL, 0}
     61};
     62static const char *short_options = "ha:t:d:";
    4763
    4864static void print_usage(char *app_name)
    4965{
     66#define INDENT "      "
    5067        printf(NAME ": query USB devices for descriptors\n\n");
    51         printf("Usage: %s /path/to/hc usb-address\n where\n", app_name);
    52         printf("   /path/to/hc   Devman path to USB host controller " \
    53             "(use `-' for\n");
    54         printf("                   default HC at `%s').\n",
    55             DEFAULT_HOST_CONTROLLER_PATH);
    56         printf("   usb-address   USB address of device to be queried\n");
     68        printf("Usage: %s [options]\n", app_name);
     69        printf(" -h --help\n" INDENT \
     70            "Display this help.\n");
     71        printf(" -tID --host-controller ID\n" INDENT \
     72            "Set host controller (ID can be path or class number)\n");
     73        printf(" -aADDR --address ADDR\n" INDENT \
     74            "Set device address\n");
    5775        printf("\n");
    58 }
    59 
    60 static int connect_to_hc(const char *path)
     76#undef INDENT
     77}
     78
     79static int set_new_host_controller(int *phone, const char *path)
    6180{
    6281        int rc;
    63         devman_handle_t handle;
    64 
    65         rc = devman_device_get_handle(path, &handle, 0);
    66         if (rc != EOK) {
    67                 return rc;
    68         }
    69 
    70         int phone = devman_device_connect(handle, 0);
    71 
    72         return phone;
    73 }
    74 
    75 int main(int argc, char *argv[])
    76 {
    77         if (argc != 3) {
    78                 print_usage(argv[0]);
    79                 return EINVAL;
    80         }
    81 
    82         char *hc_path = argv[1];
    83         long int address_long = strtol(argv[2], NULL, 0);
    84 
    85         /*
    86          * Connect to given host controller driver.
    87          */
    88         if (str_cmp(hc_path, "-") == 0) {
    89                 hc_path = (char *) DEFAULT_HOST_CONTROLLER_PATH;
    90         }
    91         int hc_phone = connect_to_hc(hc_path);
    92         if (hc_phone < 0) {
    93                 fprintf(stderr,
    94                     NAME ": unable to connect to HC at `%s': %s.\n",
    95                     hc_path, str_error(hc_phone));
    96                 return hc_phone;
    97         }
    98 
    99         /*
    100          * Verify address is okay.
    101          */
    102         usb_address_t address = (usb_address_t) address_long;
     82        int tmp_phone;
     83
     84        if (path[0] != '/') {
     85                int hc_class_index = (int) strtol(path, NULL, 10);
     86                char *dev_path;
     87                rc = asprintf(&dev_path, "class/usbhc\\%d", hc_class_index);
     88                if (rc < 0) {
     89                        internal_error(rc);
     90                        return rc;
     91                }
     92                devmap_handle_t handle;
     93                rc = devmap_device_get_handle(dev_path, &handle, 0);
     94                if (rc < 0) {
     95                        fprintf(stderr,
     96                            NAME ": failed getting handle of `devman://%s'.\n",
     97                            dev_path);
     98                        free(dev_path);
     99                        return rc;
     100                }
     101                tmp_phone = devmap_device_connect(handle, 0);
     102                if (tmp_phone < 0) {
     103                        fprintf(stderr,
     104                            NAME ": could not connect to `%s'.\n",
     105                            dev_path);
     106                        free(dev_path);
     107                        return tmp_phone;
     108                }
     109                free(dev_path);
     110        } else {
     111                devman_handle_t handle;
     112                rc = devman_device_get_handle(path, &handle, 0);
     113                if (rc != EOK) {
     114                        fprintf(stderr,
     115                            NAME ": failed getting handle of `devmap::/%s'.\n",
     116                            path);
     117                        return rc;
     118                }
     119                tmp_phone = devman_device_connect(handle, 0);
     120                if (tmp_phone < 0) {
     121                        fprintf(stderr,
     122                            NAME ": could not connect to `%s'.\n",
     123                            path);
     124                        return tmp_phone;
     125                }
     126        }
     127
     128        *phone = tmp_phone;
     129
     130        return EOK;
     131}
     132
     133static int connect_with_address(int hc_phone, const char *str_address)
     134{
     135        usb_address_t address = (usb_address_t) strtol(str_address, NULL, 0);
    103136        if ((address < 0) || (address >= USB11_ADDRESS_MAX)) {
    104137                fprintf(stderr, NAME ": USB address out of range.\n");
     
    106139        }
    107140
    108         /*
    109          * Now, learn information about the device.
    110          */
    111         int rc;
    112 
    113         /*
    114          * Dump information about possible match ids.
    115          */
    116         match_id_list_t match_id_list;
    117         init_match_ids(&match_id_list);
    118         rc = usb_drv_create_device_match_ids(hc_phone, &match_id_list, address);
    119         if (rc != EOK) {
    120                 fprintf(stderr,
    121                     NAME ": failed to fetch match ids of the device: %s.\n",
    122                     str_error(rc));
    123                 return rc;
    124         }
    125         dump_match_ids(&match_id_list);
    126 
    127         /*
    128          * Get device descriptor and dump it.
    129          */
    130         usb_standard_device_descriptor_t device_descriptor;
    131         usb_dprintf(NAME, 1,
    132             "usb_drv_req_get_device_descriptor(%d, %d, %p)\n",
    133             hc_phone, (int) address, &device_descriptor);
    134 
    135         rc = usb_drv_req_get_device_descriptor(hc_phone, address,
    136             &device_descriptor);
    137         if (rc != EOK) {
    138                 fprintf(stderr,
    139                     NAME ": failed to fetch standard device descriptor: %s.\n",
    140                     str_error(rc));
    141                 return rc;
    142         }
    143         dump_standard_device_descriptor(&device_descriptor);
    144 
    145         /*
    146          * Get first configuration descriptor and dump it.
    147          */
    148         usb_standard_configuration_descriptor_t config_descriptor;
    149         int config_index = 0;
    150         usb_dprintf(NAME, 1,
    151             "usb_drv_req_get_bare_configuration_descriptor(%d, %d, %d, %p)\n",
    152             hc_phone, (int) address, config_index, &config_descriptor);
    153 
    154         rc = usb_drv_req_get_bare_configuration_descriptor(hc_phone, address,
    155             config_index, &config_descriptor );
    156         if (rc != EOK) {
    157                 fprintf(stderr,
    158                     NAME ": failed to fetch standard configuration descriptor: %s.\n",
    159                     str_error(rc));
    160                 return rc;
    161         }
    162         dump_standard_configuration_descriptor(config_index,
    163             &config_descriptor);
    164 
    165         void *full_config_descriptor = malloc(config_descriptor.total_length);
    166         usb_dprintf(NAME, 1,
    167             "usb_drv_req_get_full_configuration_descriptor(%d, %d, %d, %p, %zu)\n",
    168             hc_phone, (int) address, config_index,
    169             full_config_descriptor, config_descriptor.total_length);
    170 
    171         rc = usb_drv_req_get_full_configuration_descriptor(hc_phone, address,
    172             config_index,
    173             full_config_descriptor, config_descriptor.total_length, NULL);
    174         if (rc != EOK) {
    175                 fprintf(stderr,
    176                     NAME ": failed to fetch full configuration descriptor: %s.\n",
    177                     str_error(rc));
    178                 return rc;
    179         }
    180         dump_buffer("Full configuration descriptor:",
    181             full_config_descriptor, config_descriptor.total_length);
    182 
    183         return EOK;
     141        if (hc_phone < 0) {
     142                fprintf(stderr, NAME ": no active host controller.\n");
     143                return ENOENT;
     144        }
     145
     146        return dump_device(hc_phone, address);
     147}
     148
     149
     150int main(int argc, char *argv[])
     151{
     152        int hc_phone = -1;
     153
     154        if (argc <= 1) {
     155                print_usage(argv[0]);
     156                return -1;
     157        }
     158
     159        int i;
     160        do {
     161                i = getopt_long(argc, argv, short_options, long_options, NULL);
     162                switch (i) {
     163                        case -1:
     164                                break;
     165
     166                        case '?':
     167                                print_usage(argv[0]);
     168                                return -1;
     169
     170                        case 'h':
     171                        case ACTION_HELP:
     172                                print_usage(argv[0]);
     173                                return 0;
     174
     175                        case 'a':
     176                        case ACTION_DEVICE_ADDRESS: {
     177                                int rc = connect_with_address(hc_phone, optarg);
     178                                if (rc != EOK) {
     179                                        return rc;
     180                                }
     181                                break;
     182                        }
     183
     184                        case 't':
     185                        case ACTION_HOST_CONTROLLER: {
     186                                int rc = set_new_host_controller(&hc_phone,
     187                                    optarg);
     188                                if (rc != EOK) {
     189                                        return rc;
     190                                }
     191                                break;
     192                        }
     193
     194                        case 'd':
     195                        case ACTION_DEVICE:
     196                                break;
     197
     198                        default:
     199                                break;
     200                }
     201
     202        } while (i != -1);
     203
     204        return 0;
    184205}
    185206
  • uspace/app/usbinfo/usbinfo.h

    ra523af4 ra97ea0f  
    4949void dump_standard_configuration_descriptor(int,
    5050    usb_standard_configuration_descriptor_t *);
     51int dump_device(int, usb_address_t);
     52
     53static inline void internal_error(int err)
     54{
     55        fprintf(stderr, NAME ": internal error (%s).\n", str_error(err));
     56}
    5157
    5258#endif
  • uspace/drv/usbkbd/main.c

    ra523af4 ra97ea0f  
    7878}
    7979
     80#if 0
    8081static void send_key(int key, int type, wchar_t c) {
    8182        async_msg_4(console_callback_phone, KBD_EVENT, type, key,
    8283            KM_NUM_LOCK, c);
    8384}
    84 
    85 static void send_alnum(int key, wchar_t c) {
    86         printf(NAME ": sending key '%lc' to console\n", (wint_t) c);
    87         send_key(key, KEY_PRESS, c);
    88         send_key(key, KEY_RELEASE, c);
    89 }
     85#endif
    9086
    9187/*
     
    231227                sizeof(usb_hid_report_in_callbacks_t));
    232228        callbacks->keyboard = usbkbd_process_keycodes;
    233 
    234         if (console_callback_phone != -1) {
    235                 static size_t counter = 0;
    236                 counter++;
    237                 if (counter > 3) {
    238                         counter = 0;
    239                         send_alnum(KC_A, L'a');
    240                 }
    241         }
    242229
    243230        usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
  • uspace/drv/vhc/hcd.c

    ra523af4 ra97ea0f  
    8686        dev->ops = &vhc_ops;
    8787
     88        devman_add_device_to_class(dev->handle, "usbhc");
     89
    8890        /*
    8991         * Initialize our hub and announce its presence.
  • uspace/lib/usb/include/usb/devreq.h

    ra523af4 ra97ea0f  
    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 int usb_drv_req_get_descriptor(int, usb_address_t, usb_request_type_t,
    95     uint8_t, uint8_t, uint16_t, void *, size_t, size_t *);
    96 
     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);
    97109
    98110#endif
  • uspace/lib/usb/include/usb/usb.h

    ra523af4 ra97ea0f  
    6161        USB_REQUEST_TYPE_VENDOR = 2
    6262} 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;
    6370
    6471/** USB transaction outcome. */
  • 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.