Add note to Bookmarking sections that bookmarking only works from the file browser...
[kugel-rb.git] / firmware / usbstack / usb_core.c
blob7b80d0bcab65ef4544b82eb7f84b5386e43807a9
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','0','0','0','0','0',
141 '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
142 '0','0','0','0','0','0','0','0','0'}
145 /* Generic for all targets */
147 /* this is stringid #0: languages supported */
148 static const struct usb_string_descriptor __attribute__((aligned(2)))
149 lang_descriptor =
152 USB_DT_STRING,
153 {0x0409} /* LANGID US English */
156 static const struct usb_string_descriptor* const usb_strings[] =
158 &lang_descriptor,
159 &usb_string_iManufacturer,
160 &usb_string_iProduct,
161 &usb_string_iSerial
164 static int usb_address = 0;
165 static bool initialized = false;
166 static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
168 static int usb_core_num_interfaces;
170 typedef void (*completion_handler_t)(int ep,int dir,int status,int length);
171 typedef bool (*control_handler_t)(struct usb_ctrlrequest* req,unsigned char* dest);
173 static struct
175 completion_handler_t completion_handler[2];
176 control_handler_t control_handler[2];
177 struct usb_transfer_completion_event_data completion_event[2];
178 } ep_data[USB_NUM_ENDPOINTS];
180 static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
182 #ifdef USB_ENABLE_STORAGE
183 [USB_DRIVER_MASS_STORAGE] = {
184 .enabled = false,
185 .needs_exclusive_storage = true,
186 .first_interface = 0,
187 .last_interface = 0,
188 .request_endpoints = usb_storage_request_endpoints,
189 .set_first_interface = usb_storage_set_first_interface,
190 .get_config_descriptor = usb_storage_get_config_descriptor,
191 .init_connection = usb_storage_init_connection,
192 .init = usb_storage_init,
193 .disconnect = usb_storage_disconnect,
194 .transfer_complete = usb_storage_transfer_complete,
195 .control_request = usb_storage_control_request,
196 #ifdef HAVE_HOTSWAP
197 .notify_hotswap = usb_storage_notify_hotswap,
198 #endif
200 #endif
201 #ifdef USB_ENABLE_SERIAL
202 [USB_DRIVER_SERIAL] = {
203 .enabled = false,
204 .needs_exclusive_storage = false,
205 .first_interface = 0,
206 .last_interface = 0,
207 .request_endpoints = usb_serial_request_endpoints,
208 .set_first_interface = usb_serial_set_first_interface,
209 .get_config_descriptor = usb_serial_get_config_descriptor,
210 .init_connection = usb_serial_init_connection,
211 .init = usb_serial_init,
212 .disconnect = usb_serial_disconnect,
213 .transfer_complete = usb_serial_transfer_complete,
214 .control_request = usb_serial_control_request,
215 #ifdef HAVE_HOTSWAP
216 .notify_hotswap = NULL,
217 #endif
219 #endif
220 #ifdef USB_ENABLE_CHARGING_ONLY
221 [USB_DRIVER_CHARGING_ONLY] = {
222 .enabled = false,
223 .needs_exclusive_storage = false,
224 .first_interface = 0,
225 .last_interface = 0,
226 .request_endpoints = usb_charging_only_request_endpoints,
227 .set_first_interface = usb_charging_only_set_first_interface,
228 .get_config_descriptor = usb_charging_only_get_config_descriptor,
229 .init_connection = NULL,
230 .init = NULL,
231 .disconnect = NULL,
232 .transfer_complete = NULL,
233 .control_request = NULL,
234 #ifdef HAVE_HOTSWAP
235 .notify_hotswap = NULL,
236 #endif
238 #endif
239 #ifdef USB_ENABLE_HID
240 [USB_DRIVER_HID] = {
241 .enabled = false,
242 .needs_exclusive_storage = false,
243 .first_interface = 0,
244 .last_interface = 0,
245 .request_endpoints = usb_hid_request_endpoints,
246 .set_first_interface = usb_hid_set_first_interface,
247 .get_config_descriptor = usb_hid_get_config_descriptor,
248 .init_connection = usb_hid_init_connection,
249 .init = usb_hid_init,
250 .disconnect = usb_hid_disconnect,
251 .transfer_complete = usb_hid_transfer_complete,
252 .control_request = usb_hid_control_request,
253 #ifdef HAVE_HOTSWAP
254 .notify_hotswap = NULL,
255 #endif
257 #endif
260 static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
262 static unsigned char response_data[256] USB_DEVBSS_ATTR;
264 static short hex[16] = {'0','1','2','3','4','5','6','7',
265 '8','9','A','B','C','D','E','F'};
266 #ifdef IPOD_ARCH
267 static void set_serial_descriptor(void)
269 #ifdef IPOD_VIDEO
270 uint32_t* serial = (uint32_t*)(0x20004034);
271 #else
272 uint32_t* serial = (uint32_t*)(0x20002034);
273 #endif
275 /* We need to convert from a little-endian 64-bit int
276 into a utf-16 string of hex characters */
277 short* p = &usb_string_iSerial.wString[24];
278 uint32_t x;
279 int i,j;
281 for (i = 0; i < 2; i++) {
282 x = serial[i];
283 for (j=0;j<8;j++) {
284 *p-- = hex[x & 0xf];
285 x >>= 4;
288 usb_string_iSerial.bLength=52;
290 #elif defined(HAVE_AS3514)
291 static void set_serial_descriptor(void)
293 unsigned char serial[16];
294 /* Align 32 digits right in the 40-digit serial number */
295 short* p = &usb_string_iSerial.wString[1];
296 int i;
298 ascodec_readbytes(AS3514_UID_0, 0x10, serial);
299 for (i = 0; i < 16; i++) {
300 *p++ = hex[(serial[i] >> 4) & 0xF];
301 *p++ = hex[(serial[i] >> 0) & 0xF];
303 usb_string_iSerial.bLength=68;
305 #elif (CONFIG_STORAGE & STORAGE_ATA)
306 /* If we don't know the device serial number, use the one
307 * from the disk */
308 static void set_serial_descriptor(void)
310 short* p = &usb_string_iSerial.wString[1];
311 unsigned short* identify = ata_get_identify();
312 unsigned short x;
313 int i;
315 for (i = 10; i < 20; i++) {
316 x = identify[i];
317 *p++ = hex[(x >> 12) & 0xF];
318 *p++ = hex[(x >> 8) & 0xF];
319 *p++ = hex[(x >> 4) & 0xF];
320 *p++ = hex[(x >> 0) & 0xF];
322 usb_string_iSerial.bLength=84;
324 #elif (CONFIG_STORAGE & STORAGE_RAMDISK)
325 /* This "serial number" isn't unique, but it should never actually
326 appear in non-testing use */
327 static void set_serial_descriptor(void)
329 short* p = &usb_string_iSerial.wString[1];
330 int i;
331 for (i = 0; i < 16; i++) {
332 *p++ = hex[(2*i)&0xF];
333 *p++ = hex[(2*i+1)&0xF];
335 usb_string_iSerial.bLength=68;
337 #else
338 static void set_serial_descriptor(void)
340 device_descriptor.iSerialNumber = 0;
342 #endif
344 void usb_core_init(void)
346 int i;
347 if (initialized)
348 return;
350 usb_drv_init();
352 /* class driver init functions should be safe to call even if the driver
353 * won't be used. This simplifies other logic (i.e. we don't need to know
354 * yet which drivers will be enabled */
355 for(i=0;i<USB_NUM_DRIVERS;i++) {
356 if(drivers[i].init != NULL)
357 drivers[i].init();
360 initialized = true;
361 usb_state = DEFAULT;
362 logf("usb_core_init() finished");
365 void usb_core_exit(void)
367 int i;
368 for(i=0;i<USB_NUM_DRIVERS;i++) {
369 if(drivers[i].enabled && drivers[i].disconnect != NULL)
371 drivers[i].disconnect();
372 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)
420 return true;
424 return false;
427 #ifdef HAVE_HOTSWAP
428 void usb_core_hotswap_event(int volume,bool inserted)
430 int i;
431 for(i=0;i<USB_NUM_DRIVERS;i++) {
432 if(drivers[i].enabled && drivers[i].notify_hotswap!=NULL)
434 drivers[i].notify_hotswap(volume,inserted);
438 #endif
440 static void usb_core_set_serial_function_id(void)
442 int id = 0;
443 int i;
444 for(i=0;i<USB_NUM_DRIVERS;i++) {
445 if(drivers[i].enabled)
446 id |= 1<<i;
448 usb_string_iSerial.wString[0] = hex[id];
451 int usb_core_request_endpoint(int type, int dir, struct usb_class_driver* drv)
453 int ret, ep;
455 ret = usb_drv_request_endpoint(type, dir);
457 if (ret==-1)
458 return -1;
460 dir = EP_DIR(ret);
461 ep = EP_NUM(ret);
463 ep_data[ep].completion_handler[dir] = drv->transfer_complete;
464 ep_data[ep].control_handler[dir] = drv->control_request;
466 return ret;
469 void usb_core_release_endpoint(int ep)
471 int dir;
473 usb_drv_release_endpoint(ep);
475 dir = EP_DIR(ep);
476 ep = EP_NUM(ep);
478 ep_data[ep].completion_handler[dir] = NULL;
479 ep_data[ep].control_handler[dir] = NULL;
482 static void allocate_interfaces_and_endpoints(void)
484 int i;
485 int interface=0;
487 memset(ep_data,0,sizeof(ep_data));
489 for (i = 0; i < USB_NUM_ENDPOINTS; i++) {
490 usb_drv_release_endpoint(i | USB_DIR_OUT);
491 usb_drv_release_endpoint(i | USB_DIR_IN);
494 for(i=0;i<USB_NUM_DRIVERS;i++) {
495 if(drivers[i].enabled) {
496 drivers[i].first_interface = interface;
498 if (drivers[i].request_endpoints(&drivers[i])) {
499 drivers[i].enabled = false;
500 continue;
503 interface = drivers[i].set_first_interface(interface);
504 drivers[i].last_interface = interface;
507 usb_core_num_interfaces = interface;
510 static int usb_core_ack_control(struct usb_ctrlrequest* req)
512 if (req->bRequestType & USB_DIR_IN)
513 return usb_drv_recv(EP_CONTROL,NULL,0);
514 else
515 return usb_drv_send(EP_CONTROL,NULL,0);
519 static void control_request_handler_drivers(struct usb_ctrlrequest* req)
521 int i, interface = req->wIndex;
522 bool handled=false;
524 for(i=0;i<USB_NUM_DRIVERS;i++) {
525 if(drivers[i].enabled &&
526 drivers[i].control_request &&
527 drivers[i].first_interface <= interface &&
528 drivers[i].last_interface > interface)
530 handled = drivers[i].control_request(req, response_data);
531 if(handled)
532 break;
535 if(!handled) {
536 /* nope. flag error */
537 logf("bad req:desc %d:%d", req->bRequest, req->wValue>>8);
538 usb_drv_stall(EP_CONTROL, true, true);
539 usb_core_ack_control(req);
543 static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req)
545 int size;
546 bool handled = true;
547 const void* ptr = NULL;
548 int length = req->wLength;
549 int index = req->wValue & 0xff;
551 switch(req->wValue>>8) { /* type */
552 case USB_DT_DEVICE:
553 ptr = &device_descriptor;
554 size = sizeof(struct usb_device_descriptor);
555 break;
557 case USB_DT_OTHER_SPEED_CONFIG:
558 case USB_DT_CONFIG: {
559 int i, max_packet_size;
561 if(req->wValue>>8==USB_DT_CONFIG) {
562 max_packet_size=(usb_drv_port_speed() ? 512 : 64);
563 config_descriptor.bDescriptorType=USB_DT_CONFIG;
565 else {
566 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
567 config_descriptor.bDescriptorType =
568 USB_DT_OTHER_SPEED_CONFIG;
570 size = sizeof(struct usb_config_descriptor);
572 for(i=0;i<USB_NUM_DRIVERS;i++) {
573 if(drivers[i].enabled && drivers[i].get_config_descriptor) {
574 size+=drivers[i].get_config_descriptor(
575 &response_data[size],max_packet_size);
578 config_descriptor.bNumInterfaces = usb_core_num_interfaces;
579 config_descriptor.wTotalLength = (uint16_t)size;
580 memcpy(&response_data[0],&config_descriptor,
581 sizeof(struct usb_config_descriptor));
583 ptr = response_data;
584 break;
587 case USB_DT_STRING:
588 logf("STRING %d",index);
589 if ((unsigned)index < (sizeof(usb_strings)/
590 sizeof(struct usb_string_descriptor*))) {
591 size = usb_strings[index]->bLength;
592 ptr = usb_strings[index];
594 else {
595 logf("bad string id %d",index);
596 usb_drv_stall(EP_CONTROL,true,true);
598 break;
600 case USB_DT_DEVICE_QUALIFIER:
601 ptr = &qualifier_descriptor;
602 size = sizeof(struct usb_qualifier_descriptor);
603 break;
605 default:
606 logf("ctrl desc.");
607 handled = false;
608 control_request_handler_drivers(req);
609 break;
612 if (ptr) {
613 logf("data %d (%d)",size,length);
614 length = MIN(size,length);
616 if (ptr != response_data) {
617 memcpy(response_data,ptr,length);
620 usb_drv_recv(EP_CONTROL,NULL,0);
621 usb_drv_send(EP_CONTROL,response_data,length);
625 static void request_handler_device(struct usb_ctrlrequest* req)
627 int i;
629 switch(req->bRequest) {
630 case USB_REQ_GET_CONFIGURATION: {
631 logf("usb_core: GET_CONFIG");
632 response_data[0] = (usb_state == ADDRESS ? 0 : 1);
633 usb_drv_recv(EP_CONTROL,NULL,0);
634 usb_drv_send(EP_CONTROL, response_data, 1);
635 break;
637 case USB_REQ_SET_CONFIGURATION: {
638 logf("usb_core: SET_CONFIG");
639 usb_drv_cancel_all_transfers();
640 if(req->wValue) {
641 usb_state = CONFIGURED;
642 for(i=0;i<USB_NUM_DRIVERS;i++) {
643 if(drivers[i].enabled && drivers[i].init_connection)
644 drivers[i].init_connection();
647 else {
648 usb_state = ADDRESS;
650 usb_drv_send(EP_CONTROL,NULL,0);
651 break;
653 case USB_REQ_SET_ADDRESS: {
654 unsigned char address = req->wValue;
655 logf("usb_core: SET_ADR %d", address);
656 usb_drv_send(EP_CONTROL,NULL,0);
657 usb_drv_cancel_all_transfers();
658 usb_address = address;
659 usb_drv_set_address(usb_address);
660 usb_state = ADDRESS;
661 break;
663 case USB_REQ_GET_DESCRIPTOR:
664 logf("usb_core: GET_DESC %d", req->wValue>>8);
665 request_handler_device_get_descriptor(req);
666 break;
667 case USB_REQ_CLEAR_FEATURE:
668 break;
669 case USB_REQ_SET_FEATURE:
670 if(req->wValue==USB_DEVICE_TEST_MODE) {
671 int mode=req->wIndex>>8;
672 usb_drv_send(EP_CONTROL,NULL,0);
673 usb_drv_set_test_mode(mode);
675 break;
676 case USB_REQ_GET_STATUS:
677 response_data[0]= 0;
678 response_data[1]= 0;
679 usb_drv_recv(EP_CONTROL,NULL,0);
680 usb_drv_send(EP_CONTROL, response_data, 2);
681 break;
682 default:
683 break;
687 static void request_handler_interface_standard(struct usb_ctrlrequest* req)
689 switch (req->bRequest)
691 case USB_REQ_SET_INTERFACE:
692 logf("usb_core: SET_INTERFACE");
693 usb_drv_send(EP_CONTROL,NULL,0);
694 break;
696 case USB_REQ_GET_INTERFACE:
697 logf("usb_core: GET_INTERFACE");
698 response_data[0]=0;
699 usb_drv_recv(EP_CONTROL,NULL,0);
700 usb_drv_send(EP_CONTROL,response_data,1);
701 break;
702 case USB_REQ_CLEAR_FEATURE:
703 break;
704 case USB_REQ_SET_FEATURE:
705 break;
706 case USB_REQ_GET_STATUS:
707 response_data[0]=0;
708 response_data[1]=0;
709 usb_drv_recv(EP_CONTROL,NULL,0);
710 usb_drv_send(EP_CONTROL, response_data, 2);
711 break;
712 default:
713 control_request_handler_drivers(req);
714 break;
718 static void request_handler_interface(struct usb_ctrlrequest* req)
720 switch(req->bRequestType & USB_TYPE_MASK) {
721 case USB_TYPE_STANDARD:
722 request_handler_interface_standard(req);
723 break;
724 case USB_TYPE_CLASS:
725 control_request_handler_drivers(req);
726 break;
727 case USB_TYPE_VENDOR:
728 break;
732 static void request_handler_endpoint(struct usb_ctrlrequest* req)
734 switch (req->bRequest) {
735 case USB_REQ_CLEAR_FEATURE:
736 if (req->wValue==USB_ENDPOINT_HALT) {
737 usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex));
739 usb_drv_send(EP_CONTROL,NULL,0);
740 break;
741 case USB_REQ_SET_FEATURE:
742 if (req->wValue==USB_ENDPOINT_HALT) {
743 usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex));
745 usb_drv_send(EP_CONTROL,NULL,0);
746 break;
747 case USB_REQ_GET_STATUS:
748 response_data[0]=0;
749 response_data[1]=0;
750 logf("usb_core: GET_STATUS");
751 if(req->wIndex>0) {
752 response_data[0]=usb_drv_stalled(EP_NUM(req->wIndex),
753 EP_DIR(req->wIndex));
755 usb_drv_recv(EP_CONTROL,NULL,0);
756 usb_drv_send(EP_CONTROL,response_data,2);
757 break;
758 default: {
759 bool handled;
760 control_handler_t control_handler;
762 control_handler=
763 ep_data[EP_NUM(req->wIndex)].control_handler[EP_CONTROL];
764 if (!control_handler)
765 break;
767 handled=control_handler(req, response_data);
768 if (!handled) {
769 /* nope. flag error */
770 logf("usb bad req %d",req->bRequest);
771 usb_drv_stall(EP_CONTROL,true,true);
772 usb_core_ack_control(req);
774 break;
779 /* Handling USB requests starts here */
780 static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
782 if (usb_state==DEFAULT) {
783 set_serial_descriptor();
784 usb_core_set_serial_function_id();
786 allocate_interfaces_and_endpoints();
789 switch(req->bRequestType & USB_RECIP_MASK) {
790 case USB_RECIP_DEVICE:
791 request_handler_device(req);
792 break;
793 case USB_RECIP_INTERFACE:
794 request_handler_interface(req);
795 break;
796 case USB_RECIP_ENDPOINT:
797 request_handler_endpoint(req);
798 break;
799 case USB_RECIP_OTHER:
800 logf("unsupported recipient");
801 break;
803 //logf("control handled");
806 /* called by usb_drv_int() */
807 void usb_core_bus_reset(void)
809 usb_address=0;
810 usb_state=DEFAULT;
813 /* called by usb_drv_transfer_completed() */
814 void usb_core_transfer_complete(int endpoint,int dir,int status,int length)
816 struct usb_transfer_completion_event_data *completion_event;
818 switch (endpoint) {
819 case EP_CONTROL:
820 /* already handled */
821 break;
823 default:
824 completion_event=&ep_data[endpoint].completion_event[EP_DIR(dir)];
826 completion_event->endpoint=endpoint;
827 completion_event->dir=dir;
828 completion_event->data=0;
829 completion_event->status=status;
830 completion_event->length=length;
831 /* All other endoints. Let the thread deal with it */
832 usb_signal_transfer_completion(completion_event);
833 break;
837 /* called by usb_drv_int() */
838 void usb_core_control_request(struct usb_ctrlrequest* req)
840 struct usb_transfer_completion_event_data* completion_event =
841 &ep_data[EP_CONTROL].completion_event[EP_DIR(USB_DIR_IN)];
843 completion_event->endpoint=EP_CONTROL;
844 completion_event->dir=0;
845 completion_event->data=(void*)req;
846 completion_event->status=0;
847 completion_event->length=0;
848 logf("ctrl received %ld",current_tick);
849 usb_signal_transfer_completion(completion_event);
852 #ifdef HAVE_USB_POWER
853 unsigned short usb_allowed_current()
855 return (usb_state==CONFIGURED) ? MAX(USB_MAX_CURRENT, 100) : 100;
857 #endif