diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/as3525/usb-drv-as3525v2.c | 46 | ||||
-rw-r--r-- | firmware/target/arm/usb-s3c6400x.c | 104 |
2 files changed, 55 insertions, 95 deletions
diff --git a/firmware/target/arm/as3525/usb-drv-as3525v2.c b/firmware/target/arm/as3525/usb-drv-as3525v2.c index 51207d8e96..c9d687f910 100644 --- a/firmware/target/arm/as3525/usb-drv-as3525v2.c +++ b/firmware/target/arm/as3525/usb-drv-as3525v2.c | |||
@@ -39,17 +39,6 @@ | |||
39 | static const uint8_t in_ep_list[] = {0, 1, 3, 5}; | 39 | static const uint8_t in_ep_list[] = {0, 1, 3, 5}; |
40 | static const uint8_t out_ep_list[] = {0, 2, 4}; | 40 | static const uint8_t out_ep_list[] = {0, 2, 4}; |
41 | 41 | ||
42 | /* store per endpoint, per direction, information */ | ||
43 | struct ep_type | ||
44 | { | ||
45 | unsigned int size; /* length of the data buffer */ | ||
46 | struct semaphore complete; /* wait object */ | ||
47 | int8_t status; /* completion status (0 for success) */ | ||
48 | bool active; /* true is endpoint has been requested (true for EP0) */ | ||
49 | bool done; /* transfer completed */ | ||
50 | bool busy; /* true is a transfer is pending */ | ||
51 | }; | ||
52 | |||
53 | /* state of EP0 (to correctly schedule setup packet enqueing) */ | 42 | /* state of EP0 (to correctly schedule setup packet enqueing) */ |
54 | enum ep0state | 43 | enum ep0state |
55 | { | 44 | { |
@@ -423,7 +412,7 @@ void usb_drv_cancel_all_transfers() | |||
423 | cancel_all_transfers(false); | 412 | cancel_all_transfers(false); |
424 | } | 413 | } |
425 | 414 | ||
426 | static void usb_drv_transfer(int ep, void *ptr, int len, bool out) | 415 | static void ep_transfer(int ep, void *ptr, int len, bool out) |
427 | { | 416 | { |
428 | /* disable interrupts to avoid any race */ | 417 | /* disable interrupts to avoid any race */ |
429 | int oldlevel = disable_irq_save(); | 418 | int oldlevel = disable_irq_save(); |
@@ -458,51 +447,20 @@ static void usb_drv_transfer(int ep, void *ptr, int len, bool out) | |||
458 | restore_irq(oldlevel); | 447 | restore_irq(oldlevel); |
459 | } | 448 | } |
460 | 449 | ||
461 | int usb_drv_recv(int ep, void *ptr, int len) | ||
462 | { | ||
463 | usb_drv_transfer(EP_NUM(ep), ptr, len, true); | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | int usb_drv_send(int ep, void *ptr, int len) | 450 | int usb_drv_send(int ep, void *ptr, int len) |
468 | { | 451 | { |
469 | ep = EP_NUM(ep); | 452 | ep = EP_NUM(ep); |
470 | struct ep_type *endpoint = &endpoints[ep][1]; | 453 | struct ep_type *endpoint = &endpoints[ep][1]; |
471 | endpoint->done = false; | 454 | endpoint->done = false; |
472 | usb_drv_transfer(ep, ptr, len, false); | 455 | ep_transfer(ep, ptr, len, false); |
473 | while (endpoint->busy && !endpoint->done) | 456 | while (endpoint->busy && !endpoint->done) |
474 | semaphore_wait(&endpoint->complete, TIMEOUT_BLOCK); | 457 | semaphore_wait(&endpoint->complete, TIMEOUT_BLOCK); |
475 | return endpoint->status; | 458 | return endpoint->status; |
476 | } | 459 | } |
477 | 460 | ||
478 | int usb_drv_send_nonblocking(int ep, void *ptr, int len) | ||
479 | { | ||
480 | usb_drv_transfer(EP_NUM(ep), ptr, len, false); | ||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | |||
485 | void usb_drv_set_test_mode(int mode) | 461 | void usb_drv_set_test_mode(int mode) |
486 | { | 462 | { |
487 | /* there is a perfect matching between usb test mode code | 463 | /* there is a perfect matching between usb test mode code |
488 | * and the register field value */ | 464 | * and the register field value */ |
489 | DCTL = (DCTL & ~bitm(DCTL, tstctl)) | (mode << DCTL_tstctl_bitp); | 465 | DCTL = (DCTL & ~bitm(DCTL, tstctl)) | (mode << DCTL_tstctl_bitp); |
490 | } | 466 | } |
491 | |||
492 | void usb_drv_set_address(int address) | ||
493 | { | ||
494 | (void) address; | ||
495 | } | ||
496 | |||
497 | void usb_drv_stall(int ep, bool stall, bool in) | ||
498 | { | ||
499 | if (stall) | ||
500 | DEPCTL(ep, !in) |= DEPCTL_stall; | ||
501 | else | ||
502 | DEPCTL(ep, !in) &= ~DEPCTL_stall; | ||
503 | } | ||
504 | |||
505 | bool usb_drv_stalled(int ep, bool in) | ||
506 | { | ||
507 | return DEPCTL(ep, !in) & DEPCTL_stall; | ||
508 | } | ||
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c index 48eca85c8c..26db55ee67 100644 --- a/firmware/target/arm/usb-s3c6400x.c +++ b/firmware/target/arm/usb-s3c6400x.c | |||
@@ -35,20 +35,56 @@ | |||
35 | #include <inttypes.h> | 35 | #include <inttypes.h> |
36 | #include "power.h" | 36 | #include "power.h" |
37 | 37 | ||
38 | /* store per endpoint, per direction, information */ | ||
39 | struct ep_type | ||
40 | { | ||
41 | unsigned int size; /* length of the data buffer */ | ||
42 | struct semaphore complete; /* wait object */ | ||
43 | int8_t status; /* completion status (0 for success) */ | ||
44 | bool active; /* true is endpoint has been requested (true for EP0) */ | ||
45 | bool done; /* transfer completed */ | ||
46 | bool busy; /* true is a transfer is pending */ | ||
47 | }; | ||
48 | |||
49 | bool usb_drv_stalled(int endpoint, bool in) | ||
50 | { | ||
51 | return DEPCTL(endpoint, !in) & DEPCTL_stall; | ||
52 | } | ||
53 | |||
54 | void usb_drv_stall(int endpoint, bool stall, bool in) | ||
55 | { | ||
56 | if (stall) | ||
57 | DEPCTL(endpoint, !in) |= DEPCTL_stall; | ||
58 | else | ||
59 | DEPCTL(endpoint, !in) &= ~DEPCTL_stall; | ||
60 | } | ||
61 | |||
62 | void usb_drv_set_address(int address) | ||
63 | { | ||
64 | (void)address; | ||
65 | /* Ignored intentionally, because the controller requires us to set the | ||
66 | new address before sending the response for some reason. So we'll | ||
67 | already set it when the control request arrives, before passing that | ||
68 | into the USB core, which will then call this dummy function. */ | ||
69 | } | ||
70 | |||
71 | static void ep_transfer(int ep, void *ptr, int length, bool out); | ||
72 | int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) | ||
73 | { | ||
74 | ep_transfer(EP_NUM(endpoint), ptr, length, false); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | int usb_drv_recv(int endpoint, void* ptr, int length) | ||
79 | { | ||
80 | ep_transfer(EP_NUM(endpoint), ptr, length, true); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
38 | #if CONFIG_CPU == AS3525v2 /* FIXME FIXME FIXME */ | 84 | #if CONFIG_CPU == AS3525v2 /* FIXME FIXME FIXME */ |
39 | # include "as3525/usb-drv-as3525v2.c" | 85 | # include "as3525/usb-drv-as3525v2.c" |
40 | #else | 86 | #else |
41 | 87 | ||
42 | struct ep_type | ||
43 | { | ||
44 | bool active; | ||
45 | bool busy; | ||
46 | bool done; | ||
47 | int rc; | ||
48 | int size; | ||
49 | struct semaphore complete; | ||
50 | } ; | ||
51 | |||
52 | static struct ep_type endpoints[USB_NUM_ENDPOINTS]; | 88 | static struct ep_type endpoints[USB_NUM_ENDPOINTS]; |
53 | 89 | ||
54 | /* USB control requests may be up to 64 bytes in size. | 90 | /* USB control requests may be up to 64 bytes in size. |
@@ -58,10 +94,10 @@ static struct ep_type endpoints[USB_NUM_ENDPOINTS]; | |||
58 | e.g. write descriptor requests (which are rejected by us, but the | 94 | e.g. write descriptor requests (which are rejected by us, but the |
59 | payload is transferred anyway) do not cause memory corruption. | 95 | payload is transferred anyway) do not cause memory corruption. |
60 | Fixes FS#12310. -- Michael Sparmann (theseven) */ | 96 | Fixes FS#12310. -- Michael Sparmann (theseven) */ |
61 | static struct | 97 | static union |
62 | { | 98 | { |
63 | struct usb_ctrlrequest header; /* 8 bytes */ | 99 | struct usb_ctrlrequest header; /* 8 bytes */ |
64 | unsigned char payload[64 - sizeof(struct usb_ctrlrequest)]; | 100 | unsigned char payload[64]; |
65 | } ctrlreq USB_DEVBSS_ATTR; | 101 | } ctrlreq USB_DEVBSS_ATTR; |
66 | 102 | ||
67 | int usb_drv_port_speed(void) | 103 | int usb_drv_port_speed(void) |
@@ -76,7 +112,7 @@ static void reset_endpoints(int reinit) | |||
76 | { | 112 | { |
77 | if (reinit) endpoints[i].active = false; | 113 | if (reinit) endpoints[i].active = false; |
78 | endpoints[i].busy = false; | 114 | endpoints[i].busy = false; |
79 | endpoints[i].rc = -1; | 115 | endpoints[i].status = -1; |
80 | endpoints[i].done = true; | 116 | endpoints[i].done = true; |
81 | semaphore_release(&endpoints[i].complete); | 117 | semaphore_release(&endpoints[i].complete); |
82 | } | 118 | } |
@@ -184,7 +220,7 @@ static void handle_ep_int(bool out) | |||
184 | if (endpoints[ep].busy) | 220 | if (endpoints[ep].busy) |
185 | { | 221 | { |
186 | endpoints[ep].busy = false; | 222 | endpoints[ep].busy = false; |
187 | endpoints[ep].rc = 0; | 223 | endpoints[ep].status = 0; |
188 | endpoints[ep].done = true; | 224 | endpoints[ep].done = true; |
189 | usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, bytes); | 225 | usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, bytes); |
190 | semaphore_release(&endpoints[ep].complete); | 226 | semaphore_release(&endpoints[ep].complete); |
@@ -199,7 +235,7 @@ static void handle_ep_int(bool out) | |||
199 | if (endpoints[ep].busy) | 235 | if (endpoints[ep].busy) |
200 | { | 236 | { |
201 | endpoints[ep].busy = false; | 237 | endpoints[ep].busy = false; |
202 | endpoints[ep].rc = 1; | 238 | endpoints[ep].status = 1; |
203 | endpoints[ep].done = true; | 239 | endpoints[ep].done = true; |
204 | semaphore_release(&endpoints[ep].complete); | 240 | semaphore_release(&endpoints[ep].complete); |
205 | } | 241 | } |
@@ -261,16 +297,7 @@ void INT_USB_FUNC(void) | |||
261 | GINTSTS = ints; | 297 | GINTSTS = ints; |
262 | } | 298 | } |
263 | 299 | ||
264 | void usb_drv_set_address(int address) | 300 | static void ep_transfer(int ep, void *ptr, int length, bool out) |
265 | { | ||
266 | (void)address; | ||
267 | /* Ignored intentionally, because the controller requires us to set the | ||
268 | new address before sending the response for some reason. So we'll | ||
269 | already set it when the control request arrives, before passing that | ||
270 | into the USB core, which will then call this dummy function. */ | ||
271 | } | ||
272 | |||
273 | static void ep_transfer(int ep, void *ptr, int length, int out) | ||
274 | { | 301 | { |
275 | endpoints[ep].busy = true; | 302 | endpoints[ep].busy = true; |
276 | endpoints[ep].size = length; | 303 | endpoints[ep].size = length; |
@@ -294,19 +321,7 @@ int usb_drv_send(int endpoint, void *ptr, int length) | |||
294 | ep_transfer(endpoint, ptr, length, false); | 321 | ep_transfer(endpoint, ptr, length, false); |
295 | while (!endpoints[endpoint].done && endpoints[endpoint].busy) | 322 | while (!endpoints[endpoint].done && endpoints[endpoint].busy) |
296 | semaphore_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK); | 323 | semaphore_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK); |
297 | return endpoints[endpoint].rc; | 324 | return endpoints[endpoint].status; |
298 | } | ||
299 | |||
300 | int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) | ||
301 | { | ||
302 | ep_transfer(EP_NUM(endpoint), ptr, length, false); | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | int usb_drv_recv(int endpoint, void* ptr, int length) | ||
307 | { | ||
308 | ep_transfer(EP_NUM(endpoint), ptr, length, true); | ||
309 | return 0; | ||
310 | } | 325 | } |
311 | 326 | ||
312 | void usb_drv_cancel_all_transfers(void) | 327 | void usb_drv_cancel_all_transfers(void) |
@@ -321,19 +336,6 @@ void usb_drv_set_test_mode(int mode) | |||
321 | (void)mode; | 336 | (void)mode; |
322 | } | 337 | } |
323 | 338 | ||
324 | bool usb_drv_stalled(int endpoint, bool in) | ||
325 | { | ||
326 | return DEPCTL(endpoint, !in) & DEPCTL_stall; | ||
327 | } | ||
328 | |||
329 | void usb_drv_stall(int endpoint, bool stall, bool in) | ||
330 | { | ||
331 | if (stall) | ||
332 | DEPCTL(endpoint, !in) |= DEPCTL_stall; | ||
333 | else | ||
334 | DEPCTL(endpoint, !in) &= ~DEPCTL_stall; | ||
335 | } | ||
336 | |||
337 | void usb_drv_init(void) | 339 | void usb_drv_init(void) |
338 | { | 340 | { |
339 | for (unsigned i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++) | 341 | for (unsigned i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++) |