Changes in / [4fa05a32:0fd82c9] in mainline
- Location:
- uspace
- Files:
-
- 2 added
- 5 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usbinfo/Makefile
r4fa05a32 r0fd82c9 34 34 35 35 SOURCES = \ 36 desctree.c \37 dev.c \38 36 dump.c \ 39 37 info.c \ -
uspace/app/usbinfo/dump.c
r4fa05a32 r0fd82c9 101 101 } 102 102 103 void dump_match_ids(match_id_list_t *matches , const char *line_prefix)103 void dump_match_ids(match_id_list_t *matches) 104 104 { 105 printf("Match ids:\n"); 105 106 link_t *link; 106 107 for (link = matches->ids.next; … … 109 110 match_id_t *match = list_get_instance(link, match_id_t, link); 110 111 111 printf( "%s%d %s\n", line_prefix, match->score, match->id);112 printf(INDENT "%d %s\n", match->score, match->id); 112 113 } 113 114 } -
uspace/app/usbinfo/info.c
r4fa05a32 r0fd82c9 40 40 #include <usb/recognise.h> 41 41 #include <usb/request.h> 42 #include <usb/classes/classes.h>43 42 #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 & 0x8093 ? 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 }155 43 156 44 int dump_device(devman_handle_t hc_handle, usb_address_t address) … … 204 92 goto leave; 205 93 } 206 dump_match_ids(&match_id_list , get_indent(0));94 dump_match_ids(&match_id_list); 207 95 208 96 /* … … 218 106 } 219 107 dump_usb_descriptor((uint8_t *)&device_descriptor, sizeof(device_descriptor)); 220 221 rc = EOK;222 goto leave;223 108 224 109 /* -
uspace/app/usbinfo/main.c
r4fa05a32 r0fd82c9 43 43 #include <devman.h> 44 44 #include <devmap.h> 45 #include <usb/usbdevice.h>46 #include <usb/pipes.h>47 45 #include "usbinfo.h" 48 46 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) 47 enum { 48 ACTION_HELP = 256, 49 ACTION_DEVICE_ADDRESS, 50 ACTION_HOST_CONTROLLER, 51 ACTION_DEVICE, 52 }; 53 54 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}, 59 {0, 0, NULL, 0} 60 }; 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) 51 80 { 52 81 int rc; 53 82 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"; 57 85 } 58 86 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 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; 62 106 } 63 107 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; 119 110 } 120 111 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 _OPTION142 #undef _INDENT143 }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";153 112 154 113 int main(int argc, char *argv[]) 155 114 { 115 devman_handle_t hc_handle = (devman_handle_t) -1; 116 usb_address_t device_address = (usb_address_t) -1; 117 156 118 if (argc <= 1) { 157 119 print_usage(argv[0]); … … 159 121 } 160 122 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; 170 124 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) { 174 127 case -1: 175 128 break; 129 176 130 case '?': 177 131 print_usage(argv[0]); 178 return 1; 132 return -1; 133 179 134 case 'h': 135 case ACTION_HELP: 180 136 print_usage(argv[0]); 181 137 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 } 184 146 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 } 187 156 break; 188 case 't': 189 action_print_descriptor_tree = true; 157 } 158 159 case 'd': 160 case ACTION_DEVICE: 190 161 break; 162 191 163 default: 192 assert(false && "unreachable code");193 164 break; 194 165 } 195 } while (opt > 0);196 166 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; 202 173 } 203 174 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); 245 176 246 177 return 0; -
uspace/app/usbinfo/usbinfo.h
r4fa05a32 r0fd82c9 38 38 #include <usb/usb.h> 39 39 #include <usb/descriptor.h> 40 #include <usb/pipes.h>41 40 #include <usb/debug.h> 42 #include <usb/dp.h>43 41 #include <ipc/devman.h> 44 42 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;52 43 53 44 #define NAME "usbinfo" … … 55 46 void dump_buffer(const char *, size_t, const uint8_t *, size_t); 56 47 const char *get_indent(size_t); 57 void dump_match_ids(match_id_list_t * , const char *);48 void dump_match_ids(match_id_list_t *matches); 58 49 void dump_usb_descriptor(uint8_t *, size_t); 59 50 int dump_device(devman_handle_t, usb_address_t); … … 65 56 } 66 57 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 80 58 #endif 81 59 /** -
uspace/lib/usb/include/usb/dp.h
r4fa05a32 r0fd82c9 77 77 usb_dp_parser_data_t *, uint8_t *, uint8_t *); 78 78 79 void usb_dp_walk_simple(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,80 void (*)(uint8_t *, size_t, void *), void *);81 82 79 #endif 83 80 /** -
uspace/lib/usb/include/usb/pipes.h
r4fa05a32 r0fd82c9 123 123 124 124 int usb_device_get_assigned_interface(ddf_dev_t *); 125 usb_address_t usb_device_get_assigned_address(devman_handle_t);126 125 127 126 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *, -
uspace/lib/usb/src/dp.c
r4fa05a32 r0fd82c9 258 258 } 259 259 260 /** Browser of the descriptor tree.261 *262 * @see usb_dp_walk_simple263 *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 start291 * of the descriptor (somewhere inside @p descriptors), depth of the nesting292 * (starting from 0 for the first descriptor) and the custom argument.293 * Note that the size of the descriptor is not passed because it can294 * 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 = NULL315 };316 317 usb_dp_parser_t parser = {318 .nesting = descriptor_nesting319 };320 321 usb_dp_browse_simple_internal(&parser, &data, descriptors,322 0, callback, arg);323 }324 260 325 261 /** @} -
uspace/lib/usb/src/pipes.c
r4fa05a32 r0fd82c9 52 52 sysarg_t address; 53 53 54 54 55 /* 55 56 * We are sending special value as a handle - zero - to get … … 93 94 94 95 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;123 96 } 124 97
Note:
See TracChangeset
for help on using the changeset viewer.