ep0.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * aspeed-vhub -- Driver for Aspeed SoC "vHub" USB gadget
  4. *
  5. * ep0.c - Endpoint 0 handling
  6. *
  7. * Copyright 2017 IBM Corporation
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/delay.h>
  18. #include <linux/ioport.h>
  19. #include <linux/slab.h>
  20. #include <linux/errno.h>
  21. #include <linux/list.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/proc_fs.h>
  24. #include <linux/prefetch.h>
  25. #include <linux/clk.h>
  26. #include <linux/usb/gadget.h>
  27. #include <linux/of.h>
  28. #include <linux/of_gpio.h>
  29. #include <linux/regmap.h>
  30. #include <linux/dma-mapping.h>
  31. #include "vhub.h"
  32. int ast_vhub_reply(struct ast_vhub_ep *ep, char *ptr, int len)
  33. {
  34. struct usb_request *req = &ep->ep0.req.req;
  35. int rc;
  36. if (WARN_ON(ep->d_idx != 0))
  37. return std_req_stall;
  38. if (WARN_ON(!ep->ep0.dir_in))
  39. return std_req_stall;
  40. if (WARN_ON(len > AST_VHUB_EP0_MAX_PACKET))
  41. return std_req_stall;
  42. if (WARN_ON(req->status == -EINPROGRESS))
  43. return std_req_stall;
  44. req->buf = ptr;
  45. req->length = len;
  46. req->complete = NULL;
  47. req->zero = true;
  48. /*
  49. * Call internal queue directly after dropping the lock. This is
  50. * safe to do as the reply is always the last thing done when
  51. * processing a SETUP packet, usually as a tail call
  52. */
  53. spin_unlock(&ep->vhub->lock);
  54. if (ep->ep.ops->queue(&ep->ep, req, GFP_ATOMIC))
  55. rc = std_req_stall;
  56. else
  57. rc = std_req_data;
  58. spin_lock(&ep->vhub->lock);
  59. return rc;
  60. }
  61. int __ast_vhub_simple_reply(struct ast_vhub_ep *ep, int len, ...)
  62. {
  63. u8 *buffer = ep->buf;
  64. unsigned int i;
  65. va_list args;
  66. va_start(args, len);
  67. /* Copy data directly into EP buffer */
  68. for (i = 0; i < len; i++)
  69. buffer[i] = va_arg(args, int);
  70. va_end(args);
  71. /* req->buf NULL means data is already there */
  72. return ast_vhub_reply(ep, NULL, len);
  73. }
  74. void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep)
  75. {
  76. struct usb_ctrlrequest crq;
  77. enum std_req_rc std_req_rc;
  78. int rc = -ENODEV;
  79. if (WARN_ON(ep->d_idx != 0))
  80. return;
  81. /*
  82. * Grab the setup packet from the chip and byteswap
  83. * interesting fields
  84. */
  85. memcpy_fromio(&crq, ep->ep0.setup, sizeof(crq));
  86. EPDBG(ep, "SETUP packet %02x/%02x/%04x/%04x/%04x [%s] st=%d\n",
  87. crq.bRequestType, crq.bRequest,
  88. le16_to_cpu(crq.wValue),
  89. le16_to_cpu(crq.wIndex),
  90. le16_to_cpu(crq.wLength),
  91. (crq.bRequestType & USB_DIR_IN) ? "in" : "out",
  92. ep->ep0.state);
  93. /* Check our state, cancel pending requests if needed */
  94. if (ep->ep0.state != ep0_state_token) {
  95. EPDBG(ep, "wrong state\n");
  96. ast_vhub_nuke(ep, -EIO);
  97. /*
  98. * Accept the packet regardless, this seems to happen
  99. * when stalling a SETUP packet that has an OUT data
  100. * phase.
  101. */
  102. ast_vhub_nuke(ep, 0);
  103. goto stall;
  104. }
  105. /* Calculate next state for EP0 */
  106. ep->ep0.state = ep0_state_data;
  107. ep->ep0.dir_in = !!(crq.bRequestType & USB_DIR_IN);
  108. /* If this is the vHub, we handle requests differently */
  109. std_req_rc = std_req_driver;
  110. if (ep->dev == NULL) {
  111. if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
  112. std_req_rc = ast_vhub_std_hub_request(ep, &crq);
  113. else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
  114. std_req_rc = ast_vhub_class_hub_request(ep, &crq);
  115. else
  116. std_req_rc = std_req_stall;
  117. } else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
  118. std_req_rc = ast_vhub_std_dev_request(ep, &crq);
  119. /* Act upon result */
  120. switch(std_req_rc) {
  121. case std_req_complete:
  122. goto complete;
  123. case std_req_stall:
  124. goto stall;
  125. case std_req_driver:
  126. break;
  127. case std_req_data:
  128. return;
  129. }
  130. /* Pass request up to the gadget driver */
  131. if (WARN_ON(!ep->dev))
  132. goto stall;
  133. if (ep->dev->driver) {
  134. EPDBG(ep, "forwarding to gadget...\n");
  135. spin_unlock(&ep->vhub->lock);
  136. rc = ep->dev->driver->setup(&ep->dev->gadget, &crq);
  137. spin_lock(&ep->vhub->lock);
  138. EPDBG(ep, "driver returned %d\n", rc);
  139. } else {
  140. EPDBG(ep, "no gadget for request !\n");
  141. }
  142. if (rc >= 0)
  143. return;
  144. stall:
  145. EPDBG(ep, "stalling\n");
  146. writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
  147. ep->ep0.state = ep0_state_status;
  148. ep->ep0.dir_in = false;
  149. return;
  150. complete:
  151. EPVDBG(ep, "sending [in] status with no data\n");
  152. writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
  153. ep->ep0.state = ep0_state_status;
  154. ep->ep0.dir_in = false;
  155. }
  156. static void ast_vhub_ep0_do_send(struct ast_vhub_ep *ep,
  157. struct ast_vhub_req *req)
  158. {
  159. unsigned int chunk;
  160. u32 reg;
  161. /* If this is a 0-length request, it's the gadget trying to
  162. * send a status on our behalf. We take it from here.
  163. */
  164. if (req->req.length == 0)
  165. req->last_desc = 1;
  166. /* Are we done ? Complete request, otherwise wait for next interrupt */
  167. if (req->last_desc >= 0) {
  168. EPVDBG(ep, "complete send %d/%d\n",
  169. req->req.actual, req->req.length);
  170. ep->ep0.state = ep0_state_status;
  171. writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat);
  172. ast_vhub_done(ep, req, 0);
  173. return;
  174. }
  175. /*
  176. * Next chunk cropped to max packet size. Also check if this
  177. * is the last packet
  178. */
  179. chunk = req->req.length - req->req.actual;
  180. if (chunk > ep->ep.maxpacket)
  181. chunk = ep->ep.maxpacket;
  182. else if ((chunk < ep->ep.maxpacket) || !req->req.zero)
  183. req->last_desc = 1;
  184. EPVDBG(ep, "send chunk=%d last=%d, req->act=%d mp=%d\n",
  185. chunk, req->last_desc, req->req.actual, ep->ep.maxpacket);
  186. /*
  187. * Copy data if any (internal requests already have data
  188. * in the EP buffer)
  189. */
  190. if (chunk && req->req.buf)
  191. memcpy(ep->buf, req->req.buf + req->req.actual, chunk);
  192. vhub_dma_workaround(ep->buf);
  193. /* Remember chunk size and trigger send */
  194. reg = VHUB_EP0_SET_TX_LEN(chunk);
  195. writel(reg, ep->ep0.ctlstat);
  196. writel(reg | VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
  197. req->req.actual += chunk;
  198. }
  199. static void ast_vhub_ep0_rx_prime(struct ast_vhub_ep *ep)
  200. {
  201. EPVDBG(ep, "rx prime\n");
  202. /* Prime endpoint for receiving data */
  203. writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat);
  204. }
  205. static void ast_vhub_ep0_do_receive(struct ast_vhub_ep *ep, struct ast_vhub_req *req,
  206. unsigned int len)
  207. {
  208. unsigned int remain;
  209. int rc = 0;
  210. /* We are receiving... grab request */
  211. remain = req->req.length - req->req.actual;
  212. EPVDBG(ep, "receive got=%d remain=%d\n", len, remain);
  213. /* Are we getting more than asked ? */
  214. if (len > remain) {
  215. EPDBG(ep, "receiving too much (ovf: %d) !\n",
  216. len - remain);
  217. len = remain;
  218. rc = -EOVERFLOW;
  219. }
  220. if (len && req->req.buf)
  221. memcpy(req->req.buf + req->req.actual, ep->buf, len);
  222. req->req.actual += len;
  223. /* Done ? */
  224. if (len < ep->ep.maxpacket || len == remain) {
  225. ep->ep0.state = ep0_state_status;
  226. writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
  227. ast_vhub_done(ep, req, rc);
  228. } else
  229. ast_vhub_ep0_rx_prime(ep);
  230. }
  231. void ast_vhub_ep0_handle_ack(struct ast_vhub_ep *ep, bool in_ack)
  232. {
  233. struct ast_vhub_req *req;
  234. struct ast_vhub *vhub = ep->vhub;
  235. struct device *dev = &vhub->pdev->dev;
  236. bool stall = false;
  237. u32 stat;
  238. /* Read EP0 status */
  239. stat = readl(ep->ep0.ctlstat);
  240. /* Grab current request if any */
  241. req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue);
  242. EPVDBG(ep, "ACK status=%08x,state=%d is_in=%d in_ack=%d req=%p\n",
  243. stat, ep->ep0.state, ep->ep0.dir_in, in_ack, req);
  244. switch(ep->ep0.state) {
  245. case ep0_state_token:
  246. /* There should be no request queued in that state... */
  247. if (req) {
  248. dev_warn(dev, "request present while in TOKEN state\n");
  249. ast_vhub_nuke(ep, -EINVAL);
  250. }
  251. dev_warn(dev, "ack while in TOKEN state\n");
  252. stall = true;
  253. break;
  254. case ep0_state_data:
  255. /* Check the state bits corresponding to our direction */
  256. if ((ep->ep0.dir_in && (stat & VHUB_EP0_TX_BUFF_RDY)) ||
  257. (!ep->ep0.dir_in && (stat & VHUB_EP0_RX_BUFF_RDY)) ||
  258. (ep->ep0.dir_in != in_ack)) {
  259. dev_warn(dev, "irq state mismatch");
  260. stall = true;
  261. break;
  262. }
  263. /*
  264. * We are in data phase and there's no request, something is
  265. * wrong, stall
  266. */
  267. if (!req) {
  268. dev_warn(dev, "data phase, no request\n");
  269. stall = true;
  270. break;
  271. }
  272. /* We have a request, handle data transfers */
  273. if (ep->ep0.dir_in)
  274. ast_vhub_ep0_do_send(ep, req);
  275. else
  276. ast_vhub_ep0_do_receive(ep, req, VHUB_EP0_RX_LEN(stat));
  277. return;
  278. case ep0_state_status:
  279. /* Nuke stale requests */
  280. if (req) {
  281. dev_warn(dev, "request present while in STATUS state\n");
  282. ast_vhub_nuke(ep, -EINVAL);
  283. }
  284. /*
  285. * If the status phase completes with the wrong ack, stall
  286. * the endpoint just in case, to abort whatever the host
  287. * was doing.
  288. */
  289. if (ep->ep0.dir_in == in_ack) {
  290. dev_warn(dev, "status direction mismatch\n");
  291. stall = true;
  292. }
  293. }
  294. /* Reset to token state */
  295. ep->ep0.state = ep0_state_token;
  296. if (stall)
  297. writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
  298. }
  299. static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req,
  300. gfp_t gfp_flags)
  301. {
  302. struct ast_vhub_req *req = to_ast_req(u_req);
  303. struct ast_vhub_ep *ep = to_ast_ep(u_ep);
  304. struct ast_vhub *vhub = ep->vhub;
  305. struct device *dev = &vhub->pdev->dev;
  306. unsigned long flags;
  307. /* Paranoid cheks */
  308. if (!u_req || (!u_req->complete && !req->internal)) {
  309. dev_warn(dev, "Bogus EP0 request ! u_req=%p\n", u_req);
  310. if (u_req) {
  311. dev_warn(dev, "complete=%p internal=%d\n",
  312. u_req->complete, req->internal);
  313. }
  314. return -EINVAL;
  315. }
  316. /* Not endpoint 0 ? */
  317. if (WARN_ON(ep->d_idx != 0))
  318. return -EINVAL;
  319. /* Disabled device */
  320. if (ep->dev && (!ep->dev->enabled || ep->dev->suspended))
  321. return -ESHUTDOWN;
  322. /* Data, no buffer and not internal ? */
  323. if (u_req->length && !u_req->buf && !req->internal) {
  324. dev_warn(dev, "Request with no buffer !\n");
  325. return -EINVAL;
  326. }
  327. EPVDBG(ep, "enqueue req @%p\n", req);
  328. EPVDBG(ep, " l=%d zero=%d noshort=%d is_in=%d\n",
  329. u_req->length, u_req->zero,
  330. u_req->short_not_ok, ep->ep0.dir_in);
  331. /* Initialize request progress fields */
  332. u_req->status = -EINPROGRESS;
  333. u_req->actual = 0;
  334. req->last_desc = -1;
  335. req->active = false;
  336. spin_lock_irqsave(&vhub->lock, flags);
  337. /* EP0 can only support a single request at a time */
  338. if (!list_empty(&ep->queue) || ep->ep0.state == ep0_state_token) {
  339. dev_warn(dev, "EP0: Request in wrong state\n");
  340. spin_unlock_irqrestore(&vhub->lock, flags);
  341. return -EBUSY;
  342. }
  343. /* Add request to list and kick processing if empty */
  344. list_add_tail(&req->queue, &ep->queue);
  345. if (ep->ep0.dir_in) {
  346. /* IN request, send data */
  347. ast_vhub_ep0_do_send(ep, req);
  348. } else if (u_req->length == 0) {
  349. /* 0-len request, send completion as rx */
  350. EPVDBG(ep, "0-length rx completion\n");
  351. ep->ep0.state = ep0_state_status;
  352. writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
  353. ast_vhub_done(ep, req, 0);
  354. } else {
  355. /* OUT request, start receiver */
  356. ast_vhub_ep0_rx_prime(ep);
  357. }
  358. spin_unlock_irqrestore(&vhub->lock, flags);
  359. return 0;
  360. }
  361. static int ast_vhub_ep0_dequeue(struct usb_ep* u_ep, struct usb_request *u_req)
  362. {
  363. struct ast_vhub_ep *ep = to_ast_ep(u_ep);
  364. struct ast_vhub *vhub = ep->vhub;
  365. struct ast_vhub_req *req;
  366. unsigned long flags;
  367. int rc = -EINVAL;
  368. spin_lock_irqsave(&vhub->lock, flags);
  369. /* Only one request can be in the queue */
  370. req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue);
  371. /* Is it ours ? */
  372. if (req && u_req == &req->req) {
  373. EPVDBG(ep, "dequeue req @%p\n", req);
  374. /*
  375. * We don't have to deal with "active" as all
  376. * DMAs go to the EP buffers, not the request.
  377. */
  378. ast_vhub_done(ep, req, -ECONNRESET);
  379. /* We do stall the EP to clean things up in HW */
  380. writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
  381. ep->ep0.state = ep0_state_status;
  382. ep->ep0.dir_in = false;
  383. rc = 0;
  384. }
  385. spin_unlock_irqrestore(&vhub->lock, flags);
  386. return rc;
  387. }
  388. static const struct usb_ep_ops ast_vhub_ep0_ops = {
  389. .queue = ast_vhub_ep0_queue,
  390. .dequeue = ast_vhub_ep0_dequeue,
  391. .alloc_request = ast_vhub_alloc_request,
  392. .free_request = ast_vhub_free_request,
  393. };
  394. void ast_vhub_init_ep0(struct ast_vhub *vhub, struct ast_vhub_ep *ep,
  395. struct ast_vhub_dev *dev)
  396. {
  397. memset(ep, 0, sizeof(*ep));
  398. INIT_LIST_HEAD(&ep->ep.ep_list);
  399. INIT_LIST_HEAD(&ep->queue);
  400. ep->ep.ops = &ast_vhub_ep0_ops;
  401. ep->ep.name = "ep0";
  402. ep->ep.caps.type_control = true;
  403. usb_ep_set_maxpacket_limit(&ep->ep, AST_VHUB_EP0_MAX_PACKET);
  404. ep->d_idx = 0;
  405. ep->dev = dev;
  406. ep->vhub = vhub;
  407. ep->ep0.state = ep0_state_token;
  408. INIT_LIST_HEAD(&ep->ep0.req.queue);
  409. ep->ep0.req.internal = true;
  410. /* Small difference between vHub and devices */
  411. if (dev) {
  412. ep->ep0.ctlstat = dev->regs + AST_VHUB_DEV_EP0_CTRL;
  413. ep->ep0.setup = vhub->regs +
  414. AST_VHUB_SETUP0 + 8 * (dev->index + 1);
  415. ep->buf = vhub->ep0_bufs +
  416. AST_VHUB_EP0_MAX_PACKET * (dev->index + 1);
  417. ep->buf_dma = vhub->ep0_bufs_dma +
  418. AST_VHUB_EP0_MAX_PACKET * (dev->index + 1);
  419. } else {
  420. ep->ep0.ctlstat = vhub->regs + AST_VHUB_EP0_CTRL;
  421. ep->ep0.setup = vhub->regs + AST_VHUB_SETUP0;
  422. ep->buf = vhub->ep0_bufs;
  423. ep->buf_dma = vhub->ep0_bufs_dma;
  424. }
  425. }