Trim down peak calculation a bit.
[kugel-rb.git] / firmware / usbstack / usb_core.c
bloba2e2b5f063a68f67cb9ccc9fc55de7d68676f7d1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 by Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "system.h"
22 #include "thread.h"
23 #include "kernel.h"
24 #include "string.h"
25 /*#define LOGF_ENABLE*/
26 #include "logf.h"
28 #include "usb.h"
29 #include "usb_ch9.h"
30 #include "usb_drv.h"
31 #include "usb_core.h"
32 #include "usb_class_driver.h"
34 #if defined(USB_ENABLE_STORAGE)
35 #include "usb_storage.h"
36 #endif
38 #if defined(USB_ENABLE_SERIAL)
39 #include "usb_serial.h"
40 #endif
42 #if defined(USB_ENABLE_CHARGING_ONLY)
43 #include "usb_charging_only.h"
44 #endif
46 #ifdef USB_ENABLE_HID
47 #include "usb_hid.h"
48 #endif
50 /* TODO: Move target-specific stuff somewhere else (serial number reading) */
52 #ifdef HAVE_AS3514
53 #include "ascodec.h"
54 #include "as3514.h"
55 #endif
57 #if !defined(HAVE_AS3514) && !defined(IPOD_ARCH) && (CONFIG_STORAGE & STORAGE_ATA)
58 #include "ata.h"
59 #endif
61 #ifndef USB_MAX_CURRENT
62 #define USB_MAX_CURRENT 500
63 #endif
65 /*-------------------------------------------------------------------------*/
66 /* USB protocol descriptors: */
68 static struct usb_device_descriptor __attribute__((aligned(2)))
69 device_descriptor=
71 .bLength = sizeof(struct usb_device_descriptor),
72 .bDescriptorType = USB_DT_DEVICE,
73 #ifndef USB_NO_HIGH_SPEED
74 .bcdUSB = 0x0200,
75 #else
76 .bcdUSB = 0x0110,
77 #endif
78 .bDeviceClass = USB_CLASS_PER_INTERFACE,
79 .bDeviceSubClass = 0,
80 .bDeviceProtocol = 0,
81 .bMaxPacketSize0 = 64,
82 .idVendor = USB_VENDOR_ID,
83 .idProduct = USB_PRODUCT_ID,
84 .bcdDevice = 0x0100,
85 .iManufacturer = 1,
86 .iProduct = 2,
87 .iSerialNumber = 3,
88 .bNumConfigurations = 1
89 } ;
91 static struct usb_config_descriptor __attribute__((aligned(2)))
92 config_descriptor =
94 .bLength = sizeof(struct usb_config_descriptor),
95 .bDescriptorType = USB_DT_CONFIG,
96 .wTotalLength = 0, /* will be filled in later */
97 .bNumInterfaces = 1,
98 .bConfigurationValue = 1,
99 .iConfiguration = 0,
100 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
101 .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */
104 static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
105 qualifier_descriptor =
107 .bLength = sizeof(struct usb_qualifier_descriptor),
108 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
109 .bcdUSB = 0x0200,
110 .bDeviceClass = 0,
111 .bDeviceSubClass = 0,
112 .bDeviceProtocol = 0,
113 .bMaxPacketSize0 = 64,
114 .bNumConfigurations = 1
117 static const struct usb_string_descriptor __attribute__((aligned(2)))
118 usb_string_iManufacturer =
121 USB_DT_STRING,
122 {'R', 'o', 'c', 'k', 'b', 'o', 'x', '.', 'o', 'r', 'g'}
125 static const struct usb_string_descriptor __attribute__((aligned(2)))
126 usb_string_iProduct =
129 USB_DT_STRING,
130 {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ',
131 'm', 'e', 'd', 'i', 'a', ' ',
132 'p', 'l', 'a', 'y', 'e', 'r'}
135 static struct usb_string_descriptor __attribute__((aligned(2)))
136 usb_string_iSerial =
139 USB_DT_STRING,
140 {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
141 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
142 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
143 '0', '0', '0', '0', '0', '0', '0', '0'}
146 /* Generic for all targets */
148 /* this is stringid #0: languages supported */
149 static const struct usb_string_descriptor __attribute__((aligned(2)))
150 lang_descriptor =
153 USB_DT_STRING,
154 {0x0409} /* LANGID US English */
157 static const struct usb_string_descriptor* const usb_strings[] =
159 &lang_descriptor,
160 &usb_string_iManufacturer,
161 &usb_string_iProduct,
162 &usb_string_iSerial
165 static int usb_address = 0;
166 static bool initialized = false;
167 static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
169 static int usb_core_num_interfaces;
171 typedef void (*completion_handler_t)(int ep, int dir, int status, int length);
172 typedef bool (*control_handler_t)(struct usb_ctrlrequest* req,
173 unsigned char* dest);
175 static struct
177 completion_handler_t completion_handler[2];
178 control_handler_t control_handler[2];
179 struct usb_transfer_completion_event_data completion_event[2];
180 } ep_data[USB_NUM_ENDPOINTS];
182 static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
184 #ifdef USB_ENABLE_STORAGE
185 [USB_DRIVER_MASS_STORAGE] = {
186 .enabled = false,
187 .needs_exclusive_storage = true,
188 .first_interface = 0,
189 .last_interface = 0,
190 .request_endpoints = usb_storage_request_endpoints,
191 .set_first_interface = usb_storage_set_first_interface,
192 .get_config_descriptor = usb_storage_get_config_descriptor,
193 .init_connection = usb_storage_init_connection,
194 .init = usb_storage_init,
195 .disconnect = usb_storage_disconnect,
196 .transfer_complete = usb_storage_transfer_complete,
197 .control_request = usb_storage_control_request,
198 #ifdef HAVE_HOTSWAP
199 .notify_hotswap = usb_storage_notify_hotswap,
200 #endif
202 #endif
203 #ifdef USB_ENABLE_SERIAL
204 [USB_DRIVER_SERIAL] = {
205 .enabled = false,
206 .needs_exclusive_storage = false,
207 .first_interface = 0,
208 .last_interface = 0,
209 .request_endpoints = usb_serial_request_endpoints,
210 .set_first_interface = usb_serial_set_first_interface,
211 .get_config_descriptor = usb_serial_get_config_descriptor,
212 .init_connection = usb_serial_init_connection,
213 .init = usb_serial_init,
214 .disconnect = usb_serial_disconnect,
215 .transfer_complete = usb_serial_transfer_complete,
216 .control_request = usb_serial_control_request,
217 #ifdef HAVE_HOTSWAP
218 .notify_hotswap = NULL,
219 #endif
221 #endif
222 #ifdef USB_ENABLE_CHARGING_ONLY
223 [USB_DRIVER_CHARGING_ONLY] = {
224 .enabled = false,
225 .needs_exclusive_storage = false,
226 .first_interface = 0,
227 .last_interface = 0,
228 .request_endpoints = usb_charging_only_request_endpoints,
229 .set_first_interface = usb_charging_only_set_first_interface,
230 .get_config_descriptor = usb_charging_only_get_config_descriptor,
231 .init_connection = NULL,
232 .init = NULL,
233 .disconnect = NULL,
234 .transfer_complete = NULL,
235 .control_request = NULL,
236 #ifdef HAVE_HOTSWAP
237 .notify_hotswap = NULL,
238 #endif
240 #endif
241 #ifdef USB_ENABLE_HID
242 [USB_DRIVER_HID] = {
243 .enabled = false,
244 .needs_exclusive_storage = false,
245 .first_interface = 0,
246 .last_interface = 0,
247 .request_endpoints = usb_hid_request_endpoints,
248 .set_first_interface = usb_hid_set_first_interface,
249 .get_config_descriptor = usb_hid_get_config_descriptor,
250 .init_connection = usb_hid_init_connection,
251 .init = usb_hid_init,
252 .disconnect = usb_hid_disconnect,
253 .transfer_complete = usb_hid_transfer_complete,
254 .control_request = usb_hid_control_request,
255 #ifdef HAVE_HOTSWAP
256 .notify_hotswap = NULL,
257 #endif
259 #endif
262 static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
264 static unsigned char response_data[256] USB_DEVBSS_ATTR;
266 static short hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
267 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
268 #ifdef IPOD_ARCH
269 static void set_serial_descriptor(void)
271 #ifdef IPOD_VIDEO
272 uint32_t* serial = (uint32_t*)0x20004034;
273 #else
274 uint32_t* serial = (uint32_t*)0x20002034;
275 #endif
277 /* We need to convert from a little-endian 64-bit int
278 into a utf-16 string of hex characters */
279 short* p = &usb_string_iSerial.wString[24];
280 uint32_t x;
281 int i, j;
283 for(i = 0; i < 2; i++) {
284 x = serial[i];
285 for(j = 0; j < 8; j++) {
286 *p-- = hex[x & 0xf];
287 x >>= 4;
290 usb_string_iSerial.bLength = 52;
292 #elif defined(HAVE_AS3514)
293 static void set_serial_descriptor(void)
295 unsigned char serial[16];
296 /* Align 32 digits right in the 40-digit serial number */
297 short* p = &usb_string_iSerial.wString[1];
298 int i;
300 ascodec_readbytes(AS3514_UID_0, 0x10, serial);
301 for(i = 0; i < 16; i++) {
302 *p++ = hex[(serial[i] >> 4) & 0xF];
303 *p++ = hex[(serial[i] >> 0) & 0xF];
305 usb_string_iSerial.bLength = 68;
307 #elif (CONFIG_STORAGE & STORAGE_ATA)
308 /* If we don't know the device serial number, use the one
309 * from the disk */
310 static void set_serial_descriptor(void)
312 short* p = &usb_string_iSerial.wString[1];
313 unsigned short* identify = ata_get_identify();
314 unsigned short x;
315 int i;
317 for(i = 10; i < 20; i++) {
318 x = identify[i];
319 *p++ = hex[(x >> 12) & 0xF];
320 *p++ = hex[(x >> 8) & 0xF];
321 *p++ = hex[(x >> 4) & 0xF];
322 *p++ = hex[(x >> 0) & 0xF];
324 usb_string_iSerial.bLength = 84;
326 #elif (CONFIG_STORAGE & STORAGE_RAMDISK)
327 /* This "serial number" isn't unique, but it should never actually
328 appear in non-testing use */
329 static void set_serial_descriptor(void)
331 short* p = &usb_string_iSerial.wString[1];
332 int i;
333 for(i = 0; i < 16; i++) {
334 *p++ = hex[(2 * i) & 0xF];
335 *p++ = hex[(2 * i + 1) & 0xF];
337 usb_string_iSerial.bLength = 68;
339 #else
340 static void set_serial_descriptor(void)
342 device_descriptor.iSerialNumber = 0;
344 #endif
346 void usb_core_init(void)
348 int i;
349 if (initialized)
350 return;
352 usb_drv_init();
354 /* class driver init functions should be safe to call even if the driver
355 * won't be used. This simplifies other logic (i.e. we don't need to know
356 * yet which drivers will be enabled */
357 for(i = 0; i < USB_NUM_DRIVERS; i++)
358 if(drivers[i].init != NULL)
359 drivers[i].init();
361 initialized = true;
362 usb_state = DEFAULT;
363 logf("usb_core_init() finished");
366 void usb_core_exit(void)
368 int i;
369 for(i = 0; i < USB_NUM_DRIVERS; i++)
370 if(drivers[i].enabled && drivers[i].disconnect != NULL)
372 drivers[i].disconnect();
373 drivers[i].enabled = false;
376 if(initialized) {
377 usb_drv_exit();
378 initialized = false;
380 usb_state = DEFAULT;
381 logf("usb_core_exit() finished");
384 void usb_core_handle_transfer_completion(
385 struct usb_transfer_completion_event_data* event)
387 completion_handler_t handler;
388 int ep = event->endpoint;
390 switch(ep) {
391 case EP_CONTROL:
392 logf("ctrl handled %ld",current_tick);
393 usb_core_control_request_handler(
394 (struct usb_ctrlrequest*)event->data);
395 break;
396 default:
397 handler = ep_data[ep].completion_handler[EP_DIR(event->dir)];
398 if(handler != NULL)
399 handler(ep, event->dir, event->status, event->length);
400 break;
404 void usb_core_enable_driver(int driver, bool enabled)
406 drivers[driver].enabled = enabled;
409 bool usb_core_driver_enabled(int driver)
411 return drivers[driver].enabled;
414 bool usb_core_any_exclusive_storage(void)
416 int i;
417 for(i = 0; i < USB_NUM_DRIVERS; i++)
418 if(drivers[i].enabled && drivers[i].needs_exclusive_storage)
419 return true;
421 return false;
424 #ifdef HAVE_HOTSWAP
425 void usb_core_hotswap_event(int volume, bool inserted)
427 int i;
428 for(i = 0; i < USB_NUM_DRIVERS; i++)
429 if(drivers[i].enabled && drivers[i].notify_hotswap != NULL)
430 drivers[i].notify_hotswap(volume, inserted);
432 #endif
434 static void usb_core_set_serial_function_id(void)
436 int i, id = 0;
438 for(i = 0; i < USB_NUM_DRIVERS; i++)
439 if(drivers[i].enabled)
440 id |= 1 << i;
442 usb_string_iSerial.wString[0] = hex[id];
445 int usb_core_request_endpoint(int type, int dir, struct usb_class_driver* drv)
447 int ret, ep;
449 ret = usb_drv_request_endpoint(type, dir);
451 if(ret == -1)
452 return -1;
454 dir = EP_DIR(ret);
455 ep = EP_NUM(ret);
457 ep_data[ep].completion_handler[dir] = drv->transfer_complete;
458 ep_data[ep].control_handler[dir] = drv->control_request;
460 return ret;
463 void usb_core_release_endpoint(int ep)
465 int dir;
467 usb_drv_release_endpoint(ep);
469 dir = EP_DIR(ep);
470 ep = EP_NUM(ep);
472 ep_data[ep].completion_handler[dir] = NULL;
473 ep_data[ep].control_handler[dir] = NULL;
476 static void allocate_interfaces_and_endpoints(void)
478 int i;
479 int interface = 0;
481 memset(ep_data, 0, sizeof(ep_data));
483 for(i = 0; i < USB_NUM_ENDPOINTS; i++) {
484 usb_drv_release_endpoint(i | USB_DIR_OUT);
485 usb_drv_release_endpoint(i | USB_DIR_IN);
488 for(i = 0; i < USB_NUM_DRIVERS; i++) {
489 if(drivers[i].enabled) {
490 drivers[i].first_interface = interface;
492 if(drivers[i].request_endpoints(&drivers[i])) {
493 drivers[i].enabled = false;
494 continue;
497 interface = drivers[i].set_first_interface(interface);
498 drivers[i].last_interface = interface;
501 usb_core_num_interfaces = interface;
505 static void control_request_handler_drivers(struct usb_ctrlrequest* req)
507 int i, interface = req->wIndex & 0xff;
508 bool handled = false;
510 for(i = 0; i < USB_NUM_DRIVERS; i++) {
511 if(drivers[i].enabled &&
512 drivers[i].control_request &&
513 drivers[i].first_interface <= interface &&
514 drivers[i].last_interface > interface)
516 handled = drivers[i].control_request(req, response_data);
517 if(handled)
518 break;
521 if(!handled) {
522 /* nope. flag error */
523 logf("bad req:desc %d:%d", req->bRequest, req->wValue >> 8);
524 usb_drv_stall(EP_CONTROL, true, true);
528 static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req)
530 int size;
531 bool handled = true;
532 const void* ptr = NULL;
533 int length = req->wLength;
534 int index = req->wValue & 0xff;
536 switch(req->wValue >> 8) { /* type */
537 case USB_DT_DEVICE:
538 ptr = &device_descriptor;
539 size = sizeof(struct usb_device_descriptor);
540 break;
542 case USB_DT_OTHER_SPEED_CONFIG:
543 case USB_DT_CONFIG: {
544 int i, max_packet_size;
546 if(req->wValue>>8==USB_DT_CONFIG) {
547 max_packet_size = (usb_drv_port_speed() ? 512 : 64);
548 config_descriptor.bDescriptorType = USB_DT_CONFIG;
550 else {
551 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
552 config_descriptor.bDescriptorType =
553 USB_DT_OTHER_SPEED_CONFIG;
555 size = sizeof(struct usb_config_descriptor);
557 for(i = 0; i < USB_NUM_DRIVERS; i++)
558 if(drivers[i].enabled && drivers[i].get_config_descriptor)
559 size += drivers[i].get_config_descriptor(
560 &response_data[size], max_packet_size);
562 config_descriptor.bNumInterfaces = usb_core_num_interfaces;
563 config_descriptor.wTotalLength = (uint16_t)size;
564 memcpy(&response_data[0], &config_descriptor,
565 sizeof(struct usb_config_descriptor));
567 ptr = response_data;
568 break;
571 case USB_DT_STRING:
572 logf("STRING %d", index);
573 if((unsigned)index < (sizeof(usb_strings) /
574 sizeof(struct usb_string_descriptor*))) {
575 size = usb_strings[index]->bLength;
576 ptr = usb_strings[index];
578 else {
579 logf("bad string id %d", index);
580 usb_drv_stall(EP_CONTROL, true, true);
582 break;
584 case USB_DT_DEVICE_QUALIFIER:
585 ptr = &qualifier_descriptor;
586 size = sizeof(struct usb_qualifier_descriptor);
587 break;
589 default:
590 logf("ctrl desc.");
591 handled = false;
592 control_request_handler_drivers(req);
593 break;
596 if(ptr) {
597 logf("data %d (%d)", size, length);
598 length = MIN(size, length);
600 if (ptr != response_data)
601 memcpy(response_data, ptr, length);
603 usb_drv_recv(EP_CONTROL, NULL, 0);
604 usb_drv_send(EP_CONTROL, response_data, length);
608 static void request_handler_device(struct usb_ctrlrequest* req)
610 int i;
612 switch(req->bRequest) {
613 case USB_REQ_GET_CONFIGURATION: {
614 logf("usb_core: GET_CONFIG");
615 response_data[0] = (usb_state == ADDRESS ? 0 : 1);
616 usb_drv_recv(EP_CONTROL, NULL, 0);
617 usb_drv_send(EP_CONTROL, response_data, 1);
618 break;
620 case USB_REQ_SET_CONFIGURATION: {
621 logf("usb_core: SET_CONFIG");
622 usb_drv_cancel_all_transfers();
623 if(req->wValue) {
624 usb_state = CONFIGURED;
625 for(i = 0; i < USB_NUM_DRIVERS; i++)
626 if(drivers[i].enabled && drivers[i].init_connection)
627 drivers[i].init_connection();
629 else
630 usb_state = ADDRESS;
632 usb_drv_send(EP_CONTROL, NULL, 0);
633 break;
635 case USB_REQ_SET_ADDRESS: {
636 unsigned char address = req->wValue;
637 logf("usb_core: SET_ADR %d", address);
638 usb_drv_send(EP_CONTROL, NULL, 0);
639 usb_drv_cancel_all_transfers();
640 usb_address = address;
641 usb_drv_set_address(usb_address);
642 usb_state = ADDRESS;
643 break;
645 case USB_REQ_GET_DESCRIPTOR:
646 logf("usb_core: GET_DESC %d", req->wValue >> 8);
647 request_handler_device_get_descriptor(req);
648 break;
649 case USB_REQ_CLEAR_FEATURE:
650 break;
651 case USB_REQ_SET_FEATURE:
652 if(req->wValue==USB_DEVICE_TEST_MODE) {
653 int mode = req->wIndex >> 8;
654 usb_drv_send(EP_CONTROL, NULL, 0);
655 usb_drv_set_test_mode(mode);
657 break;
658 case USB_REQ_GET_STATUS:
659 response_data[0] = 0;
660 response_data[1] = 0;
661 usb_drv_recv(EP_CONTROL, NULL, 0);
662 usb_drv_send(EP_CONTROL, response_data, 2);
663 break;
664 default:
665 break;
669 static void request_handler_interface_standard(struct usb_ctrlrequest* req)
671 switch (req->bRequest)
673 case USB_REQ_SET_INTERFACE:
674 logf("usb_core: SET_INTERFACE");
675 usb_drv_send(EP_CONTROL, NULL, 0);
676 break;
678 case USB_REQ_GET_INTERFACE:
679 logf("usb_core: GET_INTERFACE");
680 response_data[0] = 0;
681 usb_drv_recv(EP_CONTROL, NULL, 0);
682 usb_drv_send(EP_CONTROL, response_data, 1);
683 break;
684 case USB_REQ_CLEAR_FEATURE:
685 break;
686 case USB_REQ_SET_FEATURE:
687 break;
688 case USB_REQ_GET_STATUS:
689 response_data[0] = 0;
690 response_data[1] = 0;
691 usb_drv_recv(EP_CONTROL, NULL, 0);
692 usb_drv_send(EP_CONTROL, response_data, 2);
693 break;
694 default:
695 control_request_handler_drivers(req);
696 break;
700 static void request_handler_interface(struct usb_ctrlrequest* req)
702 switch(req->bRequestType & USB_TYPE_MASK) {
703 case USB_TYPE_STANDARD:
704 request_handler_interface_standard(req);
705 break;
706 case USB_TYPE_CLASS:
707 control_request_handler_drivers(req);
708 break;
709 case USB_TYPE_VENDOR:
710 break;
714 static void request_handler_endoint_drivers(struct usb_ctrlrequest* req)
716 bool handled = false;
717 control_handler_t control_handler = NULL;
719 if(EP_NUM(req->wIndex) < USB_NUM_ENDPOINTS)
720 control_handler =
721 ep_data[EP_NUM(req->wIndex)].control_handler[EP_DIR(req->wIndex)];
723 if(control_handler)
724 handled = control_handler(req, response_data);
726 if(!handled) {
727 /* nope. flag error */
728 logf("usb bad req %d", req->bRequest);
729 usb_drv_stall(EP_CONTROL, true, true);
733 static void request_handler_endpoint_standard(struct usb_ctrlrequest* req)
735 switch (req->bRequest) {
736 case USB_REQ_CLEAR_FEATURE:
737 if(req->wValue == USB_ENDPOINT_HALT)
738 usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex));
740 usb_drv_send(EP_CONTROL, NULL, 0);
741 break;
742 case USB_REQ_SET_FEATURE:
743 if(req->wValue == USB_ENDPOINT_HALT)
744 usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex));
746 usb_drv_send(EP_CONTROL, NULL, 0);
747 break;
748 case USB_REQ_GET_STATUS:
749 response_data[0] = 0;
750 response_data[1] = 0;
751 logf("usb_core: GET_STATUS");
752 if(req->wIndex > 0)
753 response_data[0] = usb_drv_stalled(EP_NUM(req->wIndex),
754 EP_DIR(req->wIndex));
756 usb_drv_recv(EP_CONTROL, NULL, 0);
757 usb_drv_send(EP_CONTROL, response_data, 2);
758 break;
759 default:
760 request_handler_endoint_drivers(req);
761 break;
765 static void request_handler_endpoint(struct usb_ctrlrequest* req)
767 switch(req->bRequestType & USB_TYPE_MASK) {
768 case USB_TYPE_STANDARD:
769 request_handler_endpoint_standard(req);
770 break;
771 case USB_TYPE_CLASS:
772 request_handler_endoint_drivers(req);
773 break;
774 case USB_TYPE_VENDOR:
775 default:
776 break;
780 /* Handling USB requests starts here */
781 static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
783 if(usb_state == DEFAULT) {
784 set_serial_descriptor();
785 usb_core_set_serial_function_id();
787 allocate_interfaces_and_endpoints();
790 switch(req->bRequestType & USB_RECIP_MASK) {
791 case USB_RECIP_DEVICE:
792 request_handler_device(req);
793 break;
794 case USB_RECIP_INTERFACE:
795 request_handler_interface(req);
796 break;
797 case USB_RECIP_ENDPOINT:
798 request_handler_endpoint(req);
799 break;
800 case USB_RECIP_OTHER:
801 logf("unsupported recipient");
802 break;
804 //logf("control handled");
807 /* called by usb_drv_int() */
808 void usb_core_bus_reset(void)
810 usb_address = 0;
811 usb_state = DEFAULT;
814 /* called by usb_drv_transfer_completed() */
815 void usb_core_transfer_complete(int endpoint, int dir, int status, int length)
817 struct usb_transfer_completion_event_data *completion_event;
819 switch (endpoint) {
820 case EP_CONTROL:
821 /* already handled */
822 break;
824 default:
825 completion_event = &ep_data[endpoint].completion_event[EP_DIR(dir)];
827 completion_event->endpoint = endpoint;
828 completion_event->dir = dir;
829 completion_event->data = 0;
830 completion_event->status = status;
831 completion_event->length = length;
832 /* All other endoints. Let the thread deal with it */
833 usb_signal_transfer_completion(completion_event);
834 break;
838 /* called by usb_drv_int() */
839 void usb_core_control_request(struct usb_ctrlrequest* req)
841 struct usb_transfer_completion_event_data* completion_event =
842 &ep_data[EP_CONTROL].completion_event[EP_DIR(USB_DIR_IN)];
844 completion_event->endpoint = EP_CONTROL;
845 completion_event->dir = 0;
846 completion_event->data = (void*)req;
847 completion_event->status = 0;
848 completion_event->length = 0;
849 logf("ctrl received %ld", current_tick);
850 usb_signal_transfer_completion(completion_event);
853 #ifdef HAVE_USB_POWER
854 unsigned short usb_allowed_current()
856 return (usb_state == CONFIGURED) ? MAX(USB_MAX_CURRENT, 100) : 100;
858 #endif