summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_core.c
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 /firmware/usbstack/usb_core.c
parent6219f4c862919367972e497c47324121fe48f3f6 (diff)
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
Diffstat (limited to 'firmware/usbstack/usb_core.c')
-rw-r--r--firmware/usbstack/usb_core.c84
1 files changed, 57 insertions, 27 deletions
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 @@
#include "thread.h"
#include "kernel.h"
#include "string.h"
-//#define LOGF_ENABLE
+#define LOGF_ENABLE
#include "logf.h"
#include "usb.h"
@@ -164,10 +164,13 @@ static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
static int usb_core_num_interfaces;
+typedef void (*completion_handler_t)(int ep,int dir, int status, int length);
+typedef bool (*control_handler_t)(struct usb_ctrlrequest* req);
+
static struct
{
- void (*completion_handler)(int ep,bool in, int status, int length);
- bool (*control_handler)(struct usb_ctrlrequest* req);
+ completion_handler_t completion_handler[2];
+ control_handler_t control_handler[2];
struct usb_transfer_completion_event_data completion_event;
} ep_data[NUM_ENDPOINTS];
@@ -179,8 +182,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
.needs_exclusive_ata = true,
.first_interface = 0,
.last_interface = 0,
+ .request_endpoints = usb_storage_request_endpoints,
.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,
@@ -198,8 +201,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
.needs_exclusive_ata = false,
.first_interface = 0,
.last_interface = 0,
+ .request_endpoints = usb_serial_request_endpoints,
.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,
@@ -217,8 +220,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
.needs_exclusive_ata = false,
.first_interface = 0,
.last_interface = 0,
+ .request_endpoints = usb_charging_only_request_endpoints,
.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,
@@ -339,6 +342,7 @@ void usb_core_handle_transfer_completion(
struct usb_transfer_completion_event_data* event)
{
int ep = event->endpoint;
+
switch(ep) {
case EP_CONTROL:
logf("ctrl handled %ld",current_tick);
@@ -346,8 +350,8 @@ void usb_core_handle_transfer_completion(
(struct usb_ctrlrequest*)event->data);
break;
default:
- if(ep_data[ep].completion_handler != NULL)
- ep_data[ep].completion_handler(ep,event->in,
+ if(ep_data[ep].completion_handler[event->dir>>7] != NULL)
+ ep_data[ep].completion_handler[event->dir>>7](ep,event->dir,
event->status,event->length);
break;
}
@@ -388,34 +392,60 @@ static void usb_core_set_serial_function_id(void)
usb_string_iSerial.wString[0] = hex[id];
}
+int usb_core_request_endpoint(int dir, struct usb_class_driver *drv)
+{
+ int ret, ep;
+
+ ret = usb_drv_request_endpoint(dir);
+
+ if (ret == -1)
+ return -1;
+
+ ep = ret & 0x7f;
+ dir = ret >> 7;
+
+ ep_data[ep].completion_handler[dir] = drv->transfer_complete;
+ ep_data[ep].control_handler[dir] = drv->control_request;
+
+ return ret;
+}
+
+void usb_core_release_endpoint(int ep)
+{
+ int dir;
+
+ usb_drv_release_endpoint(ep);
+
+ dir = ep >> 7;
+ ep &= 0x7f;
+
+ ep_data[ep].completion_handler[dir] = NULL;
+ ep_data[ep].control_handler[dir] = NULL;
+}
+
static void allocate_interfaces_and_endpoints(void)
{
- int i,j;
+ int i;
int interface=0;
- int endpoint=1;
memset(ep_data,0,sizeof(ep_data));
- for(i=0;i<USB_NUM_DRIVERS;i++) {
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ usb_drv_release_endpoint(i | USB_DIR_OUT);
+ usb_drv_release_endpoint(i | USB_DIR_IN);
+ }
+
+ for(i=0; i < USB_NUM_DRIVERS; i++) {
if(drivers[i].enabled) {
- int oldendpoint = endpoint;
drivers[i].first_interface = interface;
- endpoint = drivers[i].set_first_endpoint(endpoint);
- if(endpoint>NUM_ENDPOINTS) {
+ if (drivers[i].request_endpoints(&drivers[i])) {
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;
}
}
usb_core_num_interfaces = interface;
@@ -666,8 +696,8 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
break;
default: {
bool handled=false;
- if(ep_data[req->wIndex & 0xf].control_handler != NULL)
- handled = ep_data[req->wIndex & 0xf].control_handler(req);
+ if(ep_data[req->wIndex & 0xf].control_handler[0] != NULL)
+ handled = ep_data[req->wIndex & 0xf].control_handler[0](req);
if(!handled) {
/* nope. flag error */
logf("usb bad req %d", req->bRequest);
@@ -689,7 +719,7 @@ void usb_core_bus_reset(void)
}
/* called by usb_drv_transfer_completed() */
-void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
+void usb_core_transfer_complete(int endpoint, int dir, int status,int length)
{
switch (endpoint) {
case EP_CONTROL:
@@ -698,7 +728,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
default:
ep_data[endpoint].completion_event.endpoint=endpoint;
- ep_data[endpoint].completion_event.in=in;
+ ep_data[endpoint].completion_event.dir=dir;
ep_data[endpoint].completion_event.data=0;
ep_data[endpoint].completion_event.status=status;
ep_data[endpoint].completion_event.length=length;
@@ -712,7 +742,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
void usb_core_control_request(struct usb_ctrlrequest* req)
{
ep_data[0].completion_event.endpoint=0;
- ep_data[0].completion_event.in=0;
+ ep_data[0].completion_event.dir=0;
ep_data[0].completion_event.data=(void *)req;
ep_data[0].completion_event.status=0;
ep_data[0].completion_event.length=0;