usbtest.c 5.6 KB

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