]>
Commit | Line | Data |
---|---|---|
d64399b5 | 1 | /* usbtest.c - test module for USB */ |
2 | /* | |
3 | * GRUB -- GRand Unified Bootloader | |
4 | * Copyright (C) 2008 Free Software Foundation, Inc. | |
5 | * | |
6 | * GRUB is free software: you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation, either version 3 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * GRUB is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |
18 | */ | |
19 | ||
20 | #include <grub/types.h> | |
21 | #include <grub/misc.h> | |
1d3c6f1d | 22 | #include <grub/charset.h> |
d64399b5 | 23 | #include <grub/mm.h> |
24 | #include <grub/err.h> | |
25 | #include <grub/dl.h> | |
d64399b5 | 26 | #include <grub/usb.h> |
b1b797cb | 27 | #include <grub/command.h> |
77a79592 | 28 | #include <grub/i18n.h> |
d64399b5 | 29 | |
30 | static const char *usb_classes[] = | |
31 | { | |
32 | "", | |
33 | "Audio", | |
34 | "Communication Interface", | |
35 | "HID", | |
36 | "", | |
37 | "Physical", | |
38 | "Image", | |
39 | "Printer", | |
40 | "Mass Storage", | |
41 | "Hub", | |
42 | "Data Interface", | |
43 | "Smart Card", | |
44 | "Content Security", | |
45 | "Video" | |
46 | }; | |
47 | ||
48 | static const char *usb_endp_type[] = | |
49 | { | |
50 | "Control", | |
51 | "Isochronous", | |
52 | "Bulk", | |
53 | "Interrupt" | |
54 | }; | |
55 | ||
b39f9d20 | 56 | static const char *usb_devspeed[] = |
d64399b5 | 57 | { |
58 | "", | |
59 | "Low", | |
60 | "Full", | |
61 | "High" | |
62 | }; | |
63 | ||
1d3c6f1d VS |
64 | static grub_usb_err_t |
65 | grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, | |
66 | char **string) | |
67 | { | |
68 | struct grub_usb_desc_str descstr; | |
69 | struct grub_usb_desc_str *descstrp; | |
70 | grub_usb_err_t err; | |
71 | ||
72 | /* Only get the length. */ | |
73 | err = grub_usb_control_msg (dev, 1 << 7, | |
74 | 0x06, (3 << 8) | index, | |
75 | langid, 1, (char *) &descstr); | |
76 | if (err) | |
77 | return err; | |
78 | ||
79 | descstrp = grub_malloc (descstr.length); | |
80 | if (! descstrp) | |
81 | return GRUB_USB_ERR_INTERNAL; | |
82 | err = grub_usb_control_msg (dev, 1 << 7, | |
83 | 0x06, (3 << 8) | index, | |
84 | langid, descstr.length, (char *) descstrp); | |
85 | ||
db4d5813 VS |
86 | if (descstrp->length == 0) |
87 | { | |
88 | grub_free (descstrp); | |
89 | *string = grub_strdup (""); | |
90 | if (! *string) | |
91 | return GRUB_USB_ERR_INTERNAL; | |
92 | return GRUB_USB_ERR_NONE; | |
93 | } | |
94 | ||
95 | *string = grub_malloc (descstr.length * 2 + 1); | |
1d3c6f1d VS |
96 | if (! *string) |
97 | { | |
98 | grub_free (descstrp); | |
99 | return GRUB_USB_ERR_INTERNAL; | |
100 | } | |
101 | ||
db4d5813 VS |
102 | *grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, |
103 | descstrp->length / 2 - 1) = 0; | |
1d3c6f1d VS |
104 | grub_free (descstrp); |
105 | ||
106 | return GRUB_USB_ERR_NONE; | |
107 | } | |
108 | ||
d64399b5 | 109 | static void |
110 | usb_print_str (const char *description, grub_usb_device_t dev, int idx) | |
111 | { | |
112 | char *name; | |
1d3c6f1d | 113 | grub_usb_err_t err; |
d64399b5 | 114 | /* XXX: LANGID */ |
115 | ||
116 | if (! idx) | |
117 | return; | |
118 | ||
1d3c6f1d VS |
119 | err = grub_usb_get_string (dev, idx, 0x0409, &name); |
120 | if (err) | |
121 | grub_printf ("Error %d retrieving %s\n", err, description); | |
122 | else | |
123 | { | |
124 | grub_printf ("%s: `%s'\n", description, name); | |
125 | grub_free (name); | |
126 | } | |
d64399b5 | 127 | } |
128 | ||
129 | static int | |
130 | usb_iterate (grub_usb_device_t dev) | |
131 | { | |
132 | struct grub_usb_desc_device *descdev; | |
133 | int i; | |
134 | ||
135 | descdev = &dev->descdev; | |
136 | ||
137 | usb_print_str ("Product", dev, descdev->strprod); | |
138 | usb_print_str ("Vendor", dev, descdev->strvendor); | |
139 | usb_print_str ("Serial", dev, descdev->strserial); | |
b39f9d20 | 140 | |
d64399b5 | 141 | if (descdev->class > 0 && descdev->class <= 0x0E) |
142 | grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n", | |
143 | descdev->class, usb_classes[descdev->class], | |
144 | descdev->subclass, descdev->protocol); | |
145 | grub_printf ("USB version %d.%d, VendorID: 0x%02x, ProductID: 0x%02x, #conf: %d\n", | |
146 | descdev->usbrel >> 8, (descdev->usbrel >> 4) & 0x0F, | |
147 | descdev->vendorid, descdev->prodid, descdev->configcnt); | |
148 | ||
149 | grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); | |
150 | ||
151 | for (i = 0; i < descdev->configcnt; i++) | |
152 | { | |
153 | struct grub_usb_desc_config *config; | |
154 | ||
155 | config = dev->config[i].descconf; | |
156 | usb_print_str ("Configuration:", dev, config->strconfig); | |
157 | } | |
158 | ||
159 | for (i = 0; i < dev->config[0].descconf->numif; i++) | |
160 | { | |
161 | int j; | |
162 | struct grub_usb_desc_if *interf; | |
163 | interf = dev->config[0].interf[i].descif; | |
164 | ||
165 | grub_printf ("Interface #%d: #Endpoints: %d ", | |
166 | i, interf->endpointcnt); | |
167 | if (interf->class > 0 && interf->class <= 0x0E) | |
168 | grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n", | |
169 | interf->class, usb_classes[interf->class], | |
170 | interf->subclass, interf->protocol); | |
171 | ||
172 | usb_print_str ("Interface", dev, interf->strif); | |
173 | ||
174 | for (j = 0; j < interf->endpointcnt; j++) | |
175 | { | |
176 | struct grub_usb_desc_endp *endp; | |
177 | endp = &dev->config[0].interf[i].descendp[j]; | |
178 | ||
179 | grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n", | |
180 | endp->endp_addr & 15, | |
181 | (endp->endp_addr & 128) ? "IN" : "OUT", | |
182 | endp->maxpacket, usb_endp_type[endp->attrib & 3], | |
183 | endp->interval); | |
184 | } | |
185 | } | |
186 | ||
187 | grub_printf("\n"); | |
188 | ||
189 | return 0; | |
190 | } | |
191 | ||
192 | static grub_err_t | |
b1b797cb | 193 | grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)), |
d64399b5 | 194 | int argc __attribute__ ((unused)), |
195 | char **args __attribute__ ((unused))) | |
196 | { | |
197 | grub_printf ("USB devices:\n\n"); | |
198 | grub_usb_iterate (usb_iterate); | |
199 | ||
200 | return 0; | |
201 | } | |
202 | ||
b1b797cb | 203 | static grub_command_t cmd; |
204 | ||
d64399b5 | 205 | GRUB_MOD_INIT(usbtest) |
206 | { | |
b1b797cb | 207 | cmd = grub_register_command ("usb", grub_cmd_usbtest, |
77a79592 | 208 | 0, N_("Test USB support.")); |
d64399b5 | 209 | } |
210 | ||
211 | GRUB_MOD_FINI(usbtest) | |
212 | { | |
b1b797cb | 213 | grub_unregister_command (cmd); |
d64399b5 | 214 | } |