summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_core.c
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-04-26 19:02:16 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-04-26 19:02:16 +0000
commitbec6aa3176fc6d5ce80bcd4d6022358aa6c01629 (patch)
treedfbaa924ba3e13d6f73dc446b1a2149610ed3e67 /firmware/usbstack/usb_core.c
parent33c44461e1b5fb9aff2f8ba7470ad2449b3c410e (diff)
downloadrockbox-bec6aa3176fc6d5ce80bcd4d6022358aa6c01629.tar.gz
rockbox-bec6aa3176fc6d5ce80bcd4d6022358aa6c01629.zip
- change the usb class driver framework to allow for device classes with more than one interface or more than one endpoint pair
- move the charging-only dummy driver out of usb_core git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17252 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/usbstack/usb_core.c')
-rw-r--r--firmware/usbstack/usb_core.c184
1 files changed, 80 insertions, 104 deletions
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 084b8893af..759a342dd2 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -37,6 +37,10 @@
37#include "usb_serial.h" 37#include "usb_serial.h"
38#endif 38#endif
39 39
40#if defined(USB_CHARGING_ONLY)
41#include "usb_charging_only.h"
42#endif
43
40/* TODO: Move target-specific stuff somewhere else (serial number reading) */ 44/* TODO: Move target-specific stuff somewhere else (serial number reading) */
41 45
42#ifdef HAVE_AS3514 46#ifdef HAVE_AS3514
@@ -91,22 +95,6 @@ static struct usb_config_descriptor __attribute__((aligned(2)))
91 .bMaxPower = 250, /* 500mA in 2mA units */ 95 .bMaxPower = 250, /* 500mA in 2mA units */
92}; 96};
93 97
94#ifdef USB_CHARGING_ONLY
95/* dummy interface for charging-only */
96static struct usb_interface_descriptor __attribute__((aligned(2)))
97 charging_interface_descriptor =
98{
99 .bLength = sizeof(struct usb_interface_descriptor),
100 .bDescriptorType = USB_DT_INTERFACE,
101 .bInterfaceNumber = 0,
102 .bAlternateSetting = 0,
103 .bNumEndpoints = 0,
104 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
105 .bInterfaceSubClass = 0,
106 .bInterfaceProtocol = 0,
107 .iInterface = 4
108};
109#endif
110 98
111static const struct usb_qualifier_descriptor __attribute__((aligned(2))) 99static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
112 qualifier_descriptor = 100 qualifier_descriptor =
@@ -160,21 +148,12 @@ static const struct usb_string_descriptor __attribute__((aligned(2)))
160 {0x0409} /* LANGID US English */ 148 {0x0409} /* LANGID US English */
161}; 149};
162 150
163static const struct usb_string_descriptor __attribute__((aligned(2)))
164 usb_string_charging_only =
165{
166 28,
167 USB_DT_STRING,
168 {'C','h','a','r','g','i','n','g',' ','o','n','l','y'}
169};
170
171static const struct usb_string_descriptor* const usb_strings[] = 151static const struct usb_string_descriptor* const usb_strings[] =
172{ 152{
173 &lang_descriptor, 153 &lang_descriptor,
174 &usb_string_iManufacturer, 154 &usb_string_iManufacturer,
175 &usb_string_iProduct, 155 &usb_string_iProduct,
176 &usb_string_iSerial, 156 &usb_string_iSerial
177 &usb_string_charging_only
178}; 157};
179 158
180static int usb_address = 0; 159static int usb_address = 0;
@@ -183,8 +162,12 @@ static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
183 162
184static int usb_core_num_interfaces; 163static int usb_core_num_interfaces;
185 164
186static int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size, 165static struct
187 int interface_number,int endpoint); 166{
167 void (*completion_handler)(int ep,bool in, int status, int length);
168 bool (*control_handler)(struct usb_ctrlrequest* req);
169 struct usb_transfer_completion_event_data completion_event;
170} ep_data[NUM_ENDPOINTS];
188 171
189static struct usb_class_driver drivers[USB_NUM_DRIVERS] = 172static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
190{ 173{
@@ -192,8 +175,10 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
192 [USB_DRIVER_MASS_STORAGE] = { 175 [USB_DRIVER_MASS_STORAGE] = {
193 .enabled = false, 176 .enabled = false,
194 .needs_exclusive_ata = true, 177 .needs_exclusive_ata = true,
195 .usb_endpoint = 0, 178 .first_interface = 0,
196 .usb_interface = 0, 179 .last_interface = 0,
180 .set_first_interface = usb_storage_set_first_interface,
181 .set_first_endpoint = usb_storage_set_first_endpoint,
197 .get_config_descriptor = usb_storage_get_config_descriptor, 182 .get_config_descriptor = usb_storage_get_config_descriptor,
198 .init_connection = usb_storage_init_connection, 183 .init_connection = usb_storage_init_connection,
199 .init = usb_storage_init, 184 .init = usb_storage_init,
@@ -209,8 +194,10 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
209 [USB_DRIVER_SERIAL] = { 194 [USB_DRIVER_SERIAL] = {
210 .enabled = false, 195 .enabled = false,
211 .needs_exclusive_ata = false, 196 .needs_exclusive_ata = false,
212 .usb_endpoint = 0, 197 .first_interface = 0,
213 .usb_interface = 0, 198 .last_interface = 0,
199 .set_first_interface = usb_serial_set_first_interface,
200 .set_first_endpoint = usb_serial_set_first_endpoint,
214 .get_config_descriptor = usb_serial_get_config_descriptor, 201 .get_config_descriptor = usb_serial_get_config_descriptor,
215 .init_connection = usb_serial_init_connection, 202 .init_connection = usb_serial_init_connection,
216 .init = usb_serial_init, 203 .init = usb_serial_init,
@@ -226,9 +213,11 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
226 [USB_DRIVER_CHARGING_ONLY] = { 213 [USB_DRIVER_CHARGING_ONLY] = {
227 .enabled = false, 214 .enabled = false,
228 .needs_exclusive_ata = false, 215 .needs_exclusive_ata = false,
229 .usb_endpoint = 0, 216 .first_interface = 0,
230 .usb_interface = 0, 217 .last_interface = 0,
231 .get_config_descriptor = usb_charging_get_config_descriptor, 218 .set_first_interface = usb_charging_only_set_first_interface,
219 .set_first_endpoint = usb_charging_only_set_first_endpoint,
220 .get_config_descriptor = usb_charging_only_get_config_descriptor,
232 .init_connection = NULL, 221 .init_connection = NULL,
233 .init = NULL, 222 .init = NULL,
234 .disconnect = NULL, 223 .disconnect = NULL,
@@ -242,11 +231,9 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
242}; 231};
243 232
244static void usb_core_control_request_handler(struct usb_ctrlrequest* req); 233static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
245static int ack_control(struct usb_ctrlrequest* req);
246 234
247static unsigned char response_data[256] USBDEVBSS_ATTR; 235static unsigned char response_data[256] USBDEVBSS_ATTR;
248 236
249static struct usb_transfer_completion_event_data events[NUM_ENDPOINTS];
250 237
251static short hex[16] = {'0','1','2','3','4','5','6','7', 238static short hex[16] = {'0','1','2','3','4','5','6','7',
252 '8','9','A','B','C','D','E','F'}; 239 '8','9','A','B','C','D','E','F'};
@@ -331,17 +318,6 @@ void usb_core_init(void)
331 logf("usb_core_init() finished"); 318 logf("usb_core_init() finished");
332} 319}
333 320
334static int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
335 int interface_number,int endpoint)
336{
337 (void) max_packet_size;
338 (void) endpoint;
339 charging_interface_descriptor.bInterfaceNumber=interface_number;
340 memcpy(dest,&charging_interface_descriptor,
341 sizeof(struct usb_interface_descriptor));
342 return sizeof(struct usb_interface_descriptor);
343}
344
345void usb_core_exit(void) 321void usb_core_exit(void)
346{ 322{
347 int i; 323 int i;
@@ -360,24 +336,17 @@ void usb_core_exit(void)
360void usb_core_handle_transfer_completion( 336void usb_core_handle_transfer_completion(
361 struct usb_transfer_completion_event_data* event) 337 struct usb_transfer_completion_event_data* event)
362{ 338{
363 int i; 339 int ep = event->endpoint;
364 switch(event->endpoint) { 340 switch(ep) {
365 case EP_CONTROL: 341 case EP_CONTROL:
366 logf("ctrl handled %ld",current_tick); 342 logf("ctrl handled %ld",current_tick);
367 usb_core_control_request_handler( 343 usb_core_control_request_handler(
368 (struct usb_ctrlrequest*)event->data); 344 (struct usb_ctrlrequest*)event->data);
369 break; 345 break;
370 default: 346 default:
371 for(i=0;i<USB_NUM_DRIVERS;i++) { 347 if(ep_data[ep].completion_handler != NULL)
372 if(drivers[i].enabled && 348 ep_data[ep].completion_handler(ep,event->in,
373 drivers[i].usb_endpoint == event->endpoint &&
374 drivers[i].transfer_complete != NULL)
375 {
376 drivers[i].transfer_complete(event->in,
377 event->status,event->length); 349 event->status,event->length);
378 break;
379 }
380 }
381 break; 350 break;
382 } 351 }
383} 352}
@@ -419,13 +388,29 @@ static void usb_core_set_serial_function_id(void)
419 388
420static void allocate_interfaces_and_endpoints(void) 389static void allocate_interfaces_and_endpoints(void)
421{ 390{
422 int i; 391 int i,j;
423 int interface=0; 392 int interface=0;
424 int endpoint=1; 393 int endpoint=1;
394
395 memset(ep_data,0,sizeof(ep_data));
396
425 for(i=0;i<USB_NUM_DRIVERS;i++) { 397 for(i=0;i<USB_NUM_DRIVERS;i++) {
426 if(drivers[i].enabled) { 398 if(drivers[i].enabled) {
427 drivers[i].usb_endpoint = endpoint++; 399 int oldendpoint = endpoint;
428 drivers[i].usb_interface = interface++; 400 drivers[i].first_interface = interface;
401
402 endpoint = drivers[i].set_first_endpoint(endpoint);
403 if(endpoint>NUM_ENDPOINTS) {
404 drivers[i].enabled = false;
405 continue;
406 }
407 interface = drivers[i].set_first_interface(interface);
408 drivers[i].last_interface = interface;
409
410 for(j=oldendpoint;j<endpoint;j++) {
411 ep_data[j].completion_handler=drivers[i].transfer_complete;
412 ep_data[j].control_handler=drivers[i].control_request;
413 }
429 } 414 }
430 if(endpoint>NUM_ENDPOINTS) { 415 if(endpoint>NUM_ENDPOINTS) {
431 drivers[i].enabled = false; 416 drivers[i].enabled = false;
@@ -463,7 +448,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
463 response_data[0] = 1; 448 response_data[0] = 1;
464 if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0) 449 if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
465 break; 450 break;
466 ack_control(req); 451 usb_core_ack_control(req);
467 break; 452 break;
468 case USB_REQ_SET_CONFIGURATION: 453 case USB_REQ_SET_CONFIGURATION:
469 logf("usb_core: SET_CONFIG"); 454 logf("usb_core: SET_CONFIG");
@@ -474,22 +459,20 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
474 if(drivers[i].enabled && 459 if(drivers[i].enabled &&
475 drivers[i].init_connection!=NULL) 460 drivers[i].init_connection!=NULL)
476 { 461 {
477 drivers[i].init_connection( 462 drivers[i].init_connection();
478 drivers[i].usb_interface,
479 drivers[i].usb_endpoint);
480 } 463 }
481 } 464 }
482 } 465 }
483 else { 466 else {
484 usb_state = ADDRESS; 467 usb_state = ADDRESS;
485 } 468 }
486 ack_control(req); 469 usb_core_ack_control(req);
487 break; 470 break;
488 } 471 }
489 case USB_REQ_SET_ADDRESS: { 472 case USB_REQ_SET_ADDRESS: {
490 unsigned char address = req->wValue; 473 unsigned char address = req->wValue;
491 logf("usb_core: SET_ADR %d", address); 474 logf("usb_core: SET_ADR %d", address);
492 if(ack_control(req)!=0) 475 if(usb_core_ack_control(req)!=0)
493 break; 476 break;
494 usb_drv_cancel_all_transfers(); 477 usb_drv_cancel_all_transfers();
495 usb_address = address; 478 usb_address = address;
@@ -537,9 +520,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
537 { 520 {
538 size+=drivers[i].get_config_descriptor( 521 size+=drivers[i].get_config_descriptor(
539 &response_data[size], 522 &response_data[size],
540 max_packet_size, 523 max_packet_size);
541 drivers[i].usb_interface,
542 drivers[i].usb_endpoint);
543 } 524 }
544 } 525 }
545 config_descriptor.bNumInterfaces = 526 config_descriptor.bNumInterfaces =
@@ -587,7 +568,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
587 if(usb_drv_send(EP_CONTROL, response_data, length)!=0) 568 if(usb_drv_send(EP_CONTROL, response_data, length)!=0)
588 break; 569 break;
589 } 570 }
590 ack_control(req); 571 usb_core_ack_control(req);
591 break; 572 break;
592 } /* USB_REQ_GET_DESCRIPTOR */ 573 } /* USB_REQ_GET_DESCRIPTOR */
593 case USB_REQ_CLEAR_FEATURE: 574 case USB_REQ_CLEAR_FEATURE:
@@ -595,7 +576,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
595 case USB_REQ_SET_FEATURE: 576 case USB_REQ_SET_FEATURE:
596 if(req->wValue == 2) { /* TEST_MODE */ 577 if(req->wValue == 2) { /* TEST_MODE */
597 int mode=req->wIndex>>8; 578 int mode=req->wIndex>>8;
598 ack_control(req); 579 usb_core_ack_control(req);
599 usb_drv_set_test_mode(mode); 580 usb_drv_set_test_mode(mode);
600 } 581 }
601 break; 582 break;
@@ -604,7 +585,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
604 response_data[1]= 0; 585 response_data[1]= 0;
605 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0) 586 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
606 break; 587 break;
607 ack_control(req); 588 usb_core_ack_control(req);
608 break; 589 break;
609 default: 590 default:
610 break; 591 break;
@@ -614,7 +595,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
614 switch (req->bRequest) { 595 switch (req->bRequest) {
615 case USB_REQ_SET_INTERFACE: 596 case USB_REQ_SET_INTERFACE:
616 logf("usb_core: SET_INTERFACE"); 597 logf("usb_core: SET_INTERFACE");
617 ack_control(req); 598 usb_core_ack_control(req);
618 break; 599 break;
619 600
620 case USB_REQ_GET_INTERFACE: 601 case USB_REQ_GET_INTERFACE:
@@ -622,7 +603,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
622 response_data[0] = 0; 603 response_data[0] = 0;
623 if(usb_drv_send(EP_CONTROL, response_data, 1)!=0) 604 if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
624 break; 605 break;
625 ack_control(req); 606 usb_core_ack_control(req);
626 break; 607 break;
627 case USB_REQ_CLEAR_FEATURE: 608 case USB_REQ_CLEAR_FEATURE:
628 break; 609 break;
@@ -633,14 +614,15 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
633 response_data[1]= 0; 614 response_data[1]= 0;
634 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0) 615 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
635 break; 616 break;
636 ack_control(req); 617 usb_core_ack_control(req);
637 break; 618 break;
638 default: { 619 default: {
639 bool handled=false; 620 bool handled=false;
640 for(i=0;i<USB_NUM_DRIVERS;i++) { 621 for(i=0;i<USB_NUM_DRIVERS;i++) {
641 if(drivers[i].enabled && 622 if(drivers[i].enabled &&
642 drivers[i].control_request && 623 drivers[i].control_request &&
643 drivers[i].usb_interface == (req->wIndex)) 624 drivers[i].first_interface <= (req->wIndex) &&
625 drivers[i].last_interface > (req->wIndex))
644 { 626 {
645 handled = drivers[i].control_request(req); 627 handled = drivers[i].control_request(req);
646 } 628 }
@@ -649,7 +631,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
649 /* nope. flag error */ 631 /* nope. flag error */
650 logf("usb bad req %d", req->bRequest); 632 logf("usb bad req %d", req->bRequest);
651 usb_drv_stall(EP_CONTROL, true,true); 633 usb_drv_stall(EP_CONTROL, true,true);
652 ack_control(req); 634 usb_core_ack_control(req);
653 } 635 }
654 break; 636 break;
655 } 637 }
@@ -661,13 +643,13 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
661 if (req->wValue == 0 ) /* ENDPOINT_HALT */ 643 if (req->wValue == 0 ) /* ENDPOINT_HALT */
662 usb_drv_stall(req->wIndex & 0xf, false, 644 usb_drv_stall(req->wIndex & 0xf, false,
663 (req->wIndex & 0x80) !=0); 645 (req->wIndex & 0x80) !=0);
664 ack_control(req); 646 usb_core_ack_control(req);
665 break; 647 break;
666 case USB_REQ_SET_FEATURE: 648 case USB_REQ_SET_FEATURE:
667 if (req->wValue == 0 ) /* ENDPOINT_HALT */ 649 if (req->wValue == 0 ) /* ENDPOINT_HALT */
668 usb_drv_stall(req->wIndex & 0xf, true, 650 usb_drv_stall(req->wIndex & 0xf, true,
669 (req->wIndex & 0x80) !=0); 651 (req->wIndex & 0x80) !=0);
670 ack_control(req); 652 usb_core_ack_control(req);
671 break; 653 break;
672 case USB_REQ_GET_STATUS: 654 case USB_REQ_GET_STATUS:
673 response_data[0]= 0; 655 response_data[0]= 0;
@@ -678,23 +660,17 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
678 (req->wIndex&0x80)!=0); 660 (req->wIndex&0x80)!=0);
679 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0) 661 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
680 break; 662 break;
681 ack_control(req); 663 usb_core_ack_control(req);
682 break; 664 break;
683 default: { 665 default: {
684 bool handled=false; 666 bool handled=false;
685 for(i=0;i<USB_NUM_DRIVERS;i++) { 667 if(ep_data[req->wIndex & 0xf].control_handler != NULL)
686 if(drivers[i].enabled && 668 handled = ep_data[req->wIndex & 0xf].control_handler(req);
687 drivers[i].control_request &&
688 drivers[i].usb_endpoint == (req->wIndex & 0xf))
689 {
690 handled = drivers[i].control_request(req);
691 }
692 }
693 if(!handled) { 669 if(!handled) {
694 /* nope. flag error */ 670 /* nope. flag error */
695 logf("usb bad req %d", req->bRequest); 671 logf("usb bad req %d", req->bRequest);
696 usb_drv_stall(EP_CONTROL, true,true); 672 usb_drv_stall(EP_CONTROL, true,true);
697 ack_control(req); 673 usb_core_ack_control(req);
698 } 674 }
699 break; 675 break;
700 } 676 }
@@ -719,13 +695,13 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
719 break; 695 break;
720 696
721 default: 697 default:
722 events[endpoint].endpoint=endpoint; 698 ep_data[endpoint].completion_event.endpoint=endpoint;
723 events[endpoint].in=in; 699 ep_data[endpoint].completion_event.in=in;
724 events[endpoint].data=0; 700 ep_data[endpoint].completion_event.data=0;
725 events[endpoint].status=status; 701 ep_data[endpoint].completion_event.status=status;
726 events[endpoint].length=length; 702 ep_data[endpoint].completion_event.length=length;
727 /* All other endoints. Let the thread deal with it */ 703 /* All other endoints. Let the thread deal with it */
728 usb_signal_transfer_completion(&events[endpoint]); 704 usb_signal_transfer_completion(&ep_data[endpoint].completion_event);
729 break; 705 break;
730 } 706 }
731} 707}
@@ -733,16 +709,16 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
733/* called by usb_drv_int() */ 709/* called by usb_drv_int() */
734void usb_core_control_request(struct usb_ctrlrequest* req) 710void usb_core_control_request(struct usb_ctrlrequest* req)
735{ 711{
736 events[0].endpoint=0; 712 ep_data[0].completion_event.endpoint=0;
737 events[0].in=0; 713 ep_data[0].completion_event.in=0;
738 events[0].data=(void *)req; 714 ep_data[0].completion_event.data=(void *)req;
739 events[0].status=0; 715 ep_data[0].completion_event.status=0;
740 events[0].length=0; 716 ep_data[0].completion_event.length=0;
741 logf("ctrl received %ld",current_tick); 717 logf("ctrl received %ld",current_tick);
742 usb_signal_transfer_completion(&events[0]); 718 usb_signal_transfer_completion(&ep_data[0].completion_event);
743} 719}
744 720
745static int ack_control(struct usb_ctrlrequest* req) 721int usb_core_ack_control(struct usb_ctrlrequest* req)
746{ 722{
747 if (req->bRequestType & 0x80) 723 if (req->bRequestType & 0x80)
748 return usb_drv_recv(EP_CONTROL, NULL, 0); 724 return usb_drv_recv(EP_CONTROL, NULL, 0);