You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. #include <string.h>
  25. #include <errno.h>
  26. #include <ipxe/usb.h>
  27. #include <ipxe/usbhid.h>
  28. /** @file
  29. *
  30. * USB human interface devices (HID)
  31. *
  32. */
  33. /**
  34. * Open USB human interface device
  35. *
  36. * @v hid USB human interface device
  37. * @ret rc Return status code
  38. */
  39. int usbhid_open ( struct usb_hid *hid ) {
  40. int rc;
  41. /* Open interrupt IN endpoint */
  42. if ( ( rc = usb_endpoint_open ( &hid->in ) ) != 0 ) {
  43. DBGC ( hid, "HID %s could not open interrupt IN: %s\n",
  44. hid->func->name, strerror ( rc ) );
  45. goto err_open_in;
  46. }
  47. /* Refill interrupt IN endpoint */
  48. if ( ( rc = usb_refill ( &hid->in ) ) != 0 ) {
  49. DBGC ( hid, "HID %s could not refill interrupt IN: %s\n",
  50. hid->func->name, strerror ( rc ) );
  51. goto err_refill_in;
  52. }
  53. /* Open interrupt OUT endpoint, if applicable */
  54. if ( hid->out.usb &&
  55. ( ( rc = usb_endpoint_open ( &hid->out ) ) != 0 ) ) {
  56. DBGC ( hid, "HID %s could not open interrupt OUT: %s\n",
  57. hid->func->name, strerror ( rc ) );
  58. goto err_open_out;
  59. }
  60. return 0;
  61. usb_endpoint_close ( &hid->out );
  62. err_open_out:
  63. err_refill_in:
  64. usb_endpoint_close ( &hid->in );
  65. err_open_in:
  66. return rc;
  67. }
  68. /**
  69. * Close USB human interface device
  70. *
  71. * @v hid USB human interface device
  72. */
  73. void usbhid_close ( struct usb_hid *hid ) {
  74. /* Close interrupt OUT endpoint, if applicable */
  75. if ( hid->out.usb )
  76. usb_endpoint_close ( &hid->out );
  77. /* Close interrupt IN endpoint */
  78. usb_endpoint_close ( &hid->in );
  79. }
  80. /**
  81. * Refill USB human interface device endpoints
  82. *
  83. * @v hid USB human interface device
  84. * @ret rc Return status code
  85. */
  86. int usbhid_refill ( struct usb_hid *hid ) {
  87. int rc;
  88. /* Refill interrupt IN endpoint */
  89. if ( ( rc = usb_refill ( &hid->in ) ) != 0 )
  90. return rc;
  91. /* Refill interrupt OUT endpoint, if applicable */
  92. if ( hid->out.usb && ( ( rc = usb_refill ( &hid->out ) ) != 0 ) )
  93. return rc;
  94. return 0;
  95. }
  96. /**
  97. * Describe USB human interface device
  98. *
  99. * @v hid USB human interface device
  100. * @v config Configuration descriptor
  101. * @ret rc Return status code
  102. */
  103. int usbhid_describe ( struct usb_hid *hid,
  104. struct usb_configuration_descriptor *config ) {
  105. struct usb_interface_descriptor *desc;
  106. int rc;
  107. /* Locate interface descriptor */
  108. desc = usb_interface_descriptor ( config, hid->func->interface[0], 0 );
  109. if ( ! desc ) {
  110. DBGC ( hid, "HID %s has no interface descriptor\n",
  111. hid->func->name );
  112. return -EINVAL;
  113. }
  114. /* Describe interrupt IN endpoint */
  115. if ( ( rc = usb_endpoint_described ( &hid->in, config, desc,
  116. USB_INTERRUPT_IN, 0 ) ) != 0 ) {
  117. DBGC ( hid, "HID %s could not describe interrupt IN: %s\n",
  118. hid->func->name, strerror ( rc ) );
  119. return rc;
  120. }
  121. /* Describe interrupt OUT endpoint, if applicable */
  122. if ( hid->out.usb &&
  123. ( ( rc = usb_endpoint_described ( &hid->out, config, desc,
  124. USB_INTERRUPT_OUT, 0 ) ) != 0 )){
  125. DBGC ( hid, "HID %s could not describe interrupt OUT: %s\n",
  126. hid->func->name, strerror ( rc ) );
  127. return rc;
  128. }
  129. return 0;
  130. }