Kiibohd Controller
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

usb.c 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. /* Copyright (c) 2011,2012 Simon Schubert <[email protected]>.
  2. * Modifications by Jacob Alexander 2014 <[email protected]>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU 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, see <http://www.gnu.org/licenses/>.
  16. */
  17. // ----- Compiler Includes -----
  18. #include <sys/types.h>
  19. #include <inttypes.h>
  20. #include <string.h>
  21. // ----- Local Includes -----
  22. #include "usb.h"
  23. #include "usb-internal.h"
  24. // ----- Variables -----
  25. static uint8_t ep0_buf[2][EP0_BUFSIZE] __attribute__((aligned(4)));
  26. struct usbd_t usb;
  27. // ----- Functions -----
  28. /**
  29. * Returns: 0 when this is was the last transfer, 1 if there is still
  30. * more to go.
  31. */
  32. /* Defaults to EP0 for now */
  33. static int usb_tx_next(struct usbd_ep_pipe_state_t *s)
  34. {
  35. /**
  36. * Us being here means the previous transfer just completed
  37. * successfully. That means the host just toggled its data
  38. * sync bit, and so do we.
  39. */
  40. s->data01 ^= 1;
  41. if (s->transfer_size > 0) {
  42. size_t thislen = s->transfer_size;
  43. if (thislen > s->ep_maxsize)
  44. thislen = s->ep_maxsize;
  45. void *addr = s->data_buf + s->pos;
  46. if (s->copy_source) {
  47. /* Bounce buffer mode */
  48. addr = s->data_buf;
  49. memcpy(addr, s->copy_source + s->pos, thislen);
  50. }
  51. s->pos += thislen;
  52. s->transfer_size -= thislen;
  53. usb_queue_next(s, addr, thislen);
  54. s->pingpong ^= 1;
  55. return (1);
  56. }
  57. /**
  58. * All data has been shipped. Do we need to send a short
  59. * packet?
  60. */
  61. if (s->short_transfer) {
  62. s->short_transfer = 0;
  63. usb_queue_next(s, NULL, 0);
  64. s->pingpong ^= 1;
  65. return (1);
  66. }
  67. if (s->callback)
  68. s->callback(s->data_buf, s->pos, s->callback_data);
  69. return (0);
  70. }
  71. static void setup_tx(struct usbd_ep_pipe_state_t *s, const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  72. {
  73. s->data_buf = (void *)buf;
  74. s->copy_source = NULL;
  75. s->transfer_size = len;
  76. s->pos = 0;
  77. s->callback = cb;
  78. s->callback_data = cb_data;
  79. if (s->transfer_size > reqlen)
  80. s->transfer_size = reqlen;
  81. if (s->transfer_size < reqlen && s->transfer_size % s->ep_maxsize == 0)
  82. s->short_transfer = 1;
  83. else
  84. s->short_transfer = 0;
  85. }
  86. static void submit_tx(struct usbd_ep_pipe_state_t *s)
  87. {
  88. /* usb_tx_next() flips the data toggle, so invert this here. */
  89. s->data01 ^= 1;
  90. usb_tx_next(s);
  91. }
  92. /**
  93. * send USB data (IN device transaction)
  94. *
  95. * So far this function is specialized for EP 0 only.
  96. *
  97. * Returns: size to be transfered, or -1 on error.
  98. */
  99. int usb_tx(struct usbd_ep_pipe_state_t *s, const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  100. {
  101. setup_tx(s, buf, len, reqlen, cb, cb_data);
  102. submit_tx(s);
  103. return (s->transfer_size);
  104. }
  105. /**
  106. * Returns: 0 when this is was the last transfer, 1 if there is still
  107. * more to go.
  108. */
  109. /* Defaults to EP0 for now */
  110. /* XXX pass usb_stat to validate pingpong */
  111. static int usb_rx_next(struct usbd_ep_pipe_state_t *s)
  112. {
  113. /**
  114. * Us being here means the previous transfer just completed
  115. * successfully. That means the host just toggled its data
  116. * sync bit, and so do we.
  117. */
  118. s->data01 ^= 1;
  119. size_t thislen = usb_ep_get_transfer_size(s);
  120. s->transfer_size -= thislen;
  121. s->pos += thislen;
  122. /**
  123. * We're done with this buffer now. Switch the pingpong now
  124. * before we might have to receive the next piece of data.
  125. */
  126. s->pingpong ^= 1;
  127. /**
  128. * If this is a short transfer, or we received what we
  129. * expected, we're done.
  130. */
  131. if (thislen < s->ep_maxsize || s->transfer_size == 0) {
  132. if (s->callback)
  133. s->callback(s->data_buf, s->pos, s->callback_data);
  134. return (0);
  135. }
  136. /**
  137. * Otherwise we still need to receive more data.
  138. */
  139. size_t nextlen = s->transfer_size;
  140. if (nextlen > s->ep_maxsize)
  141. nextlen = s->ep_maxsize;
  142. void *addr = s->data_buf + s->pos;
  143. usb_queue_next(s, addr, nextlen);
  144. return (1);
  145. }
  146. /**
  147. * Receive USB data (OUT device transaction)
  148. *
  149. * Returns: size to be received, or -1 on error.
  150. */
  151. int usb_rx(struct usbd_ep_pipe_state_t *s, void *buf, size_t len, ep_callback_t cb, void *cb_data)
  152. {
  153. s->data_buf = buf;
  154. s->transfer_size = len;
  155. s->pos = 0;
  156. s->callback = cb;
  157. s->callback_data = cb_data;
  158. size_t thislen = s->transfer_size;
  159. if (thislen > s->ep_maxsize)
  160. thislen = s->ep_maxsize;
  161. usb_queue_next(s, s->data_buf, thislen);
  162. return (len);
  163. }
  164. int usb_ep0_tx_cp(const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  165. {
  166. struct usbd_ep_pipe_state_t *s = &usb.ep_state[0].tx;
  167. enum usb_ep_pingpong pp = s->pingpong;
  168. setup_tx(s, ep0_buf[pp], len, reqlen, cb, cb_data);
  169. s->copy_source = buf;
  170. submit_tx(s);
  171. return (s->transfer_size);
  172. }
  173. void *usb_ep0_tx_inplace_prepare(size_t len)
  174. {
  175. enum usb_ep_pingpong pp = usb.ep_state[0].tx.pingpong;
  176. if (len > EP0_BUFSIZE)
  177. return (NULL);
  178. return (ep0_buf[pp]);
  179. }
  180. int usb_ep0_tx(void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  181. {
  182. return (usb_tx(&usb.ep_state[0].tx, buf, len, reqlen, cb, cb_data));
  183. }
  184. int usb_ep0_rx(void *buf, size_t len, ep_callback_t cb, void *cb_data)
  185. {
  186. return (usb_rx(&usb.ep_state[0].rx, buf, len, cb, cb_data));
  187. }
  188. const struct usbd_config *
  189. usb_get_config_data(int config)
  190. {
  191. if (config <= 0)
  192. config = usb.config;
  193. if (config != 0)
  194. return (usb.identity->configs[config - 1]);
  195. else
  196. return (NULL);
  197. }
  198. static int usb_set_config(int config)
  199. {
  200. const struct usbd_config *config_data;
  201. if (usb.config != 0) {
  202. config_data = usb_get_config_data(-1);
  203. if (config_data != NULL && config_data->init != NULL)
  204. config_data->init(0);
  205. }
  206. if (config != 0) {
  207. /* XXX overflow */
  208. config_data = usb_get_config_data(config);
  209. if (config_data != NULL && config_data->init != NULL)
  210. config_data->init(1);
  211. }
  212. usb.config = config;
  213. return (0);
  214. }
  215. static int usb_set_interface(int iface, int altsetting)
  216. {
  217. int iface_count = 0;
  218. for (struct usbd_function_ctx_header *fh = &usb.functions;
  219. fh != NULL;
  220. fh = fh->next, iface_count += fh->function->interface_count) {
  221. if (iface - iface_count < fh->function->interface_count) {
  222. if (fh->function->configure != NULL)
  223. return (fh->function->configure(iface,
  224. iface - iface_count,
  225. altsetting,
  226. fh));
  227. /* Default to a single altsetting */
  228. if (altsetting != 0)
  229. return (-1);
  230. else
  231. return (0);
  232. }
  233. }
  234. return (-1);
  235. }
  236. static int usb_tx_config_desc(int idx, int reqlen)
  237. {
  238. const struct usb_desc_config_t *d = usb.identity->configs[idx]->desc;
  239. usb_ep0_tx_cp(d, d->wTotalLength, reqlen, NULL, NULL);
  240. return (0);
  241. }
  242. static int usb_tx_string_desc(int idx, int reqlen)
  243. {
  244. const struct usb_desc_string_t * const *d;
  245. for (d = usb.identity->string_descs; idx != 0 && *d != NULL; ++d)
  246. --idx;
  247. switch ((uintptr_t)*d) {
  248. case (uintptr_t)NULL:
  249. return (-1);
  250. case (uintptr_t)USB_DESC_STRING_SERIALNO:
  251. return (usb_tx_serialno(reqlen));
  252. default:
  253. usb_ep0_tx_cp(*d, (*d)->bLength, reqlen, NULL, NULL);
  254. return (0);
  255. }
  256. }
  257. static void usb_handle_control_done(void *data, ssize_t len, void *cbdata)
  258. {
  259. if (usb.state == USBD_STATE_SETTING_ADDRESS) {
  260. usb.state = USBD_STATE_ADDRESS;
  261. usb_set_addr(usb.address);
  262. }
  263. usb_setup_control();
  264. }
  265. void usb_handle_control_status_cb(ep_callback_t cb)
  266. {
  267. /* empty status transfer */
  268. switch (usb.ctrl_dir) {
  269. case USB_CTRL_REQ_IN:
  270. usb.ep_state[0].rx.data01 = USB_DATA01_DATA1;
  271. usb_rx(&usb.ep_state[0].rx, NULL, 0, cb, NULL);
  272. break;
  273. default:
  274. usb.ep_state[0].tx.data01 = USB_DATA01_DATA1;
  275. usb_ep0_tx_cp(NULL, 0, 1 /* short packet */, cb, NULL);
  276. break;
  277. }
  278. }
  279. void usb_handle_control_status(int fail)
  280. {
  281. if (fail) {
  282. usb_pipe_stall(&usb.ep_state[0].rx);
  283. usb_pipe_stall(&usb.ep_state[0].tx);
  284. } else {
  285. usb_handle_control_status_cb(usb_handle_control_done);
  286. }
  287. }
  288. /**
  289. * Dispatch non-standard request to registered USB functions.
  290. */
  291. static void usb_handle_control_nonstd(struct usb_ctrl_req_t *req)
  292. {
  293. /* XXX filter by interface/endpoint? */
  294. for (struct usbd_function_ctx_header *fh = &usb.functions; fh != NULL; fh = fh->next) {
  295. /* ->control() returns != 0 if it handled the request */
  296. if (fh->function->control != NULL &&
  297. fh->function->control(req, fh))
  298. return;
  299. }
  300. usb_handle_control_status(-1);
  301. }
  302. /**
  303. *
  304. * Great resource: http://wiki.osdev.org/Universal_Serial_Bus
  305. *
  306. * Control Transfers
  307. * -----------------
  308. *
  309. * A control transfer consists of a SETUP transaction (1), zero or
  310. * more data transactions (IN or OUT) (2), and a final status
  311. * transaction (3).
  312. *
  313. * Token sequence (data toggle):
  314. * 1. SETUP (0)
  315. * (2a. OUT (1) ... (toggling))
  316. * 3a. IN (1)
  317. *
  318. * or
  319. * 1. SETUP (0)
  320. * 2b. IN (1) ... (toggling)
  321. * 3b. OUT (1)
  322. *
  323. * Report errors by STALLing the control EP after (1) or (2), so that
  324. * (3) will STALL. Seems we need to clear the STALL after that so
  325. * that the next SETUP can make it through.
  326. *
  327. *
  328. */
  329. /**
  330. * The following code is not written defensively, but instead only
  331. * asserts values that are essential for correct execution. It
  332. * accepts a superset of the protocol defined by the standard. We do
  333. * this to save space.
  334. */
  335. static void usb_handle_control(void *data, ssize_t len, void *cbdata)
  336. {
  337. struct usb_ctrl_req_t *req = data;
  338. uint16_t zero16 = 0;
  339. int fail = 1;
  340. usb.ctrl_dir = req->in;
  341. if (req->type != USB_CTRL_REQ_STD) {
  342. usb_handle_control_nonstd(req);
  343. return;
  344. }
  345. /* Only STD requests here */
  346. switch (req->bRequest) {
  347. case USB_CTRL_REQ_GET_STATUS:
  348. /**
  349. * Because we don't support remote wakeup or
  350. * self-powered operation, and we are specialized to
  351. * only EP 0 so far, all GET_STATUS replies are just
  352. * empty.
  353. */
  354. usb_ep0_tx_cp(&zero16, sizeof(zero16), req->wLength, NULL, NULL);
  355. break;
  356. case USB_CTRL_REQ_CLEAR_FEATURE:
  357. case USB_CTRL_REQ_SET_FEATURE:
  358. /**
  359. * Nothing to do. Maybe return STALLs on illegal
  360. * accesses?
  361. */
  362. break;
  363. case USB_CTRL_REQ_SET_ADDRESS:
  364. /**
  365. * We must keep our previous address until the end of
  366. * the status stage; therefore we can't set the
  367. * address right now. Since this is a special case,
  368. * the EP 0 handler will take care of this later on.
  369. */
  370. usb.address = req->wValue & 0x7f;
  371. usb.state = USBD_STATE_SETTING_ADDRESS;
  372. break;
  373. case USB_CTRL_REQ_GET_DESCRIPTOR:
  374. switch (req->wValue >> 8) {
  375. case USB_DESC_DEV:
  376. usb_ep0_tx_cp(usb.identity->dev_desc, usb.identity->dev_desc->bLength,
  377. req->wLength, NULL, NULL);
  378. fail = 0;
  379. break;
  380. case USB_DESC_CONFIG:
  381. fail = usb_tx_config_desc(req->wValue & 0xff, req->wLength);
  382. break;
  383. case USB_DESC_STRING:
  384. fail = usb_tx_string_desc(req->wValue & 0xff, req->wLength);
  385. break;
  386. default:
  387. fail = -1;
  388. break;
  389. }
  390. /* we set fail already, so we can go directly to `err' */
  391. goto err;
  392. case USB_CTRL_REQ_GET_CONFIGURATION:
  393. usb_ep0_tx_cp(&usb.config, 1, req->wLength, NULL, NULL); /* XXX implicit LE */
  394. break;
  395. case USB_CTRL_REQ_SET_CONFIGURATION:
  396. if (usb_set_config(req->wValue) < 0)
  397. goto err;
  398. break;
  399. case USB_CTRL_REQ_GET_INTERFACE:
  400. /* We only support iface setting 0 */
  401. usb_ep0_tx_cp(&zero16, 1, req->wLength, NULL, NULL);
  402. break;
  403. case USB_CTRL_REQ_SET_INTERFACE:
  404. if (usb_set_interface(req->wIndex, req->wValue) < 0)
  405. goto err;
  406. break;
  407. default:
  408. goto err;
  409. }
  410. fail = 0;
  411. err:
  412. usb_handle_control_status(fail);
  413. }
  414. void usb_setup_control(void)
  415. {
  416. void *buf = ep0_buf[usb.ep_state[0].rx.pingpong];
  417. usb.ep_state[0].rx.data01 = USB_DATA01_DATA0;
  418. usb.ep_state[0].tx.data01 = USB_DATA01_DATA1;
  419. usb_rx(&usb.ep_state[0].rx, buf, EP0_BUFSIZE, usb_handle_control, NULL);
  420. }
  421. /**
  422. * This is called by the interrupt handler
  423. */
  424. void usb_handle_transaction(struct usb_xfer_info *info)
  425. {
  426. enum usb_tok_pid pid = usb_get_xfer_pid(info);
  427. struct usbd_ep_state_t *eps = &usb.ep_state[usb_get_xfer_ep(info)];
  428. struct usbd_ep_pipe_state_t *s = &eps->pipe[usb_get_xfer_dir(info)];
  429. switch (pid) {
  430. case USB_PID_SETUP:
  431. case USB_PID_OUT:
  432. /**
  433. * If we receive a SETUP transaction, but don't expect
  434. * it (callback set to somewhere else), stall the EP.
  435. */
  436. if (pid == USB_PID_SETUP && s->callback != usb_handle_control)
  437. usb_handle_control_status(1);
  438. else
  439. usb_rx_next(s);
  440. if (pid == USB_PID_SETUP)
  441. usb_enable_xfers();
  442. break;
  443. case USB_PID_IN:
  444. usb_tx_next(s);
  445. break;
  446. default:
  447. break;
  448. }
  449. }
  450. struct usbd_ep_pipe_state_t *usb_init_ep(struct usbd_function_ctx_header *ctx, int ep, enum usb_ep_dir dir, size_t size)
  451. {
  452. struct usbd_ep_pipe_state_t *s;
  453. if (dir == USB_EP_RX)
  454. s = &usb.ep_state[ctx->ep_rx_offset + ep].rx;
  455. else
  456. s = &usb.ep_state[ctx->ep_tx_offset + ep].tx;
  457. memset(s, 0, sizeof(*s));
  458. s->ep_maxsize = size;
  459. s->ep_num = ep;
  460. s->ep_dir = dir;
  461. usb_pipe_enable(s);
  462. return (s);
  463. }
  464. void usb_restart(void)
  465. {
  466. const struct usbd_device *identity = usb.identity;
  467. /* XXX reset existing functions? */
  468. memset(&usb, 0, sizeof(usb));
  469. usb.functions.function = &usb.control_function;
  470. usb.identity = identity;
  471. usb_init_ep(&usb.functions, 0, USB_EP_RX, EP0_BUFSIZE);
  472. usb_init_ep(&usb.functions, 0, USB_EP_TX, EP0_BUFSIZE);
  473. usb_setup_control();
  474. }
  475. void usb_attach_function(const struct usbd_function *function, struct usbd_function_ctx_header *ctx)
  476. {
  477. /* XXX right now this requires a sequential initialization */
  478. struct usbd_function_ctx_header *prev = &usb.functions;
  479. while (prev->next != NULL)
  480. prev = prev->next;
  481. ctx->next = NULL;
  482. ctx->function = function;
  483. ctx->interface_offset = prev->interface_offset + prev->function->interface_count;
  484. ctx->ep_rx_offset = prev->ep_rx_offset + prev->function->ep_rx_count;
  485. ctx->ep_tx_offset = prev->ep_tx_offset + prev->function->ep_tx_count;
  486. prev->next = ctx;
  487. }
  488. void usb_init(const struct usbd_device *identity)
  489. {
  490. usb.identity = identity;
  491. usb_enable();
  492. }