Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/main.c

    ra458bc9 r6dd35e0  
    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         _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 }
    145 
    146 static struct option long_options[] = {
    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'},
    152         {0, 0, NULL, 0}
    153 };
    154 static const char *short_options = "himts";
    155 
    156 static 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 };
    181112
    182113int main(int argc, char *argv[])
    183114{
     115        devman_handle_t hc_handle = (devman_handle_t) -1;
     116        usb_address_t device_address = (usb_address_t) -1;
     117
    184118        if (argc <= 1) {
    185119                print_usage(argv[0]);
     
    187121        }
    188122
    189         /*
    190          * Process command-line options. They determine what shall be
    191          * done with the device.
    192          */
    193         int opt;
     123        int i;
    194124        do {
    195                 opt = getopt_long(argc, argv,
    196                     short_options, long_options, NULL);
    197                 switch (opt) {
     125                i = getopt_long(argc, argv, short_options, long_options, NULL);
     126                switch (i) {
    198127                        case -1:
    199128                                break;
     129
    200130                        case '?':
    201131                                print_usage(argv[0]);
    202                                 return 1;
     132                                return -1;
     133
    203134                        case 'h':
     135                        case ACTION_HELP:
    204136                                print_usage(argv[0]);
    205137                                return 0;
    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++;
     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;
    214145                                }
    215146                                break;
    216147                        }
     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;
    217165                }
    218         } while (opt > 0);
    219166
    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;
     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;
    232173        }
    233174
    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         }
     175        dump_device(hc_handle, device_address);
    273176
    274177        return 0;
Note: See TracChangeset for help on using the changeset viewer.