FS#8961 - Anti-Aliased Fonts.
[kugel-rb.git] / firmware / usbstack / usb_core.c
blobd45c0efc901ef6392303dae17879caee6204162e
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 #if defined(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;
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 void control_request_handler_drivers(struct usb_ctrlrequest* req)
512 int i, interface = req->wIndex;
513 bool handled=false;
515 for(i=0;i<USB_NUM_DRIVERS;i++) {
516 if(drivers[i].enabled &&
517 drivers[i].control_request &&
518 drivers[i].first_interface <= interface &&
519 drivers[i].last_interface > interface)
521 handled = drivers[i].control_request(req, response_data);
522 if(handled)
523 break;
526 if(!handled) {
527 /* nope. flag error */
528 logf("bad req:desc %d:%d", req->bRequest, req->wValue>>8);
529 usb_drv_stall(EP_CONTROL, true, true);
530 usb_core_ack_control(req);
534 static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req)
536 int size;
537 bool handled = true;
538 const void* ptr = NULL;
539 int length = req->wLength;
540 int index = req->wValue & 0xff;
542 switch(req->wValue>>8) { /* type */
543 case USB_DT_DEVICE:
544 ptr = &device_descriptor;
545 size = sizeof(struct usb_device_descriptor);
546 break;
548 case USB_DT_OTHER_SPEED_CONFIG:
549 case USB_DT_CONFIG: {
550 int i, max_packet_size;
552 if(req->wValue>>8==USB_DT_CONFIG) {
553 max_packet_size=(usb_drv_port_speed() ? 512 : 64);
554 config_descriptor.bDescriptorType=USB_DT_CONFIG;
556 else {
557 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
558 config_descriptor.bDescriptorType =
559 USB_DT_OTHER_SPEED_CONFIG;
561 size = sizeof(struct usb_config_descriptor);
563 for(i=0;i<USB_NUM_DRIVERS;i++) {
564 if(drivers[i].enabled && drivers[i].get_config_descriptor) {
565 size+=drivers[i].get_config_descriptor(
566 &response_data[size],max_packet_size);
569 config_descriptor.bNumInterfaces = usb_core_num_interfaces;
570 config_descriptor.wTotalLength = size;
571 memcpy(&response_data[0],&config_descriptor,
572 sizeof(struct usb_config_descriptor));
574 ptr = response_data;
575 break;
578 case USB_DT_STRING:
579 logf("STRING %d",index);
580 if ((unsigned)index < (sizeof(usb_strings)/
581 sizeof(struct usb_string_descriptor*))) {
582 size = usb_strings[index]->bLength;
583 ptr = usb_strings[index];
585 else {
586 logf("bad string id %d",index);
587 usb_drv_stall(EP_CONTROL,true,true);
589 break;
591 case USB_DT_DEVICE_QUALIFIER:
592 ptr = &qualifier_descriptor;
593 size = sizeof(struct usb_qualifier_descriptor);
594 break;
596 default:
597 logf("ctrl desc.");
598 handled = false;
599 control_request_handler_drivers(req);
600 break;
603 if (ptr) {
604 logf("data %d (%d)",size,length);
605 length = MIN(size,length);
607 if (ptr != response_data) {
608 memcpy(response_data,ptr,length);
611 if(usb_drv_send(EP_CONTROL,response_data,length))
612 return;
614 if (handled)
615 usb_core_ack_control(req);
618 static void request_handler_device(struct usb_ctrlrequest* req)
620 int i;
622 switch(req->bRequest) {
623 case USB_REQ_GET_CONFIGURATION: {
624 logf("usb_core: GET_CONFIG");
625 response_data[0] = (usb_state == ADDRESS ? 0 : 1);
626 if(!usb_drv_send(EP_CONTROL, response_data, 1))
627 usb_core_ack_control(req);
628 break;
630 case USB_REQ_SET_CONFIGURATION: {
631 logf("usb_core: SET_CONFIG");
632 usb_drv_cancel_all_transfers();
633 if(req->wValue) {
634 usb_state = CONFIGURED;
635 for(i=0;i<USB_NUM_DRIVERS;i++) {
636 if(drivers[i].enabled && drivers[i].init_connection)
637 drivers[i].init_connection();
640 else {
641 usb_state = ADDRESS;
643 usb_core_ack_control(req);
644 break;
646 case USB_REQ_SET_ADDRESS: {
647 unsigned char address = req->wValue;
648 logf("usb_core: SET_ADR %d", address);
649 if(usb_core_ack_control(req))
650 break;
651 usb_drv_cancel_all_transfers();
652 usb_address = address;
653 usb_drv_set_address(usb_address);
654 usb_state = ADDRESS;
655 break;
657 case USB_REQ_GET_DESCRIPTOR:
658 logf("usb_core: GET_DESC %d", req->wValue>>8);
659 request_handler_device_get_descriptor(req);
660 break;
661 case USB_REQ_CLEAR_FEATURE:
662 break;
663 case USB_REQ_SET_FEATURE:
664 if(req->wValue==USB_DEVICE_TEST_MODE) {
665 int mode=req->wIndex>>8;
666 usb_core_ack_control(req);
667 usb_drv_set_test_mode(mode);
669 break;
670 case USB_REQ_GET_STATUS:
671 response_data[0]= 0;
672 response_data[1]= 0;
673 if(!usb_drv_send(EP_CONTROL, response_data, 2))
674 usb_core_ack_control(req);
675 break;
676 default:
677 break;
681 static void request_handler_interface_standard(struct usb_ctrlrequest* req)
683 switch (req->bRequest)
685 case USB_REQ_SET_INTERFACE:
686 logf("usb_core: SET_INTERFACE");
687 usb_core_ack_control(req);
688 break;
690 case USB_REQ_GET_INTERFACE:
691 logf("usb_core: GET_INTERFACE");
692 response_data[0]=0;
693 if(!usb_drv_send(EP_CONTROL,response_data,1))
694 usb_core_ack_control(req);
695 break;
696 case USB_REQ_CLEAR_FEATURE:
697 break;
698 case USB_REQ_SET_FEATURE:
699 break;
700 case USB_REQ_GET_STATUS:
701 response_data[0]=0;
702 response_data[1]=0;
703 if(!usb_drv_send(EP_CONTROL, response_data, 2))
704 usb_core_ack_control(req);
705 break;
706 default:
707 control_request_handler_drivers(req);
708 break;
712 static void request_handler_interface(struct usb_ctrlrequest* req)
714 switch(req->bRequestType & USB_TYPE_MASK) {
715 case USB_TYPE_STANDARD:
716 request_handler_interface_standard(req);
717 break;
718 case USB_TYPE_CLASS:
719 control_request_handler_drivers(req);
720 break;
721 case USB_TYPE_VENDOR:
722 break;
726 static void request_handler_endpoint(struct usb_ctrlrequest* req)
728 switch (req->bRequest) {
729 case USB_REQ_CLEAR_FEATURE:
730 if (req->wValue==USB_ENDPOINT_HALT) {
731 usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex));
733 usb_core_ack_control(req);
734 break;
735 case USB_REQ_SET_FEATURE:
736 if (req->wValue==USB_ENDPOINT_HALT) {
737 usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex));
739 usb_core_ack_control(req);
740 break;
741 case USB_REQ_GET_STATUS:
742 response_data[0]=0;
743 response_data[1]=0;
744 logf("usb_core: GET_STATUS");
745 if(req->wIndex>0) {
746 response_data[0]=usb_drv_stalled(EP_NUM(req->wIndex),
747 EP_DIR(req->wIndex));
749 if(!usb_drv_send(EP_CONTROL,response_data,2))
750 usb_core_ack_control(req);
751 break;
752 default: {
753 bool handled;
754 control_handler_t control_handler;
756 control_handler=
757 ep_data[EP_NUM(req->wIndex)].control_handler[EP_CONTROL];
758 if (!control_handler)
759 break;
761 handled=control_handler(req, response_data);
762 if (!handled) {
763 /* nope. flag error */
764 logf("usb bad req %d",req->bRequest);
765 usb_drv_stall(EP_CONTROL,true,true);
766 usb_core_ack_control(req);
768 break;
773 /* Handling USB requests starts here */
774 static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
776 if (usb_state==DEFAULT) {
777 set_serial_descriptor();
778 usb_core_set_serial_function_id();
780 allocate_interfaces_and_endpoints();
783 switch(req->bRequestType & USB_RECIP_MASK) {
784 case USB_RECIP_DEVICE:
785 request_handler_device(req);
786 break;
787 case USB_RECIP_INTERFACE:
788 request_handler_interface(req);
789 break;
790 case USB_RECIP_ENDPOINT:
791 request_handler_endpoint(req);
792 break;
793 case USB_RECIP_OTHER:
794 logf("unsupported recipient");
795 break;
797 //logf("control handled");
800 /* called by usb_drv_int() */
801 void usb_core_bus_reset(void)
803 usb_address=0;
804 usb_state=DEFAULT;
807 /* called by usb_drv_transfer_completed() */
808 void usb_core_transfer_complete(int endpoint,int dir,int status,int length)
810 struct usb_transfer_completion_event_data *completion_event;
812 switch (endpoint) {
813 case EP_CONTROL:
814 /* already handled */
815 break;
817 default:
818 completion_event=&ep_data[endpoint].completion_event;
820 completion_event->endpoint=endpoint;
821 completion_event->dir=dir;
822 completion_event->data=0;
823 completion_event->status=status;
824 completion_event->length=length;
825 /* All other endoints. Let the thread deal with it */
826 usb_signal_transfer_completion(completion_event);
827 break;
831 /* called by usb_drv_int() */
832 void usb_core_control_request(struct usb_ctrlrequest* req)
834 struct usb_transfer_completion_event_data* completion_event =
835 &ep_data[EP_CONTROL].completion_event;
837 completion_event->endpoint=EP_CONTROL;
838 completion_event->dir=0;
839 completion_event->data=(void*)req;
840 completion_event->status=0;
841 completion_event->length=0;
842 logf("ctrl received %ld",current_tick);
843 usb_signal_transfer_completion(completion_event);
846 int usb_core_ack_control(struct usb_ctrlrequest* req)
848 if (req->bRequestType & USB_DIR_IN)
849 return usb_drv_recv(EP_CONTROL,NULL,0);
850 else
851 return usb_drv_send(EP_CONTROL,NULL,0);
854 #ifdef HAVE_USB_POWER
855 unsigned short usb_allowed_current()
857 return (usb_state==CONFIGURED) ? MAX(USB_MAX_CURRENT, 100) : 100;
859 #endif