summaryrefslogtreecommitdiff
path: root/firmware/usbstack
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
parent33c44461e1b5fb9aff2f8ba7470ad2449b3c410e (diff)
- 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')
-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
8 files changed, 277 insertions, 152 deletions
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: $
+ *
+ * Copyright (C) 2008 by Frank Gevaerts
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "string.h"
+#include "system.h"
+#include "usb_core.h"
+#include "usb_drv.h"
+#include "kernel.h"
+
+//#define LOGF_ENABLE
+#include "logf.h"
+
+#ifdef USB_CHARGING_ONLY
+
+/* charging_only interface */
+static struct usb_interface_descriptor __attribute__((aligned(2)))
+ interface_descriptor =
+{
+ .bLength = sizeof(struct usb_interface_descriptor),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0
+};
+
+
+static int usb_interface;
+
+int usb_charging_only_set_first_endpoint(int endpoint)
+{
+ /* The dummy charging_only driver doesn't need an endpoint pair */
+ return endpoint;
+}
+int usb_charging_only_set_first_interface(int interface)
+{
+ usb_interface = interface;
+ return interface + 1;
+}
+
+int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size)
+{
+ (void)max_packet_size;
+ unsigned char *orig_dest = dest;
+
+ interface_descriptor.bInterfaceNumber=usb_interface;
+ memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
+
+ dest+=sizeof(struct usb_interface_descriptor);
+
+ return (dest-orig_dest);
+}
+
+#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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: $
+ *
+ * Copyright (C) 2008 by Frank Gevaerts
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef USB_CHARGING_ONLY_H
+#define USB_CHARGING_ONLY_H
+
+#include "usb_ch9.h"
+
+void usb_charging_only_init(void);
+int usb_charging_only_set_first_endpoint(int endpoint);
+int usb_charging_only_set_first_interface(int interface);
+int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size);
+bool usb_charging_only_control_request(struct usb_ctrlrequest* req);
+
+#endif
+
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 @@
/* Common api, implemented by all class drivers */
struct usb_class_driver {
+ /* First some runtime data */
bool enabled;
+ int first_interface;
+ int last_interface;
+
+ /* Driver api starts here */
+
+ /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
bool needs_exclusive_ata;
- int usb_endpoint;
- int usb_interface;
+
+ /* Tells the driver what its first interface number will be. The driver
+ returns the number of the first available interface for the next driver
+ (i.e. a driver with one interface will return interface+1)
+ A driver must have at least one interface
+ Mandatory function */
+ int (*set_first_interface)(int interface);
+
+ /* Tells the driver what its first endpoint pair number will be. The driver
+ returns the number of the first available endpoint pair for the next
+ driver (i.e. a driver with one endpoint pair will return endpoint +1)
+ Mandatory function */
+ int (*set_first_endpoint)(int endpoint);
/* Asks the driver to put the interface descriptor and all other
- needed descriptor for this driver at dest, for the given settings.
- Returns the number of bytes taken by these descriptors. */
- int (*get_config_descriptor)(unsigned char *dest,
- int max_packet_size, int interface_number, int endpoint);
+ needed descriptor for this driver at dest.
+ Returns the number of bytes taken by these descriptors.
+ Mandatory function */
+ int (*get_config_descriptor)(unsigned char *dest, int max_packet_size);
/* Tells the driver that a usb connection has been set up and is now
- ready to use. */
- void (*init_connection)(int interface,int endpoint);
+ ready to use.
+ Optional function */
+ void (*init_connection)(void);
/* Initialises the driver. This can be called multiple times,
and should not perform any action that can disturb other threads
- (like getting the audio buffer) */
+ (like getting the audio buffer)
+ Optional function */
void (*init)(void);
- /* Tells the driver that the usb connection is no longer active */
+ /* Tells the driver that the usb connection is no longer active
+ Optional function */
void (*disconnect)(void);
/* Tells the driver that a usb transfer has been completed. Note that "in"
- is relative to the host */
- void (*transfer_complete)(bool in, int status, int length);
+ is relative to the host
+ Optional function */
+ void (*transfer_complete)(int ep,bool in, int status, int length);
/* Tells the driver that a control request has come in. If the driver is
able to handle it, it should ack the request, and return true. Otherwise
- it should return false. */
+ it should return false.
+ Optional function */
bool (*control_request)(struct usb_ctrlrequest* req);
#ifdef HAVE_HOTSWAP
/* Tells the driver that a hotswappable disk/card was inserted or
- extracted */
+ extracted
+ Optional function */
void (*notify_hotswap)(int volume, bool inserted);
#endif
};
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 @@
#include "usb_serial.h"
#endif
+#if defined(USB_CHARGING_ONLY)
+#include "usb_charging_only.h"
+#endif
+
/* TODO: Move target-specific stuff somewhere else (serial number reading) */
#ifdef HAVE_AS3514
@@ -91,22 +95,6 @@ static struct usb_config_descriptor __attribute__((aligned(2)))
.bMaxPower = 250, /* 500mA in 2mA units */
};
-#ifdef USB_CHARGING_ONLY
-/* dummy interface for charging-only */
-static struct usb_interface_descriptor __attribute__((aligned(2)))
- charging_interface_descriptor =
-{
- .bLength = sizeof(struct usb_interface_descriptor),
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 0,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 0,
- .iInterface = 4
-};
-#endif
static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
qualifier_descriptor =
@@ -160,21 +148,12 @@ static const struct usb_string_descriptor __attribute__((aligned(2)))
{0x0409} /* LANGID US English */
};
-static const struct usb_string_descriptor __attribute__((aligned(2)))
- usb_string_charging_only =
-{
- 28,
- USB_DT_STRING,
- {'C','h','a','r','g','i','n','g',' ','o','n','l','y'}
-};
-
static const struct usb_string_descriptor* const usb_strings[] =
{
&lang_descriptor,
&usb_string_iManufacturer,
&usb_string_iProduct,
- &usb_string_iSerial,
- &usb_string_charging_only
+ &usb_string_iSerial
};
static int usb_address = 0;
@@ -183,8 +162,12 @@ static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
static int usb_core_num_interfaces;
-static int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
- int interface_number,int endpoint);
+static struct
+{
+ void (*completion_handler)(int ep,bool in, int status, int length);
+ bool (*control_handler)(struct usb_ctrlrequest* req);
+ struct usb_transfer_completion_event_data completion_event;
+} ep_data[NUM_ENDPOINTS];
static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
{
@@ -192,8 +175,10 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
[USB_DRIVER_MASS_STORAGE] = {
.enabled = false,
.needs_exclusive_ata = true,
- .usb_endpoint = 0,
- .usb_interface = 0,
+ .first_interface = 0,
+ .last_interface = 0,
+ .set_first_interface = usb_storage_set_first_interface,
+ .set_first_endpoint = usb_storage_set_first_endpoint,
.get_config_descriptor = usb_storage_get_config_descriptor,
.init_connection = usb_storage_init_connection,
.init = usb_storage_init,
@@ -209,8 +194,10 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
[USB_DRIVER_SERIAL] = {
.enabled = false,
.needs_exclusive_ata = false,
- .usb_endpoint = 0,
- .usb_interface = 0,
+ .first_interface = 0,
+ .last_interface = 0,
+ .set_first_interface = usb_serial_set_first_interface,
+ .set_first_endpoint = usb_serial_set_first_endpoint,
.get_config_descriptor = usb_serial_get_config_descriptor,
.init_connection = usb_serial_init_connection,
.init = usb_serial_init,
@@ -226,9 +213,11 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
[USB_DRIVER_CHARGING_ONLY] = {
.enabled = false,
.needs_exclusive_ata = false,
- .usb_endpoint = 0,
- .usb_interface = 0,
- .get_config_descriptor = usb_charging_get_config_descriptor,
+ .first_interface = 0,
+ .last_interface = 0,
+ .set_first_interface = usb_charging_only_set_first_interface,
+ .set_first_endpoint = usb_charging_only_set_first_endpoint,
+ .get_config_descriptor = usb_charging_only_get_config_descriptor,
.init_connection = NULL,
.init = NULL,
.disconnect = NULL,
@@ -242,11 +231,9 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
};
static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
-static int ack_control(struct usb_ctrlrequest* req);
static unsigned char response_data[256] USBDEVBSS_ATTR;
-static struct usb_transfer_completion_event_data events[NUM_ENDPOINTS];
static short hex[16] = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'};
@@ -331,17 +318,6 @@ void usb_core_init(void)
logf("usb_core_init() finished");
}
-static int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
- int interface_number,int endpoint)
-{
- (void) max_packet_size;
- (void) endpoint;
- charging_interface_descriptor.bInterfaceNumber=interface_number;
- memcpy(dest,&charging_interface_descriptor,
- sizeof(struct usb_interface_descriptor));
- return sizeof(struct usb_interface_descriptor);
-}
-
void usb_core_exit(void)
{
int i;
@@ -360,24 +336,17 @@ void usb_core_exit(void)
void usb_core_handle_transfer_completion(
struct usb_transfer_completion_event_data* event)
{
- int i;
- switch(event->endpoint) {
+ int ep = event->endpoint;
+ switch(ep) {
case EP_CONTROL:
logf("ctrl handled %ld",current_tick);
usb_core_control_request_handler(
(struct usb_ctrlrequest*)event->data);
break;
default:
- for(i=0;i<USB_NUM_DRIVERS;i++) {
- if(drivers[i].enabled &&
- drivers[i].usb_endpoint == event->endpoint &&
- drivers[i].transfer_complete != NULL)
- {
- drivers[i].transfer_complete(event->in,
+ if(ep_data[ep].completion_handler != NULL)
+ ep_data[ep].completion_handler(ep,event->in,
event->status,event->length);
- break;
- }
- }
break;
}
}
@@ -419,13 +388,29 @@ static void usb_core_set_serial_function_id(void)
static void allocate_interfaces_and_endpoints(void)
{
- int i;
+ int i,j;
int interface=0;
int endpoint=1;
+
+ memset(ep_data,0,sizeof(ep_data));
+
for(i=0;i<USB_NUM_DRIVERS;i++) {
if(drivers[i].enabled) {
- drivers[i].usb_endpoint = endpoint++;
- drivers[i].usb_interface = interface++;
+ int oldendpoint = endpoint;
+ drivers[i].first_interface = interface;
+
+ endpoint = drivers[i].set_first_endpoint(endpoint);
+ if(endpoint>NUM_ENDPOINTS) {
+ drivers[i].enabled = false;
+ continue;
+ }
+ interface = drivers[i].set_first_interface(interface);
+ drivers[i].last_interface = interface;
+
+ for(j=oldendpoint;j<endpoint;j++) {
+ ep_data[j].completion_handler=drivers[i].transfer_complete;
+ ep_data[j].control_handler=drivers[i].control_request;
+ }
}
if(endpoint>NUM_ENDPOINTS) {
drivers[i].enabled = false;
@@ -463,7 +448,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[0] = 1;
if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
break;
- ack_control(req);
+ usb_core_ack_control(req);
break;
case USB_REQ_SET_CONFIGURATION:
logf("usb_core: SET_CONFIG");
@@ -474,22 +459,20 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
if(drivers[i].enabled &&
drivers[i].init_connection!=NULL)
{
- drivers[i].init_connection(
- drivers[i].usb_interface,
- drivers[i].usb_endpoint);
+ drivers[i].init_connection();
}
}
}
else {
usb_state = ADDRESS;
}
- ack_control(req);
+ usb_core_ack_control(req);
break;
}
case USB_REQ_SET_ADDRESS: {
unsigned char address = req->wValue;
logf("usb_core: SET_ADR %d", address);
- if(ack_control(req)!=0)
+ if(usb_core_ack_control(req)!=0)
break;
usb_drv_cancel_all_transfers();
usb_address = address;
@@ -537,9 +520,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
{
size+=drivers[i].get_config_descriptor(
&response_data[size],
- max_packet_size,
- drivers[i].usb_interface,
- drivers[i].usb_endpoint);
+ max_packet_size);
}
}
config_descriptor.bNumInterfaces =
@@ -587,7 +568,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
if(usb_drv_send(EP_CONTROL, response_data, length)!=0)
break;
}
- ack_control(req);
+ usb_core_ack_control(req);
break;
} /* USB_REQ_GET_DESCRIPTOR */
case USB_REQ_CLEAR_FEATURE:
@@ -595,7 +576,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
case USB_REQ_SET_FEATURE:
if(req->wValue == 2) { /* TEST_MODE */
int mode=req->wIndex>>8;
- ack_control(req);
+ usb_core_ack_control(req);
usb_drv_set_test_mode(mode);
}
break;
@@ -604,7 +585,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[1]= 0;
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
break;
- ack_control(req);
+ usb_core_ack_control(req);
break;
default:
break;
@@ -614,7 +595,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
switch (req->bRequest) {
case USB_REQ_SET_INTERFACE:
logf("usb_core: SET_INTERFACE");
- ack_control(req);
+ usb_core_ack_control(req);
break;
case USB_REQ_GET_INTERFACE:
@@ -622,7 +603,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[0] = 0;
if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
break;
- ack_control(req);
+ usb_core_ack_control(req);
break;
case USB_REQ_CLEAR_FEATURE:
break;
@@ -633,14 +614,15 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[1]= 0;
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
break;
- ack_control(req);
+ usb_core_ack_control(req);
break;
default: {
bool handled=false;
for(i=0;i<USB_NUM_DRIVERS;i++) {
if(drivers[i].enabled &&
drivers[i].control_request &&
- drivers[i].usb_interface == (req->wIndex))
+ drivers[i].first_interface <= (req->wIndex) &&
+ drivers[i].last_interface > (req->wIndex))
{
handled = drivers[i].control_request(req);
}
@@ -649,7 +631,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
/* nope. flag error */
logf("usb bad req %d", req->bRequest);
usb_drv_stall(EP_CONTROL, true,true);
- ack_control(req);
+ usb_core_ack_control(req);
}
break;
}
@@ -661,13 +643,13 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
if (req->wValue == 0 ) /* ENDPOINT_HALT */
usb_drv_stall(req->wIndex & 0xf, false,
(req->wIndex & 0x80) !=0);
- ack_control(req);
+ usb_core_ack_control(req);
break;
case USB_REQ_SET_FEATURE:
if (req->wValue == 0 ) /* ENDPOINT_HALT */
usb_drv_stall(req->wIndex & 0xf, true,
(req->wIndex & 0x80) !=0);
- ack_control(req);
+ usb_core_ack_control(req);
break;
case USB_REQ_GET_STATUS:
response_data[0]= 0;
@@ -678,23 +660,17 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
(req->wIndex&0x80)!=0);
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
break;
- ack_control(req);
+ usb_core_ack_control(req);
break;
default: {
bool handled=false;
- for(i=0;i<USB_NUM_DRIVERS;i++) {
- if(drivers[i].enabled &&
- drivers[i].control_request &&
- drivers[i].usb_endpoint == (req->wIndex & 0xf))
- {
- handled = drivers[i].control_request(req);
- }
- }
+ if(ep_data[req->wIndex & 0xf].control_handler != NULL)
+ handled = ep_data[req->wIndex & 0xf].control_handler(req);
if(!handled) {
/* nope. flag error */
logf("usb bad req %d", req->bRequest);
usb_drv_stall(EP_CONTROL, true,true);
- ack_control(req);
+ usb_core_ack_control(req);
}
break;
}
@@ -719,13 +695,13 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
break;
default:
- events[endpoint].endpoint=endpoint;
- events[endpoint].in=in;
- events[endpoint].data=0;
- events[endpoint].status=status;
- events[endpoint].length=length;
+ ep_data[endpoint].completion_event.endpoint=endpoint;
+ ep_data[endpoint].completion_event.in=in;
+ ep_data[endpoint].completion_event.data=0;
+ ep_data[endpoint].completion_event.status=status;
+ ep_data[endpoint].completion_event.length=length;
/* All other endoints. Let the thread deal with it */
- usb_signal_transfer_completion(&events[endpoint]);
+ usb_signal_transfer_completion(&ep_data[endpoint].completion_event);
break;
}
}
@@ -733,16 +709,16 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
/* called by usb_drv_int() */
void usb_core_control_request(struct usb_ctrlrequest* req)
{
- events[0].endpoint=0;
- events[0].in=0;
- events[0].data=(void *)req;
- events[0].status=0;
- events[0].length=0;
+ ep_data[0].completion_event.endpoint=0;
+ ep_data[0].completion_event.in=0;
+ ep_data[0].completion_event.data=(void *)req;
+ ep_data[0].completion_event.status=0;
+ ep_data[0].completion_event.length=0;
logf("ctrl received %ld",current_tick);
- usb_signal_transfer_completion(&events[0]);
+ usb_signal_transfer_completion(&ep_data[0].completion_event);
}
-static int ack_control(struct usb_ctrlrequest* req)
+int usb_core_ack_control(struct usb_ctrlrequest* req)
{
if (req->bRequestType & 0x80)
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 @@
#ifdef USB_SERIAL
/* serial interface */
-struct usb_interface_descriptor __attribute__((aligned(2)))
+static struct usb_interface_descriptor __attribute__((aligned(2)))
interface_descriptor =
{
.bLength = sizeof(struct usb_interface_descriptor),
@@ -42,7 +42,8 @@ struct usb_interface_descriptor __attribute__((aligned(2)))
.iInterface = 0
};
-struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
+
+static struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
{
.bLength = sizeof(struct usb_endpoint_descriptor),
.bDescriptorType = USB_DT_ENDPOINT,
@@ -90,31 +91,42 @@ static void sendout(void)
busy_sending=true;
}
-int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
- int interface_number,int endpoint)
+int usb_serial_set_first_endpoint(int endpoint)
{
- endpoint_descriptor.wMaxPacketSize=max_packet_size;
- interface_descriptor.bInterfaceNumber=interface_number;
+ usb_endpoint = endpoint;
+ return endpoint + 1;
+}
+int usb_serial_set_first_interface(int interface)
+{
+ usb_interface = interface;
+ return interface + 1;
+}
+
+
+int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size)
+{
+ unsigned char *orig_dest = dest;
+
+ endpoint_descriptor.wMaxPacketSize=max_packet_size;
+ interface_descriptor.bInterfaceNumber=usb_interface;
memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
dest+=sizeof(struct usb_interface_descriptor);
- endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
+ endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN,
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
dest+=sizeof(struct usb_endpoint_descriptor);
- endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
+ endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT,
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
- return sizeof(struct usb_interface_descriptor) +
- 2 * sizeof(struct usb_endpoint_descriptor);
+ dest+=sizeof(struct usb_endpoint_descriptor);
+
+ return (dest - orig_dest);
}
-void usb_serial_init_connection(int interface,int endpoint)
+void usb_serial_init_connection(void)
{
- usb_interface = interface;
- usb_endpoint = endpoint;
-
/* prime rx endpoint */
usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer);
@@ -187,8 +199,9 @@ void usb_serial_send(unsigned char *data,int length)
}
/* called by usb_core_transfer_complete() */
-void usb_serial_transfer_complete(bool in, int status, int length)
+void usb_serial_transfer_complete(int ep,bool in, int status, int length)
{
+ (void)ep;
switch (in) {
case false:
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 @@
#include "usb_ch9.h"
-int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
- int interface_number, int endpoint);
-void usb_serial_init_connection(int interface,int endpoint);
+int usb_serial_set_first_endpoint(int endpoint);
+int usb_serial_set_first_interface(int interface);
+int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size);
+void usb_serial_init_connection(void);
void usb_serial_init(void);
void usb_serial_disconnect(void);
-void usb_serial_transfer_complete(bool in, int status, int length);
+void usb_serial_transfer_complete(int ep,bool in, int status, int length);
bool usb_serial_control_request(struct usb_ctrlrequest* req);
void 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)
}
-int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
- int interface_number,int endpoint)
+int usb_storage_set_first_endpoint(int endpoint)
{
- endpoint_descriptor.wMaxPacketSize=max_packet_size;
- interface_descriptor.bInterfaceNumber=interface_number;
+ usb_endpoint = endpoint;
+ return endpoint + 1;
+}
+int usb_storage_set_first_interface(int interface)
+{
+ usb_interface = interface;
+ return interface + 1;
+}
+int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size)
+{
+ endpoint_descriptor.wMaxPacketSize=max_packet_size;
+ interface_descriptor.bInterfaceNumber=usb_interface;
memcpy(dest,&interface_descriptor,
sizeof(struct usb_interface_descriptor));
dest+=sizeof(struct usb_interface_descriptor);
- endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
+ endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN,
memcpy(dest,&endpoint_descriptor,
sizeof(struct usb_endpoint_descriptor));
dest+=sizeof(struct usb_endpoint_descriptor);
- endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
+ endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT,
memcpy(dest,&endpoint_descriptor,
sizeof(struct usb_endpoint_descriptor));
@@ -350,11 +359,8 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
2*sizeof(struct usb_endpoint_descriptor);
}
-void usb_storage_init_connection(int interface,int endpoint)
+void usb_storage_init_connection(void)
{
- usb_interface = interface;
- usb_endpoint = endpoint;
-
logf("ums: set config");
/* prime rx endpoint. We only need room for commands */
state = WAITING_FOR_COMMAND;
@@ -377,8 +383,9 @@ void usb_storage_init_connection(int interface,int endpoint)
}
/* called by usb_core_transfer_complete() */
-void usb_storage_transfer_complete(bool in,int status,int length)
+void usb_storage_transfer_complete(int ep,bool in,int status,int length)
{
+ (void)ep;
struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
//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 @@
#include "usb_ch9.h"
-int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
- int interface_number,int endpoint);
-void usb_storage_init_connection(int interface,int endpoint);
+int usb_storage_set_first_endpoint(int endpoint);
+int usb_storage_set_first_interface(int interface);
+int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size);
+void usb_storage_init_connection(void);
void usb_storage_init(void);
-void usb_storage_transfer_complete(bool in,int state,int length);
+void usb_storage_transfer_complete(int ep,bool in,int state,int length);
bool usb_storage_control_request(struct usb_ctrlrequest* req);
#ifdef HAVE_HOTSWAP
void usb_storage_notify_hotswap(int volume,bool inserted);