summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-10-03 22:43:16 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-10-03 22:43:16 +0000
commit478fc5baed82e5573938041aed0f1a4f73f32128 (patch)
treeb7115cb1200101075bf93d93f61bd0be65ff9d42
parent6219f4c862919367972e497c47324121fe48f3f6 (diff)
downloadrockbox-478fc5baed82e5573938041aed0f1a4f73f32128.tar.gz
rockbox-478fc5baed82e5573938041aed0f1a4f73f32128.zip
reorganise the USB stack a bit to allow for easier integration of non-ARC controller drivers
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18703 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/usb.h2
-rw-r--r--firmware/export/usb_core.h8
-rw-r--r--firmware/export/usb_drv.h2
-rw-r--r--firmware/target/arm/usb-drv-arc.c49
-rw-r--r--firmware/usbstack/usb_charging_only.c7
-rw-r--r--firmware/usbstack/usb_charging_only.h2
-rw-r--r--firmware/usbstack/usb_class_driver.h13
-rw-r--r--firmware/usbstack/usb_core.c84
-rw-r--r--firmware/usbstack/usb_serial.c39
-rw-r--r--firmware/usbstack/usb_serial.h4
-rw-r--r--firmware/usbstack/usb_storage.c70
-rw-r--r--firmware/usbstack/usb_storage.h4
12 files changed, 185 insertions, 99 deletions
diff --git a/firmware/export/usb.h b/firmware/export/usb.h
index 9952a074bb..08ae27999a 100644
--- a/firmware/export/usb.h
+++ b/firmware/export/usb.h
@@ -85,7 +85,7 @@ enum {
85struct usb_transfer_completion_event_data 85struct usb_transfer_completion_event_data
86{ 86{
87 unsigned char endpoint; 87 unsigned char endpoint;
88 bool in; 88 int dir;
89 int status; 89 int status;
90 int length; 90 int length;
91 void* data; 91 void* data;
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h
index 6aada54399..9d9e327bb3 100644
--- a/firmware/export/usb_core.h
+++ b/firmware/export/usb_core.h
@@ -45,10 +45,12 @@
45 45
46extern int usb_max_pkt_size; 46extern int usb_max_pkt_size;
47 47
48struct usb_class_driver;
49
48void usb_core_init(void); 50void usb_core_init(void);
49void usb_core_exit(void); 51void usb_core_exit(void);
50void usb_core_control_request(struct usb_ctrlrequest* req); 52void usb_core_control_request(struct usb_ctrlrequest* req);
51void usb_core_transfer_complete(int endpoint, bool in, int status, int length); 53void usb_core_transfer_complete(int endpoint, int dir, int status, int length);
52void usb_core_bus_reset(void); 54void usb_core_bus_reset(void);
53bool usb_core_exclusive_connection(void); 55bool usb_core_exclusive_connection(void);
54void usb_core_enable_driver(int driver,bool enabled); 56void usb_core_enable_driver(int driver,bool enabled);
@@ -56,6 +58,10 @@ bool usb_core_driver_enabled (int driver);
56void usb_core_handle_transfer_completion( 58void usb_core_handle_transfer_completion(
57 struct usb_transfer_completion_event_data* event); 59 struct usb_transfer_completion_event_data* event);
58int usb_core_ack_control(struct usb_ctrlrequest* req); 60int usb_core_ack_control(struct usb_ctrlrequest* req);
61
62int usb_core_request_endpoint(int dir, struct usb_class_driver *drv);
63void usb_core_release_endpoint(int dir);
64
59#ifdef HAVE_HOTSWAP 65#ifdef HAVE_HOTSWAP
60void usb_core_hotswap_event(int volume,bool inserted); 66void usb_core_hotswap_event(int volume,bool inserted);
61#endif 67#endif
diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h
index 3db82efd6a..3bd8e1fdf4 100644
--- a/firmware/export/usb_drv.h
+++ b/firmware/export/usb_drv.h
@@ -41,5 +41,7 @@ int usb_drv_port_speed(void);
41void usb_drv_cancel_all_transfers(void); 41void usb_drv_cancel_all_transfers(void);
42void usb_drv_set_test_mode(int mode); 42void usb_drv_set_test_mode(int mode);
43bool usb_drv_connected(void); 43bool usb_drv_connected(void);
44int usb_drv_request_endpoint(int dir);
45void usb_drv_release_endpoint(int ep);
44 46
45#endif 47#endif
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c
index a30e1c5139..529f6cf7f8 100644
--- a/firmware/target/arm/usb-drv-arc.c
+++ b/firmware/target/arm/usb-drv-arc.c
@@ -363,6 +363,8 @@ static const unsigned int pipe2mask[] = {
363 0x10, 0x100000, 363 0x10, 0x100000,
364}; 364};
365 365
366static char ep_allocation[NUM_ENDPOINTS];
367
366/*-------------------------------------------------------------------------*/ 368/*-------------------------------------------------------------------------*/
367static void transfer_completed(void); 369static void transfer_completed(void);
368static void control_received(void); 370static void control_received(void);
@@ -534,23 +536,23 @@ void usb_drv_int(void)
534bool usb_drv_stalled(int endpoint,bool in) 536bool usb_drv_stalled(int endpoint,bool in)
535{ 537{
536 if(in) { 538 if(in) {
537 return ((REG_ENDPTCTRL(endpoint) & EPCTRL_TX_EP_STALL)!=0); 539 return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_TX_EP_STALL)!=0);
538 } 540 }
539 else { 541 else {
540 return ((REG_ENDPTCTRL(endpoint) & EPCTRL_RX_EP_STALL)!=0); 542 return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_RX_EP_STALL)!=0);
541 } 543 }
542 544
543} 545}
544void usb_drv_stall(int endpoint, bool stall,bool in) 546void usb_drv_stall(int endpoint, bool stall,bool in)
545{ 547{
546 logf("%sstall %d", stall?"":"un", endpoint); 548 logf("%sstall %d", stall?"":"un", endpoint&0x7f);
547 549
548 if(in) { 550 if(in) {
549 if (stall) { 551 if (stall) {
550 REG_ENDPTCTRL(endpoint) |= EPCTRL_TX_EP_STALL; 552 REG_ENDPTCTRL(endpoint&0x7f) |= EPCTRL_TX_EP_STALL;
551 } 553 }
552 else { 554 else {
553 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_TX_EP_STALL; 555 REG_ENDPTCTRL(endpoint&0x7f) &= ~EPCTRL_TX_EP_STALL;
554 } 556 }
555 } 557 }
556 else { 558 else {
@@ -565,23 +567,23 @@ void usb_drv_stall(int endpoint, bool stall,bool in)
565 567
566int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) 568int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
567{ 569{
568 return prime_transfer(endpoint, ptr, length, true, false); 570 return prime_transfer(endpoint&0x7f, ptr, length, true, false);
569} 571}
570 572
571int usb_drv_send(int endpoint, void* ptr, int length) 573int usb_drv_send(int endpoint, void* ptr, int length)
572{ 574{
573 return prime_transfer(endpoint, ptr, length, true, true); 575 return prime_transfer(endpoint&0x7f, ptr, length, true, true);
574} 576}
575 577
576int usb_drv_recv(int endpoint, void* ptr, int length) 578int usb_drv_recv(int endpoint, void* ptr, int length)
577{ 579{
578 //logf("usbrecv(%x, %d)", ptr, length); 580 //logf("usbrecv(%x, %d)", ptr, length);
579 return prime_transfer(endpoint, ptr, length, false, false); 581 return prime_transfer(endpoint&0x7f, ptr, length, false, false);
580} 582}
581 583
582void usb_drv_wait(int endpoint, bool send) 584void usb_drv_wait(int endpoint, bool send)
583{ 585{
584 int pipe = endpoint * 2 + (send ? 1 : 0); 586 int pipe = (endpoint&0x7f) * 2 + (send ? 1 : 0);
585 struct queue_head* qh = &qh_array[pipe]; 587 struct queue_head* qh = &qh_array[pipe];
586 588
587 while (qh->dtd.size_ioc_sts & QH_STATUS_ACTIVE) { 589 while (qh->dtd.size_ioc_sts & QH_STATUS_ACTIVE) {
@@ -609,7 +611,7 @@ void usb_drv_set_address(int address)
609 611
610void usb_drv_reset_endpoint(int endpoint, bool send) 612void usb_drv_reset_endpoint(int endpoint, bool send)
611{ 613{
612 int pipe = endpoint * 2 + (send ? 1 : 0); 614 int pipe = (endpoint&0x7f) * 2 + (send ? 1 : 0);
613 unsigned int mask = pipe2mask[pipe]; 615 unsigned int mask = pipe2mask[pipe];
614 REG_ENDPTFLUSH = mask; 616 REG_ENDPTFLUSH = mask;
615 while (REG_ENDPTFLUSH & mask); 617 while (REG_ENDPTFLUSH & mask);
@@ -753,6 +755,29 @@ void usb_drv_cancel_all_transfers(void)
753 } 755 }
754} 756}
755 757
758int usb_drv_request_endpoint(int dir)
759{
760 int i, bit;
761
762 bit=(dir & USB_DIR_IN)? 2:1;
763
764 for (i=1; i < NUM_ENDPOINTS; i++) {
765 if((ep_allocation[i] & bit)!=0)
766 continue;
767 ep_allocation[i] |= bit;
768 return i | dir;
769 }
770
771 return -1;
772}
773
774void usb_drv_release_endpoint(int ep)
775{
776 int mask = (ep & USB_DIR_IN)? ~2:~1;
777 ep_allocation[ep & 0x7f] &= mask;
778}
779
780
756static void prepare_td(struct transfer_descriptor* td, 781static void prepare_td(struct transfer_descriptor* td,
757 struct transfer_descriptor* previous_td, 782 struct transfer_descriptor* previous_td,
758 void *ptr, int len,int pipe) 783 void *ptr, int len,int pipe)
@@ -831,7 +856,7 @@ static void transfer_completed(void)
831 qh->wait=0; 856 qh->wait=0;
832 wakeup_signal(&transfer_completion_signal[pipe]); 857 wakeup_signal(&transfer_completion_signal[pipe]);
833 } 858 }
834 usb_core_transfer_complete(ep, dir, qh->status, qh->length); 859 usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, qh->status, qh->length);
835 } 860 }
836 } 861 }
837 } 862 }
@@ -900,6 +925,7 @@ static void init_bulk_queue_heads(void)
900 rx_packetsize = 64; 925 rx_packetsize = 64;
901 tx_packetsize = 64; 926 tx_packetsize = 64;
902 } 927 }
928 /* TODO: this should take ep_allocation into account */
903 929
904 /*** bulk ***/ 930 /*** bulk ***/
905 for(i=1;i<NUM_ENDPOINTS;i++) { 931 for(i=1;i<NUM_ENDPOINTS;i++) {
@@ -913,6 +939,7 @@ static void init_bulk_queue_heads(void)
913static void init_endpoints(void) 939static void init_endpoints(void)
914{ 940{
915 int i; 941 int i;
942 /* TODO: this should take ep_allocation into account */
916 /* bulk */ 943 /* bulk */
917 for(i=1;i<NUM_ENDPOINTS;i++) { 944 for(i=1;i<NUM_ENDPOINTS;i++) {
918 REG_ENDPTCTRL(i) = 945 REG_ENDPTCTRL(i) =
diff --git a/firmware/usbstack/usb_charging_only.c b/firmware/usbstack/usb_charging_only.c
index 8cce4fcef3..e20d1885a0 100644
--- a/firmware/usbstack/usb_charging_only.c
+++ b/firmware/usbstack/usb_charging_only.c
@@ -48,11 +48,12 @@ static struct usb_interface_descriptor __attribute__((aligned(2)))
48 48
49static int usb_interface; 49static int usb_interface;
50 50
51int usb_charging_only_set_first_endpoint(int endpoint) 51int usb_charging_only_request_endpoints(struct usb_class_driver *drv)
52{ 52{
53 /* The dummy charging_only driver doesn't need an endpoint pair */ 53 (void) drv;
54 return endpoint; 54 return 0;
55} 55}
56
56int usb_charging_only_set_first_interface(int interface) 57int usb_charging_only_set_first_interface(int interface)
57{ 58{
58 usb_interface = interface; 59 usb_interface = interface;
diff --git a/firmware/usbstack/usb_charging_only.h b/firmware/usbstack/usb_charging_only.h
index 65ab7df4c1..8bdf58ff1d 100644
--- a/firmware/usbstack/usb_charging_only.h
+++ b/firmware/usbstack/usb_charging_only.h
@@ -24,7 +24,7 @@
24#include "usb_ch9.h" 24#include "usb_ch9.h"
25 25
26void usb_charging_only_init(void); 26void usb_charging_only_init(void);
27int usb_charging_only_set_first_endpoint(int endpoint); 27int usb_charging_only_request_endpoints(struct usb_class_driver *);
28int usb_charging_only_set_first_interface(int interface); 28int usb_charging_only_set_first_interface(int interface);
29int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size); 29int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size);
30bool usb_charging_only_control_request(struct usb_ctrlrequest* req); 30bool usb_charging_only_control_request(struct usb_ctrlrequest* req);
diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h
index bda0b7663c..e089c488a8 100644
--- a/firmware/usbstack/usb_class_driver.h
+++ b/firmware/usbstack/usb_class_driver.h
@@ -35,6 +35,9 @@ struct usb_class_driver {
35 /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ 35 /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
36 bool needs_exclusive_ata; 36 bool needs_exclusive_ata;
37 37
38 /* Let the driver request endpoints it need. Returns zero on success */
39 int (*request_endpoints)(struct usb_class_driver *);
40
38 /* Tells the driver what its first interface number will be. The driver 41 /* Tells the driver what its first interface number will be. The driver
39 returns the number of the first available interface for the next driver 42 returns the number of the first available interface for the next driver
40 (i.e. a driver with one interface will return interface+1) 43 (i.e. a driver with one interface will return interface+1)
@@ -42,12 +45,6 @@ struct usb_class_driver {
42 Mandatory function */ 45 Mandatory function */
43 int (*set_first_interface)(int interface); 46 int (*set_first_interface)(int interface);
44 47
45 /* Tells the driver what its first endpoint pair number will be. The driver
46 returns the number of the first available endpoint pair for the next
47 driver (i.e. a driver with one endpoint pair will return endpoint +1)
48 Mandatory function */
49 int (*set_first_endpoint)(int endpoint);
50
51 /* Asks the driver to put the interface descriptor and all other 48 /* Asks the driver to put the interface descriptor and all other
52 needed descriptor for this driver at dest. 49 needed descriptor for this driver at dest.
53 Returns the number of bytes taken by these descriptors. 50 Returns the number of bytes taken by these descriptors.
@@ -69,10 +66,10 @@ struct usb_class_driver {
69 Optional function */ 66 Optional function */
70 void (*disconnect)(void); 67 void (*disconnect)(void);
71 68
72 /* Tells the driver that a usb transfer has been completed. Note that "in" 69 /* Tells the driver that a usb transfer has been completed. Note that "dir"
73 is relative to the host 70 is relative to the host
74 Optional function */ 71 Optional function */
75 void (*transfer_complete)(int ep,bool in, int status, int length); 72 void (*transfer_complete)(int ep,int dir, int status, int length);
76 73
77 /* Tells the driver that a control request has come in. If the driver is 74 /* Tells the driver that a control request has come in. If the driver is
78 able to handle it, it should ack the request, and return true. Otherwise 75 able to handle it, it should ack the request, and return true. Otherwise
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index d26610d82b..afdf0b176f 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -22,7 +22,7 @@
22#include "thread.h" 22#include "thread.h"
23#include "kernel.h" 23#include "kernel.h"
24#include "string.h" 24#include "string.h"
25//#define LOGF_ENABLE 25#define LOGF_ENABLE
26#include "logf.h" 26#include "logf.h"
27 27
28#include "usb.h" 28#include "usb.h"
@@ -164,10 +164,13 @@ static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
164 164
165static int usb_core_num_interfaces; 165static int usb_core_num_interfaces;
166 166
167typedef void (*completion_handler_t)(int ep,int dir, int status, int length);
168typedef bool (*control_handler_t)(struct usb_ctrlrequest* req);
169
167static struct 170static struct
168{ 171{
169 void (*completion_handler)(int ep,bool in, int status, int length); 172 completion_handler_t completion_handler[2];
170 bool (*control_handler)(struct usb_ctrlrequest* req); 173 control_handler_t control_handler[2];
171 struct usb_transfer_completion_event_data completion_event; 174 struct usb_transfer_completion_event_data completion_event;
172} ep_data[NUM_ENDPOINTS]; 175} ep_data[NUM_ENDPOINTS];
173 176
@@ -179,8 +182,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
179 .needs_exclusive_ata = true, 182 .needs_exclusive_ata = true,
180 .first_interface = 0, 183 .first_interface = 0,
181 .last_interface = 0, 184 .last_interface = 0,
185 .request_endpoints = usb_storage_request_endpoints,
182 .set_first_interface = usb_storage_set_first_interface, 186 .set_first_interface = usb_storage_set_first_interface,
183 .set_first_endpoint = usb_storage_set_first_endpoint,
184 .get_config_descriptor = usb_storage_get_config_descriptor, 187 .get_config_descriptor = usb_storage_get_config_descriptor,
185 .init_connection = usb_storage_init_connection, 188 .init_connection = usb_storage_init_connection,
186 .init = usb_storage_init, 189 .init = usb_storage_init,
@@ -198,8 +201,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
198 .needs_exclusive_ata = false, 201 .needs_exclusive_ata = false,
199 .first_interface = 0, 202 .first_interface = 0,
200 .last_interface = 0, 203 .last_interface = 0,
204 .request_endpoints = usb_serial_request_endpoints,
201 .set_first_interface = usb_serial_set_first_interface, 205 .set_first_interface = usb_serial_set_first_interface,
202 .set_first_endpoint = usb_serial_set_first_endpoint,
203 .get_config_descriptor = usb_serial_get_config_descriptor, 206 .get_config_descriptor = usb_serial_get_config_descriptor,
204 .init_connection = usb_serial_init_connection, 207 .init_connection = usb_serial_init_connection,
205 .init = usb_serial_init, 208 .init = usb_serial_init,
@@ -217,8 +220,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
217 .needs_exclusive_ata = false, 220 .needs_exclusive_ata = false,
218 .first_interface = 0, 221 .first_interface = 0,
219 .last_interface = 0, 222 .last_interface = 0,
223 .request_endpoints = usb_charging_only_request_endpoints,
220 .set_first_interface = usb_charging_only_set_first_interface, 224 .set_first_interface = usb_charging_only_set_first_interface,
221 .set_first_endpoint = usb_charging_only_set_first_endpoint,
222 .get_config_descriptor = usb_charging_only_get_config_descriptor, 225 .get_config_descriptor = usb_charging_only_get_config_descriptor,
223 .init_connection = NULL, 226 .init_connection = NULL,
224 .init = NULL, 227 .init = NULL,
@@ -339,6 +342,7 @@ void usb_core_handle_transfer_completion(
339 struct usb_transfer_completion_event_data* event) 342 struct usb_transfer_completion_event_data* event)
340{ 343{
341 int ep = event->endpoint; 344 int ep = event->endpoint;
345
342 switch(ep) { 346 switch(ep) {
343 case EP_CONTROL: 347 case EP_CONTROL:
344 logf("ctrl handled %ld",current_tick); 348 logf("ctrl handled %ld",current_tick);
@@ -346,8 +350,8 @@ void usb_core_handle_transfer_completion(
346 (struct usb_ctrlrequest*)event->data); 350 (struct usb_ctrlrequest*)event->data);
347 break; 351 break;
348 default: 352 default:
349 if(ep_data[ep].completion_handler != NULL) 353 if(ep_data[ep].completion_handler[event->dir>>7] != NULL)
350 ep_data[ep].completion_handler(ep,event->in, 354 ep_data[ep].completion_handler[event->dir>>7](ep,event->dir,
351 event->status,event->length); 355 event->status,event->length);
352 break; 356 break;
353 } 357 }
@@ -388,34 +392,60 @@ static void usb_core_set_serial_function_id(void)
388 usb_string_iSerial.wString[0] = hex[id]; 392 usb_string_iSerial.wString[0] = hex[id];
389} 393}
390 394
395int usb_core_request_endpoint(int dir, struct usb_class_driver *drv)
396{
397 int ret, ep;
398
399 ret = usb_drv_request_endpoint(dir);
400
401 if (ret == -1)
402 return -1;
403
404 ep = ret & 0x7f;
405 dir = ret >> 7;
406
407 ep_data[ep].completion_handler[dir] = drv->transfer_complete;
408 ep_data[ep].control_handler[dir] = drv->control_request;
409
410 return ret;
411}
412
413void usb_core_release_endpoint(int ep)
414{
415 int dir;
416
417 usb_drv_release_endpoint(ep);
418
419 dir = ep >> 7;
420 ep &= 0x7f;
421
422 ep_data[ep].completion_handler[dir] = NULL;
423 ep_data[ep].control_handler[dir] = NULL;
424}
425
391static void allocate_interfaces_and_endpoints(void) 426static void allocate_interfaces_and_endpoints(void)
392{ 427{
393 int i,j; 428 int i;
394 int interface=0; 429 int interface=0;
395 int endpoint=1;
396 430
397 memset(ep_data,0,sizeof(ep_data)); 431 memset(ep_data,0,sizeof(ep_data));
398 432
399 for(i=0;i<USB_NUM_DRIVERS;i++) { 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);
436 }
437
438 for(i=0; i < USB_NUM_DRIVERS; i++) {
400 if(drivers[i].enabled) { 439 if(drivers[i].enabled) {
401 int oldendpoint = endpoint;
402 drivers[i].first_interface = interface; 440 drivers[i].first_interface = interface;
403 441
404 endpoint = drivers[i].set_first_endpoint(endpoint); 442 if (drivers[i].request_endpoints(&drivers[i])) {
405 if(endpoint>NUM_ENDPOINTS) {
406 drivers[i].enabled = false; 443 drivers[i].enabled = false;
407 continue; 444 continue;
408 } 445 }
446
409 interface = drivers[i].set_first_interface(interface); 447 interface = drivers[i].set_first_interface(interface);
410 drivers[i].last_interface = interface; 448 drivers[i].last_interface = interface;
411
412 for(j=oldendpoint;j<endpoint;j++) {
413 ep_data[j].completion_handler=drivers[i].transfer_complete;
414 ep_data[j].control_handler=drivers[i].control_request;
415 }
416 }
417 if(endpoint>NUM_ENDPOINTS) {
418 drivers[i].enabled = false;
419 } 449 }
420 } 450 }
421 usb_core_num_interfaces = interface; 451 usb_core_num_interfaces = interface;
@@ -666,8 +696,8 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
666 break; 696 break;
667 default: { 697 default: {
668 bool handled=false; 698 bool handled=false;
669 if(ep_data[req->wIndex & 0xf].control_handler != NULL) 699 if(ep_data[req->wIndex & 0xf].control_handler[0] != NULL)
670 handled = ep_data[req->wIndex & 0xf].control_handler(req); 700 handled = ep_data[req->wIndex & 0xf].control_handler[0](req);
671 if(!handled) { 701 if(!handled) {
672 /* nope. flag error */ 702 /* nope. flag error */
673 logf("usb bad req %d", req->bRequest); 703 logf("usb bad req %d", req->bRequest);
@@ -689,7 +719,7 @@ void usb_core_bus_reset(void)
689} 719}
690 720
691/* called by usb_drv_transfer_completed() */ 721/* called by usb_drv_transfer_completed() */
692void usb_core_transfer_complete(int endpoint, bool in, int status,int length) 722void usb_core_transfer_complete(int endpoint, int dir, int status,int length)
693{ 723{
694 switch (endpoint) { 724 switch (endpoint) {
695 case EP_CONTROL: 725 case EP_CONTROL:
@@ -698,7 +728,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
698 728
699 default: 729 default:
700 ep_data[endpoint].completion_event.endpoint=endpoint; 730 ep_data[endpoint].completion_event.endpoint=endpoint;
701 ep_data[endpoint].completion_event.in=in; 731 ep_data[endpoint].completion_event.dir=dir;
702 ep_data[endpoint].completion_event.data=0; 732 ep_data[endpoint].completion_event.data=0;
703 ep_data[endpoint].completion_event.status=status; 733 ep_data[endpoint].completion_event.status=status;
704 ep_data[endpoint].completion_event.length=length; 734 ep_data[endpoint].completion_event.length=length;
@@ -712,7 +742,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
712void usb_core_control_request(struct usb_ctrlrequest* req) 742void usb_core_control_request(struct usb_ctrlrequest* req)
713{ 743{
714 ep_data[0].completion_event.endpoint=0; 744 ep_data[0].completion_event.endpoint=0;
715 ep_data[0].completion_event.in=0; 745 ep_data[0].completion_event.dir=0;
716 ep_data[0].completion_event.data=(void *)req; 746 ep_data[0].completion_event.data=(void *)req;
717 ep_data[0].completion_event.status=0; 747 ep_data[0].completion_event.status=0;
718 ep_data[0].completion_event.length=0; 748 ep_data[0].completion_event.length=0;
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index 8d6ce67823..1b143d56eb 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -72,7 +72,7 @@ static int buffer_start;
72static int buffer_length; 72static int buffer_length;
73static bool active = false; 73static bool active = false;
74 74
75static int usb_endpoint; 75static int ep_in, ep_out;
76static int usb_interface; 76static int usb_interface;
77 77
78static struct mutex sendlock SHAREDBSS_ATTR; 78static struct mutex sendlock SHAREDBSS_ATTR;
@@ -82,22 +82,33 @@ static void sendout(void)
82 if(buffer_start+buffer_length > BUFFER_SIZE) 82 if(buffer_start+buffer_length > BUFFER_SIZE)
83 { 83 {
84 /* Buffer wraps. Only send the first part */ 84 /* Buffer wraps. Only send the first part */
85 usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start], 85 usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start],
86 (BUFFER_SIZE - buffer_start)); 86 (BUFFER_SIZE - buffer_start));
87 } 87 }
88 else 88 else
89 { 89 {
90 /* Send everything */ 90 /* Send everything */
91 usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start], 91 usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start],
92 buffer_length); 92 buffer_length);
93 } 93 }
94 busy_sending=true; 94 busy_sending=true;
95} 95}
96 96
97int usb_serial_set_first_endpoint(int endpoint) 97int usb_serial_request_endpoints(struct usb_class_driver *drv)
98{ 98{
99 usb_endpoint = endpoint; 99 ep_in = usb_core_request_endpoint(USB_DIR_IN, drv);
100 return endpoint + 1; 100
101 if (ep_in < 0)
102 return -1;
103
104 ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv);
105
106 if (ep_out < 0) {
107 usb_core_release_endpoint(ep_in);
108 return -1;
109 }
110
111 return 0;
101} 112}
102 113
103int usb_serial_set_first_interface(int interface) 114int usb_serial_set_first_interface(int interface)
@@ -117,11 +128,11 @@ int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size)
117 memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor)); 128 memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
118 dest+=sizeof(struct usb_interface_descriptor); 129 dest+=sizeof(struct usb_interface_descriptor);
119 130
120 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN; 131 endpoint_descriptor.bEndpointAddress = ep_in;
121 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); 132 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
122 dest+=sizeof(struct usb_endpoint_descriptor); 133 dest+=sizeof(struct usb_endpoint_descriptor);
123 134
124 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT; 135 endpoint_descriptor.bEndpointAddress = ep_out;
125 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); 136 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
126 dest+=sizeof(struct usb_endpoint_descriptor); 137 dest+=sizeof(struct usb_endpoint_descriptor);
127 138
@@ -131,7 +142,7 @@ int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size)
131void usb_serial_init_connection(void) 142void usb_serial_init_connection(void)
132{ 143{
133 /* prime rx endpoint */ 144 /* prime rx endpoint */
134 usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); 145 usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer);
135 146
136 /* we come here too after a bus reset, so reset some data */ 147 /* we come here too after a bus reset, so reset some data */
137 mutex_lock(&sendlock); 148 mutex_lock(&sendlock);
@@ -202,17 +213,17 @@ void usb_serial_send(unsigned char *data,int length)
202} 213}
203 214
204/* called by usb_core_transfer_complete() */ 215/* called by usb_core_transfer_complete() */
205void usb_serial_transfer_complete(int ep,bool in, int status, int length) 216void usb_serial_transfer_complete(int ep,int dir, int status, int length)
206{ 217{
207 (void)ep; 218 (void)ep;
208 switch (in) { 219 switch (dir) {
209 case false: 220 case USB_DIR_OUT:
210 logf("serial: %s", receive_buffer); 221 logf("serial: %s", receive_buffer);
211 /* Data received. TODO : Do something with it ? */ 222 /* Data received. TODO : Do something with it ? */
212 usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); 223 usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer);
213 break; 224 break;
214 225
215 case true: 226 case USB_DIR_IN:
216 mutex_lock(&sendlock); 227 mutex_lock(&sendlock);
217 /* Data sent out. Update circular buffer */ 228 /* Data sent out. Update circular buffer */
218 if(status == 0) 229 if(status == 0)
diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h
index 69ad3fd647..94decdc42b 100644
--- a/firmware/usbstack/usb_serial.h
+++ b/firmware/usbstack/usb_serial.h
@@ -23,13 +23,13 @@
23 23
24#include "usb_ch9.h" 24#include "usb_ch9.h"
25 25
26int usb_serial_set_first_endpoint(int endpoint); 26int usb_serial_request_endpoints(struct usb_class_driver *);
27int usb_serial_set_first_interface(int interface); 27int usb_serial_set_first_interface(int interface);
28int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size); 28int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size);
29void usb_serial_init_connection(void); 29void usb_serial_init_connection(void);
30void usb_serial_init(void); 30void usb_serial_init(void);
31void usb_serial_disconnect(void); 31void usb_serial_disconnect(void);
32void usb_serial_transfer_complete(int ep,bool in, int status, int length); 32void usb_serial_transfer_complete(int ep,int dir, int status, int length);
33bool usb_serial_control_request(struct usb_ctrlrequest* req); 33bool usb_serial_control_request(struct usb_ctrlrequest* req);
34 34
35void usb_serial_send(unsigned char *data,int length); 35void usb_serial_send(unsigned char *data,int length);
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index f774d14cbc..9c524a37b8 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -22,7 +22,7 @@
22#include "system.h" 22#include "system.h"
23#include "usb_core.h" 23#include "usb_core.h"
24#include "usb_drv.h" 24#include "usb_drv.h"
25//#define LOGF_ENABLE 25#define LOGF_ENABLE
26#include "logf.h" 26#include "logf.h"
27#include "ata.h" 27#include "ata.h"
28#include "hotswap.h" 28#include "hotswap.h"
@@ -263,8 +263,8 @@ static void identify2inquiry(int lun);
263static void send_and_read_next(void); 263static void send_and_read_next(void);
264static bool ejected[NUM_VOLUMES]; 264static bool ejected[NUM_VOLUMES];
265 265
266static int usb_endpoint;
267static int usb_interface; 266static int usb_interface;
267static int ep_in, ep_out;
268 268
269static enum { 269static enum {
270 WAITING_FOR_COMMAND, 270 WAITING_FOR_COMMAND,
@@ -321,7 +321,7 @@ void usb_storage_reconnect(void)
321 && usb_inserted()) { 321 && usb_inserted()) {
322 for(i=0;i<NUM_VOLUMES;i++) 322 for(i=0;i<NUM_VOLUMES;i++)
323 ejected[i] = !check_disk_present(IF_MV(i)); 323 ejected[i] = !check_disk_present(IF_MV(i));
324 324 logf("%s", __func__);
325 usb_request_exclusive_ata(); 325 usb_request_exclusive_ata();
326 } 326 }
327} 327}
@@ -336,12 +336,23 @@ void usb_storage_init(void)
336 logf("usb_storage_init done"); 336 logf("usb_storage_init done");
337} 337}
338 338
339 339int usb_storage_request_endpoints(struct usb_class_driver *drv)
340int usb_storage_set_first_endpoint(int endpoint)
341{ 340{
342 usb_endpoint = endpoint; 341 ep_in = usb_core_request_endpoint(USB_DIR_IN, drv);
343 return endpoint + 1; 342
343 if (ep_in < 0)
344 return -1;
345
346 ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv);
347
348 if (ep_out < 0) {
349 usb_core_release_endpoint(ep_in);
350 return -1;
351 }
352
353 return 0;
344} 354}
355
345int usb_storage_set_first_interface(int interface) 356int usb_storage_set_first_interface(int interface)
346{ 357{
347 usb_interface = interface; 358 usb_interface = interface;
@@ -357,12 +368,12 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size)
357 sizeof(struct usb_interface_descriptor)); 368 sizeof(struct usb_interface_descriptor));
358 dest+=sizeof(struct usb_interface_descriptor); 369 dest+=sizeof(struct usb_interface_descriptor);
359 370
360 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN; 371 endpoint_descriptor.bEndpointAddress = ep_in;
361 memcpy(dest,&endpoint_descriptor, 372 memcpy(dest,&endpoint_descriptor,
362 sizeof(struct usb_endpoint_descriptor)); 373 sizeof(struct usb_endpoint_descriptor));
363 dest+=sizeof(struct usb_endpoint_descriptor); 374 dest+=sizeof(struct usb_endpoint_descriptor);
364 375
365 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT; 376 endpoint_descriptor.bEndpointAddress = ep_out;
366 memcpy(dest,&endpoint_descriptor, 377 memcpy(dest,&endpoint_descriptor,
367 sizeof(struct usb_endpoint_descriptor)); 378 sizeof(struct usb_endpoint_descriptor));
368 379
@@ -376,7 +387,8 @@ void usb_storage_init_connection(void)
376 /* prime rx endpoint. We only need room for commands */ 387 /* prime rx endpoint. We only need room for commands */
377 state = WAITING_FOR_COMMAND; 388 state = WAITING_FOR_COMMAND;
378 389
379#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 390#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \
391 defined(CPU_TCC77X) || defined(CPU_TCC780X)
380 static unsigned char _transfer_buffer[BUFFER_SIZE*2] 392 static unsigned char _transfer_buffer[BUFFER_SIZE*2]
381 USBDEVBSS_ATTR __attribute__((aligned(32))); 393 USBDEVBSS_ATTR __attribute__((aligned(32)));
382 tb.transfer_buffer = (void *)_transfer_buffer; 394 tb.transfer_buffer = (void *)_transfer_buffer;
@@ -390,11 +402,11 @@ void usb_storage_init_connection(void)
390 (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); 402 (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
391 invalidate_icache(); 403 invalidate_icache();
392#endif 404#endif
393 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); 405 usb_drv_recv(ep_out, tb.transfer_buffer, 1024);
394} 406}
395 407
396/* called by usb_core_transfer_complete() */ 408/* called by usb_core_transfer_complete() */
397void usb_storage_transfer_complete(int ep,bool in,int status,int length) 409void usb_storage_transfer_complete(int ep,int dir,int status,int length)
398{ 410{
399 (void)ep; 411 (void)ep;
400 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer; 412 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
@@ -402,7 +414,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
402 //logf("transfer result %X %d", status, length); 414 //logf("transfer result %X %d", status, length);
403 switch(state) { 415 switch(state) {
404 case RECEIVING_BLOCKS: 416 case RECEIVING_BLOCKS:
405 if(in==true) { 417 if(dir==USB_DIR_IN) {
406 logf("IN received in RECEIVING"); 418 logf("IN received in RECEIVING");
407 } 419 }
408 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); 420 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count);
@@ -470,7 +482,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
470 } 482 }
471 break; 483 break;
472 case WAITING_FOR_COMMAND: 484 case WAITING_FOR_COMMAND:
473 if(in==true) { 485 if(dir==USB_DIR_IN) {
474 logf("IN received in WAITING_FOR_COMMAND"); 486 logf("IN received in WAITING_FOR_COMMAND");
475 } 487 }
476 //logf("command received"); 488 //logf("command received");
@@ -478,20 +490,20 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
478 handle_scsi(cbw); 490 handle_scsi(cbw);
479 } 491 }
480 else { 492 else {
481 usb_drv_stall(usb_endpoint, true,true); 493 usb_drv_stall(ep_in, true,true);
482 usb_drv_stall(usb_endpoint, true,false); 494 usb_drv_stall(ep_out, true,false);
483 } 495 }
484 break; 496 break;
485 case SENDING_CSW: 497 case SENDING_CSW:
486 if(in==false) { 498 if(dir==USB_DIR_OUT) {
487 logf("OUT received in SENDING_CSW"); 499 logf("OUT received in SENDING_CSW");
488 } 500 }
489 //logf("csw sent, now go back to idle"); 501 //logf("csw sent, now go back to idle");
490 state = WAITING_FOR_COMMAND; 502 state = WAITING_FOR_COMMAND;
491 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); 503 usb_drv_recv(ep_out, tb.transfer_buffer, 1024);
492 break; 504 break;
493 case SENDING_RESULT: 505 case SENDING_RESULT:
494 if(in==false) { 506 if(dir==USB_DIR_OUT) {
495 logf("OUT received in SENDING"); 507 logf("OUT received in SENDING");
496 } 508 }
497 if(status==0) { 509 if(status==0) {
@@ -509,13 +521,13 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
509 } 521 }
510 break; 522 break;
511 case SENDING_FAILED_RESULT: 523 case SENDING_FAILED_RESULT:
512 if(in==false) { 524 if(dir==USB_DIR_OUT) {
513 logf("OUT received in SENDING"); 525 logf("OUT received in SENDING");
514 } 526 }
515 send_csw(UMS_STATUS_FAIL); 527 send_csw(UMS_STATUS_FAIL);
516 break; 528 break;
517 case SENDING_BLOCKS: 529 case SENDING_BLOCKS:
518 if(in==false) { 530 if(dir==USB_DIR_OUT) {
519 logf("OUT received in SENDING"); 531 logf("OUT received in SENDING");
520 } 532 }
521 if(status==0) { 533 if(status==0) {
@@ -567,8 +579,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
567 data toggle bits and endpoint STALL conditions despite 579 data toggle bits and endpoint STALL conditions despite
568 the Bulk-Only Mass Storage Reset. */ 580 the Bulk-Only Mass Storage Reset. */
569#if 0 581#if 0
570 usb_drv_reset_endpoint(usb_endpoint, false); 582 usb_drv_reset_endpoint(ep_in, false);
571 usb_drv_reset_endpoint(usb_endpoint, true); 583 usb_drv_reset_endpoint(ep_out, true);
572#endif 584#endif
573 585
574 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ 586 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
@@ -972,7 +984,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
972 984
973 default: 985 default:
974 logf("scsi unknown cmd %x",cbw->command_block[0x0]); 986 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
975 usb_drv_stall(usb_endpoint, true,true); 987 usb_drv_stall(ep_in, true,true);
976 send_csw(UMS_STATUS_FAIL); 988 send_csw(UMS_STATUS_FAIL);
977 break; 989 break;
978 } 990 }
@@ -980,25 +992,25 @@ static void handle_scsi(struct command_block_wrapper* cbw)
980 992
981static void send_block_data(void *data,int size) 993static void send_block_data(void *data,int size)
982{ 994{
983 usb_drv_send_nonblocking(usb_endpoint, data,size); 995 usb_drv_send_nonblocking(ep_in, data,size);
984 state = SENDING_BLOCKS; 996 state = SENDING_BLOCKS;
985} 997}
986 998
987static void send_command_result(void *data,int size) 999static void send_command_result(void *data,int size)
988{ 1000{
989 usb_drv_send_nonblocking(usb_endpoint, data,size); 1001 usb_drv_send_nonblocking(ep_in, data,size);
990 state = SENDING_RESULT; 1002 state = SENDING_RESULT;
991} 1003}
992 1004
993static void send_command_failed_result(void) 1005static void send_command_failed_result(void)
994{ 1006{
995 usb_drv_send_nonblocking(usb_endpoint, NULL, 0); 1007 usb_drv_send_nonblocking(ep_in, NULL, 0);
996 state = SENDING_FAILED_RESULT; 1008 state = SENDING_FAILED_RESULT;
997} 1009}
998 1010
999static void receive_block_data(void *data,int size) 1011static void receive_block_data(void *data,int size)
1000{ 1012{
1001 usb_drv_recv(usb_endpoint, data, size); 1013 usb_drv_recv(ep_out, data, size);
1002 state = RECEIVING_BLOCKS; 1014 state = RECEIVING_BLOCKS;
1003} 1015}
1004 1016
@@ -1009,7 +1021,7 @@ static void send_csw(int status)
1009 tb.csw->data_residue = 0; 1021 tb.csw->data_residue = 0;
1010 tb.csw->status = status; 1022 tb.csw->status = status;
1011 1023
1012 usb_drv_send_nonblocking(usb_endpoint, tb.csw, 1024 usb_drv_send_nonblocking(ep_in, tb.csw,
1013 sizeof(struct command_status_wrapper)); 1025 sizeof(struct command_status_wrapper));
1014 state = SENDING_CSW; 1026 state = SENDING_CSW;
1015 //logf("CSW: %X",status); 1027 //logf("CSW: %X",status);
diff --git a/firmware/usbstack/usb_storage.h b/firmware/usbstack/usb_storage.h
index 7054d24501..4c89039bfd 100644
--- a/firmware/usbstack/usb_storage.h
+++ b/firmware/usbstack/usb_storage.h
@@ -23,12 +23,12 @@
23 23
24#include "usb_ch9.h" 24#include "usb_ch9.h"
25 25
26int usb_storage_set_first_endpoint(int endpoint); 26int usb_storage_request_endpoints(struct usb_class_driver *);
27int usb_storage_set_first_interface(int interface); 27int usb_storage_set_first_interface(int interface);
28int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size); 28int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size);
29void usb_storage_init_connection(void); 29void usb_storage_init_connection(void);
30void usb_storage_init(void); 30void usb_storage_init(void);
31void usb_storage_transfer_complete(int ep,bool in,int state,int length); 31void usb_storage_transfer_complete(int ep,int dir,int state,int length);
32bool usb_storage_control_request(struct usb_ctrlrequest* req); 32bool usb_storage_control_request(struct usb_ctrlrequest* req);
33#ifdef HAVE_HOTSWAP 33#ifdef HAVE_HOTSWAP
34void usb_storage_notify_hotswap(int volume,bool inserted); 34void usb_storage_notify_hotswap(int volume,bool inserted);