Changeset 361e61b in mainline for uspace/app/usbinfo/main.c
- Timestamp:
- 2011-03-21T14:23:15Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 55e388a1
- Parents:
- c32688d (diff), 48fe0c9 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usbinfo/main.c
rc32688d r361e61b 43 43 #include <devman.h> 44 44 #include <devmap.h> 45 #include <usb/usbdevice.h> 46 #include <usb/pipes.h> 45 47 #include "usbinfo.h" 46 48 47 enum { 48 ACTION_HELP = 256, 49 ACTION_DEVICE_ADDRESS, 50 ACTION_HOST_CONTROLLER, 51 ACTION_DEVICE, 52 }; 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) 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 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("-T --descriptor-tree-full", "Print detailed descriptor tree"); 137 _OPTION("-s --strings", "Try to print all string descriptors."); 138 139 printf("\n"); 140 printf("If no option is specified, `-i' is considered default.\n"); 141 printf("\n"); 142 143 #undef _OPTION 144 #undef _INDENT 145 } 53 146 54 147 static 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}, 148 {"help", no_argument, NULL, 'h'}, 149 {"identification", no_argument, NULL, 'i'}, 150 {"match-ids", no_argument, NULL, 'm'}, 151 {"descriptor-tree", no_argument, NULL, 't'}, 152 {"descriptor-tree-full", no_argument, NULL, 'T'}, 153 {"strings", no_argument, NULL, 's'}, 59 154 {0, 0, NULL, 0} 60 155 }; 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"; 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 156 static const char *short_options = "himtTs"; 157 158 static usbinfo_action_t actions[] = { 159 { 160 .opt = 'i', 161 .action = dump_short_device_identification, 162 .active = false 163 }, 164 { 165 .opt = 'm', 166 .action = dump_device_match_ids, 167 .active = false 168 }, 169 { 170 .opt = 't', 171 .action = dump_descriptor_tree_brief, 172 .active = false 173 }, 174 { 175 .opt = 'T', 176 .action = dump_descriptor_tree_full, 177 .active = false 178 }, 179 { 180 .opt = 's', 181 .action = dump_strings, 182 .active = false 183 }, 184 { 185 .opt = 0 186 } 187 }; 112 188 113 189 int main(int argc, char *argv[]) 114 190 { 115 devman_handle_t hc_handle = (devman_handle_t) -1;116 usb_address_t device_address = (usb_address_t) -1;117 118 191 if (argc <= 1) { 119 192 print_usage(argv[0]); … … 121 194 } 122 195 123 int i; 196 /* 197 * Process command-line options. They determine what shall be 198 * done with the device. 199 */ 200 int opt; 124 201 do { 125 i = getopt_long(argc, argv, short_options, long_options, NULL); 126 switch (i) { 202 opt = getopt_long(argc, argv, 203 short_options, long_options, NULL); 204 switch (opt) { 127 205 case -1: 128 206 break; 129 130 207 case '?': 131 208 print_usage(argv[0]); 132 return -1; 133 209 return 1; 134 210 case 'h': 135 case ACTION_HELP:136 211 print_usage(argv[0]); 137 212 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; 213 default: { 214 int idx = 0; 215 while (actions[idx].opt != 0) { 216 if (actions[idx].opt == opt) { 217 actions[idx].active = true; 218 break; 219 } 220 idx++; 145 221 } 146 222 break; 147 223 } 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); 224 } 225 } while (opt > 0); 226 227 /* Set the default action. */ 228 int idx = 0; 229 bool something_active = false; 230 while (actions[idx].opt != 0) { 231 if (actions[idx].active) { 232 something_active = true; 233 break; 234 } 235 idx++; 236 } 237 if (!something_active) { 238 actions[0].active = true; 239 } 240 241 /* 242 * Go through all devices given on the command line and run the 243 * specified actions. 244 */ 245 int i; 246 for (i = optind; i < argc; i++) { 247 char *devpath = argv[i]; 248 249 /* The initialization is here only to make compiler happy. */ 250 devman_handle_t hc_handle = 0; 251 usb_address_t dev_addr = 0; 252 bool found = resolve_hc_handle_and_dev_addr(devpath, 253 &hc_handle, &dev_addr); 254 if (!found) { 255 fprintf(stderr, NAME ": device `%s' not found " 256 "or not of USB kind, skipping.\n", 257 devpath); 258 continue; 259 } 260 261 usbinfo_device_t *dev = prepare_device(hc_handle, dev_addr); 262 if (dev == NULL) { 263 continue; 264 } 265 266 /* Run actions the user specified. */ 267 printf("%s\n", devpath); 268 269 int action = 0; 270 while (actions[action].opt != 0) { 271 if (actions[action].active) { 272 actions[action].action(dev); 273 } 274 action++; 275 } 276 277 /* Destroy the control pipe (close the session etc.). */ 278 destroy_device(dev); 279 } 176 280 177 281 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.