Abstract the PortalPlayer AS3514 handling with an "ascodec" API - inspired by the...
[kugel-rb.git] / firmware / usbstack / usb_core.c
blobfa0ff5ea042ce65261c17c9e649ab0bb13d931d9
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)
54 #include "ata.h"
55 #endif
58 /*-------------------------------------------------------------------------*/
59 /* USB protocol descriptors: */
61 #define USB_SC_SCSI 0x06 /* Transparent */
62 #define USB_PROT_BULK 0x50 /* bulk only */
64 static const struct usb_device_descriptor __attribute__((aligned(2)))
65 device_descriptor=
67 .bLength = sizeof(struct usb_device_descriptor),
68 .bDescriptorType = USB_DT_DEVICE,
69 #ifdef USE_HIGH_SPEED
70 .bcdUSB = 0x0200,
71 #else
72 .bcdUSB = 0x0110,
73 #endif
74 .bDeviceClass = USB_CLASS_PER_INTERFACE,
75 .bDeviceSubClass = 0,
76 .bDeviceProtocol = 0,
77 .bMaxPacketSize0 = 64,
78 .idVendor = USB_VENDOR_ID,
79 .idProduct = USB_PRODUCT_ID,
80 .bcdDevice = 0x0100,
81 .iManufacturer = 1,
82 .iProduct = 2,
83 .iSerialNumber = 3,
84 .bNumConfigurations = 1
85 } ;
87 static struct usb_config_descriptor __attribute__((aligned(2)))
88 config_descriptor =
90 .bLength = sizeof(struct usb_config_descriptor),
91 .bDescriptorType = USB_DT_CONFIG,
92 .wTotalLength = 0, /* will be filled in later */
93 .bNumInterfaces = 1,
94 .bConfigurationValue = 1,
95 .iConfiguration = 0,
96 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
97 .bMaxPower = 250, /* 500mA in 2mA units */
101 static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
102 qualifier_descriptor =
104 .bLength = sizeof(struct usb_qualifier_descriptor),
105 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
106 .bcdUSB = 0x0200,
107 .bDeviceClass = 0,
108 .bDeviceSubClass = 0,
109 .bDeviceProtocol = 0,
110 .bMaxPacketSize0 = 64,
111 .bNumConfigurations = 1
114 static const struct usb_string_descriptor __attribute__((aligned(2)))
115 usb_string_iManufacturer =
118 USB_DT_STRING,
119 {'R','o','c','k','b','o','x','.','o','r','g'}
122 static const struct usb_string_descriptor __attribute__((aligned(2)))
123 usb_string_iProduct =
126 USB_DT_STRING,
127 {'R','o','c','k','b','o','x',' ',
128 'm','e','d','i','a',' ',
129 'p','l','a','y','e','r'}
132 static struct usb_string_descriptor __attribute__((aligned(2)))
133 usb_string_iSerial =
136 USB_DT_STRING,
137 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
138 '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
139 '0','0','0','0','0','0','0','0','0'}
142 /* Generic for all targets */
144 /* this is stringid #0: languages supported */
145 static const struct usb_string_descriptor __attribute__((aligned(2)))
146 lang_descriptor =
149 USB_DT_STRING,
150 {0x0409} /* LANGID US English */
153 static const struct usb_string_descriptor* const usb_strings[] =
155 &lang_descriptor,
156 &usb_string_iManufacturer,
157 &usb_string_iProduct,
158 &usb_string_iSerial
161 static int usb_address = 0;
162 static bool initialized = false;
163 static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
165 static int usb_core_num_interfaces;
167 typedef void (*completion_handler_t)(int ep,int dir, int status, int length);
168 typedef bool (*control_handler_t)(struct usb_ctrlrequest* req);
170 static struct
172 completion_handler_t completion_handler[2];
173 control_handler_t control_handler[2];
174 struct usb_transfer_completion_event_data completion_event;
175 } ep_data[NUM_ENDPOINTS];
177 static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
179 #ifdef USB_STORAGE
180 [USB_DRIVER_MASS_STORAGE] = {
181 .enabled = false,
182 .needs_exclusive_ata = true,
183 .first_interface = 0,
184 .last_interface = 0,
185 .request_endpoints = usb_storage_request_endpoints,
186 .set_first_interface = usb_storage_set_first_interface,
187 .get_config_descriptor = usb_storage_get_config_descriptor,
188 .init_connection = usb_storage_init_connection,
189 .init = usb_storage_init,
190 .disconnect = NULL,
191 .transfer_complete = usb_storage_transfer_complete,
192 .control_request = usb_storage_control_request,
193 #ifdef HAVE_HOTSWAP
194 .notify_hotswap = usb_storage_notify_hotswap,
195 #endif
197 #endif
198 #ifdef USB_SERIAL
199 [USB_DRIVER_SERIAL] = {
200 .enabled = false,
201 .needs_exclusive_ata = false,
202 .first_interface = 0,
203 .last_interface = 0,
204 .request_endpoints = usb_serial_request_endpoints,
205 .set_first_interface = usb_serial_set_first_interface,
206 .get_config_descriptor = usb_serial_get_config_descriptor,
207 .init_connection = usb_serial_init_connection,
208 .init = usb_serial_init,
209 .disconnect = usb_serial_disconnect,
210 .transfer_complete = usb_serial_transfer_complete,
211 .control_request = usb_serial_control_request,
212 #ifdef HAVE_HOTSWAP
213 .notify_hotswap = NULL,
214 #endif
216 #endif
217 #ifdef USB_CHARGING_ONLY
218 [USB_DRIVER_CHARGING_ONLY] = {
219 .enabled = false,
220 .needs_exclusive_ata = false,
221 .first_interface = 0,
222 .last_interface = 0,
223 .request_endpoints = usb_charging_only_request_endpoints,
224 .set_first_interface = usb_charging_only_set_first_interface,
225 .get_config_descriptor = usb_charging_only_get_config_descriptor,
226 .init_connection = NULL,
227 .init = NULL,
228 .disconnect = NULL,
229 .transfer_complete = NULL,
230 .control_request = NULL,
231 #ifdef HAVE_HOTSWAP
232 .notify_hotswap = NULL,
233 #endif
235 #endif
238 static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
240 static unsigned char response_data[256] USBDEVBSS_ATTR;
243 static short hex[16] = {'0','1','2','3','4','5','6','7',
244 '8','9','A','B','C','D','E','F'};
245 #ifdef IPOD_ARCH
246 static void set_serial_descriptor(void)
248 #ifdef IPOD_VIDEO
249 uint32_t* serial = (uint32_t*)(0x20004034);
250 #else
251 uint32_t* serial = (uint32_t*)(0x20002034);
252 #endif
254 /* We need to convert from a little-endian 64-bit int
255 into a utf-16 string of hex characters */
256 short* p = &usb_string_iSerial.wString[24];
257 uint32_t x;
258 int i,j;
260 for (i = 0; i < 2; i++) {
261 x = serial[i];
262 for (j=0;j<8;j++) {
263 *p-- = hex[x & 0xf];
264 x >>= 4;
267 usb_string_iSerial.bLength=52;
269 #elif defined(HAVE_AS3514)
270 static void set_serial_descriptor(void)
272 unsigned char serial[16];
273 /* Align 32 digits right in the 40-digit serial number */
274 short* p = &usb_string_iSerial.wString[1];
275 int i;
277 ascodec_readbytes(AS3514_UID_0, 0x10, serial);
278 for (i = 0; i < 16; i++) {
279 *p++ = hex[(serial[i] >> 4) & 0xF];
280 *p++ = hex[(serial[i] >> 0) & 0xF];
282 usb_string_iSerial.bLength=68;
284 #else
285 /* If we don't know the device serial number, use the one
286 * from the disk */
287 static void set_serial_descriptor(void)
289 short* p = &usb_string_iSerial.wString[1];
290 unsigned short* identify = ata_get_identify();
291 unsigned short x;
292 int i;
294 for (i = 10; i < 20; i++) {
295 x = identify[i];
296 *p++ = hex[(x >> 12) & 0xF];
297 *p++ = hex[(x >> 8) & 0xF];
298 *p++ = hex[(x >> 4) & 0xF];
299 *p++ = hex[(x >> 0) & 0xF];
301 usb_string_iSerial.bLength=84;
303 #endif
305 void usb_core_init(void)
307 int i;
308 if (initialized)
309 return;
311 usb_drv_init();
313 /* class driver init functions should be safe to call even if the driver
314 * won't be used. This simplifies other logic (i.e. we don't need to know
315 * yet which drivers will be enabled */
316 for(i=0;i<USB_NUM_DRIVERS;i++) {
317 if(drivers[i].enabled && drivers[i].init != NULL)
318 drivers[i].init();
321 initialized = true;
322 usb_state = DEFAULT;
323 logf("usb_core_init() finished");
326 void usb_core_exit(void)
328 int i;
329 for(i=0;i<USB_NUM_DRIVERS;i++) {
330 if(drivers[i].enabled && drivers[i].disconnect != NULL)
331 drivers[i].disconnect ();
334 if (initialized) {
335 usb_drv_exit();
337 initialized = false;
338 logf("usb_core_exit() finished");
341 void usb_core_handle_transfer_completion(
342 struct usb_transfer_completion_event_data* event)
344 int ep = event->endpoint;
346 switch(ep) {
347 case EP_CONTROL:
348 logf("ctrl handled %ld",current_tick);
349 usb_core_control_request_handler(
350 (struct usb_ctrlrequest*)event->data);
351 break;
352 default:
353 if(ep_data[ep].completion_handler[event->dir>>7] != NULL)
354 ep_data[ep].completion_handler[event->dir>>7](ep,event->dir,
355 event->status,event->length);
356 break;
360 void usb_core_enable_driver(int driver,bool enabled)
362 drivers[driver].enabled = enabled;
365 bool usb_core_driver_enabled(int driver)
367 return drivers[driver].enabled;
370 #ifdef HAVE_HOTSWAP
371 void usb_core_hotswap_event(int volume,bool inserted)
373 int i;
374 for(i=0;i<USB_NUM_DRIVERS;i++) {
375 if(drivers[i].enabled &&
376 drivers[i].notify_hotswap!=NULL)
378 drivers[i].notify_hotswap(volume,inserted);
382 #endif
384 static void usb_core_set_serial_function_id(void)
386 int id = 0;
387 int i;
388 for(i=0;i<USB_NUM_DRIVERS;i++) {
389 if(drivers[i].enabled)
390 id |= 1<<i;
392 usb_string_iSerial.wString[0] = hex[id];
395 int usb_core_request_endpoint(int dir, struct usb_class_driver *drv)
397 int ret, ep;
399 ret = usb_drv_request_endpoint(dir);
401 if (ret == -1)
402 return -1;
404 ep = ret & 0x7f;
405 dir = ret >> 7;
407 ep_data[ep].completion_handler[dir] = drv->transfer_complete;
408 ep_data[ep].control_handler[dir] = drv->control_request;
410 return ret;
413 void usb_core_release_endpoint(int ep)
415 int dir;
417 usb_drv_release_endpoint(ep);
419 dir = ep >> 7;
420 ep &= 0x7f;
422 ep_data[ep].completion_handler[dir] = NULL;
423 ep_data[ep].control_handler[dir] = NULL;
426 static void allocate_interfaces_and_endpoints(void)
428 int i;
429 int interface=0;
431 memset(ep_data,0,sizeof(ep_data));
433 for (i = 0; i < NUM_ENDPOINTS; i++) {
434 usb_drv_release_endpoint(i | USB_DIR_OUT);
435 usb_drv_release_endpoint(i | USB_DIR_IN);
438 for(i=0; i < USB_NUM_DRIVERS; i++) {
439 if(drivers[i].enabled) {
440 drivers[i].first_interface = interface;
442 if (drivers[i].request_endpoints(&drivers[i])) {
443 drivers[i].enabled = false;
444 continue;
447 interface = drivers[i].set_first_interface(interface);
448 drivers[i].last_interface = interface;
451 usb_core_num_interfaces = interface;
454 static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
456 int i;
457 if(usb_state == DEFAULT) {
458 set_serial_descriptor();
459 usb_core_set_serial_function_id();
461 allocate_interfaces_and_endpoints();
463 for(i=0;i<USB_NUM_DRIVERS;i++) {
464 if(drivers[i].enabled &&
465 drivers[i].needs_exclusive_ata) {
466 usb_request_exclusive_ata();
467 break;
472 switch(req->bRequestType & 0x1f) {
473 case 0: /* Device */
474 switch (req->bRequest) {
475 case USB_REQ_GET_CONFIGURATION: {
476 logf("usb_core: GET_CONFIG");
477 if (usb_state == ADDRESS)
478 response_data[0] = 0;
479 else
480 response_data[0] = 1;
481 if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
482 break;
483 usb_core_ack_control(req);
484 break;
485 case USB_REQ_SET_CONFIGURATION:
486 logf("usb_core: SET_CONFIG");
487 usb_drv_cancel_all_transfers();
488 if (req->wValue) {
489 usb_state = CONFIGURED;
490 for(i=0;i<USB_NUM_DRIVERS;i++) {
491 if(drivers[i].enabled &&
492 drivers[i].init_connection!=NULL)
494 drivers[i].init_connection();
498 else {
499 usb_state = ADDRESS;
501 usb_core_ack_control(req);
502 break;
504 case USB_REQ_SET_ADDRESS: {
505 unsigned char address = req->wValue;
506 logf("usb_core: SET_ADR %d", address);
507 if(usb_core_ack_control(req)!=0)
508 break;
509 usb_drv_cancel_all_transfers();
510 usb_address = address;
511 usb_drv_set_address(usb_address);
512 usb_state = ADDRESS;
513 break;
515 case USB_REQ_GET_DESCRIPTOR: {
516 int index = req->wValue & 0xff;
517 int length = req->wLength;
518 int size;
519 const void* ptr = NULL;
520 logf("usb_core: GET_DESC %d", req->wValue >> 8);
522 switch (req->wValue >> 8) { /* type */
523 case USB_DT_DEVICE:
524 ptr = &device_descriptor;
525 size = sizeof(struct usb_device_descriptor);
526 break;
528 case USB_DT_OTHER_SPEED_CONFIG:
529 case USB_DT_CONFIG: {
530 int max_packet_size;
532 if(req->wValue >> 8 == USB_DT_CONFIG) {
533 if(usb_drv_port_speed())
534 max_packet_size=512;
535 else
536 max_packet_size=64;
537 config_descriptor.bDescriptorType=USB_DT_CONFIG;
539 else {
540 if(usb_drv_port_speed())
541 max_packet_size=64;
542 else
543 max_packet_size=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 &&
551 drivers[i].get_config_descriptor)
553 size+=drivers[i].get_config_descriptor(
554 &response_data[size],
555 max_packet_size);
558 config_descriptor.bNumInterfaces =
559 usb_core_num_interfaces;
560 config_descriptor.wTotalLength = size;
561 memcpy(&response_data[0],&config_descriptor,
562 sizeof(struct usb_config_descriptor));
564 ptr = response_data;
565 break;
568 case USB_DT_STRING:
569 logf("STRING %d",index);
570 if ((unsigned)index < (sizeof(usb_strings)/
571 sizeof(struct usb_string_descriptor*)))
573 size = usb_strings[index]->bLength;
574 ptr = usb_strings[index];
576 else {
577 logf("bad string id %d", index);
578 usb_drv_stall(EP_CONTROL, true,true);
580 break;
582 case USB_DT_DEVICE_QUALIFIER:
583 ptr = &qualifier_descriptor;
584 size = sizeof (struct usb_qualifier_descriptor);
585 break;
587 default:
588 logf("bad desc %d", req->wValue >> 8);
589 usb_drv_stall(EP_CONTROL, true,true);
590 break;
593 if (ptr) {
594 length = MIN(size, length);
596 if (ptr != response_data) {
597 memcpy(response_data, ptr, length);
600 if(usb_drv_send(EP_CONTROL, response_data, length)!=0)
601 break;
603 usb_core_ack_control(req);
604 break;
605 } /* USB_REQ_GET_DESCRIPTOR */
606 case USB_REQ_CLEAR_FEATURE:
607 break;
608 case USB_REQ_SET_FEATURE:
609 if(req->wValue == 2) { /* TEST_MODE */
610 int mode=req->wIndex>>8;
611 usb_core_ack_control(req);
612 usb_drv_set_test_mode(mode);
614 break;
615 case USB_REQ_GET_STATUS:
616 response_data[0]= 0;
617 response_data[1]= 0;
618 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
619 break;
620 usb_core_ack_control(req);
621 break;
622 default:
623 break;
625 break;
626 case 1: /* Interface */
627 switch (req->bRequest) {
628 case USB_REQ_SET_INTERFACE:
629 logf("usb_core: SET_INTERFACE");
630 usb_core_ack_control(req);
631 break;
633 case USB_REQ_GET_INTERFACE:
634 logf("usb_core: GET_INTERFACE");
635 response_data[0] = 0;
636 if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
637 break;
638 usb_core_ack_control(req);
639 break;
640 case USB_REQ_CLEAR_FEATURE:
641 break;
642 case USB_REQ_SET_FEATURE:
643 break;
644 case USB_REQ_GET_STATUS:
645 response_data[0]= 0;
646 response_data[1]= 0;
647 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
648 break;
649 usb_core_ack_control(req);
650 break;
651 default: {
652 bool handled=false;
653 for(i=0;i<USB_NUM_DRIVERS;i++) {
654 if(drivers[i].enabled &&
655 drivers[i].control_request &&
656 drivers[i].first_interface <= (req->wIndex) &&
657 drivers[i].last_interface > (req->wIndex))
659 handled = drivers[i].control_request(req);
662 if(!handled) {
663 /* nope. flag error */
664 logf("usb bad req %d", req->bRequest);
665 usb_drv_stall(EP_CONTROL, true,true);
666 usb_core_ack_control(req);
668 break;
671 break;
672 case 2: /* Endpoint */
673 switch (req->bRequest) {
674 case USB_REQ_CLEAR_FEATURE:
675 if (req->wValue == 0 ) /* ENDPOINT_HALT */
676 usb_drv_stall(req->wIndex & 0xf, false,
677 (req->wIndex & 0x80) !=0);
678 usb_core_ack_control(req);
679 break;
680 case USB_REQ_SET_FEATURE:
681 if (req->wValue == 0 ) /* ENDPOINT_HALT */
682 usb_drv_stall(req->wIndex & 0xf, true,
683 (req->wIndex & 0x80) !=0);
684 usb_core_ack_control(req);
685 break;
686 case USB_REQ_GET_STATUS:
687 response_data[0]= 0;
688 response_data[1]= 0;
689 logf("usb_core: GET_STATUS");
690 if(req->wIndex>0)
691 response_data[0] = usb_drv_stalled(req->wIndex&0xf,
692 (req->wIndex&0x80)!=0);
693 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
694 break;
695 usb_core_ack_control(req);
696 break;
697 default: {
698 bool handled=false;
699 if(ep_data[req->wIndex & 0xf].control_handler[0] != NULL)
700 handled = ep_data[req->wIndex & 0xf].control_handler[0](req);
701 if(!handled) {
702 /* nope. flag error */
703 logf("usb bad req %d", req->bRequest);
704 usb_drv_stall(EP_CONTROL, true,true);
705 usb_core_ack_control(req);
707 break;
711 logf("control handled");
714 /* called by usb_drv_int() */
715 void usb_core_bus_reset(void)
717 usb_address = 0;
718 usb_state = DEFAULT;
721 /* called by usb_drv_transfer_completed() */
722 void usb_core_transfer_complete(int endpoint, int dir, int status,int length)
724 switch (endpoint) {
725 case EP_CONTROL:
726 /* already handled */
727 break;
729 default:
730 ep_data[endpoint].completion_event.endpoint=endpoint;
731 ep_data[endpoint].completion_event.dir=dir;
732 ep_data[endpoint].completion_event.data=0;
733 ep_data[endpoint].completion_event.status=status;
734 ep_data[endpoint].completion_event.length=length;
735 /* All other endoints. Let the thread deal with it */
736 usb_signal_transfer_completion(&ep_data[endpoint].completion_event);
737 break;
741 /* called by usb_drv_int() */
742 void usb_core_control_request(struct usb_ctrlrequest* req)
744 ep_data[0].completion_event.endpoint=0;
745 ep_data[0].completion_event.dir=0;
746 ep_data[0].completion_event.data=(void *)req;
747 ep_data[0].completion_event.status=0;
748 ep_data[0].completion_event.length=0;
749 logf("ctrl received %ld",current_tick);
750 usb_signal_transfer_completion(&ep_data[0].completion_event);
753 int usb_core_ack_control(struct usb_ctrlrequest* req)
755 if (req->bRequestType & 0x80)
756 return usb_drv_recv(EP_CONTROL, NULL, 0);
757 else
758 return usb_drv_send(EP_CONTROL, NULL, 0);
761 #ifdef HAVE_USB_POWER
762 unsigned short usb_allowed_current()
764 if (usb_state == CONFIGURED)
766 return 500;
768 else
770 return 100;
773 #endif