summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/usb-s3c6400x.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c
index 71bd127dab..7bcfcedc89 100644
--- a/firmware/target/arm/usb-s3c6400x.c
+++ b/firmware/target/arm/usb-s3c6400x.c
@@ -515,7 +515,7 @@ int usb_drv_send(int ep, void *ptr, int len)
515} 515}
516#else 516#else
517 517
518static struct ep_type endpoints[USB_NUM_ENDPOINTS]; 518static struct ep_type endpoints[USB_NUM_ENDPOINTS][2];
519 519
520/* USB control requests may be up to 64 bytes in size. 520/* USB control requests may be up to 64 bytes in size.
521 Even though we never use anything more than the 8 header bytes, 521 Even though we never use anything more than the 8 header bytes,
@@ -535,15 +535,15 @@ static volatile bool plugged = false;
535 535
536static void reset_endpoints(int reinit) 536static void reset_endpoints(int reinit)
537{ 537{
538 unsigned int i; 538 for (unsigned i = 0; i < sizeof(endpoints)/(2*sizeof(struct ep_type)); i++)
539 for (i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++) 539 for (unsigned dir = 0; dir < 2; dir++)
540 { 540 {
541 if (reinit) endpoints[i].active = false; 541 if (reinit) endpoints[i][dir].active = false;
542 endpoints[i].busy = false; 542 endpoints[i][dir].busy = false;
543 endpoints[i].status = -1; 543 endpoints[i][dir].status = -1;
544 endpoints[i].done = true; 544 endpoints[i][dir].done = true;
545 semaphore_release(&endpoints[i].complete); 545 semaphore_release(&endpoints[i][dir].complete);
546 } 546 }
547 547
548 DEPCTL(0, false) = DEPCTL_usbactep | (1 << DEPCTL_nextep_bitp); 548 DEPCTL(0, false) = DEPCTL_usbactep | (1 << DEPCTL_nextep_bitp);
549 DEPCTL(0, true) = DEPCTL_usbactep; 549 DEPCTL(0, true) = DEPCTL_usbactep;
@@ -575,26 +575,28 @@ static void reset_endpoints(int reinit)
575int usb_drv_request_endpoint(int type, int dir) 575int usb_drv_request_endpoint(int type, int dir)
576{ 576{
577 bool out = dir == USB_DIR_OUT; 577 bool out = dir == USB_DIR_OUT;
578 for(size_t ep = out ? 2 : 1; ep < USB_NUM_ENDPOINTS; ep += 2) 578 for(size_t ep = out ? 2 : 1; ep < USB_NUM_ENDPOINTS; ep += 2) {
579 if (!endpoints[ep].active) 579 if (!endpoints[ep][out ? DIR_OUT : DIR_IN].active)
580 { 580 {
581 endpoints[ep].active = true; 581 endpoints[ep][out ? DIR_OUT : DIR_IN].active = true;
582 DEPCTL(ep, out) = (DEPCTL(ep, out) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp)) | 582 DEPCTL(ep, out) = (DEPCTL(ep, out) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp)) |
583 (type << DEPCTL_eptype_bitp); 583 (type << DEPCTL_eptype_bitp);
584 return ep | dir; 584 return ep | dir;
585 } 585 }
586 }
586 587
587 return -1; 588 return -1;
588} 589}
589 590
590void usb_drv_release_endpoint(int ep) 591void usb_drv_release_endpoint(int ep)
591{ 592{
593 bool out = !(ep & USB_DIR_IN);
592 ep = ep & 0x7f; 594 ep = ep & 0x7f;
593 595
594 if (ep < 1 || ep > USB_NUM_ENDPOINTS) 596 if (ep < 1 || ep > USB_NUM_ENDPOINTS)
595 return; 597 return;
596 598
597 endpoints[ep].active = false; 599 endpoints[ep][out ? DIR_OUT : DIR_IN].active = false;
598} 600}
599 601
600static void usb_reset(void) 602static void usb_reset(void)
@@ -646,14 +648,14 @@ static void handle_ep_int(bool out)
646 { 648 {
647 if (!out) inflight = false; 649 if (!out) inflight = false;
648 commit_discard_dcache(); 650 commit_discard_dcache();
649 int bytes = endpoints[ep].size - (DEPTSIZ(ep, out) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp)); 651 int bytes = endpoints[ep][out ? DIR_OUT : DIR_IN].size - (DEPTSIZ(ep, out) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp));
650 if (endpoints[ep].busy) 652 if (endpoints[ep][out ? DIR_OUT : DIR_IN].busy)
651 { 653 {
652 endpoints[ep].busy = false; 654 endpoints[ep][out ? DIR_OUT : DIR_IN].busy = false;
653 endpoints[ep].status = 0; 655 endpoints[ep][out ? DIR_OUT : DIR_IN].status = 0;
654 endpoints[ep].done = true; 656 endpoints[ep][out ? DIR_OUT : DIR_IN].done = true;
655 usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, bytes); 657 usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, bytes);
656 semaphore_release(&endpoints[ep].complete); 658 semaphore_release(&endpoints[ep][out ? DIR_OUT : DIR_IN].complete);
657 } 659 }
658 } 660 }
659 661
@@ -662,12 +664,12 @@ static void handle_ep_int(bool out)
662 664
663 if (!out && (epints & DIEPINT_timeout)) 665 if (!out && (epints & DIEPINT_timeout))
664 { 666 {
665 if (endpoints[ep].busy) 667 if (endpoints[ep][out ? DIR_OUT : DIR_IN].busy)
666 { 668 {
667 endpoints[ep].busy = false; 669 endpoints[ep][out ? DIR_OUT : DIR_IN].busy = false;
668 endpoints[ep].status = 1; 670 endpoints[ep][out ? DIR_OUT : DIR_IN].status = 1;
669 endpoints[ep].done = true; 671 endpoints[ep][out ? DIR_OUT : DIR_IN].done = true;
670 semaphore_release(&endpoints[ep].complete); 672 semaphore_release(&endpoints[ep][out ? DIR_OUT : DIR_IN].complete);
671 } 673 }
672 } 674 }
673 675
@@ -735,8 +737,8 @@ static void ep_transfer(int ep, void *ptr, int len, bool out)
735 /* disable interrupts to avoid any race */ 737 /* disable interrupts to avoid any race */
736 int oldlevel = disable_irq_save(); 738 int oldlevel = disable_irq_save();
737 if (!out) inflight = true; 739 if (!out) inflight = true;
738 endpoints[ep].busy = true; 740 endpoints[ep][out ? DIR_OUT : DIR_IN].busy = true;
739 endpoints[ep].size = len; 741 endpoints[ep][out ? DIR_OUT : DIR_IN].size = len;
740 742
741 if (out) DEPCTL(ep, out) &= ~DEPCTL_stall; 743 if (out) DEPCTL(ep, out) &= ~DEPCTL_stall;
742 744
@@ -762,11 +764,11 @@ static void ep_transfer(int ep, void *ptr, int len, bool out)
762int usb_drv_send(int endpoint, void *ptr, int length) 764int usb_drv_send(int endpoint, void *ptr, int length)
763{ 765{
764 endpoint = EP_NUM(endpoint); 766 endpoint = EP_NUM(endpoint);
765 endpoints[endpoint].done = false; 767 endpoints[endpoint][1].done = false;
766 ep_transfer(endpoint, ptr, length, false); 768 ep_transfer(endpoint, ptr, length, false);
767 while (!endpoints[endpoint].done && endpoints[endpoint].busy) 769 while (!endpoints[endpoint][1].done && endpoints[endpoint][1].busy)
768 semaphore_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK); 770 semaphore_wait(&endpoints[endpoint][1].complete, TIMEOUT_BLOCK);
769 return endpoints[endpoint].status; 771 return endpoints[endpoint][1].status;
770} 772}
771 773
772void usb_drv_cancel_all_transfers(void) 774void usb_drv_cancel_all_transfers(void)
@@ -778,8 +780,9 @@ void usb_drv_cancel_all_transfers(void)
778 780
779void usb_drv_init(void) 781void usb_drv_init(void)
780{ 782{
781 for (unsigned i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++) 783 for (unsigned i = 0; i < sizeof(endpoints)/(2*sizeof(struct ep_type)); i++)
782 semaphore_init(&endpoints[i].complete, 1, 0); 784 for (unsigned dir = 0; dir < 2; dir++)
785 semaphore_init(&endpoints[i][dir].complete, 1, 0);
783 786
784 /* Enable USB clock */ 787 /* Enable USB clock */
785#if CONFIG_CPU==S5L8701 788#if CONFIG_CPU==S5L8701