summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/CREDITS1
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4760.c376
2 files changed, 293 insertions, 84 deletions
diff --git a/docs/CREDITS b/docs/CREDITS
index 7743ba0af8..03ba132b39 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -666,6 +666,7 @@ Alessandro Stoppani
666Alexander Yurenin 666Alexander Yurenin
667Roman Stolyarov 667Roman Stolyarov
668Solomon Peachy 668Solomon Peachy
669Igor Poretsky
669 670
670The libmad team 671The libmad team
671The wavpack team 672The wavpack team
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
index bc2158fb6f..3c7bb80f2c 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
@@ -53,14 +53,14 @@ enum ep_type
53 53
54struct usb_endpoint 54struct usb_endpoint
55{ 55{
56 void *buf; 56 volatile void *buf;
57 size_t length; 57 volatile size_t length;
58 union 58 union
59 { 59 {
60 size_t sent; 60 volatile size_t sent;
61 size_t received; 61 volatile size_t received;
62 }; 62 };
63 bool busy; 63 volatile bool busy;
64 64
65 const enum ep_type type; 65 const enum ep_type type;
66 const bool use_dma; 66 const bool use_dma;
@@ -68,23 +68,35 @@ struct usb_endpoint
68 const long fifo_addr; 68 const long fifo_addr;
69 unsigned short fifo_size; 69 unsigned short fifo_size;
70 70
71 bool wait; 71 volatile bool wait;
72 struct semaphore complete; 72 struct semaphore complete;
73
74 volatile int rc;
75 bool allocated;
73}; 76};
74 77
75#define EP_INIT(_type, _fifo_addr, _fifo_size, _buf, _use_dma) \ 78#define EP_INIT(_type, _fifo_addr, _fifo_size, _buf, _use_dma) \
76 { .type = (_type), .fifo_addr = (_fifo_addr), .fifo_size = (_fifo_size), \ 79 { .type = (_type), .fifo_addr = (_fifo_addr), .fifo_size = (_fifo_size), \
77 .buf = (_buf), .use_dma = (_use_dma), .length = 0, .busy = false, .wait = false } 80 .buf = (_buf), .use_dma = (_use_dma), \
81 .length = 0, .busy = false, .wait = false, .allocated = false }
82
83static union
84{
85 int buf[64 / sizeof(int)];
86 struct usb_ctrlrequest request;
87} ep0_rx;
88
89static volatile bool ep0_data_supplied = false;
90static volatile bool ep0_data_requested = false;
78 91
79static unsigned char ep0_rx_buf[64];
80static struct usb_endpoint endpoints[] = 92static struct usb_endpoint endpoints[] =
81{ 93{
82 EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL, false), 94 EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL, false),
83 EP_INIT(ep_control, USB_FIFO_EP(0), 64, &ep0_rx_buf, false), 95 EP_INIT(ep_control, USB_FIFO_EP(0), 64, &ep0_rx.buf, false),
84 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false), 96 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false),
85 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false), 97 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false),
86 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 64, NULL, false), 98 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL, false),
87 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 64, NULL, false), 99 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL, false),
88}; 100};
89 101
90static inline void select_endpoint(int ep) 102static inline void select_endpoint(int ep)
@@ -133,16 +145,32 @@ static void writeFIFO(struct usb_endpoint *ep, size_t size)
133 logf("%s(EP%d, %d)", __func__, EP_NUMBER2(ep), size); 145 logf("%s(EP%d, %d)", __func__, EP_NUMBER2(ep), size);
134 146
135 register unsigned int *d32 = (unsigned int *)EP_PTR(ep); 147 register unsigned int *d32 = (unsigned int *)EP_PTR(ep);
148 register unsigned char *d8 = (unsigned char *)d32;
136 register size_t s = size >> 2; 149 register size_t s = size >> 2;
150 register unsigned int x;
137 151
138 if(size > 0) 152 if(size > 0)
139 { 153 {
140 while (s--) 154 if( ((unsigned int)d8 & 3) == 0 )
141 REG32(ep->fifo_addr) = *d32++; 155 {
156 while (s--)
157 REG32(ep->fifo_addr) = *d32++;
158 d8 = (unsigned char *)d32;
159 }
160 else
161 {
162 while (s--)
163 {
164 x = (unsigned int)(*d8++) & 0xff;
165 x |= ((unsigned int)(*d8++) & 0xff) << 8;
166 x |= ((unsigned int)(*d8++) & 0xff) << 16;
167 x |= ((unsigned int)(*d8++) & 0xff) << 24;
168 REG32(ep->fifo_addr) = x;
169 }
170 }
142 171
143 if( (s = size & 3) ) 172 if( (s = size & 3) )
144 { 173 {
145 register unsigned char *d8 = (unsigned char *)d32;
146 while (s--) 174 while (s--)
147 REG8(ep->fifo_addr) = *d8++; 175 REG8(ep->fifo_addr) = *d8++;
148 } 176 }
@@ -183,13 +211,16 @@ static void EP0_send(void)
183{ 211{
184 struct usb_endpoint* ep = &endpoints[0]; 212 struct usb_endpoint* ep = &endpoints[0];
185 unsigned int length; 213 unsigned int length;
186 unsigned char csr0; 214 unsigned short csr0;
187 215
188 select_endpoint(0); 216 select_endpoint(0);
189 csr0 = REG_USB_CSR0; 217 csr0 = REG_USB_CSR0;
190 218
191 if(ep->sent == 0) 219 if(ep->sent == 0)
220 {
192 length = MIN(ep->length, ep->fifo_size); 221 length = MIN(ep->length, ep->fifo_size);
222 REG_USB_CSR0 = (csr0 | USB_CSR0_FLUSHFIFO);
223 }
193 else 224 else
194 length = MIN(EP_BUF_LEFT(ep), ep->fifo_size); 225 length = MIN(EP_BUF_LEFT(ep), ep->fifo_size);
195 226
@@ -199,7 +230,9 @@ static void EP0_send(void)
199 if(ep->sent >= ep->length) 230 if(ep->sent >= ep->length)
200 { 231 {
201 REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ 232 REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */
202 usb_core_transfer_complete(0, USB_DIR_IN, 0, ep->sent); 233 if (!ep->wait)
234 usb_core_transfer_complete(0, USB_DIR_IN, 0, ep->sent);
235 ep->rc = 0;
203 ep_transfer_completed(ep); 236 ep_transfer_completed(ep);
204 } 237 }
205 else 238 else
@@ -208,9 +241,7 @@ static void EP0_send(void)
208 241
209static void EP0_handler(void) 242static void EP0_handler(void)
210{ 243{
211 logf("%s()", __func__); 244 unsigned short csr0;
212
213 unsigned char csr0;
214 struct usb_endpoint *ep_send = &endpoints[0]; 245 struct usb_endpoint *ep_send = &endpoints[0];
215 struct usb_endpoint *ep_recv = &endpoints[1]; 246 struct usb_endpoint *ep_recv = &endpoints[1];
216 247
@@ -218,6 +249,8 @@ static void EP0_handler(void)
218 select_endpoint(0); 249 select_endpoint(0);
219 csr0 = REG_USB_CSR0; 250 csr0 = REG_USB_CSR0;
220 251
252 logf("%s(): 0x%x", __func__, csr0);
253
221 /* Check for SentStall: 254 /* Check for SentStall:
222 This bit is set when a STALL handshake is transmitted. The CPU should clear this bit. 255 This bit is set when a STALL handshake is transmitted. The CPU should clear this bit.
223 */ 256 */
@@ -234,19 +267,66 @@ static void EP0_handler(void)
234 */ 267 */
235 if(csr0 & USB_CSR0_SETUPEND) 268 if(csr0 & USB_CSR0_SETUPEND)
236 { 269 {
237 REG_USB_CSR0 = csr0 | USB_CSR0_SVDSETUPEND; 270 csr0 |= USB_CSR0_SVDSETUPEND;
238 return; 271 REG_USB_CSR0 = csr0;
272 ep0_data_supplied = false;
273 ep0_data_requested = false;
274 if (ep_send->busy)
275 {
276 if (!ep_send->wait)
277 usb_core_transfer_complete(0, USB_DIR_IN, -1, 0);
278 ep_transfer_completed(ep_send);
279 }
280 if (ep_recv->busy)
281 {
282 usb_core_transfer_complete(0, USB_DIR_OUT, -1, 0);
283 ep_transfer_completed(ep_recv);
284 }
239 } 285 }
240 286
241 /* Call relevant routines for endpoint 0 state */ 287 /* Call relevant routines for endpoint 0 state */
242 if(ep_send->busy) 288 if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */
243 EP0_send();
244 else if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */
245 { 289 {
246 readFIFO(ep_recv, REG_USB_COUNT0); 290 if (ep_send->busy)
247 REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ 291 {
248 usb_core_control_request((struct usb_ctrlrequest*)ep_recv->buf); 292 if (!ep_send->wait)
293 usb_core_transfer_complete(0, USB_DIR_IN, -1, 0);
294 ep_transfer_completed(ep_send);
295 }
296 if (ep_recv->busy && ep_recv->buf && ep_recv->length)
297 {
298 unsigned int size = REG_USB_COUNT0;
299 readFIFO(ep_recv, size);
300 ep_recv->received += size;
301 if (size < ep_recv->fifo_size || ep_recv->received >= ep_recv->length)
302 {
303 REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND; /* Set data end! */
304 usb_core_transfer_complete(0, USB_DIR_OUT, 0, ep_recv->received);
305 ep_transfer_completed(ep_recv);
306 }
307 else REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */
308 }
309 else if (!ep0_data_supplied)
310 {
311 ep_recv->buf = ep0_rx.buf;
312 readFIFO(ep_recv, REG_USB_COUNT0);
313 csr0 |= USB_CSR0_SVDOUTPKTRDY;
314 if (!ep0_rx.request.wLength)
315 {
316 csr0 |= USB_CSR0_DATAEND; /* Set data end! */
317 ep0_data_requested = false;
318 ep0_data_supplied = false;
319 }
320 else if (ep0_rx.request.bRequestType & USB_DIR_IN)
321 ep0_data_requested = true;
322 else ep0_data_supplied = true;
323 REG_USB_CSR0 = csr0;
324 usb_core_control_request(&ep0_rx.request);
325 ep_transfer_completed(ep_recv);
326 }
249 } 327 }
328 else if (ep_send->busy)
329 EP0_send();
250} 330}
251 331
252static void EPIN_handler(unsigned int endpoint) 332static void EPIN_handler(unsigned int endpoint)
@@ -292,7 +372,9 @@ static void EPIN_handler(unsigned int endpoint)
292 372
293 if(ep->sent >= ep->length) 373 if(ep->sent >= ep->length)
294 { 374 {
295 usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); 375 if (!ep->wait)
376 usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent);
377 ep->rc = 0;
296 ep_transfer_completed(ep); 378 ep_transfer_completed(ep);
297 logf("sent complete"); 379 logf("sent complete");
298 } 380 }
@@ -352,20 +434,23 @@ static void EPDMA_handler(int number)
352{ 434{
353 int endpoint = -1; 435 int endpoint = -1;
354 unsigned int size = 0; 436 unsigned int size = 0;
437 struct usb_endpoint* ep = NULL;
355 438
356 if(number == USB_INTR_DMA_BULKIN) 439 if(number == USB_INTR_DMA_BULKIN)
440 {
357 endpoint = (REG_USB_CNTL(0) >> 4) & 0xF; 441 endpoint = (REG_USB_CNTL(0) >> 4) & 0xF;
442 ep = &endpoints[endpoint*2];
443 size = (unsigned int)ep->buf - REG_USB_ADDR(0);
444 }
358 else if(number == USB_INTR_DMA_BULKOUT) 445 else if(number == USB_INTR_DMA_BULKOUT)
446 {
359 endpoint = (REG_USB_CNTL(1) >> 4) & 0xF; 447 endpoint = (REG_USB_CNTL(1) >> 4) & 0xF;
448 ep = &endpoints[endpoint*2+1];
449 size = (unsigned int)ep->buf - REG_USB_ADDR(1);
450 }
360 451
361 struct usb_endpoint* ep = &endpoints[endpoint];
362 logf("DMA_BULK%d %d", number, endpoint); 452 logf("DMA_BULK%d %d", number, endpoint);
363 453
364 if(number == USB_INTR_DMA_BULKIN)
365 size = (unsigned int)ep->buf - REG_USB_ADDR(0);
366 else if(number == USB_INTR_DMA_BULKOUT)
367 size = (unsigned int)ep->buf - REG_USB_ADDR(1);
368
369 if(number == USB_INTR_DMA_BULKOUT) 454 if(number == USB_INTR_DMA_BULKOUT)
370 { 455 {
371 /* Disable DMA */ 456 /* Disable DMA */
@@ -389,29 +474,41 @@ static void EPDMA_handler(int number)
389 REG_USB_INCSR |= USB_INCSR_INPKTRDY; 474 REG_USB_INCSR |= USB_INCSR_INPKTRDY;
390 } 475 }
391 476
392 usb_core_transfer_complete(endpoint, EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT, 477 if (ep)
393 0, ep->length); 478 {
394 ep_transfer_completed(ep); 479 int dir = EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT;
480 if ((dir == USB_DIR_OUT) || !ep->wait)
481 usb_core_transfer_complete(endpoint, dir, 0, ep->length);
482 ep->rc = 0;
483 ep_transfer_completed(ep);
484 }
395} 485}
396 486
397static void setup_endpoint(struct usb_endpoint *ep) 487static void setup_endpoint(struct usb_endpoint *ep)
398{ 488{
399 int csr, csrh; 489 int endpoint = EP_NUMBER2(ep);
490 unsigned char csr, csrh;
491
492 select_endpoint(endpoint);
400 493
401 select_endpoint(EP_NUMBER2(ep)); 494 if (ep->busy)
495 {
496 if(EP_IS_IN(ep))
497 {
498 if (ep->wait)
499 semaphore_release(&ep->complete);
500 else usb_core_transfer_complete(endpoint, USB_DIR_IN, -1, 0);
501 }
502 else usb_core_transfer_complete(endpoint, USB_DIR_OUT, -1, 0);
503 }
402 504
403 ep->busy = false; 505 ep->busy = false;
404 ep->wait = false; 506 ep->wait = false;
405 ep->sent = 0; 507 ep->sent = 0;
406 ep->length = 0; 508 ep->length = 0;
407 509
408 if(ep->type == ep_bulk) 510 if(ep->type != ep_control)
409 { 511 ep->fifo_size = usb_drv_port_speed() ? 512 : 64;
410 if(REG_USB_POWER & USB_POWER_HSMODE)
411 ep->fifo_size = 512;
412 else
413 ep->fifo_size = 64;
414 }
415 512
416 if(EP_IS_IN(ep)) 513 if(EP_IS_IN(ep))
417 { 514 {
@@ -427,7 +524,9 @@ static void setup_endpoint(struct usb_endpoint *ep)
427 REG_USB_INMAXP = ep->fifo_size; 524 REG_USB_INMAXP = ep->fifo_size;
428 REG_USB_INCSR = csr; 525 REG_USB_INCSR = csr;
429 REG_USB_INCSRH = csrh; 526 REG_USB_INCSRH = csrh;
430 REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); 527
528 if (ep->allocated)
529 REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep));
431 } 530 }
432 else 531 else
433 { 532 {
@@ -443,7 +542,9 @@ static void setup_endpoint(struct usb_endpoint *ep)
443 REG_USB_OUTMAXP = ep->fifo_size; 542 REG_USB_OUTMAXP = ep->fifo_size;
444 REG_USB_OUTCSR = csr; 543 REG_USB_OUTCSR = csr;
445 REG_USB_OUTCSRH = csrh; 544 REG_USB_OUTCSRH = csrh;
446 REG_USB_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); 545
546 if (ep->allocated)
547 REG_USB_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep));
447 } 548 }
448} 549}
449 550
@@ -483,10 +584,35 @@ static void udc_reset(void)
483 select_endpoint(0); 584 select_endpoint(0);
484 REG_USB_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND | USB_CSR0_FLUSHFIFO); 585 REG_USB_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND | USB_CSR0_FLUSHFIFO);
485 586
587 if (endpoints[0].busy)
588 {
589 if (endpoints[0].wait)
590 semaphore_release(&endpoints[0].complete);
591 else usb_core_transfer_complete(0, USB_DIR_IN, -1, 0);
592 }
593
594 endpoints[0].busy = false;
595 endpoints[0].wait = false;
596 endpoints[0].sent = 0;
597 endpoints[0].length = 0;
598 endpoints[0].allocated = true;
599
600 if (endpoints[1].busy)
601 usb_core_transfer_complete(0, USB_DIR_OUT, -1, 0);
602
603 endpoints[1].busy = false;
604 endpoints[1].wait = false;
605 endpoints[1].received = 0;
606 endpoints[1].length = 0;
607 endpoints[1].allocated = true;
608
486 /* Reset other endpoints */ 609 /* Reset other endpoints */
487 for(i=2; i<TOTAL_EP(); i++) 610 for(i=2; i<TOTAL_EP(); i++)
488 setup_endpoint(&endpoints[i]); 611 setup_endpoint(&endpoints[i]);
489 612
613 ep0_data_supplied = false;
614 ep0_data_requested = false;
615
490 /* Enable interrupts */ 616 /* Enable interrupts */
491 REG_USB_INTRINE |= USB_INTR_EP(0); 617 REG_USB_INTRINE |= USB_INTR_EP(0);
492 REG_USB_INTRUSBE |= USB_INTR_RESET; 618 REG_USB_INTRUSBE |= USB_INTR_RESET;
@@ -498,7 +624,7 @@ static void udc_reset(void)
498void OTG(void) 624void OTG(void)
499{ 625{
500 /* Read interrupt registers */ 626 /* Read interrupt registers */
501 unsigned char intrUSB = REG_USB_INTRUSB & 0x07; /* Mask SOF */ 627 unsigned char intrUSB = REG_USB_INTRUSB;
502 unsigned short intrIn = REG_USB_INTRIN; 628 unsigned short intrIn = REG_USB_INTRIN;
503 unsigned short intrOut = REG_USB_INTROUT; 629 unsigned short intrOut = REG_USB_INTROUT;
504 unsigned char intrDMA = REG_USB_INTR; 630 unsigned char intrDMA = REG_USB_INTR;
@@ -689,17 +815,28 @@ void usb_drv_set_address(int address)
689 815
690static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length, bool blocking) 816static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length, bool blocking)
691{ 817{
692 if(ep->type == ep_control && ptr == NULL && length == 0)
693 return; /* ACK request, handled in the ISR */
694
695 int flags = disable_irq_save(); 818 int flags = disable_irq_save();
696 819
820 if(ep->type == ep_control)
821 {
822 if ((ptr == NULL && length == 0) || !ep0_data_requested)
823 {
824 restore_irq(flags);
825 return;
826 }
827 ep0_data_requested = false;
828 }
829
697 ep->buf = ptr; 830 ep->buf = ptr;
698 ep->sent = 0; 831 ep->sent = 0;
699 ep->length = length; 832 ep->length = length;
700 ep->busy = true; 833 ep->busy = true;
701 if(blocking) 834 if(blocking)
835 {
836 ep->rc = -1;
702 ep->wait = true; 837 ep->wait = true;
838 }
839 else ep->rc = 0;
703 840
704 if(ep->type == ep_control) 841 if(ep->type == ep_control)
705 { 842 {
@@ -725,27 +862,39 @@ static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length
725 862
726 if(blocking) 863 if(blocking)
727 { 864 {
728 semaphore_wait(&ep->complete, TIMEOUT_BLOCK); 865 semaphore_wait(&ep->complete, HZ);
729 ep->wait = false; 866 ep->wait = false;
730 } 867 }
731} 868}
732 869
733int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) 870int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
734{ 871{
872 struct usb_endpoint *ep = &endpoints[(endpoint & 0x7F)*2];
873
735 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); 874 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
736 875
737 usb_drv_send_internal(&endpoints[(endpoint & 0x7F)*2], ptr, length, false); 876 if (ep->allocated)
877 {
878 usb_drv_send_internal(ep, ptr, length, false);
879 return 0;
880 }
738 881
739 return 0; 882 return -1;
740} 883}
741 884
742int usb_drv_send(int endpoint, void* ptr, int length) 885int usb_drv_send(int endpoint, void* ptr, int length)
743{ 886{
887 struct usb_endpoint *ep = &endpoints[(endpoint & 0x7F)*2];
888
744 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); 889 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
745 890
746 usb_drv_send_internal(&endpoints[(endpoint & 0x7F)*2], ptr, length, true); 891 if (ep->allocated)
892 {
893 usb_drv_send_internal(ep, ptr, length, true);
894 return ep->rc;
895 }
747 896
748 return 0; 897 return -1;
749} 898}
750 899
751int usb_drv_recv(int endpoint, void* ptr, int length) 900int usb_drv_recv(int endpoint, void* ptr, int length)
@@ -756,33 +905,42 @@ int usb_drv_recv(int endpoint, void* ptr, int length)
756 905
757 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); 906 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
758 907
759 if(endpoint == EP_CONTROL) 908 if (ptr == NULL || length == 0)
760 return 0; /* all EP0 OUT transactions are handled within the ISR */ 909 return 0;
910
911 ep = &endpoints[endpoint*2+1];
912
913 if (!ep->allocated)
914 return -1;
915
916 flags = disable_irq_save();
917
918 ep->buf = ptr;
919 ep->received = 0;
920 ep->length = length;
921 ep->busy = true;
922 if(ep->use_dma)
923 {
924 //dma_cache_wback_inv((unsigned long)ptr, length);
925 __dcache_writeback_all();
926 REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr);
927 REG_USB_COUNT(1) = length;
928 REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
929 USB_CNTL_ENA | USB_CNTL_EP(endpoint) |
930 USB_CNTL_BURST_16);
931 }
761 else 932 else
762 { 933 {
763 flags = disable_irq_save(); 934 if (endpoint == EP_CONTROL)
764 ep = &endpoints[endpoint*2+1];
765
766 ep->buf = ptr;
767 ep->received = 0;
768 ep->length = length;
769 ep->busy = true;
770 if(ep->use_dma)
771 { 935 {
772 //dma_cache_wback_inv((unsigned long)ptr, length); 936 ep0_data_supplied = false;
773 __dcache_writeback_all(); 937 EP0_handler();
774 REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr);
775 REG_USB_COUNT(1) = length;
776 REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
777 USB_CNTL_ENA | USB_CNTL_EP(endpoint) |
778 USB_CNTL_BURST_16);
779 } 938 }
780 else 939 else EPOUT_handler(endpoint);
781 EPOUT_handler(endpoint);
782
783 restore_irq(flags);
784 return 0;
785 } 940 }
941
942 restore_irq(flags);
943 return 0;
786} 944}
787 945
788void usb_drv_set_test_mode(int mode) 946void usb_drv_set_test_mode(int mode)
@@ -818,11 +976,19 @@ void usb_drv_cancel_all_transfers(void)
818{ 976{
819 logf("%s()", __func__); 977 logf("%s()", __func__);
820 978
821 unsigned int i, flags; 979 unsigned int i, flags = disable_irq_save();
822 flags = disable_irq_save();
823 980
824 for(i=0; i<TOTAL_EP(); i++) 981 for(i=0; i<TOTAL_EP(); i++)
825 { 982 {
983 if (endpoints[i].busy)
984 {
985 if (i & 1)
986 usb_core_transfer_complete(i >> 1, USB_DIR_OUT, -1, 0);
987 else if (endpoints[i].wait)
988 semaphore_release(&endpoints[i].complete);
989 else usb_core_transfer_complete(i >> 1, USB_DIR_IN, -1, 0);
990 }
991
826 if(i != 1) /* ep0 out needs special handling */ 992 if(i != 1) /* ep0 out needs special handling */
827 endpoints[i].buf = NULL; 993 endpoints[i].buf = NULL;
828 994
@@ -835,11 +1001,27 @@ void usb_drv_cancel_all_transfers(void)
835 restore_irq(flags); 1001 restore_irq(flags);
836} 1002}
837 1003
838
839void usb_drv_release_endpoint(int ep) 1004void usb_drv_release_endpoint(int ep)
840{ 1005{
841 (void)ep; 1006 int n = ep & 0x7f;
1007
842 logf("%s(%d, %s)", __func__, (ep & 0x7F), (ep >> 7) ? "IN" : "OUT"); 1008 logf("%s(%d, %s)", __func__, (ep & 0x7F), (ep >> 7) ? "IN" : "OUT");
1009
1010 if (n)
1011 {
1012 int dir = ep & USB_ENDPOINT_DIR_MASK;
1013
1014 if(dir == USB_DIR_IN)
1015 {
1016 REG_USB_INTRINE &= ~USB_INTR_EP(n);
1017 endpoints[n << 1].allocated = false;
1018 }
1019 else
1020 {
1021 REG_USB_INTROUTE &= ~USB_INTR_EP(n);
1022 endpoints[(n << 1) + 1].allocated = false;
1023 }
1024 }
843} 1025}
844 1026
845int usb_drv_request_endpoint(int type, int dir) 1027int usb_drv_request_endpoint(int type, int dir)
@@ -854,17 +1036,43 @@ int usb_drv_request_endpoint(int type, int dir)
854 { 1036 {
855 case USB_ENDPOINT_XFER_BULK: 1037 case USB_ENDPOINT_XFER_BULK:
856 if(dir == USB_DIR_IN) 1038 if(dir == USB_DIR_IN)
1039 {
1040 if (endpoints[2].allocated)
1041 break;
1042 endpoints[2].allocated = true;
1043 REG_USB_INTRINE |= USB_INTR_EP(1);
857 return (1 | USB_DIR_IN); 1044 return (1 | USB_DIR_IN);
1045 }
858 else 1046 else
1047 {
1048 if (endpoints[3].allocated)
1049 break;
1050 endpoints[3].allocated = true;
1051 REG_USB_INTROUTE |= USB_INTR_EP(1);
859 return (1 | USB_DIR_OUT); 1052 return (1 | USB_DIR_OUT);
1053 }
860 1054
861 case USB_ENDPOINT_XFER_INT: 1055 case USB_ENDPOINT_XFER_INT:
862 if(dir == USB_DIR_IN) 1056 if(dir == USB_DIR_IN)
1057 {
1058 if (endpoints[4].allocated)
1059 break;
1060 endpoints[4].allocated = true;
1061 REG_USB_INTRINE |= USB_INTR_EP(2);
863 return (2 | USB_DIR_IN); 1062 return (2 | USB_DIR_IN);
1063 }
864 else 1064 else
1065 {
1066 if (endpoints[5].allocated)
1067 break;
1068 endpoints[5].allocated = true;
1069 REG_USB_INTROUTE |= USB_INTR_EP(2);
865 return (2 | USB_DIR_OUT); 1070 return (2 | USB_DIR_OUT);
1071 }
866 1072
867 default: 1073 default:
868 return -1; 1074 break;
869 } 1075 }
1076
1077 return -1;
870} 1078}