diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-10-03 22:43:16 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-10-03 22:43:16 +0000 |
commit | 478fc5baed82e5573938041aed0f1a4f73f32128 (patch) | |
tree | b7115cb1200101075bf93d93f61bd0be65ff9d42 /firmware/usbstack/usb_core.c | |
parent | 6219f4c862919367972e497c47324121fe48f3f6 (diff) | |
download | rockbox-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.c | 84 |
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 | ||
165 | static int usb_core_num_interfaces; | 165 | static int usb_core_num_interfaces; |
166 | 166 | ||
167 | typedef void (*completion_handler_t)(int ep,int dir, int status, int length); | ||
168 | typedef bool (*control_handler_t)(struct usb_ctrlrequest* req); | ||
169 | |||
167 | static struct | 170 | static 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 | ||
395 | int 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 | |||
413 | void 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 | |||
391 | static void allocate_interfaces_and_endpoints(void) | 426 | static 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() */ |
692 | void usb_core_transfer_complete(int endpoint, bool in, int status,int length) | 722 | void 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) | |||
712 | void usb_core_control_request(struct usb_ctrlrequest* req) | 742 | void 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; |