summaryrefslogtreecommitdiff
path: root/firmware/target/mips
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4760.c376
1 files changed, 292 insertions, 84 deletions
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}