Changeset 1614ce3 in mainline


Ignore:
Timestamp:
2011-03-18T09:14:22Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b64eac6
Parents:
0fd82c9 (diff), b8e2f93 (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:

Improvements of usbinfo application

Refactored the code, filtering output via command line switches, easier
extensibility.

Location:
uspace
Files:
3 added
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/Makefile

    r0fd82c9 r1614ce3  
    3434
    3535SOURCES = \
     36        desctree.c \
     37        dev.c \
    3638        dump.c \
    3739        info.c \
  • uspace/app/usbinfo/dump.c

    r0fd82c9 r1614ce3  
    101101}
    102102
    103 void dump_match_ids(match_id_list_t *matches)
     103void dump_match_ids(match_id_list_t *matches, const char *line_prefix)
    104104{
    105         printf("Match ids:\n");
    106105        link_t *link;
    107106        for (link = matches->ids.next;
     
    110109                match_id_t *match = list_get_instance(link, match_id_t, link);
    111110
    112                 printf(INDENT "%d %s\n", match->score, match->id);
     111                printf("%s%3d %s\n", line_prefix, match->score, match->id);
    113112        }
    114113}
  • uspace/app/usbinfo/info.c

    r0fd82c9 r1614ce3  
    4040#include <usb/recognise.h>
    4141#include <usb/request.h>
     42#include <usb/classes/classes.h>
     43#include <usb/classes/hid.h>
    4244#include "usbinfo.h"
    4345
    44 int dump_device(devman_handle_t hc_handle, usb_address_t address)
    45 {
    46         int rc;
    47         usb_device_connection_t wire;
    48         usb_endpoint_pipe_t ctrl_pipe;
    49 
    50         /*
    51          * Initialize pipes.
    52          */
    53         rc = usb_device_connection_initialize(&wire, hc_handle, address);
    54         if (rc != EOK) {
    55                 fprintf(stderr,
    56                     NAME ": failed to create connection to the device: %s.\n",
    57                     str_error(rc));
    58                 goto leave;
    59         }
    60         rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe, &wire);
    61         if (rc != EOK) {
    62                 fprintf(stderr,
    63                     NAME ": failed to create default control pipe: %s.\n",
    64                     str_error(rc));
    65                 goto leave;
    66         }
    67         rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe);
    68         if (rc != EOK) {
    69                 fprintf(stderr,
    70                     NAME ": probing default control pipe failed: %s.\n",
    71                     str_error(rc));
    72                 goto leave;
    73         }
    74         rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
    75         if (rc != EOK) {
    76                 fprintf(stderr,
    77                     NAME ": failed to start session on control pipe: %s.\n",
    78                     str_error(rc));
    79                 goto leave;
    80         }
    81 
    82         /*
    83          * Dump information about possible match ids.
    84          */
    85         match_id_list_t match_id_list;
    86         init_match_ids(&match_id_list);
    87         rc = usb_device_create_match_ids(&ctrl_pipe, &match_id_list);
    88         if (rc != EOK) {
    89                 fprintf(stderr,
    90                     NAME ": failed to fetch match ids of the device: %s.\n",
    91                     str_error(rc));
    92                 goto leave;
    93         }
    94         dump_match_ids(&match_id_list);
    95 
    96         /*
    97          * Get device descriptor and dump it.
    98          */
    99         usb_standard_device_descriptor_t device_descriptor;
    100         rc = usb_request_get_device_descriptor(&ctrl_pipe, &device_descriptor);
    101         if (rc != EOK) {
    102                 fprintf(stderr,
    103                     NAME ": failed to fetch standard device descriptor: %s.\n",
    104                     str_error(rc));
    105                 goto leave;
    106         }
    107         dump_usb_descriptor((uint8_t *)&device_descriptor, sizeof(device_descriptor));
    108 
    109         /*
    110          * Get first configuration descriptor and dump it.
    111          */
    112         usb_standard_configuration_descriptor_t config_descriptor;
    113         int config_index = 0;
    114         rc = usb_request_get_bare_configuration_descriptor(&ctrl_pipe,
    115             config_index, &config_descriptor);
    116         if (rc != EOK) {
    117                 fprintf(stderr,
    118                     NAME ": failed to fetch standard configuration descriptor: %s.\n",
    119                     str_error(rc));
    120                 goto leave;
    121         }
    122         //dump_standard_configuration_descriptor(config_index, &config_descriptor);
    123 
    124         void *full_config_descriptor = malloc(config_descriptor.total_length);
    125         rc = usb_request_get_full_configuration_descriptor(&ctrl_pipe,
    126             config_index,
    127             full_config_descriptor, config_descriptor.total_length, NULL);
    128         if (rc != EOK) {
    129                 fprintf(stderr,
    130                     NAME ": failed to fetch full configuration descriptor: %s.\n",
    131                     str_error(rc));
    132                 goto leave;
    133         }
    134 
    135         dump_descriptor_tree(full_config_descriptor,
    136             config_descriptor.total_length);
    137 
    138         /*
    139          * Get supported languages of STRING descriptors.
    140          */
     46void dump_short_device_identification(usbinfo_device_t *dev)
     47{
     48        printf("%sDevice 0x%04x by vendor 0x%04x\n", get_indent(0),
     49            (int) dev->device_descriptor.product_id,
     50            (int) dev->device_descriptor.vendor_id);
     51}
     52
     53static void dump_match_ids_from_interface(uint8_t *descriptor, size_t depth,
     54    void *arg)
     55{
     56        if (depth != 1) {
     57                return;
     58        }
     59        size_t descr_size = descriptor[0];
     60        if (descr_size < sizeof(usb_standard_interface_descriptor_t)) {
     61                return;
     62        }
     63        int descr_type = descriptor[1];
     64        if (descr_type != USB_DESCTYPE_INTERFACE) {
     65                return;
     66        }
     67
     68        usbinfo_device_t *dev = (usbinfo_device_t *) arg;
     69
     70        usb_standard_interface_descriptor_t *iface
     71            = (usb_standard_interface_descriptor_t *) descriptor;
     72
     73        printf("%sInterface #%d match ids (%s, 0x%02x, 0x%02x)\n",
     74            get_indent(0),
     75            (int) iface->interface_number,
     76            usb_str_class(iface->interface_class),
     77            (int) iface->interface_subclass,
     78            (int) iface->interface_protocol);
     79
     80        match_id_list_t matches;
     81        init_match_ids(&matches);
     82        usb_device_create_match_ids_from_interface(&dev->device_descriptor,
     83            iface, &matches);
     84        dump_match_ids(&matches, get_indent(1));
     85        clean_match_ids(&matches);
     86}
     87
     88void dump_device_match_ids(usbinfo_device_t *dev)
     89{
     90        match_id_list_t matches;
     91        init_match_ids(&matches);
     92        usb_device_create_match_ids_from_device_descriptor(
     93            &dev->device_descriptor, &matches);
     94        printf("%sDevice match ids (0x%04x by 0x%04x, %s)\n", get_indent(0),
     95            (int) dev->device_descriptor.product_id,
     96            (int) dev->device_descriptor.vendor_id,
     97            usb_str_class(dev->device_descriptor.device_class));
     98        dump_match_ids(&matches, get_indent(1));
     99        clean_match_ids(&matches);
     100
     101        usb_dp_walk_simple(dev->full_configuration_descriptor,
     102            dev->full_configuration_descriptor_size,
     103            usb_dp_standard_descriptor_nesting,
     104            dump_match_ids_from_interface,
     105            dev);
     106}
     107
     108static void dump_descriptor_tree_brief_device(const char *prefix,
     109    usb_standard_device_descriptor_t *descriptor)
     110{
     111        printf("%sDevice (0x%04x by 0x%04x, %s)\n", prefix,
     112            (int) descriptor->product_id,
     113            (int) descriptor->vendor_id,
     114            usb_str_class(descriptor->device_class));
     115}
     116
     117static void dump_descriptor_tree_brief_configuration(const char *prefix,
     118    usb_standard_configuration_descriptor_t *descriptor)
     119{
     120        printf("%sConfiguration #%d\n", prefix,
     121            (int) descriptor->configuration_number);
     122}
     123
     124static void dump_descriptor_tree_brief_interface(const char *prefix,
     125    usb_standard_interface_descriptor_t *descriptor)
     126{
     127        printf("%sInterface #%d (%s, 0x%02x, 0x%02x)\n", prefix,
     128            (int) descriptor->interface_number,
     129            usb_str_class(descriptor->interface_class),
     130            (int) descriptor->interface_subclass,
     131            (int) descriptor->interface_protocol);
     132}
     133
     134static void dump_descriptor_tree_brief_endpoint(const char *prefix,
     135    usb_standard_endpoint_descriptor_t *descriptor)
     136{
     137        usb_endpoint_t endpoint_no = descriptor->endpoint_address & 0xF;
     138        usb_transfer_type_t transfer = descriptor->attributes & 0x3;
     139        usb_direction_t direction = descriptor->endpoint_address & 0x80
     140            ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
     141        printf("%sEndpoint #%d (%s %s, %zu)\n", prefix,
     142            endpoint_no, usb_str_transfer_type(transfer),
     143            direction == USB_DIRECTION_IN ? "in" : "out",
     144            (size_t) descriptor->max_packet_size);
     145}
     146
     147static void dump_descriptor_tree_brief_hid(const char *prefix,
     148    usb_standard_hid_descriptor_t *descriptor)
     149{
     150        printf("%sHID (country %d, %d descriptors)\n", prefix,
     151            (int) descriptor->country_code,
     152            (int) descriptor->class_desc_count);
     153}
     154
     155
     156static void dump_descriptor_tree_brief_callback(uint8_t *descriptor,
     157    size_t depth, void *arg)
     158{
     159        const char *indent = get_indent(depth + 1);
     160
     161        int descr_type = -1;
     162        size_t descr_size = descriptor[0];
     163        if (descr_size > 0) {
     164                descr_type = descriptor[1];
     165        }
     166
     167        switch (descr_type) {
     168
     169#define _BRANCH(type_enum, descriptor_type, callback) \
     170        case type_enum: \
     171                if (descr_size >= sizeof(descriptor_type)) { \
     172                        callback(indent, (descriptor_type *) descriptor); \
     173                } else { \
     174                        descr_type = -1; \
     175                } \
     176                break;
     177
     178                _BRANCH(USB_DESCTYPE_DEVICE,
     179                    usb_standard_device_descriptor_t,
     180                    dump_descriptor_tree_brief_device);
     181                _BRANCH(USB_DESCTYPE_CONFIGURATION,
     182                    usb_standard_configuration_descriptor_t,
     183                    dump_descriptor_tree_brief_configuration);
     184                _BRANCH(USB_DESCTYPE_INTERFACE,
     185                    usb_standard_interface_descriptor_t,
     186                    dump_descriptor_tree_brief_interface);
     187                _BRANCH(USB_DESCTYPE_ENDPOINT,
     188                    usb_standard_endpoint_descriptor_t,
     189                    dump_descriptor_tree_brief_endpoint);
     190                _BRANCH(USB_DESCTYPE_HID,
     191                    usb_standard_hid_descriptor_t,
     192                    dump_descriptor_tree_brief_hid);
     193
     194                default:
     195                        break;
     196        }
     197
     198        if (descr_type == -1) {
     199                printf("%sInvalid descriptor.\n", indent);
     200        }
     201}
     202
     203void dump_descriptor_tree_brief(usbinfo_device_t *dev)
     204{
     205        dump_descriptor_tree_brief_callback((uint8_t *)&dev->device_descriptor,
     206            (size_t) -1, NULL);
     207        usb_dp_walk_simple(dev->full_configuration_descriptor,
     208            dev->full_configuration_descriptor_size,
     209            usb_dp_standard_descriptor_nesting,
     210            dump_descriptor_tree_brief_callback,
     211            NULL);
     212}
     213
     214void dump_strings(usbinfo_device_t *dev)
     215{
     216        /* Get supported languages. */
    141217        l18_win_locales_t *langs;
    142218        size_t langs_count;
    143         rc = usb_request_get_supported_languages(&ctrl_pipe,
     219        int rc = usb_request_get_supported_languages(&dev->ctrl_pipe,
    144220            &langs, &langs_count);
    145221        if (rc != EOK) {
     
    147223                    NAME ": failed to get list of supported languages: %s.\n",
    148224                    str_error(rc));
    149                 goto skip_strings;
    150         }
    151 
    152         printf("String languages (%zu):", langs_count);
     225                return;
     226        }
     227
     228        printf("%sString languages (%zu):", get_indent(0), langs_count);
    153229        size_t i;
    154230        for (i = 0; i < langs_count; i++) {
     
    157233        printf(".\n");
    158234
    159         /*
    160          * Dump all strings in all available langages;
    161          */
     235        /* Get all strings and dump them. */
    162236        for (i = 0; i < langs_count; i++) {
    163237                l18_win_locales_t lang = langs[i];
    164238
    165                 printf("%sStrings for language 0x%04x:\n", get_indent(0),
    166                     (int) lang);
    167 
     239                printf("%sStrings in %s:\n", get_indent(0),
     240                    str_l18_win_locale(lang));
    168241                /*
    169                  * Try all indexes - we will see what pops-up ;-).
    170                  * However, to speed things up, we will stop after
    171                  * encountering several broken (or nonexistent ones)
    172                  * descriptors in line.
     242                 * Try only the first 15 strings
     243                 * (typically, device will not have much more anyway).
    173244                 */
    174245                size_t idx;
    175                 size_t failed_count = 0;
    176                 for (idx = 1; idx < 0xFF; idx++) {
     246                for (idx = 1; idx < 0x0F; idx++) {
    177247                        char *string;
    178                         rc = usb_request_get_string(&ctrl_pipe, idx, lang,
     248                        rc = usb_request_get_string(&dev->ctrl_pipe, idx, lang,
    179249                            &string);
    180250                        if (rc != EOK) {
    181                                 failed_count++;
    182                                 if (failed_count > 3) {
    183                                         break;
    184                                 }
    185251                                continue;
    186252                        }
     
    188254                            idx, string);
    189255                        free(string);
    190                         failed_count = 0; /* Reset failed counter. */
    191256                }
    192257        }
    193 
    194 
    195 skip_strings:
    196 
    197         rc = EOK;
    198 
    199 leave:
    200         /* Ignoring errors here. */
    201         usb_endpoint_pipe_end_session(&ctrl_pipe);
    202 
    203         return rc;
    204258}
    205259
  • uspace/app/usbinfo/main.c

    r0fd82c9 r1614ce3  
    4343#include <devman.h>
    4444#include <devmap.h>
     45#include <usb/usbdevice.h>
     46#include <usb/pipes.h>
    4547#include "usbinfo.h"
    4648
    47 enum {
    48         ACTION_HELP = 256,
    49         ACTION_DEVICE_ADDRESS,
    50         ACTION_HOST_CONTROLLER,
    51         ACTION_DEVICE,
    52 };
     49static bool resolve_hc_handle_and_dev_addr(const char *devpath,
     50    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
     51{
     52        int rc;
     53
     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";
     57        }
     58
     59        char *path = str_dup(devpath);
     60        if (path == NULL) {
     61                return ENOMEM;
     62        }
     63
     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        }
     119}
     120
     121static 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        _OPTION("-s --strings", "Try to print all string descriptors.");
     137
     138        printf("\n");
     139        printf("If no option is specified, `-i' is considered default.\n");
     140        printf("\n");
     141
     142#undef _OPTION
     143#undef _INDENT
     144}
    53145
    54146static 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},
     147        {"help", no_argument, NULL, 'h'},
     148        {"identification", no_argument, NULL, 'i'},
     149        {"match-ids", no_argument, NULL, 'm'},
     150        {"descriptor-tree", no_argument, NULL, 't'},
     151        {"strings", no_argument, NULL, 's'},
    59152        {0, 0, NULL, 0}
    60153};
    61 static const char *short_options = "ha:t:d:";
    62 
    63 static 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 
    78 static int get_host_controller_handle(const char *path,
    79     devman_handle_t *hc_handle)
    80 {
    81         int rc;
    82 
    83         if (str_cmp(path, "uhci") == 0) {
    84                 path = "/hw/pci0/00:01.2/uhci-hc";
    85         }
    86 
    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 
    100 static 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;
    106         }
    107 
    108         *address = addr;
    109         return EOK;
    110 }
    111 
     154static const char *short_options = "himts";
     155
     156static usbinfo_action_t actions[] = {
     157        {
     158                .opt = 'i',
     159                .action = dump_short_device_identification,
     160                .active = false
     161        },
     162        {
     163                .opt = 'm',
     164                .action = dump_device_match_ids,
     165                .active = false
     166        },
     167        {
     168                .opt = 't',
     169                .action = dump_descriptor_tree_brief,
     170                .active = false
     171        },
     172        {
     173                .opt = 's',
     174                .action = dump_strings,
     175                .active = false
     176        },
     177        {
     178                .opt = 0
     179        }
     180};
    112181
    113182int main(int argc, char *argv[])
    114183{
    115         devman_handle_t hc_handle = (devman_handle_t) -1;
    116         usb_address_t device_address = (usb_address_t) -1;
    117 
    118184        if (argc <= 1) {
    119185                print_usage(argv[0]);
     
    121187        }
    122188
    123         int i;
     189        /*
     190         * Process command-line options. They determine what shall be
     191         * done with the device.
     192         */
     193        int opt;
    124194        do {
    125                 i = getopt_long(argc, argv, short_options, long_options, NULL);
    126                 switch (i) {
     195                opt = getopt_long(argc, argv,
     196                    short_options, long_options, NULL);
     197                switch (opt) {
    127198                        case -1:
    128199                                break;
    129 
    130200                        case '?':
    131201                                print_usage(argv[0]);
    132                                 return -1;
    133 
     202                                return 1;
    134203                        case 'h':
    135                         case ACTION_HELP:
    136204                                print_usage(argv[0]);
    137205                                return 0;
    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;
     206                        default: {
     207                                int idx = 0;
     208                                while (actions[idx].opt != 0) {
     209                                        if (actions[idx].opt == opt) {
     210                                                actions[idx].active = true;
     211                                                break;
     212                                        }
     213                                        idx++;
    145214                                }
    146215                                break;
    147216                        }
    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                                 }
    156                                 break;
    157                         }
    158 
    159                         case 'd':
    160                         case ACTION_DEVICE:
    161                                 break;
    162 
    163                         default:
    164                                 break;
    165                 }
    166 
    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;
    173         }
    174 
    175         dump_device(hc_handle, device_address);
     217                }
     218        } while (opt > 0);
     219
     220        /* Set the default action. */
     221        int idx = 0;
     222        bool something_active = false;
     223        while (actions[idx].opt != 0) {
     224                if (actions[idx].active) {
     225                        something_active = true;
     226                        break;
     227                }
     228                idx++;
     229        }
     230        if (!something_active) {
     231                actions[0].active = true;
     232        }
     233
     234        /*
     235         * Go through all devices given on the command line and run the
     236         * specified actions.
     237         */
     238        int i;
     239        for (i = optind; i < argc; i++) {
     240                char *devpath = argv[i];
     241
     242                /* The initialization is here only to make compiler happy. */
     243                devman_handle_t hc_handle = 0;
     244                usb_address_t dev_addr = 0;
     245                bool found = resolve_hc_handle_and_dev_addr(devpath,
     246                    &hc_handle, &dev_addr);
     247                if (!found) {
     248                        fprintf(stderr, NAME ": device `%s' not found "
     249                            "or not of USB kind, skipping.\n",
     250                            devpath);
     251                        continue;
     252                }
     253
     254                usbinfo_device_t *dev = prepare_device(hc_handle, dev_addr);
     255                if (dev == NULL) {
     256                        continue;
     257                }
     258
     259                /* Run actions the user specified. */
     260                printf("%s\n", devpath);
     261
     262                int action = 0;
     263                while (actions[action].opt != 0) {
     264                        if (actions[action].active) {
     265                                actions[action].action(dev);
     266                        }
     267                        action++;
     268                }
     269
     270                /* Destroy the control pipe (close the session etc.). */
     271                destroy_device(dev);
     272        }
    176273
    177274        return 0;
  • uspace/app/usbinfo/usbinfo.h

    r0fd82c9 r1614ce3  
    3838#include <usb/usb.h>
    3939#include <usb/descriptor.h>
     40#include <usb/pipes.h>
    4041#include <usb/debug.h>
     42#include <usb/dp.h>
    4143#include <ipc/devman.h>
     44
     45typedef 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;
     52
     53typedef struct {
     54        int opt;
     55        void (*action)(usbinfo_device_t *dev);
     56        bool active;
     57} usbinfo_action_t;
    4258
    4359
     
    4662void dump_buffer(const char *, size_t, const uint8_t *, size_t);
    4763const char *get_indent(size_t);
    48 void dump_match_ids(match_id_list_t *matches);
     64void dump_match_ids(match_id_list_t *, const char *);
    4965void dump_usb_descriptor(uint8_t *, size_t);
    50 int dump_device(devman_handle_t, usb_address_t);
    5166void dump_descriptor_tree(uint8_t *, size_t);
    5267
     
    5671}
    5772
     73usbinfo_device_t *prepare_device(devman_handle_t, usb_address_t);
     74void destroy_device(usbinfo_device_t *);
     75
     76typedef void (*dump_descriptor_in_tree_t)(uint8_t *, size_t, void *);
     77void browse_descriptor_tree(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,
     78    dump_descriptor_in_tree_t, size_t, void *);
     79
     80
     81void dump_short_device_identification(usbinfo_device_t *);
     82void dump_device_match_ids(usbinfo_device_t *);
     83void dump_descriptor_tree_brief(usbinfo_device_t *);
     84void dump_strings(usbinfo_device_t *);
     85
     86
    5887#endif
    5988/**
  • uspace/lib/c/Makefile

    r0fd82c9 r1614ce3  
    6565        generic/str.c \
    6666        generic/str_error.c \
     67        generic/l18n/langs.c \
    6768        generic/fibril.c \
    6869        generic/fibril_synch.c \
  • uspace/lib/c/include/l18n/langs.h

    r0fd82c9 r1614ce3  
    5757} l18_win_locales_t;
    5858
     59const char *str_l18_win_locale(l18_win_locales_t);
     60
    5961#endif
    6062
  • uspace/lib/usb/include/usb/dp.h

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

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

    r0fd82c9 r1614ce3  
    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 */
     271static 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 */
     302void 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}
    260324
    261325/** @}
  • uspace/lib/usb/src/pipes.c

    r0fd82c9 r1614ce3  
    5252        sysarg_t address;
    5353
    54 
    5554        /*
    5655         * We are sending special value as a handle - zero - to get
     
    9493
    9594        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 */
     102usb_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;
    96123}
    97124
Note: See TracChangeset for help on using the changeset viewer.