Changes in / [4fa05a32:0fd82c9] in mainline


Ignore:
Location:
uspace
Files:
2 added
5 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/Makefile

    r4fa05a32 r0fd82c9  
    3434
    3535SOURCES = \
    36         desctree.c \
    37         dev.c \
    3836        dump.c \
    3937        info.c \
  • uspace/app/usbinfo/dump.c

    r4fa05a32 r0fd82c9  
    101101}
    102102
    103 void dump_match_ids(match_id_list_t *matches, const char *line_prefix)
     103void dump_match_ids(match_id_list_t *matches)
    104104{
     105        printf("Match ids:\n");
    105106        link_t *link;
    106107        for (link = matches->ids.next;
     
    109110                match_id_t *match = list_get_instance(link, match_id_t, link);
    110111
    111                 printf("%s%d %s\n", line_prefix, match->score, match->id);
     112                printf(INDENT "%d %s\n", match->score, match->id);
    112113        }
    113114}
  • uspace/app/usbinfo/info.c

    r4fa05a32 r0fd82c9  
    4040#include <usb/recognise.h>
    4141#include <usb/request.h>
    42 #include <usb/classes/classes.h>
    4342#include "usbinfo.h"
    44 
    45 void dump_short_device_identification(usbinfo_device_t *dev)
    46 {
    47         printf("%sDevice 0x%04x by vendor 0x%04x\n", get_indent(0),
    48             (int) dev->device_descriptor.product_id,
    49             (int) dev->device_descriptor.vendor_id);
    50 }
    51 
    52 void dump_device_match_ids(usbinfo_device_t *dev)
    53 {
    54         match_id_list_t matches;
    55         init_match_ids(&matches);
    56         usb_device_create_match_ids_from_device_descriptor(
    57             &dev->device_descriptor, &matches);
    58         dump_match_ids(&matches, get_indent(0));
    59 }
    60 
    61 static void dump_descriptor_tree_brief_device(const char *prefix,
    62     usb_standard_device_descriptor_t *descriptor)
    63 {
    64         printf("%sDevice (0x%04x by 0x%04x, %s)\n", prefix,
    65             (int) descriptor->product_id,
    66             (int) descriptor->vendor_id,
    67             usb_str_class(descriptor->device_class));
    68 }
    69 
    70 static void dump_descriptor_tree_brief_configuration(const char *prefix,
    71     usb_standard_configuration_descriptor_t *descriptor)
    72 {
    73         printf("%sConfiguration #%d\n", prefix,
    74             (int) descriptor->configuration_number);
    75 }
    76 
    77 static void dump_descriptor_tree_brief_interface(const char *prefix,
    78     usb_standard_interface_descriptor_t *descriptor)
    79 {
    80         printf("%sInterface #%d (%s, 0x%02x, 0x%02x)\n", prefix,
    81             (int) descriptor->interface_number,
    82             usb_str_class(descriptor->interface_class),
    83             (int) descriptor->interface_subclass,
    84             (int) descriptor->interface_protocol);
    85 }
    86 
    87 static void dump_descriptor_tree_brief_endpoint(const char *prefix,
    88     usb_standard_endpoint_descriptor_t *descriptor)
    89 {
    90         usb_endpoint_t endpoint_no = descriptor->endpoint_address & 0xF;
    91         usb_transfer_type_t transfer = descriptor->attributes & 0x3;
    92         usb_direction_t direction = descriptor->endpoint_address & 0x80
    93             ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
    94         printf("%sEndpoint #%d (%s %s, %zu)\n", prefix,
    95             endpoint_no, usb_str_transfer_type(transfer),
    96             direction == USB_DIRECTION_IN ? "in" : "out",
    97             (size_t) descriptor->max_packet_size);
    98 }
    99 
    100 
    101 static void dump_descriptor_tree_brief_callback(uint8_t *descriptor,
    102     size_t depth, void *arg)
    103 {
    104         const char *indent = get_indent(depth + 1);
    105 
    106         int descr_type = -1;
    107         size_t descr_size = descriptor[0];
    108         if (descr_size > 0) {
    109                 descr_type = descriptor[1];
    110         }
    111 
    112         switch (descr_type) {
    113 
    114 #define _BRANCH(type_enum, descriptor_type, callback) \
    115         case type_enum: \
    116                 if (descr_size >= sizeof(descriptor_type)) { \
    117                         callback(indent, (descriptor_type *) descriptor); \
    118                 } else { \
    119                         descr_type = -1; \
    120                 } \
    121                 break;
    122 
    123                 _BRANCH(USB_DESCTYPE_DEVICE,
    124                     usb_standard_device_descriptor_t,
    125                     dump_descriptor_tree_brief_device);
    126                 _BRANCH(USB_DESCTYPE_CONFIGURATION,
    127                     usb_standard_configuration_descriptor_t,
    128                     dump_descriptor_tree_brief_configuration);
    129                 _BRANCH(USB_DESCTYPE_INTERFACE,
    130                     usb_standard_interface_descriptor_t,
    131                     dump_descriptor_tree_brief_interface);
    132                 _BRANCH(USB_DESCTYPE_ENDPOINT,
    133                     usb_standard_endpoint_descriptor_t,
    134                     dump_descriptor_tree_brief_endpoint);
    135 
    136                 default:
    137                         break;
    138         }
    139 
    140         if (descr_type == -1) {
    141                 printf("%sInvalid descriptor.\n", indent);
    142         }
    143 }
    144 
    145 void dump_descriptor_tree_brief(usbinfo_device_t *dev)
    146 {
    147         dump_descriptor_tree_brief_callback((uint8_t *)&dev->device_descriptor,
    148             (size_t) -1, NULL);
    149         usb_dp_walk_simple(dev->full_configuration_descriptor,
    150             dev->full_configuration_descriptor_size,
    151             usb_dp_standard_descriptor_nesting,
    152             dump_descriptor_tree_brief_callback,
    153             NULL);
    154 }
    15543
    15644int dump_device(devman_handle_t hc_handle, usb_address_t address)
     
    20492                goto leave;
    20593        }
    206         dump_match_ids(&match_id_list, get_indent(0));
     94        dump_match_ids(&match_id_list);
    20795
    20896        /*
     
    218106        }
    219107        dump_usb_descriptor((uint8_t *)&device_descriptor, sizeof(device_descriptor));
    220 
    221         rc = EOK;
    222         goto leave;
    223108
    224109        /*
  • uspace/app/usbinfo/main.c

    r4fa05a32 r0fd82c9  
    4343#include <devman.h>
    4444#include <devmap.h>
    45 #include <usb/usbdevice.h>
    46 #include <usb/pipes.h>
    4745#include "usbinfo.h"
    4846
    49 static bool resolve_hc_handle_and_dev_addr(const char *devpath,
    50     devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
     47enum {
     48        ACTION_HELP = 256,
     49        ACTION_DEVICE_ADDRESS,
     50        ACTION_HOST_CONTROLLER,
     51        ACTION_DEVICE,
     52};
     53
     54static struct option long_options[] = {
     55        {"help", no_argument, NULL, ACTION_HELP},
     56        {"address", required_argument, NULL, ACTION_DEVICE_ADDRESS},
     57        {"host-controller", required_argument, NULL, ACTION_HOST_CONTROLLER},
     58        {"device", required_argument, NULL, ACTION_DEVICE},
     59        {0, 0, NULL, 0}
     60};
     61static const char *short_options = "ha:t:d:";
     62
     63static void print_usage(char *app_name)
     64{
     65#define INDENT "      "
     66        printf(NAME ": query USB devices for descriptors\n\n");
     67        printf("Usage: %s [options]\n", app_name);
     68        printf(" -h --help\n" INDENT \
     69            "Display this help.\n");
     70        printf(" -tID --host-controller ID\n" INDENT \
     71            "Set host controller (ID can be path or class number)\n");
     72        printf(" -aADDR --address ADDR\n" INDENT \
     73            "Set device address\n");
     74        printf("\n");
     75#undef INDENT
     76}
     77
     78static int get_host_controller_handle(const char *path,
     79    devman_handle_t *hc_handle)
    5180{
    5281        int rc;
    5382
    54         /* Hack for QEMU to save-up on typing ;-). */
    55         if (str_cmp(devpath, "qemu") == 0) {
    56                 devpath = "/hw/pci0/00:01.2/uhci-rh/usb00_a1";
     83        if (str_cmp(path, "uhci") == 0) {
     84                path = "/hw/pci0/00:01.2/uhci-hc";
    5785        }
    5886
    59         char *path = str_dup(devpath);
    60         if (path == NULL) {
    61                 return ENOMEM;
     87        devman_handle_t handle;
     88        rc = devman_device_get_handle(path, &handle, 0);
     89        if (rc != EOK) {
     90                fprintf(stderr,
     91                    NAME ": failed getting handle of `devman::/%s'.\n",
     92                    path);
     93                return rc;
     94        }
     95        *hc_handle = handle;
     96
     97        return EOK;
     98}
     99
     100static int get_device_address(const char *str_address, usb_address_t *address)
     101{
     102        usb_address_t addr = (usb_address_t) strtol(str_address, NULL, 0);
     103        if ((addr < 0) || (addr >= USB11_ADDRESS_MAX)) {
     104                fprintf(stderr, NAME ": USB address out of range.\n");
     105                return ERANGE;
    62106        }
    63107
    64         devman_handle_t hc = 0;
    65         bool hc_found = false;
    66         usb_address_t addr = 0;
    67         bool addr_found = false;
    68 
    69         /* Remove suffixes and hope that we will encounter device node. */
    70         while (str_length(path) > 0) {
    71                 /* Get device handle first. */
    72                 devman_handle_t dev_handle;
    73                 rc = devman_device_get_handle(path, &dev_handle, 0);
    74                 if (rc != EOK) {
    75                         free(path);
    76                         return false;
    77                 }
    78 
    79                 /* Try to find its host controller. */
    80                 if (!hc_found) {
    81                         rc = usb_hc_find(dev_handle, &hc);
    82                         if (rc == EOK) {
    83                                 hc_found = true;
    84                         }
    85                 }
    86                 /* Try to get its address. */
    87                 if (!addr_found) {
    88                         addr = usb_device_get_assigned_address(dev_handle);
    89                         if (addr >= 0) {
    90                                 addr_found = true;
    91                         }
    92                 }
    93 
    94                 /* Speed-up. */
    95                 if (hc_found && addr_found) {
    96                         break;
    97                 }
    98 
    99                 /* Remove the last suffix. */
    100                 char *slash_pos = str_rchr(path, '/');
    101                 if (slash_pos != NULL) {
    102                         *slash_pos = 0;
    103                 }
    104         }
    105 
    106         free(path);
    107 
    108         if (hc_found && addr_found) {
    109                 if (out_hc_handle != NULL) {
    110                         *out_hc_handle = hc;
    111                 }
    112                 if (out_device_address != NULL) {
    113                         *out_device_address = addr;
    114                 }
    115                 return true;
    116         } else {
    117                 return false;
    118         }
     108        *address = addr;
     109        return EOK;
    119110}
    120111
    121 static void print_usage(char *app_name)
    122 {
    123 #define _INDENT "      "
    124 #define _OPTION(opt, description) \
    125         printf(_INDENT opt "\n" _INDENT _INDENT description "\n")
    126 
    127         printf(NAME ": query USB devices for descriptors\n\n");
    128         printf("Usage: %s [options] device [device [device [ ... ]]]\n",
    129             app_name);
    130         printf(_INDENT "The device is a devman path to the device.\n");
    131 
    132         _OPTION("-h --help", "Print this help and exit.");
    133         _OPTION("-i --identification", "Brief device identification.");
    134         _OPTION("-m --match-ids", "Print match ids generated for the device.");
    135         _OPTION("-t --descriptor-tree", "Print descriptor tree.");
    136 
    137         printf("\n");
    138         printf("If no option is specified, `-i' is considered default.\n");
    139         printf("\n");
    140 
    141 #undef _OPTION
    142 #undef _INDENT
    143 }
    144 
    145 static struct option long_options[] = {
    146         {"help", no_argument, NULL, 'h'},
    147         {"identification", no_argument, NULL, 'i'},
    148         {"match-ids", no_argument, NULL, 'm'},
    149         {"descriptor-tree", no_argument, NULL, 't'},
    150         {0, 0, NULL, 0}
    151 };
    152 static const char *short_options = "himt";
    153112
    154113int main(int argc, char *argv[])
    155114{
     115        devman_handle_t hc_handle = (devman_handle_t) -1;
     116        usb_address_t device_address = (usb_address_t) -1;
     117
    156118        if (argc <= 1) {
    157119                print_usage(argv[0]);
     
    159121        }
    160122
    161         bool action_print_short_identification = false;
    162         bool action_print_match_ids = false;
    163         bool action_print_descriptor_tree = false;
    164 
    165         /*
    166          * Process command-line options. They determine what shall be
    167          * done with the device.
    168          */
    169         int opt;
     123        int i;
    170124        do {
    171                 opt = getopt_long(argc, argv,
    172                     short_options, long_options, NULL);
    173                 switch (opt) {
     125                i = getopt_long(argc, argv, short_options, long_options, NULL);
     126                switch (i) {
    174127                        case -1:
    175128                                break;
     129
    176130                        case '?':
    177131                                print_usage(argv[0]);
    178                                 return 1;
     132                                return -1;
     133
    179134                        case 'h':
     135                        case ACTION_HELP:
    180136                                print_usage(argv[0]);
    181137                                return 0;
    182                         case 'i':
    183                                 action_print_short_identification = true;
     138
     139                        case 'a':
     140                        case ACTION_DEVICE_ADDRESS: {
     141                                int rc = get_device_address(optarg,
     142                                    &device_address);
     143                                if (rc != EOK) {
     144                                        return rc;
     145                                }
    184146                                break;
    185                         case 'm':
    186                                 action_print_match_ids = true;
     147                        }
     148
     149                        case 't':
     150                        case ACTION_HOST_CONTROLLER: {
     151                                int rc = get_host_controller_handle(optarg,
     152                                   &hc_handle);
     153                                if (rc != EOK) {
     154                                        return rc;
     155                                }
    187156                                break;
    188                         case 't':
    189                                 action_print_descriptor_tree = true;
     157                        }
     158
     159                        case 'd':
     160                        case ACTION_DEVICE:
    190161                                break;
     162
    191163                        default:
    192                                 assert(false && "unreachable code");
    193164                                break;
    194165                }
    195         } while (opt > 0);
    196166
    197         /* Set the default action. */
    198         if (!action_print_match_ids
    199             && !action_print_short_identification
    200             && !action_print_descriptor_tree) {
    201                 action_print_short_identification = true;
     167        } while (i != -1);
     168
     169        if ((hc_handle == (devman_handle_t) -1)
     170            || (device_address == (usb_address_t) -1)) {
     171                fprintf(stderr, NAME ": no target specified.\n");
     172                return EINVAL;
    202173        }
    203174
    204         /*
    205          * Go through all devices given on the command line and run the
    206          * specified actions.
    207          */
    208         int i;
    209         for (i = optind; i < argc; i++) {
    210                 char *devpath = argv[i];
    211 
    212                 /* The initialization is here only to make compiler happy. */
    213                 devman_handle_t hc_handle = 0;
    214                 usb_address_t dev_addr = 0;
    215                 bool found = resolve_hc_handle_and_dev_addr(devpath,
    216                     &hc_handle, &dev_addr);
    217                 if (!found) {
    218                         fprintf(stderr, NAME ": device `%s' not found "
    219                             "or not of USB kind, skipping.\n",
    220                             devpath);
    221                         continue;
    222                 }
    223 
    224                 usbinfo_device_t *dev = prepare_device(hc_handle, dev_addr);
    225                 if (dev == NULL) {
    226                         continue;
    227                 }
    228 
    229                 /* Run actions the user specified. */
    230                 printf("%s\n", devpath);
    231 
    232                 if (action_print_short_identification) {
    233                         dump_short_device_identification(dev);
    234                 }
    235                 if (action_print_match_ids) {
    236                         dump_device_match_ids(dev);
    237                 }
    238                 if (action_print_descriptor_tree) {
    239                         dump_descriptor_tree_brief(dev);
    240                 }
    241 
    242                 /* Destroy the control pipe (close the session etc.). */
    243                 destroy_device(dev);
    244         }
     175        dump_device(hc_handle, device_address);
    245176
    246177        return 0;
  • uspace/app/usbinfo/usbinfo.h

    r4fa05a32 r0fd82c9  
    3838#include <usb/usb.h>
    3939#include <usb/descriptor.h>
    40 #include <usb/pipes.h>
    4140#include <usb/debug.h>
    42 #include <usb/dp.h>
    4341#include <ipc/devman.h>
    4442
    45 typedef struct {
    46         usb_endpoint_pipe_t ctrl_pipe;
    47         usb_device_connection_t wire;
    48         usb_standard_device_descriptor_t device_descriptor;
    49         uint8_t *full_configuration_descriptor;
    50         size_t full_configuration_descriptor_size;
    51 } usbinfo_device_t;
    5243
    5344#define NAME "usbinfo"
     
    5546void dump_buffer(const char *, size_t, const uint8_t *, size_t);
    5647const char *get_indent(size_t);
    57 void dump_match_ids(match_id_list_t *, const char *);
     48void dump_match_ids(match_id_list_t *matches);
    5849void dump_usb_descriptor(uint8_t *, size_t);
    5950int dump_device(devman_handle_t, usb_address_t);
     
    6556}
    6657
    67 usbinfo_device_t *prepare_device(devman_handle_t, usb_address_t);
    68 void destroy_device(usbinfo_device_t *);
    69 
    70 typedef void (*dump_descriptor_in_tree_t)(uint8_t *, size_t, void *);
    71 void browse_descriptor_tree(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,
    72     dump_descriptor_in_tree_t, size_t, void *);
    73 
    74 
    75 void dump_short_device_identification(usbinfo_device_t *);
    76 void dump_device_match_ids(usbinfo_device_t *);
    77 void dump_descriptor_tree_brief(usbinfo_device_t *);
    78 
    79 
    8058#endif
    8159/**
  • uspace/lib/usb/include/usb/dp.h

    r4fa05a32 r0fd82c9  
    7777    usb_dp_parser_data_t *, uint8_t *, uint8_t *);
    7878
    79 void usb_dp_walk_simple(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,
    80     void (*)(uint8_t *, size_t, void *), void *);
    81 
    8279#endif
    8380/**
  • uspace/lib/usb/include/usb/pipes.h

    r4fa05a32 r0fd82c9  
    123123
    124124int usb_device_get_assigned_interface(ddf_dev_t *);
    125 usb_address_t usb_device_get_assigned_address(devman_handle_t);
    126125
    127126int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *,
  • uspace/lib/usb/src/dp.c

    r4fa05a32 r0fd82c9  
    258258}
    259259
    260 /** Browser of the descriptor tree.
    261  *
    262  * @see usb_dp_walk_simple
    263  *
    264  * @param parser Descriptor parser.
    265  * @param data Data for descriptor parser.
    266  * @param root Pointer to current root of the tree.
    267  * @param depth Current nesting depth.
    268  * @param callback Callback for each found descriptor.
    269  * @param arg Custom (user) argument.
    270  */
    271 static void usb_dp_browse_simple_internal(usb_dp_parser_t *parser,
    272     usb_dp_parser_data_t *data, uint8_t *root, size_t depth,
    273     void (*callback)(uint8_t *, size_t, void *), void *arg)
    274 {
    275         if (root == NULL) {
    276                 return;
    277         }
    278         callback(root, depth, arg);
    279         uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
    280         do {
    281                 usb_dp_browse_simple_internal(parser, data, child, depth + 1,
    282                     callback, arg);
    283                 child = usb_dp_get_sibling_descriptor(parser, data,
    284                     root, child);
    285         } while (child != NULL);
    286 }
    287 
    288 /** Browse flatten descriptor tree.
    289  *
    290  * The callback is called with following arguments: pointer to the start
    291  * of the descriptor (somewhere inside @p descriptors), depth of the nesting
    292  * (starting from 0 for the first descriptor) and the custom argument.
    293  * Note that the size of the descriptor is not passed because it can
    294  * be read from the first byte of the descriptor.
    295  *
    296  * @param descriptors Descriptor data.
    297  * @param descriptors_size Size of descriptor data (in bytes).
    298  * @param descriptor_nesting Possible descriptor nesting.
    299  * @param callback Callback for each found descriptor.
    300  * @param arg Custom (user) argument.
    301  */
    302 void usb_dp_walk_simple(uint8_t *descriptors, size_t descriptors_size,
    303     usb_dp_descriptor_nesting_t *descriptor_nesting,
    304     void (*callback)(uint8_t *, size_t, void *), void *arg)
    305 {
    306         if ((descriptors == NULL) || (descriptors_size == 0)
    307             || (descriptor_nesting == NULL) || (callback == NULL)) {
    308                 return;
    309         }
    310 
    311         usb_dp_parser_data_t data = {
    312                 .data = descriptors,
    313                 .size = descriptors_size,
    314                 .arg = NULL
    315         };
    316 
    317         usb_dp_parser_t parser = {
    318                 .nesting = descriptor_nesting
    319         };
    320 
    321         usb_dp_browse_simple_internal(&parser, &data, descriptors,
    322             0, callback, arg);
    323 }
    324260
    325261/** @}
  • uspace/lib/usb/src/pipes.c

    r4fa05a32 r0fd82c9  
    5252        sysarg_t address;
    5353
     54
    5455        /*
    5556         * We are sending special value as a handle - zero - to get
     
    9394
    9495        return (int) iface_no;
    95 }
    96 
    97 /** Tell USB address assigned to given device.
    98  *
    99  * @param dev_handle Devman handle of the USB device in question.
    100  * @return USB address or negative error code.
    101  */
    102 usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle)
    103 {
    104         int parent_phone = devman_parent_device_connect(dev_handle,
    105             IPC_FLAG_BLOCKING);
    106         if (parent_phone < 0) {
    107                 return parent_phone;
    108         }
    109 
    110         sysarg_t address;
    111 
    112         int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
    113             IPC_M_USB_GET_ADDRESS,
    114             dev_handle, &address);
    115 
    116         if (rc != EOK) {
    117                 return rc;
    118         }
    119 
    120         async_hangup(parent_phone);
    121 
    122         return (usb_address_t) address;
    12396}
    12497
Note: See TracChangeset for help on using the changeset viewer.