]> git.proxmox.com Git - grub2.git/blob - grub-core/commands/usbtest.c
Implement automatic module license checking according to new GNU
[grub2.git] / grub-core / commands / usbtest.c
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>
22 #include <grub/charset.h>
23 #include <grub/mm.h>
24 #include <grub/err.h>
25 #include <grub/dl.h>
26 #include <grub/usb.h>
27 #include <grub/command.h>
28 #include <grub/i18n.h>
29
30 GRUB_MOD_LICENSE ("GPLv3+");
31
32 static const char *usb_classes[] =
33 {
34 "Unknown",
35 "Audio",
36 "Communication Interface",
37 "HID",
38 "Unknown",
39 "Physical",
40 "Image",
41 "Printer",
42 "Mass Storage",
43 "Hub",
44 "Data Interface",
45 "Smart Card",
46 "Content Security",
47 "Video"
48 };
49
50 static const char *usb_endp_type[] =
51 {
52 "Control",
53 "Isochronous",
54 "Bulk",
55 "Interrupt"
56 };
57
58 static const char *usb_devspeed[] =
59 {
60 "",
61 "Low",
62 "Full",
63 "High"
64 };
65
66 static grub_usb_err_t
67 grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
68 char **string)
69 {
70 struct grub_usb_desc_str descstr;
71 struct grub_usb_desc_str *descstrp;
72 grub_usb_err_t err;
73
74 /* Only get the length. */
75 err = grub_usb_control_msg (dev, 1 << 7,
76 0x06, (3 << 8) | index,
77 langid, 1, (char *) &descstr);
78 if (err)
79 return err;
80
81 descstrp = grub_malloc (descstr.length);
82 if (! descstrp)
83 return GRUB_USB_ERR_INTERNAL;
84 err = grub_usb_control_msg (dev, 1 << 7,
85 0x06, (3 << 8) | index,
86 langid, descstr.length, (char *) descstrp);
87
88 if (descstrp->length == 0)
89 {
90 grub_free (descstrp);
91 *string = grub_strdup ("");
92 if (! *string)
93 return GRUB_USB_ERR_INTERNAL;
94 return GRUB_USB_ERR_NONE;
95 }
96
97 *string = grub_malloc (descstr.length * 2 + 1);
98 if (! *string)
99 {
100 grub_free (descstrp);
101 return GRUB_USB_ERR_INTERNAL;
102 }
103
104 *grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str,
105 descstrp->length / 2 - 1) = 0;
106 grub_free (descstrp);
107
108 return GRUB_USB_ERR_NONE;
109 }
110
111 static void
112 usb_print_str (const char *description, grub_usb_device_t dev, int idx)
113 {
114 char *name;
115 grub_usb_err_t err;
116 /* XXX: LANGID */
117
118 if (! idx)
119 return;
120
121 err = grub_usb_get_string (dev, idx, 0x0409, &name);
122 if (err)
123 grub_printf ("Error %d retrieving %s\n", err, description);
124 else
125 {
126 grub_printf ("%s: `%s'\n", description, name);
127 grub_free (name);
128 }
129 }
130
131 static int
132 usb_iterate (grub_usb_device_t dev)
133 {
134 struct grub_usb_desc_device *descdev;
135 int i;
136
137 descdev = &dev->descdev;
138
139 usb_print_str ("Product", dev, descdev->strprod);
140 usb_print_str ("Vendor", dev, descdev->strvendor);
141 usb_print_str ("Serial", dev, descdev->strserial);
142
143 grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
144 descdev->class, descdev->class < ARRAY_SIZE (usb_classes)
145 ? usb_classes[descdev->class] : "Unknown",
146 descdev->subclass, descdev->protocol);
147 grub_printf ("USB version %d.%d, VendorID: 0x%02x, ProductID: 0x%02x, #conf: %d\n",
148 descdev->usbrel >> 8, (descdev->usbrel >> 4) & 0x0F,
149 descdev->vendorid, descdev->prodid, descdev->configcnt);
150
151 grub_printf ("%s speed device\n", usb_devspeed[dev->speed]);
152
153 for (i = 0; i < descdev->configcnt; i++)
154 {
155 struct grub_usb_desc_config *config;
156
157 config = dev->config[i].descconf;
158 usb_print_str ("Configuration:", dev, config->strconfig);
159 }
160
161 for (i = 0; i < dev->config[0].descconf->numif; i++)
162 {
163 int j;
164 struct grub_usb_desc_if *interf;
165 interf = dev->config[0].interf[i].descif;
166
167 grub_printf ("Interface #%d: #Endpoints: %d ",
168 i, interf->endpointcnt);
169 grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
170 interf->class, interf->class < ARRAY_SIZE (usb_classes)
171 ? usb_classes[interf->class] : "Unknown",
172 interf->subclass, interf->protocol);
173
174 usb_print_str ("Interface", dev, interf->strif);
175
176 for (j = 0; j < interf->endpointcnt; j++)
177 {
178 struct grub_usb_desc_endp *endp;
179 endp = &dev->config[0].interf[i].descendp[j];
180
181 grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n",
182 endp->endp_addr & 15,
183 (endp->endp_addr & 128) ? "IN" : "OUT",
184 endp->maxpacket, usb_endp_type[endp->attrib & 3],
185 endp->interval);
186 }
187 }
188
189 grub_printf("\n");
190
191 return 0;
192 }
193
194 static grub_err_t
195 grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
196 int argc __attribute__ ((unused)),
197 char **args __attribute__ ((unused)))
198 {
199 grub_usb_poll_devices ();
200
201 grub_printf ("USB devices:\n\n");
202 grub_usb_iterate (usb_iterate);
203
204 return 0;
205 }
206
207 static grub_command_t cmd;
208
209 GRUB_MOD_INIT(usbtest)
210 {
211 cmd = grub_register_command ("usb", grub_cmd_usbtest,
212 0, N_("Test USB support."));
213 }
214
215 GRUB_MOD_FINI(usbtest)
216 {
217 grub_unregister_command (cmd);
218 }