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