summaryrefslogtreecommitdiff
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
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
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/export/usb_core.h1
-rw-r--r--firmware/usbstack/usb_charging_only.c72
-rw-r--r--firmware/usbstack/usb_charging_only.h31
-rw-r--r--firmware/usbstack/usb_class_driver.h52
-rw-r--r--firmware/usbstack/usb_core.c184
-rw-r--r--firmware/usbstack/usb_serial.c43
-rw-r--r--firmware/usbstack/usb_serial.h9
-rw-r--r--firmware/usbstack/usb_storage.c29
-rw-r--r--firmware/usbstack/usb_storage.h9
10 files changed, 279 insertions, 152 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index ac9ac46212..0e72755798 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -235,6 +235,7 @@ drivers/audio/mas35xx.c
235usbstack/usb_core.c 235usbstack/usb_core.c
236usbstack/usb_storage.c 236usbstack/usb_storage.c
237usbstack/usb_serial.c 237usbstack/usb_serial.c
238usbstack/usb_charging_only.c
238#if CONFIG_USBOTG == USBOTG_ARC 239#if CONFIG_USBOTG == USBOTG_ARC
239target/arm/usb-drv-arc.c 240target/arm/usb-drv-arc.c
240#elif CONFIG_USBOTG == USBOTG_ISP1583 241#elif CONFIG_USBOTG == USBOTG_ISP1583
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h
index fc1c742286..5d888ce438 100644
--- a/firmware/export/usb_core.h
+++ b/firmware/export/usb_core.h
@@ -53,6 +53,7 @@ void usb_core_enable_driver(int driver,bool enabled);
53bool usb_core_driver_enabled (int driver); 53bool usb_core_driver_enabled (int driver);
54void usb_core_handle_transfer_completion( 54void usb_core_handle_transfer_completion(
55 struct usb_transfer_completion_event_data* event); 55 struct usb_transfer_completion_event_data* event);
56int usb_core_ack_control(struct usb_ctrlrequest* req);
56#ifdef HAVE_HOTSWAP 57#ifdef HAVE_HOTSWAP
57void usb_core_hotswap_event(int volume,bool inserted); 58void usb_core_hotswap_event(int volume,bool inserted);
58#endif 59#endif
diff --git a/firmware/usbstack/usb_charging_only.c b/firmware/usbstack/usb_charging_only.c
new file mode 100644
index 0000000000..501a7aa596
--- /dev/null
+++ b/firmware/usbstack/usb_charging_only.c
@@ -0,0 +1,72 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2008 by Frank Gevaerts
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "string.h"
20#include "system.h"
21#include "usb_core.h"
22#include "usb_drv.h"
23#include "kernel.h"
24
25//#define LOGF_ENABLE
26#include "logf.h"
27
28#ifdef USB_CHARGING_ONLY
29
30/* charging_only interface */
31static struct usb_interface_descriptor __attribute__((aligned(2)))
32 interface_descriptor =
33{
34 .bLength = sizeof(struct usb_interface_descriptor),
35 .bDescriptorType = USB_DT_INTERFACE,
36 .bInterfaceNumber = 0,
37 .bAlternateSetting = 0,
38 .bNumEndpoints = 0,
39 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
40 .bInterfaceSubClass = 0,
41 .bInterfaceProtocol = 0,
42 .iInterface = 0
43};
44
45
46static int usb_interface;
47
48int usb_charging_only_set_first_endpoint(int endpoint)
49{
50 /* The dummy charging_only driver doesn't need an endpoint pair */
51 return endpoint;
52}
53int usb_charging_only_set_first_interface(int interface)
54{
55 usb_interface = interface;
56 return interface + 1;
57}
58
59int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size)
60{
61 (void)max_packet_size;
62 unsigned char *orig_dest = dest;
63
64 interface_descriptor.bInterfaceNumber=usb_interface;
65 memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
66
67 dest+=sizeof(struct usb_interface_descriptor);
68
69 return (dest-orig_dest);
70}
71
72#endif /*USB_CHARGING_ONLY*/
diff --git a/firmware/usbstack/usb_charging_only.h b/firmware/usbstack/usb_charging_only.h
new file mode 100644
index 0000000000..f866443e1b
--- /dev/null
+++ b/firmware/usbstack/usb_charging_only.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2008 by Frank Gevaerts
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef USB_CHARGING_ONLY_H
20#define USB_CHARGING_ONLY_H
21
22#include "usb_ch9.h"
23
24void usb_charging_only_init(void);
25int usb_charging_only_set_first_endpoint(int endpoint);
26int usb_charging_only_set_first_interface(int interface);
27int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size);
28bool usb_charging_only_control_request(struct usb_ctrlrequest* req);
29
30#endif
31
diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h
index 8bd9de0119..df21228480 100644
--- a/firmware/usbstack/usb_class_driver.h
+++ b/firmware/usbstack/usb_class_driver.h
@@ -23,41 +23,65 @@
23/* Common api, implemented by all class drivers */ 23/* Common api, implemented by all class drivers */
24 24
25struct usb_class_driver { 25struct usb_class_driver {
26 /* First some runtime data */
26 bool enabled; 27 bool enabled;
28 int first_interface;
29 int last_interface;
30
31 /* Driver api starts here */
32
33 /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
27 bool needs_exclusive_ata; 34 bool needs_exclusive_ata;
28 int usb_endpoint; 35
29 int usb_interface; 36 /* Tells the driver what its first interface number will be. The driver
37 returns the number of the first available interface for the next driver
38 (i.e. a driver with one interface will return interface+1)
39 A driver must have at least one interface
40 Mandatory function */
41 int (*set_first_interface)(int interface);
42
43 /* Tells the driver what its first endpoint pair number will be. The driver
44 returns the number of the first available endpoint pair for the next
45 driver (i.e. a driver with one endpoint pair will return endpoint +1)
46 Mandatory function */
47 int (*set_first_endpoint)(int endpoint);
30 48
31 /* Asks the driver to put the interface descriptor and all other 49 /* Asks the driver to put the interface descriptor and all other
32 needed descriptor for this driver at dest, for the given settings. 50 needed descriptor for this driver at dest.
33 Returns the number of bytes taken by these descriptors. */ 51 Returns the number of bytes taken by these descriptors.
34 int (*get_config_descriptor)(unsigned char *dest, 52 Mandatory function */
35 int max_packet_size, int interface_number, int endpoint); 53 int (*get_config_descriptor)(unsigned char *dest, int max_packet_size);
36 54
37 /* Tells the driver that a usb connection has been set up and is now 55 /* Tells the driver that a usb connection has been set up and is now
38 ready to use. */ 56 ready to use.
39 void (*init_connection)(int interface,int endpoint); 57 Optional function */
58 void (*init_connection)(void);
40 59
41 /* Initialises the driver. This can be called multiple times, 60 /* Initialises the driver. This can be called multiple times,
42 and should not perform any action that can disturb other threads 61 and should not perform any action that can disturb other threads
43 (like getting the audio buffer) */ 62 (like getting the audio buffer)
63 Optional function */
44 void (*init)(void); 64 void (*init)(void);
45 65
46 /* Tells the driver that the usb connection is no longer active */ 66 /* Tells the driver that the usb connection is no longer active
67 Optional function */
47 void (*disconnect)(void); 68 void (*disconnect)(void);
48 69
49 /* Tells the driver that a usb transfer has been completed. Note that "in" 70 /* Tells the driver that a usb transfer has been completed. Note that "in"
50 is relative to the host */ 71 is relative to the host
51 void (*transfer_complete)(bool in, int status, int length); 72 Optional function */
73 void (*transfer_complete)(int ep,bool in, int status, int length);
52 74
53 /* Tells the driver that a control request has come in. If the driver is 75 /* Tells the driver that a control request has come in. If the driver is
54 able to handle it, it should ack the request, and return true. Otherwise 76 able to handle it, it should ack the request, and return true. Otherwise
55 it should return false. */ 77 it should return false.
78 Optional function */
56 bool (*control_request)(struct usb_ctrlrequest* req); 79 bool (*control_request)(struct usb_ctrlrequest* req);
57 80
58#ifdef HAVE_HOTSWAP 81#ifdef HAVE_HOTSWAP
59 /* Tells the driver that a hotswappable disk/card was inserted or 82 /* Tells the driver that a hotswappable disk/card was inserted or
60 extracted */ 83 extracted
84 Optional function */
61 void (*notify_hotswap)(int volume, bool inserted); 85 void (*notify_hotswap)(int volume, bool inserted);
62#endif 86#endif
63}; 87};
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);
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index 08eb1213ea..197ef47cb7 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -28,7 +28,7 @@
28#ifdef USB_SERIAL 28#ifdef USB_SERIAL
29 29
30/* serial interface */ 30/* serial interface */
31struct usb_interface_descriptor __attribute__((aligned(2))) 31static struct usb_interface_descriptor __attribute__((aligned(2)))
32 interface_descriptor = 32 interface_descriptor =
33{ 33{
34 .bLength = sizeof(struct usb_interface_descriptor), 34 .bLength = sizeof(struct usb_interface_descriptor),
@@ -42,7 +42,8 @@ struct usb_interface_descriptor __attribute__((aligned(2)))
42 .iInterface = 0 42 .iInterface = 0
43}; 43};
44 44
45struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor = 45
46static struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
46{ 47{
47 .bLength = sizeof(struct usb_endpoint_descriptor), 48 .bLength = sizeof(struct usb_endpoint_descriptor),
48 .bDescriptorType = USB_DT_ENDPOINT, 49 .bDescriptorType = USB_DT_ENDPOINT,
@@ -90,31 +91,42 @@ static void sendout(void)
90 busy_sending=true; 91 busy_sending=true;
91} 92}
92 93
93int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size, 94int usb_serial_set_first_endpoint(int endpoint)
94 int interface_number,int endpoint)
95{ 95{
96 endpoint_descriptor.wMaxPacketSize=max_packet_size; 96 usb_endpoint = endpoint;
97 interface_descriptor.bInterfaceNumber=interface_number; 97 return endpoint + 1;
98}
98 99
100int usb_serial_set_first_interface(int interface)
101{
102 usb_interface = interface;
103 return interface + 1;
104}
105
106
107int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size)
108{
109 unsigned char *orig_dest = dest;
110
111 endpoint_descriptor.wMaxPacketSize=max_packet_size;
112 interface_descriptor.bInterfaceNumber=usb_interface;
99 113
100 memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor)); 114 memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
101 dest+=sizeof(struct usb_interface_descriptor); 115 dest+=sizeof(struct usb_interface_descriptor);
102 116
103 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN, 117 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN,
104 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); 118 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
105 dest+=sizeof(struct usb_endpoint_descriptor); 119 dest+=sizeof(struct usb_endpoint_descriptor);
106 120
107 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT, 121 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT,
108 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); 122 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
109 return sizeof(struct usb_interface_descriptor) + 123 dest+=sizeof(struct usb_endpoint_descriptor);
110 2 * sizeof(struct usb_endpoint_descriptor); 124
125 return (dest - orig_dest);
111} 126}
112 127
113void usb_serial_init_connection(int interface,int endpoint) 128void usb_serial_init_connection(void)
114{ 129{
115 usb_interface = interface;
116 usb_endpoint = endpoint;
117
118 /* prime rx endpoint */ 130 /* prime rx endpoint */
119 usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); 131 usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer);
120 132
@@ -187,8 +199,9 @@ void usb_serial_send(unsigned char *data,int length)
187} 199}
188 200
189/* called by usb_core_transfer_complete() */ 201/* called by usb_core_transfer_complete() */
190void usb_serial_transfer_complete(bool in, int status, int length) 202void usb_serial_transfer_complete(int ep,bool in, int status, int length)
191{ 203{
204 (void)ep;
192 switch (in) { 205 switch (in) {
193 case false: 206 case false:
194 logf("serial: %s", receive_buffer); 207 logf("serial: %s", receive_buffer);
diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h
index bd3c192d07..384626a811 100644
--- a/firmware/usbstack/usb_serial.h
+++ b/firmware/usbstack/usb_serial.h
@@ -21,12 +21,13 @@
21 21
22#include "usb_ch9.h" 22#include "usb_ch9.h"
23 23
24int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size, 24int usb_serial_set_first_endpoint(int endpoint);
25 int interface_number, int endpoint); 25int usb_serial_set_first_interface(int interface);
26void usb_serial_init_connection(int interface,int endpoint); 26int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size);
27void usb_serial_init_connection(void);
27void usb_serial_init(void); 28void usb_serial_init(void);
28void usb_serial_disconnect(void); 29void usb_serial_disconnect(void);
29void usb_serial_transfer_complete(bool in, int status, int length); 30void usb_serial_transfer_complete(int ep,bool in, int status, int length);
30bool usb_serial_control_request(struct usb_ctrlrequest* req); 31bool usb_serial_control_request(struct usb_ctrlrequest* req);
31 32
32void usb_serial_send(unsigned char *data,int length); 33void usb_serial_send(unsigned char *data,int length);
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index 693d50c009..c7bced9ecc 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -326,23 +326,32 @@ void usb_storage_init(void)
326} 326}
327 327
328 328
329int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size, 329int usb_storage_set_first_endpoint(int endpoint)
330 int interface_number,int endpoint)
331{ 330{
332 endpoint_descriptor.wMaxPacketSize=max_packet_size; 331 usb_endpoint = endpoint;
333 interface_descriptor.bInterfaceNumber=interface_number; 332 return endpoint + 1;
333}
334int usb_storage_set_first_interface(int interface)
335{
336 usb_interface = interface;
337 return interface + 1;
338}
334 339
340int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size)
341{
342 endpoint_descriptor.wMaxPacketSize=max_packet_size;
343 interface_descriptor.bInterfaceNumber=usb_interface;
335 344
336 memcpy(dest,&interface_descriptor, 345 memcpy(dest,&interface_descriptor,
337 sizeof(struct usb_interface_descriptor)); 346 sizeof(struct usb_interface_descriptor));
338 dest+=sizeof(struct usb_interface_descriptor); 347 dest+=sizeof(struct usb_interface_descriptor);
339 348
340 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN, 349 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN,
341 memcpy(dest,&endpoint_descriptor, 350 memcpy(dest,&endpoint_descriptor,
342 sizeof(struct usb_endpoint_descriptor)); 351 sizeof(struct usb_endpoint_descriptor));
343 dest+=sizeof(struct usb_endpoint_descriptor); 352 dest+=sizeof(struct usb_endpoint_descriptor);
344 353
345 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT, 354 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT,
346 memcpy(dest,&endpoint_descriptor, 355 memcpy(dest,&endpoint_descriptor,
347 sizeof(struct usb_endpoint_descriptor)); 356 sizeof(struct usb_endpoint_descriptor));
348 357
@@ -350,11 +359,8 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
350 2*sizeof(struct usb_endpoint_descriptor); 359 2*sizeof(struct usb_endpoint_descriptor);
351} 360}
352 361
353void usb_storage_init_connection(int interface,int endpoint) 362void usb_storage_init_connection(void)
354{ 363{
355 usb_interface = interface;
356 usb_endpoint = endpoint;
357
358 logf("ums: set config"); 364 logf("ums: set config");
359 /* prime rx endpoint. We only need room for commands */ 365 /* prime rx endpoint. We only need room for commands */
360 state = WAITING_FOR_COMMAND; 366 state = WAITING_FOR_COMMAND;
@@ -377,8 +383,9 @@ void usb_storage_init_connection(int interface,int endpoint)
377} 383}
378 384
379/* called by usb_core_transfer_complete() */ 385/* called by usb_core_transfer_complete() */
380void usb_storage_transfer_complete(bool in,int status,int length) 386void usb_storage_transfer_complete(int ep,bool in,int status,int length)
381{ 387{
388 (void)ep;
382 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer; 389 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
383 390
384 //logf("transfer result %X %d", status, length); 391 //logf("transfer result %X %d", status, length);
diff --git a/firmware/usbstack/usb_storage.h b/firmware/usbstack/usb_storage.h
index 7baef466f6..e657e03825 100644
--- a/firmware/usbstack/usb_storage.h
+++ b/firmware/usbstack/usb_storage.h
@@ -21,11 +21,12 @@
21 21
22#include "usb_ch9.h" 22#include "usb_ch9.h"
23 23
24int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size, 24int usb_storage_set_first_endpoint(int endpoint);
25 int interface_number,int endpoint); 25int usb_storage_set_first_interface(int interface);
26void usb_storage_init_connection(int interface,int endpoint); 26int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size);
27void usb_storage_init_connection(void);
27void usb_storage_init(void); 28void usb_storage_init(void);
28void usb_storage_transfer_complete(bool in,int state,int length); 29void usb_storage_transfer_complete(int ep,bool in,int state,int length);
29bool usb_storage_control_request(struct usb_ctrlrequest* req); 30bool usb_storage_control_request(struct usb_ctrlrequest* req);
30#ifdef HAVE_HOTSWAP 31#ifdef HAVE_HOTSWAP
31void usb_storage_notify_hotswap(int volume,bool inserted); 32void usb_storage_notify_hotswap(int volume,bool inserted);