reorganise usb_core.c a bit, to make the code more readable and more maintainable...
[kugel-rb.git] / firmware / usbstack / usb_core.c
blob8c235723ad1ba0cdda6f7b9d46206f82857db0cc
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_STORAGE)
35 #include "usb_storage.h"
36 #endif
38 #if defined(USB_SERIAL)
39 #include "usb_serial.h"
40 #endif
42 #if defined(USB_CHARGING_ONLY)
43 #include "usb_charging_only.h"
44 #endif
46 /* TODO: Move target-specific stuff somewhere else (serial number reading) */
48 #ifdef HAVE_AS3514
49 #include "ascodec.h"
50 #include "as3514.h"
51 #endif
53 #if !defined(HAVE_AS3514) && !defined(IPOD_ARCH) && (CONFIG_STORAGE & STORAGE_ATA)
54 #include "ata.h"
55 #endif
57 #ifndef USB_MAX_CURRENT
58 #define USB_MAX_CURRENT 500
59 #endif
61 /*-------------------------------------------------------------------------*/
62 /* USB protocol descriptors: */
64 #define USB_SC_SCSI 0x06 /* Transparent */
65 #define USB_PROT_BULK 0x50 /* bulk only */
67 static const struct usb_device_descriptor __attribute__((aligned(2)))
68 device_descriptor=
70 .bLength = sizeof(struct usb_device_descriptor),
71 .bDescriptorType = USB_DT_DEVICE,
72 #ifndef USB_NO_HIGH_SPEED
73 .bcdUSB = 0x0200,
74 #else
75 .bcdUSB = 0x0110,
76 #endif
77 .bDeviceClass = USB_CLASS_PER_INTERFACE,
78 .bDeviceSubClass = 0,
79 .bDeviceProtocol = 0,
80 .bMaxPacketSize0 = 64,
81 .idVendor = USB_VENDOR_ID,
82 .idProduct = USB_PRODUCT_ID,
83 .bcdDevice = 0x0100,
84 .iManufacturer = 1,
85 .iProduct = 2,
86 .iSerialNumber = 3,
87 .bNumConfigurations = 1
88 } ;
90 static struct usb_config_descriptor __attribute__((aligned(2)))
91 config_descriptor =
93 .bLength = sizeof(struct usb_config_descriptor),
94 .bDescriptorType = USB_DT_CONFIG,
95 .wTotalLength = 0, /* will be filled in later */
96 .bNumInterfaces = 1,
97 .bConfigurationValue = 1,
98 .iConfiguration = 0,
99 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
100 .bMaxPower = (USB_MAX_CURRENT+1) / 2, /* In 2mA units */
103 static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
104 qualifier_descriptor =
106 .bLength = sizeof(struct usb_qualifier_descriptor),
107 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
108 .bcdUSB = 0x0200,
109 .bDeviceClass = 0,
110 .bDeviceSubClass = 0,
111 .bDeviceProtocol = 0,
112 .bMaxPacketSize0 = 64,
113 .bNumConfigurations = 1
116 static const struct usb_string_descriptor __attribute__((aligned(2)))
117 usb_string_iManufacturer =
120 USB_DT_STRING,
121 {'R','o','c','k','b','o','x','.','o','r','g'}
124 static const struct usb_string_descriptor __attribute__((aligned(2)))
125 usb_string_iProduct =
128 USB_DT_STRING,
129 {'R','o','c','k','b','o','x',' ',
130 'm','e','d','i','a',' ',
131 'p','l','a','y','e','r'}
134 static struct usb_string_descriptor __attribute__((aligned(2)))
135 usb_string_iSerial =
138 USB_DT_STRING,
139 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
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'}
144 /* Generic for all targets */
146 /* this is stringid #0: languages supported */
147 static const struct usb_string_descriptor __attribute__((aligned(2)))
148 lang_descriptor =
151 USB_DT_STRING,
152 {0x0409} /* LANGID US English */
155 static const struct usb_string_descriptor* const usb_strings[] =
157 &lang_descriptor,
158 &usb_string_iManufacturer,
159 &usb_string_iProduct,
160 &usb_string_iSerial
163 static int usb_address = 0;
164 static bool initialized = false;
165 static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
167 static int usb_core_num_interfaces;
169 typedef void (*completion_handler_t)(int ep,int dir, int status, int length);
170 typedef bool (*control_handler_t)(struct usb_ctrlrequest* req, unsigned char* dest);
172 static struct
174 completion_handler_t completion_handler[2];
175 control_handler_t control_handler[2];
176 struct usb_transfer_completion_event_data completion_event;
177 } ep_data[USB_NUM_ENDPOINTS];
179 static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
181 #ifdef USB_STORAGE
182 [USB_DRIVER_MASS_STORAGE] = {
183 .enabled = false,
184 .needs_exclusive_storage = true,
185 .first_interface = 0,
186 .last_interface = 0,
187 .request_endpoints = usb_storage_request_endpoints,
188 .set_first_interface = usb_storage_set_first_interface,
189 .get_config_descriptor = usb_storage_get_config_descriptor,
190 .init_connection = usb_storage_init_connection,
191 .init = usb_storage_init,
192 .disconnect = usb_storage_disconnect,
193 .transfer_complete = usb_storage_transfer_complete,
194 .control_request = usb_storage_control_request,
195 #ifdef HAVE_HOTSWAP
196 .notify_hotswap = usb_storage_notify_hotswap,
197 #endif
199 #endif
200 #ifdef USB_SERIAL
201 [USB_DRIVER_SERIAL] = {
202 .enabled = false,
203 .needs_exclusive_storage = false,
204 .first_interface = 0,
205 .last_interface = 0,
206 .request_endpoints = usb_serial_request_endpoints,
207 .set_first_interface = usb_serial_set_first_interface,
208 .get_config_descriptor = usb_serial_get_config_descriptor,
209 .init_connection = usb_serial_init_connection,
210 .init = usb_serial_init,
211 .disconnect = usb_serial_disconnect,
212 .transfer_complete = usb_serial_transfer_complete,
213 .control_request = usb_serial_control_request,
214 #ifdef HAVE_HOTSWAP
215 .notify_hotswap = NULL,
216 #endif
218 #endif
219 #ifdef USB_CHARGING_ONLY
220 [USB_DRIVER_CHARGING_ONLY] = {
221 .enabled = false,
222 .needs_exclusive_storage = false,
223 .first_interface = 0,
224 .last_interface = 0,
225 .request_endpoints = usb_charging_only_request_endpoints,
226 .set_first_interface = usb_charging_only_set_first_interface,
227 .get_config_descriptor = usb_charging_only_get_config_descriptor,
228 .init_connection = NULL,
229 .init = NULL,
230 .disconnect = NULL,
231 .transfer_complete = NULL,
232 .control_request = NULL,
233 #ifdef HAVE_HOTSWAP
234 .notify_hotswap = NULL,
235 #endif
237 #endif
240 static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
242 static unsigned char response_data[256] USB_DEVBSS_ATTR;
244 static short hex[16] = {'0','1','2','3','4','5','6','7',
245 '8','9','A','B','C','D','E','F'};
246 #ifdef IPOD_ARCH
247 static void set_serial_descriptor(void)
249 #ifdef IPOD_VIDEO
250 uint32_t* serial = (uint32_t*)(0x20004034);
251 #else
252 uint32_t* serial = (uint32_t*)(0x20002034);
253 #endif
255 /* We need to convert from a little-endian 64-bit int
256 into a utf-16 string of hex characters */
257 short* p = &usb_string_iSerial.wString[24];
258 uint32_t x;
259 int i,j;
261 for (i = 0; i < 2; i++) {
262 x = serial[i];
263 for (j=0;j<8;j++) {
264 *p-- = hex[x & 0xf];
265 x >>= 4;
268 usb_string_iSerial.bLength=52;
270 #elif defined(HAVE_AS3514)
271 static void set_serial_descriptor(void)
273 unsigned char serial[16];
274 /* Align 32 digits right in the 40-digit serial number */
275 short* p = &usb_string_iSerial.wString[1];
276 int i;
278 ascodec_readbytes(AS3514_UID_0, 0x10, serial);
279 for (i = 0; i < 16; i++) {
280 *p++ = hex[(serial[i] >> 4) & 0xF];
281 *p++ = hex[(serial[i] >> 0) & 0xF];
283 usb_string_iSerial.bLength=68;
285 #elif (CONFIG_STORAGE & STORAGE_ATA)
286 /* If we don't know the device serial number, use the one
287 * from the disk */
288 static void set_serial_descriptor(void)
290 short* p = &usb_string_iSerial.wString[1];
291 unsigned short* identify = ata_get_identify();
292 unsigned short x;
293 int i;
295 for (i = 10; i < 20; i++) {
296 x = identify[i];
297 *p++ = hex[(x >> 12) & 0xF];
298 *p++ = hex[(x >> 8) & 0xF];
299 *p++ = hex[(x >> 4) & 0xF];
300 *p++ = hex[(x >> 0) & 0xF];
302 usb_string_iSerial.bLength=84;
304 #elif (CONFIG_STORAGE & STORAGE_RAMDISK)
305 /* This "serial number" isn't unique, but it should never actually
306 appear in non-testing use */
307 static void set_serial_descriptor(void)
309 short* p = &usb_string_iSerial.wString[1];
310 int i;
311 for (i = 0; i < 16; i++) {
312 *p++ = hex[(2*i)&0xF];
313 *p++ = hex[(2*i+1)&0xF];
315 usb_string_iSerial.bLength=68;
317 #else
318 #warning No proper set_serial_descriptor() implementation for this target
319 static void set_serial_descriptor(void)
321 short* p = &usb_string_iSerial.wString[1];
322 int i;
323 for (i = 0; i < 16; i++) {
324 *p++ = hex[(2*i)&0xF];
325 *p++ = hex[(2*i+1)&0xF];
327 usb_string_iSerial.bLength=68;
329 #endif
331 void usb_core_init(void)
333 int i;
334 if (initialized)
335 return;
337 usb_drv_init();
339 /* class driver init functions should be safe to call even if the driver
340 * won't be used. This simplifies other logic (i.e. we don't need to know
341 * yet which drivers will be enabled */
342 for(i=0;i<USB_NUM_DRIVERS;i++) {
343 if(drivers[i].enabled && drivers[i].init != NULL)
344 drivers[i].init();
347 initialized = true;
348 usb_state = DEFAULT;
349 logf("usb_core_init() finished");
352 void usb_core_exit(void)
354 int i;
355 for(i=0;i<USB_NUM_DRIVERS;i++) {
356 if(drivers[i].enabled && drivers[i].disconnect != NULL)
358 drivers[i].disconnect();
359 drivers[i].enabled = false;
363 if (initialized) {
364 usb_drv_exit();
365 initialized = false;
367 usb_state = DEFAULT;
368 logf("usb_core_exit() finished");
371 void usb_core_handle_transfer_completion(
372 struct usb_transfer_completion_event_data* event)
374 completion_handler_t handler;
375 int ep = event->endpoint;
377 switch(ep) {
378 case EP_CONTROL:
379 logf("ctrl handled %ld",current_tick);
380 usb_core_control_request_handler(
381 (struct usb_ctrlrequest*)event->data);
382 break;
383 default:
384 handler = ep_data[ep].completion_handler[event->dir>>7];
385 if(handler != NULL)
386 handler(ep,event->dir,event->status,event->length);
387 break;
391 void usb_core_enable_driver(int driver,bool enabled)
393 drivers[driver].enabled = enabled;
396 bool usb_core_driver_enabled(int driver)
398 return drivers[driver].enabled;
401 bool usb_core_any_exclusive_storage(void)
403 int i;
404 for(i=0;i<USB_NUM_DRIVERS;i++) {
405 if(drivers[i].enabled && drivers[i].needs_exclusive_storage)
407 return true;
411 return false;
414 #ifdef HAVE_HOTSWAP
415 void usb_core_hotswap_event(int volume,bool inserted)
417 int i;
418 for(i=0;i<USB_NUM_DRIVERS;i++) {
419 if(drivers[i].enabled && drivers[i].notify_hotswap!=NULL)
421 drivers[i].notify_hotswap(volume,inserted);
425 #endif
427 static void usb_core_set_serial_function_id(void)
429 int id = 0;
430 int i;
431 for(i=0;i<USB_NUM_DRIVERS;i++) {
432 if(drivers[i].enabled)
433 id |= 1<<i;
435 usb_string_iSerial.wString[0] = hex[id];
438 int usb_core_request_endpoint(int dir, struct usb_class_driver* drv)
440 int ret, ep;
442 ret = usb_drv_request_endpoint(dir);
444 if (ret==-1)
445 return -1;
447 ep = ret & 0x7f;
448 dir = ret >> 7;
450 ep_data[ep].completion_handler[dir] = drv->transfer_complete;
451 ep_data[ep].control_handler[dir] = drv->control_request;
453 return ret;
456 void usb_core_release_endpoint(int ep)
458 int dir;
460 usb_drv_release_endpoint(ep);
462 dir = ep >> 7;
463 ep &= 0x7f;
465 ep_data[ep].completion_handler[dir] = NULL;
466 ep_data[ep].control_handler[dir] = NULL;
469 static void allocate_interfaces_and_endpoints(void)
471 int i;
472 int interface=0;
474 memset(ep_data,0,sizeof(ep_data));
476 for (i = 0; i < USB_NUM_ENDPOINTS; i++) {
477 usb_drv_release_endpoint(i | USB_DIR_OUT);
478 usb_drv_release_endpoint(i | USB_DIR_IN);
481 for(i=0;i<USB_NUM_DRIVERS;i++) {
482 if(drivers[i].enabled) {
483 drivers[i].first_interface = interface;
485 if (drivers[i].request_endpoints(&drivers[i])) {
486 drivers[i].enabled = false;
487 continue;
490 interface = drivers[i].set_first_interface(interface);
491 drivers[i].last_interface = interface;
494 usb_core_num_interfaces = interface;
497 static void control_request_handler_drivers(struct usb_ctrlrequest* req)
499 int i;
500 bool handled=false;
501 for(i=0;i<USB_NUM_DRIVERS;i++) {
502 if(drivers[i].enabled &&
503 drivers[i].control_request &&
504 drivers[i].first_interface <= (req->wIndex) &&
505 drivers[i].last_interface > (req->wIndex))
507 handled = drivers[i].control_request(req, response_data);
508 if(handled)
509 break;
512 if(!handled) {
513 /* nope. flag error */
514 logf("bad req:desc %d:%d", req->bRequest, req->wValue>>8);
515 usb_drv_stall(EP_CONTROL, true,true);
516 usb_core_ack_control(req);
520 static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req)
522 int size;
523 bool handled = true;
524 const void* ptr = NULL;
525 int length = req->wLength;
526 int index = req->wValue & 0xff;
528 switch(req->wValue>>8) { /* type */
529 case USB_DT_DEVICE:
530 ptr = &device_descriptor;
531 size = sizeof(struct usb_device_descriptor);
532 break;
534 case USB_DT_OTHER_SPEED_CONFIG:
535 case USB_DT_CONFIG: {
536 int i, max_packet_size;
538 if(req->wValue>>8==USB_DT_CONFIG) {
539 max_packet_size=(usb_drv_port_speed() ? 512 : 64);
540 config_descriptor.bDescriptorType=USB_DT_CONFIG;
542 else {
543 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
544 config_descriptor.bDescriptorType =
545 USB_DT_OTHER_SPEED_CONFIG;
547 size = sizeof(struct usb_config_descriptor);
549 for(i=0;i<USB_NUM_DRIVERS;i++) {
550 if(drivers[i].enabled && drivers[i].get_config_descriptor) {
551 size+=drivers[i].get_config_descriptor(
552 &response_data[size],max_packet_size);
555 config_descriptor.bNumInterfaces = usb_core_num_interfaces;
556 config_descriptor.wTotalLength = size;
557 memcpy(&response_data[0],&config_descriptor,
558 sizeof(struct usb_config_descriptor));
560 ptr = response_data;
561 break;
564 case USB_DT_STRING:
565 logf("STRING %d",index);
566 if ((unsigned)index < (sizeof(usb_strings)/
567 sizeof(struct usb_string_descriptor*))) {
568 size = usb_strings[index]->bLength;
569 ptr = usb_strings[index];
571 else {
572 logf("bad string id %d",index);
573 usb_drv_stall(EP_CONTROL,true,true);
575 break;
577 case USB_DT_DEVICE_QUALIFIER:
578 ptr = &qualifier_descriptor;
579 size = sizeof(struct usb_qualifier_descriptor);
580 break;
582 default:
583 logf("ctrl desc.");
584 handled = false;
585 control_request_handler_drivers(req);
586 break;
589 if (ptr) {
590 logf("data %d (%d)",size,length);
591 length = MIN(size,length);
593 if (ptr != response_data) {
594 memcpy(response_data,ptr,length);
597 if(usb_drv_send(EP_CONTROL,response_data,length))
598 return;
600 if (handled)
601 usb_core_ack_control(req);
604 static void request_handler_device(struct usb_ctrlrequest* req)
606 int i;
608 switch(req->bRequest) {
609 case USB_REQ_GET_CONFIGURATION: {
610 logf("usb_core: GET_CONFIG");
611 response_data[0] = (usb_state == ADDRESS ? 0 : 1);
612 if(!usb_drv_send(EP_CONTROL, response_data, 1))
613 usb_core_ack_control(req);
614 break;
616 case USB_REQ_SET_CONFIGURATION: {
617 logf("usb_core: SET_CONFIG");
618 usb_drv_cancel_all_transfers();
619 if(req->wValue) {
620 usb_state = CONFIGURED;
621 for(i=0;i<USB_NUM_DRIVERS;i++) {
622 if(drivers[i].enabled && drivers[i].init_connection)
623 drivers[i].init_connection();
626 else {
627 usb_state = ADDRESS;
629 usb_core_ack_control(req);
630 break;
632 case USB_REQ_SET_ADDRESS: {
633 unsigned char address = req->wValue;
634 logf("usb_core: SET_ADR %d", address);
635 if(usb_core_ack_control(req))
636 break;
637 usb_drv_cancel_all_transfers();
638 usb_address = address;
639 usb_drv_set_address(usb_address);
640 usb_state = ADDRESS;
641 break;
643 case USB_REQ_GET_DESCRIPTOR:
644 logf("usb_core: GET_DESC %d", req->wValue>>8);
645 request_handler_device_get_descriptor(req);
646 break;
647 case USB_REQ_CLEAR_FEATURE:
648 break;
649 case USB_REQ_SET_FEATURE:
650 if(req->wValue==USB_DEVICE_TEST_MODE) {
651 int mode=req->wIndex>>8;
652 usb_core_ack_control(req);
653 usb_drv_set_test_mode(mode);
655 break;
656 case USB_REQ_GET_STATUS:
657 response_data[0]= 0;
658 response_data[1]= 0;
659 if(!usb_drv_send(EP_CONTROL, response_data, 2))
660 usb_core_ack_control(req);
661 break;
662 default:
663 break;
667 static void request_handler_interface_standard(struct usb_ctrlrequest* req)
669 switch (req->bRequest)
671 case USB_REQ_SET_INTERFACE:
672 logf("usb_core: SET_INTERFACE");
673 usb_core_ack_control(req);
674 break;
676 case USB_REQ_GET_INTERFACE:
677 logf("usb_core: GET_INTERFACE");
678 response_data[0]=0;
679 if(!usb_drv_send(EP_CONTROL,response_data,1))
680 usb_core_ack_control(req);
681 break;
682 case USB_REQ_CLEAR_FEATURE:
683 break;
684 case USB_REQ_SET_FEATURE:
685 break;
686 case USB_REQ_GET_STATUS:
687 response_data[0]=0;
688 response_data[1]=0;
689 if(!usb_drv_send(EP_CONTROL, response_data, 2))
690 usb_core_ack_control(req);
691 break;
692 default:
693 control_request_handler_drivers(req);
694 break;
698 static void request_handler_interface(struct usb_ctrlrequest* req)
700 switch(req->bRequestType & USB_TYPE_MASK) {
701 case USB_TYPE_STANDARD:
702 request_handler_interface_standard(req);
703 break;
704 case USB_TYPE_CLASS:
705 control_request_handler_drivers(req);
706 break;
707 case USB_TYPE_VENDOR:
708 break;
712 static void request_handler_endpoint(struct usb_ctrlrequest* req)
714 switch (req->bRequest) {
715 case USB_REQ_CLEAR_FEATURE:
716 if (req->wValue==USB_ENDPOINT_HALT) {
717 usb_drv_stall(req->wIndex & 0xf, false,
718 (req->wIndex & USB_DIR_IN)!=0);
720 usb_core_ack_control(req);
721 break;
722 case USB_REQ_SET_FEATURE:
723 if (req->wValue==USB_ENDPOINT_HALT) {
724 usb_drv_stall(req->wIndex & 0xf,true,
725 (req->wIndex & USB_DIR_IN)!=0);
727 usb_core_ack_control(req);
728 break;
729 case USB_REQ_GET_STATUS:
730 response_data[0]=0;
731 response_data[1]=0;
732 logf("usb_core: GET_STATUS");
733 if(req->wIndex>0) {
734 response_data[0]=usb_drv_stalled(req->wIndex & 0xf,
735 (req->wIndex & USB_DIR_IN)!=0);
737 if(!usb_drv_send(EP_CONTROL,response_data,2))
738 usb_core_ack_control(req);
739 break;
740 default: {
741 bool handled;
742 control_handler_t control_handler;
744 control_handler=ep_data[req->wIndex & 0xf].control_handler[0];
745 if (!control_handler)
746 break;
748 handled=control_handler(req, response_data);
749 if (!handled) {
750 /* nope. flag error */
751 logf("usb bad req %d",req->bRequest);
752 usb_drv_stall(EP_CONTROL,true,true);
753 usb_core_ack_control(req);
755 break;
760 /* Handling USB requests starts here */
761 static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
763 if (usb_state==DEFAULT) {
764 set_serial_descriptor();
765 usb_core_set_serial_function_id();
767 allocate_interfaces_and_endpoints();
770 switch(req->bRequestType & USB_RECIP_MASK) {
771 case USB_RECIP_DEVICE:
772 request_handler_device(req);
773 break;
774 case USB_RECIP_INTERFACE:
775 request_handler_interface(req);
776 break;
777 case USB_RECIP_ENDPOINT:
778 request_handler_endpoint(req);
779 break;
780 case USB_RECIP_OTHER:
781 logf("unsupported recipient");
782 break;
784 //logf("control handled");
787 /* called by usb_drv_int() */
788 void usb_core_bus_reset(void)
790 usb_address=0;
791 usb_state=DEFAULT;
794 /* called by usb_drv_transfer_completed() */
795 void usb_core_transfer_complete(int endpoint,int dir,int status,int length)
797 struct usb_transfer_completion_event_data *completion_event;
799 switch (endpoint) {
800 case EP_CONTROL:
801 /* already handled */
802 break;
804 default:
805 completion_event=&ep_data[endpoint].completion_event;
807 completion_event->endpoint=endpoint;
808 completion_event->dir=dir;
809 completion_event->data=0;
810 completion_event->status=status;
811 completion_event->length=length;
812 /* All other endoints. Let the thread deal with it */
813 usb_signal_transfer_completion(completion_event);
814 break;
818 /* called by usb_drv_int() */
819 void usb_core_control_request(struct usb_ctrlrequest* req)
821 struct usb_transfer_completion_event_data* completion_event =
822 &ep_data[0].completion_event;
824 completion_event->endpoint=0;
825 completion_event->dir=0;
826 completion_event->data=(void*)req;
827 completion_event->status=0;
828 completion_event->length=0;
829 logf("ctrl received %ld",current_tick);
830 usb_signal_transfer_completion(completion_event);
833 int usb_core_ack_control(struct usb_ctrlrequest* req)
835 if (req->bRequestType & USB_DIR_IN)
836 return usb_drv_recv(EP_CONTROL,NULL,0);
837 else
838 return usb_drv_send(EP_CONTROL,NULL,0);
841 #ifdef HAVE_USB_POWER
842 unsigned short usb_allowed_current()
844 return (usb_state==CONFIGURED) ? MAX(USB_MAX_CURRENT, 100) : 100;
846 #endif