usb.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * USB host driver for the Greybus "generic" USB module.
  3. *
  4. * Copyright 2014 Google Inc.
  5. * Copyright 2014 Linaro Ltd.
  6. *
  7. * Released under the GPLv2 only.
  8. *
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/slab.h>
  13. #include <linux/usb.h>
  14. #include <linux/usb/hcd.h>
  15. #include "greybus.h"
  16. #include "gbphy.h"
  17. /* Greybus USB request types */
  18. #define GB_USB_TYPE_HCD_START 0x02
  19. #define GB_USB_TYPE_HCD_STOP 0x03
  20. #define GB_USB_TYPE_HUB_CONTROL 0x04
  21. struct gb_usb_hub_control_request {
  22. __le16 typeReq;
  23. __le16 wValue;
  24. __le16 wIndex;
  25. __le16 wLength;
  26. };
  27. struct gb_usb_hub_control_response {
  28. u8 buf[0];
  29. };
  30. struct gb_usb_device {
  31. struct gb_connection *connection;
  32. struct gbphy_device *gbphy_dev;
  33. };
  34. static inline struct gb_usb_device *to_gb_usb_device(struct usb_hcd *hcd)
  35. {
  36. return (struct gb_usb_device *)hcd->hcd_priv;
  37. }
  38. static inline struct usb_hcd *gb_usb_device_to_hcd(struct gb_usb_device *dev)
  39. {
  40. return container_of((void *)dev, struct usb_hcd, hcd_priv);
  41. }
  42. static void hcd_stop(struct usb_hcd *hcd)
  43. {
  44. struct gb_usb_device *dev = to_gb_usb_device(hcd);
  45. int ret;
  46. ret = gb_operation_sync(dev->connection, GB_USB_TYPE_HCD_STOP,
  47. NULL, 0, NULL, 0);
  48. if (ret)
  49. dev_err(&dev->gbphy_dev->dev, "HCD stop failed '%d'\n", ret);
  50. }
  51. static int hcd_start(struct usb_hcd *hcd)
  52. {
  53. struct usb_bus *bus = hcd_to_bus(hcd);
  54. struct gb_usb_device *dev = to_gb_usb_device(hcd);
  55. int ret;
  56. ret = gb_operation_sync(dev->connection, GB_USB_TYPE_HCD_START,
  57. NULL, 0, NULL, 0);
  58. if (ret) {
  59. dev_err(&dev->gbphy_dev->dev, "HCD start failed '%d'\n", ret);
  60. return ret;
  61. }
  62. hcd->state = HC_STATE_RUNNING;
  63. if (bus->root_hub)
  64. usb_hcd_resume_root_hub(hcd);
  65. return 0;
  66. }
  67. static int urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
  68. {
  69. return -ENXIO;
  70. }
  71. static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
  72. {
  73. return -ENXIO;
  74. }
  75. static int get_frame_number(struct usb_hcd *hcd)
  76. {
  77. return 0;
  78. }
  79. static int hub_status_data(struct usb_hcd *hcd, char *buf)
  80. {
  81. return 0;
  82. }
  83. static int hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
  84. char *buf, u16 wLength)
  85. {
  86. struct gb_usb_device *dev = to_gb_usb_device(hcd);
  87. struct gb_operation *operation;
  88. struct gb_usb_hub_control_request *request;
  89. struct gb_usb_hub_control_response *response;
  90. size_t response_size;
  91. int ret;
  92. /* FIXME: handle unspecified lengths */
  93. response_size = sizeof(*response) + wLength;
  94. operation = gb_operation_create(dev->connection,
  95. GB_USB_TYPE_HUB_CONTROL,
  96. sizeof(*request),
  97. response_size,
  98. GFP_KERNEL);
  99. if (!operation)
  100. return -ENOMEM;
  101. request = operation->request->payload;
  102. request->typeReq = cpu_to_le16(typeReq);
  103. request->wValue = cpu_to_le16(wValue);
  104. request->wIndex = cpu_to_le16(wIndex);
  105. request->wLength = cpu_to_le16(wLength);
  106. ret = gb_operation_request_send_sync(operation);
  107. if (ret)
  108. goto out;
  109. if (wLength) {
  110. /* Greybus core has verified response size */
  111. response = operation->response->payload;
  112. memcpy(buf, response->buf, wLength);
  113. }
  114. out:
  115. gb_operation_put(operation);
  116. return ret;
  117. }
  118. static struct hc_driver usb_gb_hc_driver = {
  119. .description = "greybus-hcd",
  120. .product_desc = "Greybus USB Host Controller",
  121. .hcd_priv_size = sizeof(struct gb_usb_device),
  122. .flags = HCD_USB2,
  123. .start = hcd_start,
  124. .stop = hcd_stop,
  125. .urb_enqueue = urb_enqueue,
  126. .urb_dequeue = urb_dequeue,
  127. .get_frame_number = get_frame_number,
  128. .hub_status_data = hub_status_data,
  129. .hub_control = hub_control,
  130. };
  131. static int gb_usb_probe(struct gbphy_device *gbphy_dev,
  132. const struct gbphy_device_id *id)
  133. {
  134. struct gb_connection *connection;
  135. struct device *dev = &gbphy_dev->dev;
  136. struct gb_usb_device *gb_usb_dev;
  137. struct usb_hcd *hcd;
  138. int retval;
  139. hcd = usb_create_hcd(&usb_gb_hc_driver, dev, dev_name(dev));
  140. if (!hcd)
  141. return -ENOMEM;
  142. connection = gb_connection_create(gbphy_dev->bundle,
  143. le16_to_cpu(gbphy_dev->cport_desc->id),
  144. NULL);
  145. if (IS_ERR(connection)) {
  146. retval = PTR_ERR(connection);
  147. goto exit_usb_put;
  148. }
  149. gb_usb_dev = to_gb_usb_device(hcd);
  150. gb_usb_dev->connection = connection;
  151. gb_connection_set_data(connection, gb_usb_dev);
  152. gb_usb_dev->gbphy_dev = gbphy_dev;
  153. gb_gbphy_set_data(gbphy_dev, gb_usb_dev);
  154. hcd->has_tt = 1;
  155. retval = gb_connection_enable(connection);
  156. if (retval)
  157. goto exit_connection_destroy;
  158. /*
  159. * FIXME: The USB bridged-PHY protocol driver depends on changes to
  160. * USB core which are not yet upstream.
  161. *
  162. * Disable for now.
  163. */
  164. if (1) {
  165. dev_warn(dev, "USB protocol disabled\n");
  166. retval = -EPROTONOSUPPORT;
  167. goto exit_connection_disable;
  168. }
  169. retval = usb_add_hcd(hcd, 0, 0);
  170. if (retval)
  171. goto exit_connection_disable;
  172. return 0;
  173. exit_connection_disable:
  174. gb_connection_disable(connection);
  175. exit_connection_destroy:
  176. gb_connection_destroy(connection);
  177. exit_usb_put:
  178. usb_put_hcd(hcd);
  179. return retval;
  180. }
  181. static void gb_usb_remove(struct gbphy_device *gbphy_dev)
  182. {
  183. struct gb_usb_device *gb_usb_dev = gb_gbphy_get_data(gbphy_dev);
  184. struct gb_connection *connection = gb_usb_dev->connection;
  185. struct usb_hcd *hcd = gb_usb_device_to_hcd(gb_usb_dev);
  186. usb_remove_hcd(hcd);
  187. gb_connection_disable(connection);
  188. gb_connection_destroy(connection);
  189. usb_put_hcd(hcd);
  190. }
  191. static const struct gbphy_device_id gb_usb_id_table[] = {
  192. { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_USB) },
  193. { },
  194. };
  195. MODULE_DEVICE_TABLE(gbphy, gb_usb_id_table);
  196. static struct gbphy_driver usb_driver = {
  197. .name = "usb",
  198. .probe = gb_usb_probe,
  199. .remove = gb_usb_remove,
  200. .id_table = gb_usb_id_table,
  201. };
  202. module_gbphy_driver(usb_driver);
  203. MODULE_LICENSE("GPL v2");