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 | |
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')
-rw-r--r-- | firmware/usbstack/usb_charging_only.c | 7 | ||||
-rw-r--r-- | firmware/usbstack/usb_charging_only.h | 2 | ||||
-rw-r--r-- | firmware/usbstack/usb_class_driver.h | 13 | ||||
-rw-r--r-- | firmware/usbstack/usb_core.c | 84 | ||||
-rw-r--r-- | firmware/usbstack/usb_serial.c | 39 | ||||
-rw-r--r-- | firmware/usbstack/usb_serial.h | 4 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.c | 70 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.h | 4 |
8 files changed, 137 insertions, 86 deletions
diff --git a/firmware/usbstack/usb_charging_only.c b/firmware/usbstack/usb_charging_only.c index 8cce4fcef3..e20d1885a0 100644 --- a/firmware/usbstack/usb_charging_only.c +++ b/firmware/usbstack/usb_charging_only.c | |||
@@ -48,11 +48,12 @@ static struct usb_interface_descriptor __attribute__((aligned(2))) | |||
48 | 48 | ||
49 | static int usb_interface; | 49 | static int usb_interface; |
50 | 50 | ||
51 | int usb_charging_only_set_first_endpoint(int endpoint) | 51 | int usb_charging_only_request_endpoints(struct usb_class_driver *drv) |
52 | { | 52 | { |
53 | /* The dummy charging_only driver doesn't need an endpoint pair */ | 53 | (void) drv; |
54 | return endpoint; | 54 | return 0; |
55 | } | 55 | } |
56 | |||
56 | int usb_charging_only_set_first_interface(int interface) | 57 | int usb_charging_only_set_first_interface(int interface) |
57 | { | 58 | { |
58 | usb_interface = interface; | 59 | usb_interface = interface; |
diff --git a/firmware/usbstack/usb_charging_only.h b/firmware/usbstack/usb_charging_only.h index 65ab7df4c1..8bdf58ff1d 100644 --- a/firmware/usbstack/usb_charging_only.h +++ b/firmware/usbstack/usb_charging_only.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "usb_ch9.h" | 24 | #include "usb_ch9.h" |
25 | 25 | ||
26 | void usb_charging_only_init(void); | 26 | void usb_charging_only_init(void); |
27 | int usb_charging_only_set_first_endpoint(int endpoint); | 27 | int usb_charging_only_request_endpoints(struct usb_class_driver *); |
28 | int usb_charging_only_set_first_interface(int interface); | 28 | int usb_charging_only_set_first_interface(int interface); |
29 | int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size); | 29 | int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size); |
30 | bool usb_charging_only_control_request(struct usb_ctrlrequest* req); | 30 | bool usb_charging_only_control_request(struct usb_ctrlrequest* req); |
diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h index bda0b7663c..e089c488a8 100644 --- a/firmware/usbstack/usb_class_driver.h +++ b/firmware/usbstack/usb_class_driver.h | |||
@@ -35,6 +35,9 @@ struct usb_class_driver { | |||
35 | /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ | 35 | /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ |
36 | bool needs_exclusive_ata; | 36 | bool needs_exclusive_ata; |
37 | 37 | ||
38 | /* Let the driver request endpoints it need. Returns zero on success */ | ||
39 | int (*request_endpoints)(struct usb_class_driver *); | ||
40 | |||
38 | /* Tells the driver what its first interface number will be. The driver | 41 | /* Tells the driver what its first interface number will be. The driver |
39 | returns the number of the first available interface for the next driver | 42 | returns the number of the first available interface for the next driver |
40 | (i.e. a driver with one interface will return interface+1) | 43 | (i.e. a driver with one interface will return interface+1) |
@@ -42,12 +45,6 @@ struct usb_class_driver { | |||
42 | Mandatory function */ | 45 | Mandatory function */ |
43 | int (*set_first_interface)(int interface); | 46 | int (*set_first_interface)(int interface); |
44 | 47 | ||
45 | /* Tells the driver what its first endpoint pair number will be. The driver | ||
46 | returns the number of the first available endpoint pair for the next | ||
47 | driver (i.e. a driver with one endpoint pair will return endpoint +1) | ||
48 | Mandatory function */ | ||
49 | int (*set_first_endpoint)(int endpoint); | ||
50 | |||
51 | /* Asks the driver to put the interface descriptor and all other | 48 | /* Asks the driver to put the interface descriptor and all other |
52 | needed descriptor for this driver at dest. | 49 | needed descriptor for this driver at dest. |
53 | Returns the number of bytes taken by these descriptors. | 50 | Returns the number of bytes taken by these descriptors. |
@@ -69,10 +66,10 @@ struct usb_class_driver { | |||
69 | Optional function */ | 66 | Optional function */ |
70 | void (*disconnect)(void); | 67 | void (*disconnect)(void); |
71 | 68 | ||
72 | /* Tells the driver that a usb transfer has been completed. Note that "in" | 69 | /* Tells the driver that a usb transfer has been completed. Note that "dir" |
73 | is relative to the host | 70 | is relative to the host |
74 | Optional function */ | 71 | Optional function */ |
75 | void (*transfer_complete)(int ep,bool in, int status, int length); | 72 | void (*transfer_complete)(int ep,int dir, int status, int length); |
76 | 73 | ||
77 | /* Tells the driver that a control request has come in. If the driver is | 74 | /* Tells the driver that a control request has come in. If the driver is |
78 | able to handle it, it should ack the request, and return true. Otherwise | 75 | able to handle it, it should ack the request, and return true. Otherwise |
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; |
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c index 8d6ce67823..1b143d56eb 100644 --- a/firmware/usbstack/usb_serial.c +++ b/firmware/usbstack/usb_serial.c | |||
@@ -72,7 +72,7 @@ static int buffer_start; | |||
72 | static int buffer_length; | 72 | static int buffer_length; |
73 | static bool active = false; | 73 | static bool active = false; |
74 | 74 | ||
75 | static int usb_endpoint; | 75 | static int ep_in, ep_out; |
76 | static int usb_interface; | 76 | static int usb_interface; |
77 | 77 | ||
78 | static struct mutex sendlock SHAREDBSS_ATTR; | 78 | static struct mutex sendlock SHAREDBSS_ATTR; |
@@ -82,22 +82,33 @@ static void sendout(void) | |||
82 | if(buffer_start+buffer_length > BUFFER_SIZE) | 82 | if(buffer_start+buffer_length > BUFFER_SIZE) |
83 | { | 83 | { |
84 | /* Buffer wraps. Only send the first part */ | 84 | /* Buffer wraps. Only send the first part */ |
85 | usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start], | 85 | usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], |
86 | (BUFFER_SIZE - buffer_start)); | 86 | (BUFFER_SIZE - buffer_start)); |
87 | } | 87 | } |
88 | else | 88 | else |
89 | { | 89 | { |
90 | /* Send everything */ | 90 | /* Send everything */ |
91 | usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start], | 91 | usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], |
92 | buffer_length); | 92 | buffer_length); |
93 | } | 93 | } |
94 | busy_sending=true; | 94 | busy_sending=true; |
95 | } | 95 | } |
96 | 96 | ||
97 | int usb_serial_set_first_endpoint(int endpoint) | 97 | int usb_serial_request_endpoints(struct usb_class_driver *drv) |
98 | { | 98 | { |
99 | usb_endpoint = endpoint; | 99 | ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); |
100 | return endpoint + 1; | 100 | |
101 | if (ep_in < 0) | ||
102 | return -1; | ||
103 | |||
104 | ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv); | ||
105 | |||
106 | if (ep_out < 0) { | ||
107 | usb_core_release_endpoint(ep_in); | ||
108 | return -1; | ||
109 | } | ||
110 | |||
111 | return 0; | ||
101 | } | 112 | } |
102 | 113 | ||
103 | int usb_serial_set_first_interface(int interface) | 114 | int usb_serial_set_first_interface(int interface) |
@@ -117,11 +128,11 @@ int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size) | |||
117 | memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor)); | 128 | memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor)); |
118 | dest+=sizeof(struct usb_interface_descriptor); | 129 | dest+=sizeof(struct usb_interface_descriptor); |
119 | 130 | ||
120 | endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN; | 131 | endpoint_descriptor.bEndpointAddress = ep_in; |
121 | memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); | 132 | memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); |
122 | dest+=sizeof(struct usb_endpoint_descriptor); | 133 | dest+=sizeof(struct usb_endpoint_descriptor); |
123 | 134 | ||
124 | endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT; | 135 | endpoint_descriptor.bEndpointAddress = ep_out; |
125 | memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); | 136 | memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); |
126 | dest+=sizeof(struct usb_endpoint_descriptor); | 137 | dest+=sizeof(struct usb_endpoint_descriptor); |
127 | 138 | ||
@@ -131,7 +142,7 @@ int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size) | |||
131 | void usb_serial_init_connection(void) | 142 | void usb_serial_init_connection(void) |
132 | { | 143 | { |
133 | /* prime rx endpoint */ | 144 | /* prime rx endpoint */ |
134 | usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); | 145 | usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer); |
135 | 146 | ||
136 | /* we come here too after a bus reset, so reset some data */ | 147 | /* we come here too after a bus reset, so reset some data */ |
137 | mutex_lock(&sendlock); | 148 | mutex_lock(&sendlock); |
@@ -202,17 +213,17 @@ void usb_serial_send(unsigned char *data,int length) | |||
202 | } | 213 | } |
203 | 214 | ||
204 | /* called by usb_core_transfer_complete() */ | 215 | /* called by usb_core_transfer_complete() */ |
205 | void usb_serial_transfer_complete(int ep,bool in, int status, int length) | 216 | void usb_serial_transfer_complete(int ep,int dir, int status, int length) |
206 | { | 217 | { |
207 | (void)ep; | 218 | (void)ep; |
208 | switch (in) { | 219 | switch (dir) { |
209 | case false: | 220 | case USB_DIR_OUT: |
210 | logf("serial: %s", receive_buffer); | 221 | logf("serial: %s", receive_buffer); |
211 | /* Data received. TODO : Do something with it ? */ | 222 | /* Data received. TODO : Do something with it ? */ |
212 | usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); | 223 | usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer); |
213 | break; | 224 | break; |
214 | 225 | ||
215 | case true: | 226 | case USB_DIR_IN: |
216 | mutex_lock(&sendlock); | 227 | mutex_lock(&sendlock); |
217 | /* Data sent out. Update circular buffer */ | 228 | /* Data sent out. Update circular buffer */ |
218 | if(status == 0) | 229 | if(status == 0) |
diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h index 69ad3fd647..94decdc42b 100644 --- a/firmware/usbstack/usb_serial.h +++ b/firmware/usbstack/usb_serial.h | |||
@@ -23,13 +23,13 @@ | |||
23 | 23 | ||
24 | #include "usb_ch9.h" | 24 | #include "usb_ch9.h" |
25 | 25 | ||
26 | int usb_serial_set_first_endpoint(int endpoint); | 26 | int usb_serial_request_endpoints(struct usb_class_driver *); |
27 | int usb_serial_set_first_interface(int interface); | 27 | int usb_serial_set_first_interface(int interface); |
28 | int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size); | 28 | int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size); |
29 | void usb_serial_init_connection(void); | 29 | void usb_serial_init_connection(void); |
30 | void usb_serial_init(void); | 30 | void usb_serial_init(void); |
31 | void usb_serial_disconnect(void); | 31 | void usb_serial_disconnect(void); |
32 | void usb_serial_transfer_complete(int ep,bool in, int status, int length); | 32 | void usb_serial_transfer_complete(int ep,int dir, int status, int length); |
33 | bool usb_serial_control_request(struct usb_ctrlrequest* req); | 33 | bool usb_serial_control_request(struct usb_ctrlrequest* req); |
34 | 34 | ||
35 | void usb_serial_send(unsigned char *data,int length); | 35 | void usb_serial_send(unsigned char *data,int length); |
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index f774d14cbc..9c524a37b8 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "system.h" | 22 | #include "system.h" |
23 | #include "usb_core.h" | 23 | #include "usb_core.h" |
24 | #include "usb_drv.h" | 24 | #include "usb_drv.h" |
25 | //#define LOGF_ENABLE | 25 | #define LOGF_ENABLE |
26 | #include "logf.h" | 26 | #include "logf.h" |
27 | #include "ata.h" | 27 | #include "ata.h" |
28 | #include "hotswap.h" | 28 | #include "hotswap.h" |
@@ -263,8 +263,8 @@ static void identify2inquiry(int lun); | |||
263 | static void send_and_read_next(void); | 263 | static void send_and_read_next(void); |
264 | static bool ejected[NUM_VOLUMES]; | 264 | static bool ejected[NUM_VOLUMES]; |
265 | 265 | ||
266 | static int usb_endpoint; | ||
267 | static int usb_interface; | 266 | static int usb_interface; |
267 | static int ep_in, ep_out; | ||
268 | 268 | ||
269 | static enum { | 269 | static enum { |
270 | WAITING_FOR_COMMAND, | 270 | WAITING_FOR_COMMAND, |
@@ -321,7 +321,7 @@ void usb_storage_reconnect(void) | |||
321 | && usb_inserted()) { | 321 | && usb_inserted()) { |
322 | for(i=0;i<NUM_VOLUMES;i++) | 322 | for(i=0;i<NUM_VOLUMES;i++) |
323 | ejected[i] = !check_disk_present(IF_MV(i)); | 323 | ejected[i] = !check_disk_present(IF_MV(i)); |
324 | 324 | logf("%s", __func__); | |
325 | usb_request_exclusive_ata(); | 325 | usb_request_exclusive_ata(); |
326 | } | 326 | } |
327 | } | 327 | } |
@@ -336,12 +336,23 @@ void usb_storage_init(void) | |||
336 | logf("usb_storage_init done"); | 336 | logf("usb_storage_init done"); |
337 | } | 337 | } |
338 | 338 | ||
339 | 339 | int usb_storage_request_endpoints(struct usb_class_driver *drv) | |
340 | int usb_storage_set_first_endpoint(int endpoint) | ||
341 | { | 340 | { |
342 | usb_endpoint = endpoint; | 341 | ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); |
343 | return endpoint + 1; | 342 | |
343 | if (ep_in < 0) | ||
344 | return -1; | ||
345 | |||
346 | ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv); | ||
347 | |||
348 | if (ep_out < 0) { | ||
349 | usb_core_release_endpoint(ep_in); | ||
350 | return -1; | ||
351 | } | ||
352 | |||
353 | return 0; | ||
344 | } | 354 | } |
355 | |||
345 | int usb_storage_set_first_interface(int interface) | 356 | int usb_storage_set_first_interface(int interface) |
346 | { | 357 | { |
347 | usb_interface = interface; | 358 | usb_interface = interface; |
@@ -357,12 +368,12 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size) | |||
357 | sizeof(struct usb_interface_descriptor)); | 368 | sizeof(struct usb_interface_descriptor)); |
358 | dest+=sizeof(struct usb_interface_descriptor); | 369 | dest+=sizeof(struct usb_interface_descriptor); |
359 | 370 | ||
360 | endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN; | 371 | endpoint_descriptor.bEndpointAddress = ep_in; |
361 | memcpy(dest,&endpoint_descriptor, | 372 | memcpy(dest,&endpoint_descriptor, |
362 | sizeof(struct usb_endpoint_descriptor)); | 373 | sizeof(struct usb_endpoint_descriptor)); |
363 | dest+=sizeof(struct usb_endpoint_descriptor); | 374 | dest+=sizeof(struct usb_endpoint_descriptor); |
364 | 375 | ||
365 | endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT; | 376 | endpoint_descriptor.bEndpointAddress = ep_out; |
366 | memcpy(dest,&endpoint_descriptor, | 377 | memcpy(dest,&endpoint_descriptor, |
367 | sizeof(struct usb_endpoint_descriptor)); | 378 | sizeof(struct usb_endpoint_descriptor)); |
368 | 379 | ||
@@ -376,7 +387,8 @@ void usb_storage_init_connection(void) | |||
376 | /* prime rx endpoint. We only need room for commands */ | 387 | /* prime rx endpoint. We only need room for commands */ |
377 | state = WAITING_FOR_COMMAND; | 388 | state = WAITING_FOR_COMMAND; |
378 | 389 | ||
379 | #if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 | 390 | #if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \ |
391 | defined(CPU_TCC77X) || defined(CPU_TCC780X) | ||
380 | static unsigned char _transfer_buffer[BUFFER_SIZE*2] | 392 | static unsigned char _transfer_buffer[BUFFER_SIZE*2] |
381 | USBDEVBSS_ATTR __attribute__((aligned(32))); | 393 | USBDEVBSS_ATTR __attribute__((aligned(32))); |
382 | tb.transfer_buffer = (void *)_transfer_buffer; | 394 | tb.transfer_buffer = (void *)_transfer_buffer; |
@@ -390,11 +402,11 @@ void usb_storage_init_connection(void) | |||
390 | (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); | 402 | (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); |
391 | invalidate_icache(); | 403 | invalidate_icache(); |
392 | #endif | 404 | #endif |
393 | usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); | 405 | usb_drv_recv(ep_out, tb.transfer_buffer, 1024); |
394 | } | 406 | } |
395 | 407 | ||
396 | /* called by usb_core_transfer_complete() */ | 408 | /* called by usb_core_transfer_complete() */ |
397 | void usb_storage_transfer_complete(int ep,bool in,int status,int length) | 409 | void usb_storage_transfer_complete(int ep,int dir,int status,int length) |
398 | { | 410 | { |
399 | (void)ep; | 411 | (void)ep; |
400 | struct command_block_wrapper* cbw = (void*)tb.transfer_buffer; | 412 | struct command_block_wrapper* cbw = (void*)tb.transfer_buffer; |
@@ -402,7 +414,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) | |||
402 | //logf("transfer result %X %d", status, length); | 414 | //logf("transfer result %X %d", status, length); |
403 | switch(state) { | 415 | switch(state) { |
404 | case RECEIVING_BLOCKS: | 416 | case RECEIVING_BLOCKS: |
405 | if(in==true) { | 417 | if(dir==USB_DIR_IN) { |
406 | logf("IN received in RECEIVING"); | 418 | logf("IN received in RECEIVING"); |
407 | } | 419 | } |
408 | logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); | 420 | logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); |
@@ -470,7 +482,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) | |||
470 | } | 482 | } |
471 | break; | 483 | break; |
472 | case WAITING_FOR_COMMAND: | 484 | case WAITING_FOR_COMMAND: |
473 | if(in==true) { | 485 | if(dir==USB_DIR_IN) { |
474 | logf("IN received in WAITING_FOR_COMMAND"); | 486 | logf("IN received in WAITING_FOR_COMMAND"); |
475 | } | 487 | } |
476 | //logf("command received"); | 488 | //logf("command received"); |
@@ -478,20 +490,20 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) | |||
478 | handle_scsi(cbw); | 490 | handle_scsi(cbw); |
479 | } | 491 | } |
480 | else { | 492 | else { |
481 | usb_drv_stall(usb_endpoint, true,true); | 493 | usb_drv_stall(ep_in, true,true); |
482 | usb_drv_stall(usb_endpoint, true,false); | 494 | usb_drv_stall(ep_out, true,false); |
483 | } | 495 | } |
484 | break; | 496 | break; |
485 | case SENDING_CSW: | 497 | case SENDING_CSW: |
486 | if(in==false) { | 498 | if(dir==USB_DIR_OUT) { |
487 | logf("OUT received in SENDING_CSW"); | 499 | logf("OUT received in SENDING_CSW"); |
488 | } | 500 | } |
489 | //logf("csw sent, now go back to idle"); | 501 | //logf("csw sent, now go back to idle"); |
490 | state = WAITING_FOR_COMMAND; | 502 | state = WAITING_FOR_COMMAND; |
491 | usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); | 503 | usb_drv_recv(ep_out, tb.transfer_buffer, 1024); |
492 | break; | 504 | break; |
493 | case SENDING_RESULT: | 505 | case SENDING_RESULT: |
494 | if(in==false) { | 506 | if(dir==USB_DIR_OUT) { |
495 | logf("OUT received in SENDING"); | 507 | logf("OUT received in SENDING"); |
496 | } | 508 | } |
497 | if(status==0) { | 509 | if(status==0) { |
@@ -509,13 +521,13 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) | |||
509 | } | 521 | } |
510 | break; | 522 | break; |
511 | case SENDING_FAILED_RESULT: | 523 | case SENDING_FAILED_RESULT: |
512 | if(in==false) { | 524 | if(dir==USB_DIR_OUT) { |
513 | logf("OUT received in SENDING"); | 525 | logf("OUT received in SENDING"); |
514 | } | 526 | } |
515 | send_csw(UMS_STATUS_FAIL); | 527 | send_csw(UMS_STATUS_FAIL); |
516 | break; | 528 | break; |
517 | case SENDING_BLOCKS: | 529 | case SENDING_BLOCKS: |
518 | if(in==false) { | 530 | if(dir==USB_DIR_OUT) { |
519 | logf("OUT received in SENDING"); | 531 | logf("OUT received in SENDING"); |
520 | } | 532 | } |
521 | if(status==0) { | 533 | if(status==0) { |
@@ -567,8 +579,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req) | |||
567 | data toggle bits and endpoint STALL conditions despite | 579 | data toggle bits and endpoint STALL conditions despite |
568 | the Bulk-Only Mass Storage Reset. */ | 580 | the Bulk-Only Mass Storage Reset. */ |
569 | #if 0 | 581 | #if 0 |
570 | usb_drv_reset_endpoint(usb_endpoint, false); | 582 | usb_drv_reset_endpoint(ep_in, false); |
571 | usb_drv_reset_endpoint(usb_endpoint, true); | 583 | usb_drv_reset_endpoint(ep_out, true); |
572 | #endif | 584 | #endif |
573 | 585 | ||
574 | usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ | 586 | usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ |
@@ -972,7 +984,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
972 | 984 | ||
973 | default: | 985 | default: |
974 | logf("scsi unknown cmd %x",cbw->command_block[0x0]); | 986 | logf("scsi unknown cmd %x",cbw->command_block[0x0]); |
975 | usb_drv_stall(usb_endpoint, true,true); | 987 | usb_drv_stall(ep_in, true,true); |
976 | send_csw(UMS_STATUS_FAIL); | 988 | send_csw(UMS_STATUS_FAIL); |
977 | break; | 989 | break; |
978 | } | 990 | } |
@@ -980,25 +992,25 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
980 | 992 | ||
981 | static void send_block_data(void *data,int size) | 993 | static void send_block_data(void *data,int size) |
982 | { | 994 | { |
983 | usb_drv_send_nonblocking(usb_endpoint, data,size); | 995 | usb_drv_send_nonblocking(ep_in, data,size); |
984 | state = SENDING_BLOCKS; | 996 | state = SENDING_BLOCKS; |
985 | } | 997 | } |
986 | 998 | ||
987 | static void send_command_result(void *data,int size) | 999 | static void send_command_result(void *data,int size) |
988 | { | 1000 | { |
989 | usb_drv_send_nonblocking(usb_endpoint, data,size); | 1001 | usb_drv_send_nonblocking(ep_in, data,size); |
990 | state = SENDING_RESULT; | 1002 | state = SENDING_RESULT; |
991 | } | 1003 | } |
992 | 1004 | ||
993 | static void send_command_failed_result(void) | 1005 | static void send_command_failed_result(void) |
994 | { | 1006 | { |
995 | usb_drv_send_nonblocking(usb_endpoint, NULL, 0); | 1007 | usb_drv_send_nonblocking(ep_in, NULL, 0); |
996 | state = SENDING_FAILED_RESULT; | 1008 | state = SENDING_FAILED_RESULT; |
997 | } | 1009 | } |
998 | 1010 | ||
999 | static void receive_block_data(void *data,int size) | 1011 | static void receive_block_data(void *data,int size) |
1000 | { | 1012 | { |
1001 | usb_drv_recv(usb_endpoint, data, size); | 1013 | usb_drv_recv(ep_out, data, size); |
1002 | state = RECEIVING_BLOCKS; | 1014 | state = RECEIVING_BLOCKS; |
1003 | } | 1015 | } |
1004 | 1016 | ||
@@ -1009,7 +1021,7 @@ static void send_csw(int status) | |||
1009 | tb.csw->data_residue = 0; | 1021 | tb.csw->data_residue = 0; |
1010 | tb.csw->status = status; | 1022 | tb.csw->status = status; |
1011 | 1023 | ||
1012 | usb_drv_send_nonblocking(usb_endpoint, tb.csw, | 1024 | usb_drv_send_nonblocking(ep_in, tb.csw, |
1013 | sizeof(struct command_status_wrapper)); | 1025 | sizeof(struct command_status_wrapper)); |
1014 | state = SENDING_CSW; | 1026 | state = SENDING_CSW; |
1015 | //logf("CSW: %X",status); | 1027 | //logf("CSW: %X",status); |
diff --git a/firmware/usbstack/usb_storage.h b/firmware/usbstack/usb_storage.h index 7054d24501..4c89039bfd 100644 --- a/firmware/usbstack/usb_storage.h +++ b/firmware/usbstack/usb_storage.h | |||
@@ -23,12 +23,12 @@ | |||
23 | 23 | ||
24 | #include "usb_ch9.h" | 24 | #include "usb_ch9.h" |
25 | 25 | ||
26 | int usb_storage_set_first_endpoint(int endpoint); | 26 | int usb_storage_request_endpoints(struct usb_class_driver *); |
27 | int usb_storage_set_first_interface(int interface); | 27 | int usb_storage_set_first_interface(int interface); |
28 | int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size); | 28 | int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size); |
29 | void usb_storage_init_connection(void); | 29 | void usb_storage_init_connection(void); |
30 | void usb_storage_init(void); | 30 | void usb_storage_init(void); |
31 | void usb_storage_transfer_complete(int ep,bool in,int state,int length); | 31 | void usb_storage_transfer_complete(int ep,int dir,int state,int length); |
32 | bool usb_storage_control_request(struct usb_ctrlrequest* req); | 32 | bool usb_storage_control_request(struct usb_ctrlrequest* req); |
33 | #ifdef HAVE_HOTSWAP | 33 | #ifdef HAVE_HOTSWAP |
34 | void usb_storage_notify_hotswap(int volume,bool inserted); | 34 | void usb_storage_notify_hotswap(int volume,bool inserted); |