make the ipod serial number 24 characters long. This makes the Vista BSOD go away
[kugel-rb.git] / firmware / usbstack / usb_core.c
blobfdfd049002b81ec090f77e36dce463e83fc90adf
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
10 * Copyright (C) 2007 by Bj�rn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "system.h"
20 #include "thread.h"
21 #include "kernel.h"
22 #include "string.h"
23 //#define LOGF_ENABLE
24 #include "logf.h"
26 #include "usb.h"
27 #include "usb_ch9.h"
28 #include "usb_drv.h"
29 #include "usb_core.h"
31 #if defined(USB_STORAGE)
32 #include "usb_storage.h"
33 #endif
35 #if defined(USB_SERIAL)
36 #include "usb_serial.h"
37 #endif
39 #if defined(USB_BENCHMARK)
40 #include "usb_benchmark.h"
41 #endif
43 /* TODO: Move this target-specific stuff somewhere else (serial number reading) */
45 #ifdef HAVE_AS3514
46 #include "i2c-pp.h"
47 #include "as3514.h"
48 #endif
50 #if !defined(HAVE_AS3514) && !defined(IPOD_ARCH)
51 #include "ata.h"
52 #endif
55 /*-------------------------------------------------------------------------*/
56 /* USB protocol descriptors: */
58 #define USB_SC_SCSI 0x06 /* Transparent */
59 #define USB_PROT_BULK 0x50 /* bulk only */
61 static const struct usb_device_descriptor device_descriptor= {
62 .bLength = sizeof(struct usb_device_descriptor),
63 .bDescriptorType = USB_DT_DEVICE,
64 #ifdef USE_HIGH_SPEED
65 .bcdUSB = 0x0200,
66 #else
67 .bcdUSB = 0x0110,
68 #endif
69 .bDeviceClass = USB_CLASS_PER_INTERFACE,
70 .bDeviceSubClass = 0,
71 .bDeviceProtocol = 0,
72 .bMaxPacketSize0 = 64,
73 .idVendor = USB_VENDOR_ID,
74 .idProduct = USB_PRODUCT_ID,
75 .bcdDevice = 0x0100,
76 .iManufacturer = 1,
77 .iProduct = 2,
78 .iSerialNumber = 3,
79 .bNumConfigurations = 1
82 struct usb_config_descriptor config_descriptor =
84 .bLength = sizeof(struct usb_config_descriptor),
85 .bDescriptorType = USB_DT_CONFIG,
86 .wTotalLength = 0, /* will be filled in later */
87 .bNumInterfaces = 1,
88 .bConfigurationValue = 1,
89 .iConfiguration = 0,
90 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
91 .bMaxPower = 250, /* 500mA in 2mA units */
94 #ifdef USB_CHARGING_ONLY
95 /* dummy interface for charging-only */
96 struct usb_interface_descriptor charging_interface_descriptor =
98 .bLength = sizeof(struct usb_interface_descriptor),
99 .bDescriptorType = USB_DT_INTERFACE,
100 .bInterfaceNumber = 0,
101 .bAlternateSetting = 0,
102 .bNumEndpoints = 0,
103 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
104 .bInterfaceSubClass = 0,
105 .bInterfaceProtocol = 0,
106 .iInterface = 5
108 #endif
110 #ifdef USB_STORAGE
111 /* storage interface */
112 struct usb_interface_descriptor mass_storage_interface_descriptor =
114 .bLength = sizeof(struct usb_interface_descriptor),
115 .bDescriptorType = USB_DT_INTERFACE,
116 .bInterfaceNumber = 0,
117 .bAlternateSetting = 0,
118 .bNumEndpoints = 2,
119 .bInterfaceClass = USB_CLASS_MASS_STORAGE,
120 .bInterfaceSubClass = USB_SC_SCSI,
121 .bInterfaceProtocol = USB_PROT_BULK,
122 .iInterface = 0
125 struct usb_endpoint_descriptor mass_storage_ep_in_descriptor =
127 .bLength = sizeof(struct usb_endpoint_descriptor),
128 .bDescriptorType = USB_DT_ENDPOINT,
129 .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_IN,
130 .bmAttributes = USB_ENDPOINT_XFER_BULK,
131 .wMaxPacketSize = 16,
132 .bInterval = 0
134 struct usb_endpoint_descriptor mass_storage_ep_out_descriptor =
136 .bLength = sizeof(struct usb_endpoint_descriptor),
137 .bDescriptorType = USB_DT_ENDPOINT,
138 .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_OUT,
139 .bmAttributes = USB_ENDPOINT_XFER_BULK,
140 .wMaxPacketSize = 16,
141 .bInterval = 0
143 #endif
145 #ifdef USB_SERIAL
146 /* serial interface */
147 struct usb_interface_descriptor serial_interface_descriptor =
149 .bLength = sizeof(struct usb_interface_descriptor),
150 .bDescriptorType = USB_DT_INTERFACE,
151 .bInterfaceNumber = 0,
152 .bAlternateSetting = 0,
153 .bNumEndpoints = 2,
154 .bInterfaceClass = USB_CLASS_CDC_DATA,
155 .bInterfaceSubClass = 0,
156 .bInterfaceProtocol = 0,
157 .iInterface = 0
160 struct usb_endpoint_descriptor serial_ep_in_descriptor =
162 .bLength = sizeof(struct usb_endpoint_descriptor),
163 .bDescriptorType = USB_DT_ENDPOINT,
164 .bEndpointAddress = EP_SERIAL | USB_DIR_IN,
165 .bmAttributes = USB_ENDPOINT_XFER_BULK,
166 .wMaxPacketSize = 16,
167 .bInterval = 0
169 struct usb_endpoint_descriptor serial_ep_out_descriptor =
171 .bLength = sizeof(struct usb_endpoint_descriptor),
172 .bDescriptorType = USB_DT_ENDPOINT,
173 .bEndpointAddress = EP_SERIAL | USB_DIR_OUT,
174 .bmAttributes = USB_ENDPOINT_XFER_BULK,
175 .wMaxPacketSize = 16,
176 .bInterval = 0
178 #endif
180 #ifdef USB_BENCHMARK
181 /* bulk test interface */
182 struct usb_interface_descriptor benchmark_interface_descriptor =
184 .bLength = sizeof(struct usb_interface_descriptor),
185 .bDescriptorType = USB_DT_INTERFACE,
186 .bInterfaceNumber = 0,
187 .bAlternateSetting = 0,
188 .bNumEndpoints = 2,
189 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
190 .bInterfaceSubClass = 255,
191 .bInterfaceProtocol = 255,
192 .iInterface = 4
195 struct usb_endpoint_descriptor benchmark_ep_in_descriptor =
197 .bLength = sizeof(struct usb_endpoint_descriptor),
198 .bDescriptorType = USB_DT_ENDPOINT,
199 .bEndpointAddress = EP_BENCHMARK | USB_DIR_OUT,
200 .bmAttributes = USB_ENDPOINT_XFER_BULK,
201 .wMaxPacketSize = 16,
202 .bInterval = 0
204 struct usb_endpoint_descriptor benchmark_ep_out_descriptor =
206 .bLength = sizeof(struct usb_endpoint_descriptor),
207 .bDescriptorType = USB_DT_ENDPOINT,
208 .bEndpointAddress = EP_BENCHMARK | USB_DIR_IN,
209 .bmAttributes = USB_ENDPOINT_XFER_BULK,
210 .wMaxPacketSize = 16,
211 .bInterval = 0
213 #endif
215 static const struct usb_qualifier_descriptor qualifier_descriptor =
217 .bLength = sizeof(struct usb_qualifier_descriptor),
218 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
219 .bcdUSB = 0x0200,
220 .bDeviceClass = 0,
221 .bDeviceSubClass = 0,
222 .bDeviceProtocol = 0,
223 .bMaxPacketSize0 = 64,
224 .bNumConfigurations = 1
227 static struct usb_string_descriptor usb_string_iManufacturer =
230 USB_DT_STRING,
231 {'R','o','c','k','b','o','x','.','o','r','g'}
234 static struct usb_string_descriptor usb_string_iProduct =
237 USB_DT_STRING,
238 {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'}
241 static struct usb_string_descriptor usb_string_iSerial =
244 USB_DT_STRING,
245 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
246 '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
247 '0','0','0','0','0','0','0','0'}
250 /* Generic for all targets */
252 /* this is stringid #0: languages supported */
253 static struct usb_string_descriptor lang_descriptor =
256 USB_DT_STRING,
257 {0x0409} /* LANGID US English */
260 static struct usb_string_descriptor usb_string_usb_benchmark =
263 USB_DT_STRING,
264 {'B','u','l','k',' ','t','e','s','t',' ','i','n','t','e','r','f','a','c','e'}
267 static struct usb_string_descriptor usb_string_charging_only =
270 USB_DT_STRING,
271 {'C','h','a','r','g','i','n','g',' ','o','n','l','y'}
274 static struct usb_string_descriptor* usb_strings[] =
276 &lang_descriptor,
277 &usb_string_iManufacturer,
278 &usb_string_iProduct,
279 &usb_string_iSerial,
280 &usb_string_usb_benchmark,
281 &usb_string_charging_only
284 static int usb_address = 0;
285 static bool initialized = false;
286 static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
288 static bool usb_core_storage_enabled = false;
289 static bool usb_core_serial_enabled = false;
290 static bool usb_core_charging_enabled = false;
291 #if defined(USB_BENCHMARK)
292 static bool usb_core_benchmark_enabled = false;
293 #endif
295 static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
296 static int ack_control(struct usb_ctrlrequest* req);
298 static unsigned char *response_data;
299 static unsigned char __response_data[CACHEALIGN_UP(256)] CACHEALIGN_ATTR;
301 static struct usb_transfer_completion_event_data events[NUM_ENDPOINTS];
303 #ifdef IPOD_ARCH
304 static void set_serial_descriptor(void)
306 static short hex[16] = {'0','1','2','3','4','5','6','7',
307 '8','9','A','B','C','D','E','F'};
308 #ifdef IPOD_VIDEO
309 uint32_t* serial = (uint32_t*)(0x20004034);
310 #else
311 uint32_t* serial = (uint32_t*)(0x20002034);
312 #endif
314 /* We need to convert from a little-endian 64-bit int
315 into a utf-16 string of hex characters */
316 short* p = &usb_string_iSerial.wString[23];
317 uint32_t x;
318 int i,j;
320 for (i = 0; i < 2; i++)
322 x = serial[i];
323 for (j=0;j<8;j++)
325 *p-- = hex[x & 0xf];
326 x >>= 4;
329 usb_string_iSerial.bLength=50;
331 #elif defined(HAVE_AS3514)
332 static void set_serial_descriptor(void)
334 static short hex[16] = {'0','1','2','3','4','5','6','7',
335 '8','9','A','B','C','D','E','F'};
337 unsigned char serial[16];
338 /* Align 32 digits right in the 40-digit serial number */
339 short* p = usb_string_iSerial.wString;
340 int i;
342 i2c_readbytes(AS3514_I2C_ADDR, 0x30, 0x10, serial);
343 for (i = 0; i < 16; i++)
345 *p++ = hex[(serial[i] >> 4) & 0xF];
346 *p++ = hex[(serial[i] >> 0) & 0xF];
348 usb_string_iSerial.bLength=66;
350 #else
351 /* If we don't know the device serial number, use the one
352 * from the disk */
353 static void set_serial_descriptor(void)
355 static short hex[16] = {'0','1','2','3','4','5','6','7',
356 '8','9','A','B','C','D','E','F'};
358 short* p = usb_string_iSerial.wString;
359 unsigned short* identify = ata_get_identify();
360 unsigned short x;
361 int i;
363 for (i = 10; i < 20; i++)
365 x = identify[i];
366 *p++ = hex[(x >> 12) & 0xF];
367 *p++ = hex[(x >> 8) & 0xF];
368 *p++ = hex[(x >> 4) & 0xF];
369 *p++ = hex[(x >> 0) & 0xF];
371 usb_string_iSerial.bLength=82;
373 #endif
375 void usb_core_init(void)
377 if (initialized)
378 return;
380 response_data = (void*)UNCACHED_ADDR(&__response_data);
382 usb_drv_init();
384 /* class driver init functions should be safe to call even if the driver
385 * won't be used. This simplifies other logic (i.e. we don't need to know
386 * yet which drivers will be enabled */
387 #ifdef USB_STORAGE
388 usb_storage_init();
389 #endif
391 #ifdef USB_SERIAL
392 usb_serial_init();
393 #endif
395 #ifdef USB_BENCHMARK
396 usb_benchmark_init();
397 #endif
398 initialized = true;
399 usb_state = DEFAULT;
400 logf("usb_core_init() finished");
403 void usb_core_exit(void)
405 if (initialized) {
406 usb_drv_exit();
408 initialized = false;
409 logf("usb_core_exit() finished");
412 void usb_core_handle_transfer_completion(struct usb_transfer_completion_event_data* event)
414 switch(event->endpoint) {
415 case EP_CONTROL:
416 logf("ctrl handled %ld",current_tick);
417 usb_core_control_request_handler((struct usb_ctrlrequest*)event->data);
418 break;
419 #ifdef USB_STORAGE
420 case EP_MASS_STORAGE:
421 usb_storage_transfer_complete(event->in,event->status,event->length);
422 break;
423 #endif
424 #ifdef USB_SERIAL
425 case EP_SERIAL:
426 usb_serial_transfer_complete(event->in,event->status,event->length);
427 break;
428 #endif
429 #ifdef USB_BENCHMARK
430 case EP_BENCHMARK:
431 usb_benchmark_transfer_complete(event->in);
432 break;
433 #endif
434 #ifdef USB_CHARGING_ONLY
435 case EP_CHARGING_ONLY:
436 break;
437 #endif
441 void usb_core_enable_protocol(int driver,bool enabled)
443 switch(driver) {
444 case USB_DRIVER_MASS_STORAGE:
445 usb_core_storage_enabled = enabled;
446 break;
447 case USB_DRIVER_SERIAL:
448 usb_core_serial_enabled = enabled;
449 break;
450 case USB_DRIVER_CHARGING_ONLY:
451 usb_core_charging_enabled = enabled;
452 break;
456 static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
458 if(usb_state == DEFAULT) {
459 set_serial_descriptor();
462 #ifdef USB_BENCHMARK
463 if ((req->bRequestType & 0x60) == USB_TYPE_VENDOR) {
464 usb_benchmark_control_request(req);
465 return;
467 #endif
469 switch (req->bRequest) {
470 case USB_REQ_SET_CONFIGURATION:
471 logf("usb_core: SET_CONFIG");
472 usb_drv_cancel_all_transfers();
473 if (req->wValue){
474 usb_state = CONFIGURED;
475 #ifdef USB_STORAGE
476 if(usb_core_storage_enabled)
477 usb_storage_control_request(req);
478 #endif
480 #ifdef USB_SERIAL
481 if(usb_core_serial_enabled)
482 usb_serial_control_request(req);
483 #endif
485 else {
486 usb_state = ADDRESS;
488 ack_control(req);
489 break;
491 case USB_REQ_GET_CONFIGURATION: {
492 logf("usb_core: GET_CONFIG");
493 if (usb_state == ADDRESS)
494 response_data[0] = 0;
495 else
496 response_data[0] = 1;
497 if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
498 break;
499 ack_control(req);
500 break;
503 case USB_REQ_SET_INTERFACE:
504 logf("usb_core: SET_INTERFACE");
505 ack_control(req);
506 break;
508 case USB_REQ_GET_INTERFACE:
509 logf("usb_core: GET_INTERFACE");
510 response_data[0] = 0;
511 if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
512 break;
513 ack_control(req);
514 break;
515 case USB_REQ_CLEAR_FEATURE:
516 logf("usb_core: CLEAR_FEATURE");
517 if (req->wValue)
518 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
519 else
520 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
521 ack_control(req);
522 break;
524 case USB_REQ_SET_FEATURE:
525 logf("usb_core: SET_FEATURE");
526 switch(req->bRequestType & 0x0f){
527 case 0: /* Device */
528 if(req->wValue == 2) { /* TEST_MODE */
529 int mode=req->wIndex>>8;
530 ack_control(req);
531 usb_drv_set_test_mode(mode);
533 break;
534 case 2: /* Endpoint */
535 if (req->wValue)
536 usb_drv_stall(req->wIndex & 0xf, true,(req->wIndex & 0x80) !=0);
537 else
538 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
539 ack_control(req);
540 break;
541 default:
542 break;
544 break;
546 case USB_REQ_SET_ADDRESS: {
547 unsigned char address = req->wValue;
548 logf("usb_core: SET_ADR %d", address);
549 if(ack_control(req)!=0)
550 break;
551 usb_drv_cancel_all_transfers();
552 usb_address = address;
553 usb_drv_set_address(usb_address);
554 usb_state = ADDRESS;
555 break;
558 case USB_REQ_GET_STATUS: {
559 response_data[0]= 0;
560 response_data[1]= 0;
561 logf("usb_core: GET_STATUS");
562 if(req->wIndex>0) {
563 if(usb_drv_stalled(req->wIndex&0xf,(req->wIndex&0x80)!=0))
564 response_data[0] = 1;
566 logf("usb_core: %X %X",response_data[0],response_data[1]);
567 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
568 break;
569 ack_control(req);
570 break;
573 case USB_REQ_GET_DESCRIPTOR: {
574 int index = req->wValue & 0xff;
575 int length = req->wLength;
576 int size;
577 const void* ptr = NULL;
578 logf("usb_core: GET_DESC %d", req->wValue >> 8);
580 switch (req->wValue >> 8) { /* type */
581 case USB_DT_DEVICE:
582 ptr = &device_descriptor;
583 size = sizeof device_descriptor;
584 break;
586 case USB_DT_OTHER_SPEED_CONFIG:
587 case USB_DT_CONFIG: {
588 int max_packet_size;
589 int interface_number=0;
591 if(req->wValue >> 8 == USB_DT_CONFIG) {
592 if(usb_drv_port_speed()) {
593 max_packet_size=512;
595 else {
596 max_packet_size=64;
598 config_descriptor.bDescriptorType=USB_DT_CONFIG;
600 else {
601 if(usb_drv_port_speed()) {
602 max_packet_size=64;
604 else {
605 max_packet_size=512;
607 config_descriptor.bDescriptorType=USB_DT_OTHER_SPEED_CONFIG;
609 size = sizeof(config_descriptor);
611 #ifdef USB_CHARGING_ONLY
612 if(usb_core_charging_enabled){
613 charging_interface_descriptor.bInterfaceNumber=interface_number;
614 interface_number++;
615 memcpy(&response_data[size],&charging_interface_descriptor,sizeof(struct usb_interface_descriptor));
616 size += sizeof(struct usb_interface_descriptor);
618 #endif
619 #ifdef USB_STORAGE
620 if(usb_core_storage_enabled){
621 mass_storage_ep_in_descriptor.wMaxPacketSize=max_packet_size;
622 mass_storage_ep_out_descriptor.wMaxPacketSize=max_packet_size;
623 mass_storage_interface_descriptor.bInterfaceNumber=interface_number;
624 interface_number++;
626 memcpy(&response_data[size],&mass_storage_interface_descriptor,sizeof(struct usb_interface_descriptor));
627 size += sizeof(struct usb_interface_descriptor);
628 memcpy(&response_data[size],&mass_storage_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor));
629 size += sizeof(struct usb_endpoint_descriptor);
630 memcpy(&response_data[size],&mass_storage_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor));
631 size += sizeof(struct usb_endpoint_descriptor);
633 #endif
634 #ifdef USB_SERIAL
635 if(usb_core_serial_enabled){
636 serial_ep_in_descriptor.wMaxPacketSize=max_packet_size;
637 serial_ep_out_descriptor.wMaxPacketSize=max_packet_size;
638 serial_interface_descriptor.bInterfaceNumber=interface_number;
639 interface_number++;
641 memcpy(&response_data[size],&serial_interface_descriptor,sizeof(struct usb_interface_descriptor));
642 size += sizeof(struct usb_interface_descriptor);
643 memcpy(&response_data[size],&serial_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor));
644 size += sizeof(struct usb_endpoint_descriptor);
645 memcpy(&response_data[size],&serial_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor));
646 size += sizeof(struct usb_endpoint_descriptor);
648 #endif
649 #ifdef USB_BENCHMARK
650 if(usb_core_benchmark_enabled){
651 benchmark_ep_in_descriptor.wMaxPacketSize=max_packet_size;
652 benchmark_ep_out_descriptor.wMaxPacketSize=max_packet_size;
653 config_descriptor.bNumInterfaces=interface_number;
655 memcpy(&response_data[size],&benchmark_interface_descriptor,sizeof(struct usb_interface_descriptor));
656 size += sizeof(struct usb_interface_descriptor);
657 memcpy(&response_data[size],&benchmark_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor));
658 size += sizeof(struct usb_endpoint_descriptor);
659 memcpy(&response_data[size],&benchmark_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor));
660 size += sizeof(struct usb_endpoint_descriptor);
662 #endif
663 config_descriptor.wTotalLength = size;
664 memcpy(&response_data[0],&config_descriptor,sizeof(struct usb_config_descriptor));
666 ptr = response_data;
667 break;
670 case USB_DT_STRING:
671 logf("STRING %d",index);
672 if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) {
673 size = usb_strings[index]->bLength;
674 memcpy(&response_data[0],usb_strings[index],size);
675 ptr = response_data;
677 else {
678 logf("bad string id %d", index);
679 usb_drv_stall(EP_CONTROL, true,true);
681 break;
683 case USB_DT_DEVICE_QUALIFIER:
684 ptr = &qualifier_descriptor;
685 size = sizeof qualifier_descriptor;
686 break;
688 default:
689 logf("bad desc %d", req->wValue >> 8);
690 usb_drv_stall(EP_CONTROL, true,true);
691 break;
694 if (ptr) {
695 length = MIN(size, length);
696 if(usb_drv_send(EP_CONTROL, (void*)UNCACHED_ADDR(ptr), length)!=0)
697 break;
699 ack_control(req);
700 break;
701 } /* USB_REQ_GET_DESCRIPTOR */
703 default:
704 #ifdef USB_STORAGE
705 /* does usb_storage know this request? */
706 if (!usb_storage_control_request(req))
707 #endif
709 #ifdef USB_SERIAL
710 /* does usb_serial know this request? */
711 if (!usb_serial_control_request(req))
712 #endif
714 /* nope. flag error */
715 logf("usb bad req %d", req->bRequest);
716 usb_drv_stall(EP_CONTROL, true,true);
717 ack_control(req);
719 break;
721 logf("control handled");
724 /* called by usb_drv_int() */
725 void usb_core_bus_reset(void)
727 usb_address = 0;
728 usb_state = DEFAULT;
731 /* called by usb_drv_transfer_completed() */
732 void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
734 #if defined(USB_CHARGING_ONLY) || defined(USB_STORAGE)
735 (void)in;
736 #endif
738 switch (endpoint) {
739 case EP_CONTROL:
740 /* already handled */
741 break;
743 default:
744 events[endpoint].endpoint=endpoint;
745 events[endpoint].in=in;
746 events[endpoint].data=0;
747 events[endpoint].status=status;
748 events[endpoint].length=length;
749 /* All other endoints. Let the thread deal with it */
750 usb_signal_transfer_completion(&events[endpoint]);
751 break;
755 /* called by usb_drv_int() */
756 void usb_core_control_request(struct usb_ctrlrequest* req)
758 events[0].endpoint=0;
759 events[0].in=0;
760 events[0].data=(void *)req;
761 events[0].status=0;
762 events[0].length=0;
763 logf("ctrl received %ld",current_tick);
764 usb_signal_transfer_completion(&events[0]);
767 static int ack_control(struct usb_ctrlrequest* req)
769 if (req->bRequestType & 0x80)
770 return usb_drv_recv(EP_CONTROL, NULL, 0);
771 else
772 return usb_drv_send(EP_CONTROL, NULL, 0);