usb.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* usb.c - Generic USB interfaces. */
  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/dl.h>
  20. #include <grub/mm.h>
  21. #include <grub/usb.h>
  22. #include <grub/misc.h>
  23. #include <grub/list.h>
  24. #include <grub/term.h>
  25. GRUB_MOD_LICENSE ("GPLv3+");
  26. static struct grub_usb_attach_desc *attach_hooks;
  27. #if 0
  28. /* Context for grub_usb_controller_iterate. */
  29. struct grub_usb_controller_iterate_ctx
  30. {
  31. grub_usb_controller_iterate_hook_t hook;
  32. void *hook_data;
  33. grub_usb_controller_dev_t p;
  34. };
  35. /* Helper for grub_usb_controller_iterate. */
  36. static int
  37. grub_usb_controller_iterate_iter (grub_usb_controller_t dev, void *data)
  38. {
  39. struct grub_usb_controller_iterate_ctx *ctx = data;
  40. dev->dev = ctx->p;
  41. if (ctx->hook (dev, ctx->hook_data))
  42. return 1;
  43. return 0;
  44. }
  45. int
  46. grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook,
  47. void *hook_data)
  48. {
  49. struct grub_usb_controller_iterate_ctx ctx = {
  50. .hook = hook,
  51. .hook_data = hook_data
  52. };
  53. /* Iterate over all controller drivers. */
  54. for (ctx.p = grub_usb_list; ctx.p; ctx.p = ctx.p->next)
  55. {
  56. /* Iterate over the busses of the controllers. XXX: Actually, a
  57. hub driver should do this. */
  58. if (ctx.p->iterate (grub_usb_controller_iterate_iter, &ctx))
  59. return 1;
  60. }
  61. return 0;
  62. }
  63. #endif
  64. grub_usb_err_t
  65. grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
  66. {
  67. dev->toggle[endpoint] = 0;
  68. return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
  69. | GRUB_USB_REQTYPE_STANDARD
  70. | GRUB_USB_REQTYPE_TARGET_ENDP),
  71. GRUB_USB_REQ_CLEAR_FEATURE,
  72. GRUB_USB_FEATURE_ENDP_HALT,
  73. endpoint, 0, 0);
  74. }
  75. grub_usb_err_t
  76. grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
  77. {
  78. grub_memset (dev->toggle, 0, sizeof (dev->toggle));
  79. return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
  80. | GRUB_USB_REQTYPE_STANDARD
  81. | GRUB_USB_REQTYPE_TARGET_DEV),
  82. GRUB_USB_REQ_SET_CONFIGURATION, configuration,
  83. 0, 0, NULL);
  84. }
  85. grub_usb_err_t
  86. grub_usb_get_descriptor (grub_usb_device_t dev,
  87. grub_uint8_t type, grub_uint8_t index,
  88. grub_size_t size, char *data)
  89. {
  90. return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
  91. | GRUB_USB_REQTYPE_STANDARD
  92. | GRUB_USB_REQTYPE_TARGET_DEV),
  93. GRUB_USB_REQ_GET_DESCRIPTOR,
  94. (type << 8) | index,
  95. 0, size, data);
  96. }
  97. grub_usb_err_t
  98. grub_usb_device_initialize (grub_usb_device_t dev)
  99. {
  100. struct grub_usb_desc_device *descdev;
  101. struct grub_usb_desc_config config;
  102. grub_usb_err_t err;
  103. int i;
  104. /* First we have to read first 8 bytes only and determine
  105. * max. size of packet */
  106. dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */
  107. err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
  108. 0, 8, (char *) &dev->descdev);
  109. if (err)
  110. return err;
  111. /* Now we have valid value in dev->descdev.maxsize0,
  112. * so we can read whole device descriptor */
  113. err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
  114. 0, sizeof (struct grub_usb_desc_device),
  115. (char *) &dev->descdev);
  116. if (err)
  117. return err;
  118. descdev = &dev->descdev;
  119. for (i = 0; i < 8; i++)
  120. dev->config[i].descconf = NULL;
  121. if (descdev->configcnt == 0)
  122. {
  123. err = GRUB_USB_ERR_BADDEVICE;
  124. goto fail;
  125. }
  126. for (i = 0; i < descdev->configcnt; i++)
  127. {
  128. int pos;
  129. int currif;
  130. char *data;
  131. struct grub_usb_desc *desc;
  132. /* First just read the first 4 bytes of the configuration
  133. descriptor, after that it is known how many bytes really have
  134. to be read. */
  135. err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4,
  136. (char *) &config);
  137. data = grub_malloc (config.totallen);
  138. if (! data)
  139. {
  140. err = GRUB_USB_ERR_INTERNAL;
  141. goto fail;
  142. }
  143. dev->config[i].descconf = (struct grub_usb_desc_config *) data;
  144. err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i,
  145. config.totallen, data);
  146. if (err)
  147. goto fail;
  148. /* Skip the configuration descriptor. */
  149. pos = dev->config[i].descconf->length;
  150. /* Read all interfaces. */
  151. for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
  152. {
  153. while (pos < config.totallen)
  154. {
  155. desc = (struct grub_usb_desc *)&data[pos];
  156. if (desc->type == GRUB_USB_DESCRIPTOR_INTERFACE)
  157. break;
  158. if (!desc->length)
  159. {
  160. err = GRUB_USB_ERR_BADDEVICE;
  161. goto fail;
  162. }
  163. pos += desc->length;
  164. }
  165. dev->config[i].interf[currif].descif
  166. = (struct grub_usb_desc_if *) &data[pos];
  167. pos += dev->config[i].interf[currif].descif->length;
  168. while (pos < config.totallen)
  169. {
  170. desc = (struct grub_usb_desc *)&data[pos];
  171. if (desc->type == GRUB_USB_DESCRIPTOR_ENDPOINT)
  172. break;
  173. if (!desc->length)
  174. {
  175. err = GRUB_USB_ERR_BADDEVICE;
  176. goto fail;
  177. }
  178. pos += desc->length;
  179. }
  180. /* Point to the first endpoint. */
  181. dev->config[i].interf[currif].descendp
  182. = (struct grub_usb_desc_endp *) &data[pos];
  183. pos += (sizeof (struct grub_usb_desc_endp)
  184. * dev->config[i].interf[currif].descif->endpointcnt);
  185. }
  186. }
  187. return GRUB_USB_ERR_NONE;
  188. fail:
  189. for (i = 0; i < 8; i++)
  190. grub_free (dev->config[i].descconf);
  191. return err;
  192. }
  193. void grub_usb_device_attach (grub_usb_device_t dev)
  194. {
  195. int i;
  196. /* XXX: Just check configuration 0 for now. */
  197. for (i = 0; i < dev->config[0].descconf->numif; i++)
  198. {
  199. struct grub_usb_desc_if *interf;
  200. struct grub_usb_attach_desc *desc;
  201. interf = dev->config[0].interf[i].descif;
  202. grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
  203. i, interf->class, interf->subclass, interf->protocol);
  204. if (dev->config[0].interf[i].attached)
  205. continue;
  206. for (desc = attach_hooks; desc; desc = desc->next)
  207. if (interf->class == desc->class)
  208. {
  209. grub_boot_time ("Probing USB device driver class %x", desc->class);
  210. if (desc->hook (dev, 0, i))
  211. dev->config[0].interf[i].attached = 1;
  212. grub_boot_time ("Probed USB device driver class %x", desc->class);
  213. }
  214. if (dev->config[0].interf[i].attached)
  215. continue;
  216. switch (interf->class)
  217. {
  218. case GRUB_USB_CLASS_MASS_STORAGE:
  219. grub_dl_load ("usbms");
  220. grub_print_error ();
  221. break;
  222. case GRUB_USB_CLASS_HID:
  223. grub_dl_load ("usb_keyboard");
  224. grub_print_error ();
  225. break;
  226. case 0xff:
  227. /* FIXME: don't load useless modules. */
  228. grub_dl_load ("usbserial_ftdi");
  229. grub_print_error ();
  230. grub_dl_load ("usbserial_pl2303");
  231. grub_print_error ();
  232. grub_dl_load ("usbserial_usbdebug");
  233. grub_print_error ();
  234. break;
  235. }
  236. }
  237. }
  238. /* Helper for grub_usb_register_attach_hook_class. */
  239. static int
  240. grub_usb_register_attach_hook_class_iter (grub_usb_device_t usbdev, void *data)
  241. {
  242. struct grub_usb_attach_desc *desc = data;
  243. struct grub_usb_desc_device *descdev = &usbdev->descdev;
  244. int i;
  245. if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0
  246. || descdev->configcnt == 0)
  247. return 0;
  248. /* XXX: Just check configuration 0 for now. */
  249. for (i = 0; i < usbdev->config[0].descconf->numif; i++)
  250. {
  251. struct grub_usb_desc_if *interf;
  252. interf = usbdev->config[0].interf[i].descif;
  253. grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
  254. i, interf->class, interf->subclass, interf->protocol);
  255. if (usbdev->config[0].interf[i].attached)
  256. continue;
  257. if (interf->class != desc->class)
  258. continue;
  259. if (desc->hook (usbdev, 0, i))
  260. usbdev->config[0].interf[i].attached = 1;
  261. }
  262. return 0;
  263. }
  264. void
  265. grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc)
  266. {
  267. desc->next = attach_hooks;
  268. attach_hooks = desc;
  269. grub_usb_iterate (grub_usb_register_attach_hook_class_iter, desc);
  270. }
  271. void
  272. grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc)
  273. {
  274. grub_list_remove (GRUB_AS_LIST (desc));
  275. }
  276. GRUB_MOD_INIT(usb)
  277. {
  278. grub_term_poll_usb = grub_usb_poll_devices;
  279. }
  280. GRUB_MOD_FINI(usb)
  281. {
  282. grub_term_poll_usb = NULL;
  283. }