f_loopback.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. * f_loopback.c - USB peripheral loopback configuration driver
  3. *
  4. * Copyright (C) 2003-2008 David Brownell
  5. * Copyright (C) 2008 by Nokia Corporation
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. /* #define VERBOSE_DEBUG */
  22. #include <linux/slab.h>
  23. #include <linux/kernel.h>
  24. #include <linux/device.h>
  25. #include "g_zero.h"
  26. #include "gadget_chips.h"
  27. /*
  28. * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals,
  29. *
  30. * This takes messages of various sizes written OUT to a device, and loops
  31. * them back so they can be read IN from it. It has been used by certain
  32. * test applications. It supports limited testing of data queueing logic.
  33. *
  34. *
  35. * This is currently packaged as a configuration driver, which can't be
  36. * combined with other functions to make composite devices. However, it
  37. * can be combined with other independent configurations.
  38. */
  39. struct f_loopback {
  40. struct usb_function function;
  41. struct usb_ep *in_ep;
  42. struct usb_ep *out_ep;
  43. };
  44. static inline struct f_loopback *func_to_loop(struct usb_function *f)
  45. {
  46. return container_of(f, struct f_loopback, function);
  47. }
  48. static unsigned qlen = 32;
  49. module_param(qlen, uint, 0);
  50. MODULE_PARM_DESC(qlenn, "depth of loopback queue");
  51. /*-------------------------------------------------------------------------*/
  52. static struct usb_interface_descriptor loopback_intf = {
  53. .bLength = sizeof loopback_intf,
  54. .bDescriptorType = USB_DT_INTERFACE,
  55. .bNumEndpoints = 2,
  56. .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
  57. /* .iInterface = DYNAMIC */
  58. };
  59. /* full speed support: */
  60. static struct usb_endpoint_descriptor fs_loop_source_desc = {
  61. .bLength = USB_DT_ENDPOINT_SIZE,
  62. .bDescriptorType = USB_DT_ENDPOINT,
  63. .bEndpointAddress = USB_DIR_IN,
  64. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  65. };
  66. static struct usb_endpoint_descriptor fs_loop_sink_desc = {
  67. .bLength = USB_DT_ENDPOINT_SIZE,
  68. .bDescriptorType = USB_DT_ENDPOINT,
  69. .bEndpointAddress = USB_DIR_OUT,
  70. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  71. };
  72. static struct usb_descriptor_header *fs_loopback_descs[] = {
  73. (struct usb_descriptor_header *) &loopback_intf,
  74. (struct usb_descriptor_header *) &fs_loop_sink_desc,
  75. (struct usb_descriptor_header *) &fs_loop_source_desc,
  76. NULL,
  77. };
  78. /* high speed support: */
  79. static struct usb_endpoint_descriptor hs_loop_source_desc = {
  80. .bLength = USB_DT_ENDPOINT_SIZE,
  81. .bDescriptorType = USB_DT_ENDPOINT,
  82. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  83. .wMaxPacketSize = cpu_to_le16(512),
  84. };
  85. static struct usb_endpoint_descriptor hs_loop_sink_desc = {
  86. .bLength = USB_DT_ENDPOINT_SIZE,
  87. .bDescriptorType = USB_DT_ENDPOINT,
  88. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  89. .wMaxPacketSize = cpu_to_le16(512),
  90. };
  91. static struct usb_descriptor_header *hs_loopback_descs[] = {
  92. (struct usb_descriptor_header *) &loopback_intf,
  93. (struct usb_descriptor_header *) &hs_loop_source_desc,
  94. (struct usb_descriptor_header *) &hs_loop_sink_desc,
  95. NULL,
  96. };
  97. /* super speed support: */
  98. static struct usb_endpoint_descriptor ss_loop_source_desc = {
  99. .bLength = USB_DT_ENDPOINT_SIZE,
  100. .bDescriptorType = USB_DT_ENDPOINT,
  101. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  102. .wMaxPacketSize = cpu_to_le16(1024),
  103. };
  104. struct usb_ss_ep_comp_descriptor ss_loop_source_comp_desc = {
  105. .bLength = USB_DT_SS_EP_COMP_SIZE,
  106. .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
  107. .bMaxBurst = 0,
  108. .bmAttributes = 0,
  109. .wBytesPerInterval = 0,
  110. };
  111. static struct usb_endpoint_descriptor ss_loop_sink_desc = {
  112. .bLength = USB_DT_ENDPOINT_SIZE,
  113. .bDescriptorType = USB_DT_ENDPOINT,
  114. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  115. .wMaxPacketSize = cpu_to_le16(1024),
  116. };
  117. struct usb_ss_ep_comp_descriptor ss_loop_sink_comp_desc = {
  118. .bLength = USB_DT_SS_EP_COMP_SIZE,
  119. .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
  120. .bMaxBurst = 0,
  121. .bmAttributes = 0,
  122. .wBytesPerInterval = 0,
  123. };
  124. static struct usb_descriptor_header *ss_loopback_descs[] = {
  125. (struct usb_descriptor_header *) &loopback_intf,
  126. (struct usb_descriptor_header *) &ss_loop_source_desc,
  127. (struct usb_descriptor_header *) &ss_loop_source_comp_desc,
  128. (struct usb_descriptor_header *) &ss_loop_sink_desc,
  129. (struct usb_descriptor_header *) &ss_loop_sink_comp_desc,
  130. NULL,
  131. };
  132. /* function-specific strings: */
  133. static struct usb_string strings_loopback[] = {
  134. [0].s = "loop input to output",
  135. { } /* end of list */
  136. };
  137. static struct usb_gadget_strings stringtab_loop = {
  138. .language = 0x0409, /* en-us */
  139. .strings = strings_loopback,
  140. };
  141. static struct usb_gadget_strings *loopback_strings[] = {
  142. &stringtab_loop,
  143. NULL,
  144. };
  145. /*-------------------------------------------------------------------------*/
  146. static int __init
  147. loopback_bind(struct usb_configuration *c, struct usb_function *f)
  148. {
  149. struct usb_composite_dev *cdev = c->cdev;
  150. struct f_loopback *loop = func_to_loop(f);
  151. int id;
  152. /* allocate interface ID(s) */
  153. id = usb_interface_id(c, f);
  154. if (id < 0)
  155. return id;
  156. loopback_intf.bInterfaceNumber = id;
  157. /* allocate endpoints */
  158. loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc);
  159. if (!loop->in_ep) {
  160. autoconf_fail:
  161. ERROR(cdev, "%s: can't autoconfigure on %s\n",
  162. f->name, cdev->gadget->name);
  163. return -ENODEV;
  164. }
  165. loop->in_ep->driver_data = cdev; /* claim */
  166. loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
  167. if (!loop->out_ep)
  168. goto autoconf_fail;
  169. loop->out_ep->driver_data = cdev; /* claim */
  170. /* support high speed hardware */
  171. if (gadget_is_dualspeed(c->cdev->gadget)) {
  172. hs_loop_source_desc.bEndpointAddress =
  173. fs_loop_source_desc.bEndpointAddress;
  174. hs_loop_sink_desc.bEndpointAddress =
  175. fs_loop_sink_desc.bEndpointAddress;
  176. f->hs_descriptors = hs_loopback_descs;
  177. }
  178. /* support super speed hardware */
  179. if (gadget_is_superspeed(c->cdev->gadget)) {
  180. ss_loop_source_desc.bEndpointAddress =
  181. fs_loop_source_desc.bEndpointAddress;
  182. ss_loop_sink_desc.bEndpointAddress =
  183. fs_loop_sink_desc.bEndpointAddress;
  184. f->ss_descriptors = ss_loopback_descs;
  185. }
  186. DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
  187. (gadget_is_superspeed(c->cdev->gadget) ? "super" :
  188. (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
  189. f->name, loop->in_ep->name, loop->out_ep->name);
  190. return 0;
  191. }
  192. static void
  193. loopback_unbind(struct usb_configuration *c, struct usb_function *f)
  194. {
  195. kfree(func_to_loop(f));
  196. }
  197. static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
  198. {
  199. struct f_loopback *loop = ep->driver_data;
  200. struct usb_composite_dev *cdev = loop->function.config->cdev;
  201. int status = req->status;
  202. switch (status) {
  203. case 0: /* normal completion? */
  204. if (ep == loop->out_ep) {
  205. /* loop this OUT packet back IN to the host */
  206. req->zero = (req->actual < req->length);
  207. req->length = req->actual;
  208. status = usb_ep_queue(loop->in_ep, req, GFP_ATOMIC);
  209. if (status == 0)
  210. return;
  211. /* "should never get here" */
  212. ERROR(cdev, "can't loop %s to %s: %d\n",
  213. ep->name, loop->in_ep->name,
  214. status);
  215. }
  216. /* queue the buffer for some later OUT packet */
  217. req->length = buflen;
  218. status = usb_ep_queue(loop->out_ep, req, GFP_ATOMIC);
  219. if (status == 0)
  220. return;
  221. /* "should never get here" */
  222. /* FALLTHROUGH */
  223. default:
  224. ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name,
  225. status, req->actual, req->length);
  226. /* FALLTHROUGH */
  227. /* NOTE: since this driver doesn't maintain an explicit record
  228. * of requests it submitted (just maintains qlen count), we
  229. * rely on the hardware driver to clean up on disconnect or
  230. * endpoint disable.
  231. */
  232. case -ECONNABORTED: /* hardware forced ep reset */
  233. case -ECONNRESET: /* request dequeued */
  234. case -ESHUTDOWN: /* disconnect from host */
  235. free_ep_req(ep, req);
  236. return;
  237. }
  238. }
  239. static void disable_loopback(struct f_loopback *loop)
  240. {
  241. struct usb_composite_dev *cdev;
  242. cdev = loop->function.config->cdev;
  243. disable_endpoints(cdev, loop->in_ep, loop->out_ep);
  244. VDBG(cdev, "%s disabled\n", loop->function.name);
  245. }
  246. static int
  247. enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
  248. {
  249. int result = 0;
  250. struct usb_ep *ep;
  251. struct usb_request *req;
  252. unsigned i;
  253. /* one endpoint writes data back IN to the host */
  254. ep = loop->in_ep;
  255. result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
  256. if (result)
  257. return result;
  258. result = usb_ep_enable(ep);
  259. if (result < 0)
  260. return result;
  261. ep->driver_data = loop;
  262. /* one endpoint just reads OUT packets */
  263. ep = loop->out_ep;
  264. result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
  265. if (result)
  266. goto fail0;
  267. result = usb_ep_enable(ep);
  268. if (result < 0) {
  269. fail0:
  270. ep = loop->in_ep;
  271. usb_ep_disable(ep);
  272. ep->driver_data = NULL;
  273. return result;
  274. }
  275. ep->driver_data = loop;
  276. /* allocate a bunch of read buffers and queue them all at once.
  277. * we buffer at most 'qlen' transfers; fewer if any need more
  278. * than 'buflen' bytes each.
  279. */
  280. for (i = 0; i < qlen && result == 0; i++) {
  281. req = alloc_ep_req(ep);
  282. if (req) {
  283. req->complete = loopback_complete;
  284. result = usb_ep_queue(ep, req, GFP_ATOMIC);
  285. if (result)
  286. ERROR(cdev, "%s queue req --> %d\n",
  287. ep->name, result);
  288. } else {
  289. usb_ep_disable(ep);
  290. ep->driver_data = NULL;
  291. result = -ENOMEM;
  292. goto fail0;
  293. }
  294. }
  295. DBG(cdev, "%s enabled\n", loop->function.name);
  296. return result;
  297. }
  298. static int loopback_set_alt(struct usb_function *f,
  299. unsigned intf, unsigned alt)
  300. {
  301. struct f_loopback *loop = func_to_loop(f);
  302. struct usb_composite_dev *cdev = f->config->cdev;
  303. /* we know alt is zero */
  304. if (loop->in_ep->driver_data)
  305. disable_loopback(loop);
  306. return enable_loopback(cdev, loop);
  307. }
  308. static void loopback_disable(struct usb_function *f)
  309. {
  310. struct f_loopback *loop = func_to_loop(f);
  311. disable_loopback(loop);
  312. }
  313. /*-------------------------------------------------------------------------*/
  314. static int __init loopback_bind_config(struct usb_configuration *c)
  315. {
  316. struct f_loopback *loop;
  317. int status;
  318. loop = kzalloc(sizeof *loop, GFP_KERNEL);
  319. if (!loop)
  320. return -ENOMEM;
  321. loop->function.name = "loopback";
  322. loop->function.descriptors = fs_loopback_descs;
  323. loop->function.bind = loopback_bind;
  324. loop->function.unbind = loopback_unbind;
  325. loop->function.set_alt = loopback_set_alt;
  326. loop->function.disable = loopback_disable;
  327. status = usb_add_function(c, &loop->function);
  328. if (status)
  329. kfree(loop);
  330. return status;
  331. }
  332. static struct usb_configuration loopback_driver = {
  333. .label = "loopback",
  334. .strings = loopback_strings,
  335. .bConfigurationValue = 2,
  336. .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
  337. /* .iConfiguration = DYNAMIC */
  338. };
  339. /**
  340. * loopback_add - add a loopback testing configuration to a device
  341. * @cdev: the device to support the loopback configuration
  342. */
  343. int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
  344. {
  345. int id;
  346. /* allocate string ID(s) */
  347. id = usb_string_id(cdev);
  348. if (id < 0)
  349. return id;
  350. strings_loopback[0].id = id;
  351. loopback_intf.iInterface = id;
  352. loopback_driver.iConfiguration = id;
  353. /* support autoresume for remote wakeup testing */
  354. if (autoresume)
  355. sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
  356. /* support OTG systems */
  357. if (gadget_is_otg(cdev->gadget)) {
  358. loopback_driver.descriptors = otg_desc;
  359. loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
  360. }
  361. return usb_add_config(cdev, &loopback_driver, loopback_bind_config);
  362. }