Use a struct for the necessary status variables for rockblox. Will make dumping the...
[kugel-rb.git] / firmware / usbstack / usb_core.c
blob250544f202c81eed931be6553ce8277699bbbc94
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 #if defined(USB_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 #define USB_SC_SCSI 0x06 /* Transparent */
69 #define USB_PROT_BULK 0x50 /* bulk only */
71 static struct usb_device_descriptor __attribute__((aligned(2)))
72 device_descriptor=
74 .bLength = sizeof(struct usb_device_descriptor),
75 .bDescriptorType = USB_DT_DEVICE,
76 #ifndef USB_NO_HIGH_SPEED
77 .bcdUSB = 0x0200,
78 #else
79 .bcdUSB = 0x0110,
80 #endif
81 .bDeviceClass = USB_CLASS_PER_INTERFACE,
82 .bDeviceSubClass = 0,
83 .bDeviceProtocol = 0,
84 .bMaxPacketSize0 = 64,
85 .idVendor = USB_VENDOR_ID,
86 .idProduct = USB_PRODUCT_ID,
87 .bcdDevice = 0x0100,
88 .iManufacturer = 1,
89 .iProduct = 2,
90 .iSerialNumber = 3,
91 .bNumConfigurations = 1
92 } ;
94 static struct usb_config_descriptor __attribute__((aligned(2)))
95 config_descriptor =
97 .bLength = sizeof(struct usb_config_descriptor),
98 .bDescriptorType = USB_DT_CONFIG,
99 .wTotalLength = 0, /* will be filled in later */
100 .bNumInterfaces = 1,
101 .bConfigurationValue = 1,
102 .iConfiguration = 0,
103 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
104 .bMaxPower = (USB_MAX_CURRENT+1) / 2, /* In 2mA units */
107 static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
108 qualifier_descriptor =
110 .bLength = sizeof(struct usb_qualifier_descriptor),
111 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
112 .bcdUSB = 0x0200,
113 .bDeviceClass = 0,
114 .bDeviceSubClass = 0,
115 .bDeviceProtocol = 0,
116 .bMaxPacketSize0 = 64,
117 .bNumConfigurations = 1
120 static const struct usb_string_descriptor __attribute__((aligned(2)))
121 usb_string_iManufacturer =
124 USB_DT_STRING,
125 {'R','o','c','k','b','o','x','.','o','r','g'}
128 static const struct usb_string_descriptor __attribute__((aligned(2)))
129 usb_string_iProduct =
132 USB_DT_STRING,
133 {'R','o','c','k','b','o','x',' ',
134 'm','e','d','i','a',' ',
135 'p','l','a','y','e','r'}
138 static struct usb_string_descriptor __attribute__((aligned(2)))
139 usb_string_iSerial =
142 USB_DT_STRING,
143 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
144 '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
145 '0','0','0','0','0','0','0','0','0'}
148 /* Generic for all targets */
150 /* this is stringid #0: languages supported */
151 static const struct usb_string_descriptor __attribute__((aligned(2)))
152 lang_descriptor =
155 USB_DT_STRING,
156 {0x0409} /* LANGID US English */
159 static const struct usb_string_descriptor* const usb_strings[] =
161 &lang_descriptor,
162 &usb_string_iManufacturer,
163 &usb_string_iProduct,
164 &usb_string_iSerial
167 static int usb_address = 0;
168 static bool initialized = false;
169 static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
171 static int usb_core_num_interfaces;
173 typedef void (*completion_handler_t)(int ep,int dir,int status,int length);
174 typedef bool (*control_handler_t)(struct usb_ctrlrequest* req,unsigned char* dest);
176 static struct
178 completion_handler_t completion_handler[2];
179 control_handler_t control_handler[2];
180 struct usb_transfer_completion_event_data completion_event;
181 } ep_data[USB_NUM_ENDPOINTS];
183 static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
185 #ifdef USB_STORAGE
186 [USB_DRIVER_MASS_STORAGE] = {
187 .enabled = false,
188 .needs_exclusive_storage = true,
189 .first_interface = 0,
190 .last_interface = 0,
191 .request_endpoints = usb_storage_request_endpoints,
192 .set_first_interface = usb_storage_set_first_interface,
193 .get_config_descriptor = usb_storage_get_config_descriptor,
194 .init_connection = usb_storage_init_connection,
195 .init = usb_storage_init,
196 .disconnect = usb_storage_disconnect,
197 .transfer_complete = usb_storage_transfer_complete,
198 .control_request = usb_storage_control_request,
199 #ifdef HAVE_HOTSWAP
200 .notify_hotswap = usb_storage_notify_hotswap,
201 #endif
203 #endif
204 #ifdef USB_SERIAL
205 [USB_DRIVER_SERIAL] = {
206 .enabled = false,
207 .needs_exclusive_storage = false,
208 .first_interface = 0,
209 .last_interface = 0,
210 .request_endpoints = usb_serial_request_endpoints,
211 .set_first_interface = usb_serial_set_first_interface,
212 .get_config_descriptor = usb_serial_get_config_descriptor,
213 .init_connection = usb_serial_init_connection,
214 .init = usb_serial_init,
215 .disconnect = usb_serial_disconnect,
216 .transfer_complete = usb_serial_transfer_complete,
217 .control_request = usb_serial_control_request,
218 #ifdef HAVE_HOTSWAP
219 .notify_hotswap = NULL,
220 #endif
222 #endif
223 #ifdef USB_CHARGING_ONLY
224 [USB_DRIVER_CHARGING_ONLY] = {
225 .enabled = false,
226 .needs_exclusive_storage = false,
227 .first_interface = 0,
228 .last_interface = 0,
229 .request_endpoints = usb_charging_only_request_endpoints,
230 .set_first_interface = usb_charging_only_set_first_interface,
231 .get_config_descriptor = usb_charging_only_get_config_descriptor,
232 .init_connection = NULL,
233 .init = NULL,
234 .disconnect = NULL,
235 .transfer_complete = NULL,
236 .control_request = NULL,
237 #ifdef HAVE_HOTSWAP
238 .notify_hotswap = NULL,
239 #endif
241 #ifdef USB_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
260 #endif
263 static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
265 static unsigned char response_data[256] USB_DEVBSS_ATTR;
267 static short hex[16] = {'0','1','2','3','4','5','6','7',
268 '8','9','A','B','C','D','E','F'};
269 #ifdef IPOD_ARCH
270 static void set_serial_descriptor(void)
272 #ifdef IPOD_VIDEO
273 uint32_t* serial = (uint32_t*)(0x20004034);
274 #else
275 uint32_t* serial = (uint32_t*)(0x20002034);
276 #endif
278 /* We need to convert from a little-endian 64-bit int
279 into a utf-16 string of hex characters */
280 short* p = &usb_string_iSerial.wString[24];
281 uint32_t x;
282 int i,j;
284 for (i = 0; i < 2; i++) {
285 x = serial[i];
286 for (j=0;j<8;j++) {
287 *p-- = hex[x & 0xf];
288 x >>= 4;
291 usb_string_iSerial.bLength=52;
293 #elif defined(HAVE_AS3514)
294 static void set_serial_descriptor(void)
296 unsigned char serial[16];
297 /* Align 32 digits right in the 40-digit serial number */
298 short* p = &usb_string_iSerial.wString[1];
299 int i;
301 ascodec_readbytes(AS3514_UID_0, 0x10, serial);
302 for (i = 0; i < 16; i++) {
303 *p++ = hex[(serial[i] >> 4) & 0xF];
304 *p++ = hex[(serial[i] >> 0) & 0xF];
306 usb_string_iSerial.bLength=68;
308 #elif (CONFIG_STORAGE & STORAGE_ATA)
309 /* If we don't know the device serial number, use the one
310 * from the disk */
311 static void set_serial_descriptor(void)
313 short* p = &usb_string_iSerial.wString[1];
314 unsigned short* identify = ata_get_identify();
315 unsigned short x;
316 int i;
318 for (i = 10; i < 20; i++) {
319 x = identify[i];
320 *p++ = hex[(x >> 12) & 0xF];
321 *p++ = hex[(x >> 8) & 0xF];
322 *p++ = hex[(x >> 4) & 0xF];
323 *p++ = hex[(x >> 0) & 0xF];
325 usb_string_iSerial.bLength=84;
327 #elif (CONFIG_STORAGE & STORAGE_RAMDISK)
328 /* This "serial number" isn't unique, but it should never actually
329 appear in non-testing use */
330 static void set_serial_descriptor(void)
332 short* p = &usb_string_iSerial.wString[1];
333 int i;
334 for (i = 0; i < 16; i++) {
335 *p++ = hex[(2*i)&0xF];
336 *p++ = hex[(2*i+1)&0xF];
338 usb_string_iSerial.bLength=68;
340 #else
341 static void set_serial_descriptor(void)
343 device_descriptor.iSerialNumber = 0;
345 #endif
347 void usb_core_init(void)
349 int i;
350 if (initialized)
351 return;
353 usb_drv_init();
355 /* class driver init functions should be safe to call even if the driver
356 * won't be used. This simplifies other logic (i.e. we don't need to know
357 * yet which drivers will be enabled */
358 for(i=0;i<USB_NUM_DRIVERS;i++) {
359 if(drivers[i].enabled && drivers[i].init != NULL)
360 drivers[i].init();
363 initialized = true;
364 usb_state = DEFAULT;
365 logf("usb_core_init() finished");
368 void usb_core_exit(void)
370 int i;
371 for(i=0;i<USB_NUM_DRIVERS;i++) {
372 if(drivers[i].enabled && drivers[i].disconnect != NULL)
374 drivers[i].disconnect();
375 drivers[i].enabled = false;
379 if (initialized) {
380 usb_drv_exit();
381 initialized = false;
383 usb_state = DEFAULT;
384 logf("usb_core_exit() finished");
387 void usb_core_handle_transfer_completion(
388 struct usb_transfer_completion_event_data* event)
390 completion_handler_t handler;
391 int ep = event->endpoint;
393 switch(ep) {
394 case EP_CONTROL:
395 logf("ctrl handled %ld",current_tick);
396 usb_core_control_request_handler(
397 (struct usb_ctrlrequest*)event->data);
398 break;
399 default:
400 handler = ep_data[ep].completion_handler[EP_DIR(event->dir)];
401 if(handler != NULL)
402 handler(ep,event->dir,event->status,event->length);
403 break;
407 void usb_core_enable_driver(int driver,bool enabled)
409 drivers[driver].enabled = enabled;
412 bool usb_core_driver_enabled(int driver)
414 return drivers[driver].enabled;
417 bool usb_core_any_exclusive_storage(void)
419 int i;
420 for(i=0;i<USB_NUM_DRIVERS;i++) {
421 if(drivers[i].enabled && drivers[i].needs_exclusive_storage)
423 return true;
427 return false;
430 #ifdef HAVE_HOTSWAP
431 void usb_core_hotswap_event(int volume,bool inserted)
433 int i;
434 for(i=0;i<USB_NUM_DRIVERS;i++) {
435 if(drivers[i].enabled && drivers[i].notify_hotswap!=NULL)
437 drivers[i].notify_hotswap(volume,inserted);
441 #endif
443 static void usb_core_set_serial_function_id(void)
445 int id = 0;
446 int i;
447 for(i=0;i<USB_NUM_DRIVERS;i++) {
448 if(drivers[i].enabled)
449 id |= 1<<i;
451 usb_string_iSerial.wString[0] = hex[id];
454 int usb_core_request_endpoint(int type, int dir, struct usb_class_driver* drv)
456 int ret, ep;
458 ret = usb_drv_request_endpoint(type, dir);
460 if (ret==-1)
461 return -1;
463 dir = EP_DIR(ret);
464 ep = EP_NUM(ret);
466 ep_data[ep].completion_handler[dir] = drv->transfer_complete;
467 ep_data[ep].control_handler[dir] = drv->control_request;
469 return ret;
472 void usb_core_release_endpoint(int ep)
474 int dir;
476 usb_drv_release_endpoint(ep);
478 dir = EP_DIR(ep);
479 ep = EP_NUM(ep);
481 ep_data[ep].completion_handler[dir] = NULL;
482 ep_data[ep].control_handler[dir] = NULL;
485 static void allocate_interfaces_and_endpoints(void)
487 int i;
488 int interface=0;
490 memset(ep_data,0,sizeof(ep_data));
492 for (i = 0; i < USB_NUM_ENDPOINTS; i++) {
493 usb_drv_release_endpoint(i | USB_DIR_OUT);
494 usb_drv_release_endpoint(i | USB_DIR_IN);
497 for(i=0;i<USB_NUM_DRIVERS;i++) {
498 if(drivers[i].enabled) {
499 drivers[i].first_interface = interface;
501 if (drivers[i].request_endpoints(&drivers[i])) {
502 drivers[i].enabled = false;
503 continue;
506 interface = drivers[i].set_first_interface(interface);
507 drivers[i].last_interface = interface;
510 usb_core_num_interfaces = interface;
513 static void control_request_handler_drivers(struct usb_ctrlrequest* req)
515 int i, interface = req->wIndex;
516 bool handled=false;
518 for(i=0;i<USB_NUM_DRIVERS;i++) {
519 if(drivers[i].enabled &&
520 drivers[i].control_request &&
521 drivers[i].first_interface <= interface &&
522 drivers[i].last_interface > interface)
524 handled = drivers[i].control_request(req, response_data);
525 if(handled)
526 break;
529 if(!handled) {
530 /* nope. flag error */
531 logf("bad req:desc %d:%d", req->bRequest, req->wValue>>8);
532 usb_drv_stall(EP_CONTROL, true, true);
533 usb_core_ack_control(req);
537 static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req)
539 int size;
540 bool handled = true;
541 const void* ptr = NULL;
542 int length = req->wLength;
543 int index = req->wValue & 0xff;
545 switch(req->wValue>>8) { /* type */
546 case USB_DT_DEVICE:
547 ptr = &device_descriptor;
548 size = sizeof(struct usb_device_descriptor);
549 break;
551 case USB_DT_OTHER_SPEED_CONFIG:
552 case USB_DT_CONFIG: {
553 int i, max_packet_size;
555 if(req->wValue>>8==USB_DT_CONFIG) {
556 max_packet_size=(usb_drv_port_speed() ? 512 : 64);
557 config_descriptor.bDescriptorType=USB_DT_CONFIG;
559 else {
560 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
561 config_descriptor.bDescriptorType =
562 USB_DT_OTHER_SPEED_CONFIG;
564 size = sizeof(struct usb_config_descriptor);
566 for(i=0;i<USB_NUM_DRIVERS;i++) {
567 if(drivers[i].enabled && drivers[i].get_config_descriptor) {
568 size+=drivers[i].get_config_descriptor(
569 &response_data[size],max_packet_size);
572 config_descriptor.bNumInterfaces = usb_core_num_interfaces;
573 config_descriptor.wTotalLength = size;
574 memcpy(&response_data[0],&config_descriptor,
575 sizeof(struct usb_config_descriptor));
577 ptr = response_data;
578 break;
581 case USB_DT_STRING:
582 logf("STRING %d",index);
583 if ((unsigned)index < (sizeof(usb_strings)/
584 sizeof(struct usb_string_descriptor*))) {
585 size = usb_strings[index]->bLength;
586 ptr = usb_strings[index];
588 else {
589 logf("bad string id %d",index);
590 usb_drv_stall(EP_CONTROL,true,true);
592 break;
594 case USB_DT_DEVICE_QUALIFIER:
595 ptr = &qualifier_descriptor;
596 size = sizeof(struct usb_qualifier_descriptor);
597 break;
599 default:
600 logf("ctrl desc.");
601 handled = false;
602 control_request_handler_drivers(req);
603 break;
606 if (ptr) {
607 logf("data %d (%d)",size,length);
608 length = MIN(size,length);
610 if (ptr != response_data) {
611 memcpy(response_data,ptr,length);
614 if(usb_drv_send(EP_CONTROL,response_data,length))
615 return;
617 if (handled)
618 usb_core_ack_control(req);
621 static void request_handler_device(struct usb_ctrlrequest* req)
623 int i;
625 switch(req->bRequest) {
626 case USB_REQ_GET_CONFIGURATION: {
627 logf("usb_core: GET_CONFIG");
628 response_data[0] = (usb_state == ADDRESS ? 0 : 1);
629 if(!usb_drv_send(EP_CONTROL, response_data, 1))
630 usb_core_ack_control(req);
631 break;
633 case USB_REQ_SET_CONFIGURATION: {
634 logf("usb_core: SET_CONFIG");
635 usb_drv_cancel_all_transfers();
636 if(req->wValue) {
637 usb_state = CONFIGURED;
638 for(i=0;i<USB_NUM_DRIVERS;i++) {
639 if(drivers[i].enabled && drivers[i].init_connection)
640 drivers[i].init_connection();
643 else {
644 usb_state = ADDRESS;
646 usb_core_ack_control(req);
647 break;
649 case USB_REQ_SET_ADDRESS: {
650 unsigned char address = req->wValue;
651 logf("usb_core: SET_ADR %d", address);
652 if(usb_core_ack_control(req))
653 break;
654 usb_drv_cancel_all_transfers();
655 usb_address = address;
656 usb_drv_set_address(usb_address);
657 usb_state = ADDRESS;
658 break;
660 case USB_REQ_GET_DESCRIPTOR:
661 logf("usb_core: GET_DESC %d", req->wValue>>8);
662 request_handler_device_get_descriptor(req);
663 break;
664 case USB_REQ_CLEAR_FEATURE:
665 break;
666 case USB_REQ_SET_FEATURE:
667 if(req->wValue==USB_DEVICE_TEST_MODE) {
668 int mode=req->wIndex>>8;
669 usb_core_ack_control(req);
670 usb_drv_set_test_mode(mode);
672 break;
673 case USB_REQ_GET_STATUS:
674 response_data[0]= 0;
675 response_data[1]= 0;
676 if(!usb_drv_send(EP_CONTROL, response_data, 2))
677 usb_core_ack_control(req);
678 break;
679 default:
680 break;
684 static void request_handler_interface_standard(struct usb_ctrlrequest* req)
686 switch (req->bRequest)
688 case USB_REQ_SET_INTERFACE:
689 logf("usb_core: SET_INTERFACE");
690 usb_core_ack_control(req);
691 break;
693 case USB_REQ_GET_INTERFACE:
694 logf("usb_core: GET_INTERFACE");
695 response_data[0]=0;
696 if(!usb_drv_send(EP_CONTROL,response_data,1))
697 usb_core_ack_control(req);
698 break;
699 case USB_REQ_CLEAR_FEATURE:
700 break;
701 case USB_REQ_SET_FEATURE:
702 break;
703 case USB_REQ_GET_STATUS:
704 response_data[0]=0;
705 response_data[1]=0;
706 if(!usb_drv_send(EP_CONTROL, response_data, 2))
707 usb_core_ack_control(req);
708 break;
709 default:
710 control_request_handler_drivers(req);
711 break;
715 static void request_handler_interface(struct usb_ctrlrequest* req)
717 switch(req->bRequestType & USB_TYPE_MASK) {
718 case USB_TYPE_STANDARD:
719 request_handler_interface_standard(req);
720 break;
721 case USB_TYPE_CLASS:
722 control_request_handler_drivers(req);
723 break;
724 case USB_TYPE_VENDOR:
725 break;
729 static void request_handler_endpoint(struct usb_ctrlrequest* req)
731 switch (req->bRequest) {
732 case USB_REQ_CLEAR_FEATURE:
733 if (req->wValue==USB_ENDPOINT_HALT) {
734 usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex));
736 usb_core_ack_control(req);
737 break;
738 case USB_REQ_SET_FEATURE:
739 if (req->wValue==USB_ENDPOINT_HALT) {
740 usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex));
742 usb_core_ack_control(req);
743 break;
744 case USB_REQ_GET_STATUS:
745 response_data[0]=0;
746 response_data[1]=0;
747 logf("usb_core: GET_STATUS");
748 if(req->wIndex>0) {
749 response_data[0]=usb_drv_stalled(EP_NUM(req->wIndex),
750 EP_DIR(req->wIndex));
752 if(!usb_drv_send(EP_CONTROL,response_data,2))
753 usb_core_ack_control(req);
754 break;
755 default: {
756 bool handled;
757 control_handler_t control_handler;
759 control_handler=
760 ep_data[EP_NUM(req->wIndex)].control_handler[EP_CONTROL];
761 if (!control_handler)
762 break;
764 handled=control_handler(req, response_data);
765 if (!handled) {
766 /* nope. flag error */
767 logf("usb bad req %d",req->bRequest);
768 usb_drv_stall(EP_CONTROL,true,true);
769 usb_core_ack_control(req);
771 break;
776 /* Handling USB requests starts here */
777 static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
779 if (usb_state==DEFAULT) {
780 set_serial_descriptor();
781 usb_core_set_serial_function_id();
783 allocate_interfaces_and_endpoints();
786 switch(req->bRequestType & USB_RECIP_MASK) {
787 case USB_RECIP_DEVICE:
788 request_handler_device(req);
789 break;
790 case USB_RECIP_INTERFACE:
791 request_handler_interface(req);
792 break;
793 case USB_RECIP_ENDPOINT:
794 request_handler_endpoint(req);
795 break;
796 case USB_RECIP_OTHER:
797 logf("unsupported recipient");
798 break;
800 //logf("control handled");
803 /* called by usb_drv_int() */
804 void usb_core_bus_reset(void)
806 usb_address=0;
807 usb_state=DEFAULT;
810 /* called by usb_drv_transfer_completed() */
811 void usb_core_transfer_complete(int endpoint,int dir,int status,int length)
813 struct usb_transfer_completion_event_data *completion_event;
815 switch (endpoint) {
816 case EP_CONTROL:
817 /* already handled */
818 break;
820 default:
821 completion_event=&ep_data[endpoint].completion_event;
823 completion_event->endpoint=endpoint;
824 completion_event->dir=dir;
825 completion_event->data=0;
826 completion_event->status=status;
827 completion_event->length=length;
828 /* All other endoints. Let the thread deal with it */
829 usb_signal_transfer_completion(completion_event);
830 break;
834 /* called by usb_drv_int() */
835 void usb_core_control_request(struct usb_ctrlrequest* req)
837 struct usb_transfer_completion_event_data* completion_event =
838 &ep_data[EP_CONTROL].completion_event;
840 completion_event->endpoint=EP_CONTROL;
841 completion_event->dir=0;
842 completion_event->data=(void*)req;
843 completion_event->status=0;
844 completion_event->length=0;
845 logf("ctrl received %ld",current_tick);
846 usb_signal_transfer_completion(completion_event);
849 int usb_core_ack_control(struct usb_ctrlrequest* req)
851 if (req->bRequestType & USB_DIR_IN)
852 return usb_drv_recv(EP_CONTROL,NULL,0);
853 else
854 return usb_drv_send(EP_CONTROL,NULL,0);
857 #ifdef HAVE_USB_POWER
858 unsigned short usb_allowed_current()
860 return (usb_state==CONFIGURED) ? MAX(USB_MAX_CURRENT, 100) : 100;
862 #endif