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)
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
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 @@
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;