diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/usb-drv-arc.c | 185 | ||||
-rw-r--r-- | firmware/target/arm/usb-tcc.c | 5 |
2 files changed, 122 insertions, 68 deletions
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c index 200601eb24..8a10c5fbd6 100644 --- a/firmware/target/arm/usb-drv-arc.c +++ b/firmware/target/arm/usb-drv-arc.c | |||
@@ -248,10 +248,6 @@ | |||
248 | #define EPCTRL_RX_EP_STALL (0x00000001) | 248 | #define EPCTRL_RX_EP_STALL (0x00000001) |
249 | 249 | ||
250 | /* bit 19-18 and 3-2 are endpoint type */ | 250 | /* bit 19-18 and 3-2 are endpoint type */ |
251 | #define EPCTRL_EP_TYPE_CONTROL (0) | ||
252 | #define EPCTRL_EP_TYPE_ISO (1) | ||
253 | #define EPCTRL_EP_TYPE_BULK (2) | ||
254 | #define EPCTRL_EP_TYPE_INTERRUPT (3) | ||
255 | #define EPCTRL_TX_EP_TYPE_SHIFT (18) | 251 | #define EPCTRL_TX_EP_TYPE_SHIFT (18) |
256 | #define EPCTRL_RX_EP_TYPE_SHIFT (2) | 252 | #define EPCTRL_RX_EP_TYPE_SHIFT (2) |
257 | 253 | ||
@@ -312,6 +308,14 @@ | |||
312 | transfer size, so it seems like a good size */ | 308 | transfer size, so it seems like a good size */ |
313 | #define NUM_TDS_PER_EP 4 | 309 | #define NUM_TDS_PER_EP 4 |
314 | 310 | ||
311 | typedef struct usb_endpoint | ||
312 | { | ||
313 | bool allocated[2]; | ||
314 | short type[2]; | ||
315 | short max_pkt_size[2]; | ||
316 | } usb_endpoint_t; | ||
317 | static usb_endpoint_t endpoints[USB_NUM_ENDPOINTS]; | ||
318 | |||
315 | /* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ | 319 | /* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ |
316 | struct transfer_descriptor { | 320 | struct transfer_descriptor { |
317 | unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set | 321 | unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set |
@@ -356,16 +360,12 @@ static const unsigned int pipe2mask[] = { | |||
356 | 0x10, 0x100000, | 360 | 0x10, 0x100000, |
357 | }; | 361 | }; |
358 | 362 | ||
359 | static char ep_allocation[USB_NUM_ENDPOINTS]; | ||
360 | |||
361 | /*-------------------------------------------------------------------------*/ | 363 | /*-------------------------------------------------------------------------*/ |
362 | static void transfer_completed(void); | 364 | static void transfer_completed(void); |
363 | static void control_received(void); | 365 | static void control_received(void); |
364 | static int prime_transfer(int endpoint, void* ptr, | 366 | static int prime_transfer(int ep_num, void* ptr, int len, bool send, bool wait); |
365 | int len, bool send, bool wait); | ||
366 | static void prepare_td(struct transfer_descriptor* td, | 367 | static void prepare_td(struct transfer_descriptor* td, |
367 | struct transfer_descriptor* previous_td, | 368 | struct transfer_descriptor* previous_td, void *ptr, int len,int pipe); |
368 | void *ptr, int len,int pipe); | ||
369 | static void bus_reset(void); | 369 | static void bus_reset(void); |
370 | static void init_control_queue_heads(void); | 370 | static void init_control_queue_heads(void); |
371 | static void init_bulk_queue_heads(void); | 371 | static void init_bulk_queue_heads(void); |
@@ -394,7 +394,7 @@ void usb_drv_reset(void) | |||
394 | while (REG_USBCMD & USBCMD_CTRL_RESET); | 394 | while (REG_USBCMD & USBCMD_CTRL_RESET); |
395 | 395 | ||
396 | #if CONFIG_CPU == PP5022 || CONFIG_CPU == PP5024 | 396 | #if CONFIG_CPU == PP5022 || CONFIG_CPU == PP5024 |
397 | /* On a CPU which identifies as a PP5022, this | 397 | /* On a CPU which identifies as a PP5022, this |
398 | initialization must be done after USB is reset. | 398 | initialization must be done after USB is reset. |
399 | */ | 399 | */ |
400 | outl(inl(0x70000060) | 0xF, 0x70000060); | 400 | outl(inl(0x70000060) | 0xF, 0x70000060); |
@@ -475,6 +475,27 @@ static void _usb_drv_init(bool attach) | |||
475 | (void)attach; | 475 | (void)attach; |
476 | } | 476 | } |
477 | 477 | ||
478 | #ifdef LOGF_ENABLE | ||
479 | #define XFER_DIR_STR(dir) ((dir) ? "IN" : "OUT") | ||
480 | #define XFER_TYPE_STR(type) \ | ||
481 | ((type) == USB_ENDPOINT_XFER_CONTROL ? "CTRL" : \ | ||
482 | ((type) == USB_ENDPOINT_XFER_ISOC ? "ISOC" : \ | ||
483 | ((type) == USB_ENDPOINT_XFER_BULK ? "BULK" : \ | ||
484 | ((type) == USB_ENDPOINT_XFER_INT ? "INTR" : "INVL")))) | ||
485 | |||
486 | static void log_ep(int ep_num, int ep_dir, char* prefix) | ||
487 | { | ||
488 | usb_endpoint_t* endpoint = &endpoints[ep_num]; | ||
489 | |||
490 | logf("%s: ep%d %s %s %d", prefix, ep_num, XFER_DIR_STR(ep_dir), | ||
491 | XFER_TYPE_STR(endpoint->type[ep_dir]), | ||
492 | endpoint->max_pkt_size[ep_dir]); | ||
493 | } | ||
494 | #else | ||
495 | #undef log_ep | ||
496 | #define log_ep(...) | ||
497 | #endif | ||
498 | |||
478 | void usb_drv_init(void) | 499 | void usb_drv_init(void) |
479 | { | 500 | { |
480 | _usb_drv_init(false); | 501 | _usb_drv_init(false); |
@@ -483,6 +504,7 @@ void usb_drv_init(void) | |||
483 | /* fully enable driver */ | 504 | /* fully enable driver */ |
484 | void usb_drv_attach(void) | 505 | void usb_drv_attach(void) |
485 | { | 506 | { |
507 | logf("usb_drv_attach"); | ||
486 | sleep(HZ/10); | 508 | sleep(HZ/10); |
487 | _usb_drv_init(true); | 509 | _usb_drv_init(true); |
488 | } | 510 | } |
@@ -555,49 +577,51 @@ void usb_drv_int(void) | |||
555 | bool usb_drv_stalled(int endpoint,bool in) | 577 | bool usb_drv_stalled(int endpoint,bool in) |
556 | { | 578 | { |
557 | if(in) { | 579 | if(in) { |
558 | return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_TX_EP_STALL)!=0); | 580 | return ((REG_ENDPTCTRL(EP_NUM(endpoint)) & EPCTRL_TX_EP_STALL)!=0); |
559 | } | 581 | } |
560 | else { | 582 | else { |
561 | return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_RX_EP_STALL)!=0); | 583 | return ((REG_ENDPTCTRL(EP_NUM(endpoint)) & EPCTRL_RX_EP_STALL)!=0); |
562 | } | 584 | } |
563 | 585 | ||
564 | } | 586 | } |
565 | void usb_drv_stall(int endpoint, bool stall,bool in) | 587 | void usb_drv_stall(int endpoint, bool stall, bool in) |
566 | { | 588 | { |
567 | logf("%sstall %d", stall?"":"un", endpoint&0x7f); | 589 | int ep_num = EP_NUM(endpoint); |
590 | |||
591 | logf("%sstall %d", stall ? "" : "un", ep_num); | ||
568 | 592 | ||
569 | if(in) { | 593 | if(in) { |
570 | if (stall) { | 594 | if (stall) { |
571 | REG_ENDPTCTRL(endpoint&0x7f) |= EPCTRL_TX_EP_STALL; | 595 | REG_ENDPTCTRL(ep_num) |= EPCTRL_TX_EP_STALL; |
572 | } | 596 | } |
573 | else { | 597 | else { |
574 | REG_ENDPTCTRL(endpoint&0x7f) &= ~EPCTRL_TX_EP_STALL; | 598 | REG_ENDPTCTRL(ep_num) &= ~EPCTRL_TX_EP_STALL; |
575 | } | 599 | } |
576 | } | 600 | } |
577 | else { | 601 | else { |
578 | if (stall) { | 602 | if (stall) { |
579 | REG_ENDPTCTRL(endpoint) |= EPCTRL_RX_EP_STALL; | 603 | REG_ENDPTCTRL(ep_num) |= EPCTRL_RX_EP_STALL; |
580 | } | 604 | } |
581 | else { | 605 | else { |
582 | REG_ENDPTCTRL(endpoint) &= ~EPCTRL_RX_EP_STALL; | 606 | REG_ENDPTCTRL(ep_num) &= ~EPCTRL_RX_EP_STALL; |
583 | } | 607 | } |
584 | } | 608 | } |
585 | } | 609 | } |
586 | 610 | ||
587 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | 611 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) |
588 | { | 612 | { |
589 | return prime_transfer(endpoint&0x7f, ptr, length, true, false); | 613 | return prime_transfer(EP_NUM(endpoint), ptr, length, true, false); |
590 | } | 614 | } |
591 | 615 | ||
592 | int usb_drv_send(int endpoint, void* ptr, int length) | 616 | int usb_drv_send(int endpoint, void* ptr, int length) |
593 | { | 617 | { |
594 | return prime_transfer(endpoint&0x7f, ptr, length, true, true); | 618 | return prime_transfer(EP_NUM(endpoint), ptr, length, true, true); |
595 | } | 619 | } |
596 | 620 | ||
597 | int usb_drv_recv(int endpoint, void* ptr, int length) | 621 | int usb_drv_recv(int endpoint, void* ptr, int length) |
598 | { | 622 | { |
599 | //logf("usbrecv(%x, %d)", ptr, length); | 623 | //logf("usbrecv(%x, %d)", ptr, length); |
600 | return prime_transfer(endpoint&0x7f, ptr, length, false, false); | 624 | return prime_transfer(EP_NUM(endpoint), ptr, length, false, false); |
601 | } | 625 | } |
602 | 626 | ||
603 | int usb_drv_port_speed(void) | 627 | int usb_drv_port_speed(void) |
@@ -627,7 +651,7 @@ void usb_drv_set_address(int address) | |||
627 | 651 | ||
628 | void usb_drv_reset_endpoint(int endpoint, bool send) | 652 | void usb_drv_reset_endpoint(int endpoint, bool send) |
629 | { | 653 | { |
630 | int pipe = (endpoint&0x7f) * 2 + (send ? 1 : 0); | 654 | int pipe = EP_NUM(endpoint) * 2 + (send ? 1 : 0); |
631 | unsigned int mask = pipe2mask[pipe]; | 655 | unsigned int mask = pipe2mask[pipe]; |
632 | REG_ENDPTFLUSH = mask; | 656 | REG_ENDPTFLUSH = mask; |
633 | while (REG_ENDPTFLUSH & mask); | 657 | while (REG_ENDPTFLUSH & mask); |
@@ -662,23 +686,23 @@ void usb_drv_set_test_mode(int mode) | |||
662 | /*-------------------------------------------------------------------------*/ | 686 | /*-------------------------------------------------------------------------*/ |
663 | 687 | ||
664 | /* manual: 32.14.5.2 */ | 688 | /* manual: 32.14.5.2 */ |
665 | static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait) | 689 | static int prime_transfer(int ep_num, void* ptr, int len, bool send, bool wait) |
666 | { | 690 | { |
667 | int rc = 0; | 691 | int rc = 0; |
668 | int pipe = endpoint * 2 + (send ? 1 : 0); | 692 | int pipe = ep_num * 2 + (send ? 1 : 0); |
669 | unsigned int mask = pipe2mask[pipe]; | 693 | unsigned int mask = pipe2mask[pipe]; |
670 | struct queue_head* qh = &qh_array[pipe]; | 694 | struct queue_head* qh = &qh_array[pipe]; |
671 | static long last_tick; | 695 | static long last_tick; |
672 | struct transfer_descriptor* new_td,*cur_td,*prev_td; | 696 | struct transfer_descriptor *new_td, *cur_td, *prev_td; |
673 | 697 | ||
674 | int oldlevel = disable_irq_save(); | 698 | int oldlevel = disable_irq_save(); |
675 | /* | 699 | /* |
676 | if (send && endpoint > EP_CONTROL) { | 700 | if (send && ep_num > EP_CONTROL) { |
677 | logf("usb: sent %d bytes", len); | 701 | logf("usb: sent %d bytes", len); |
678 | } | 702 | } |
679 | */ | 703 | */ |
680 | qh->status = 0; | 704 | qh->status = 0; |
681 | qh->wait = wait; | 705 | qh->wait = wait; |
682 | 706 | ||
683 | new_td=&td_array[pipe*NUM_TDS_PER_EP]; | 707 | new_td=&td_array[pipe*NUM_TDS_PER_EP]; |
684 | cur_td=new_td; | 708 | cur_td=new_td; |
@@ -694,15 +718,15 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait | |||
694 | cur_td++; | 718 | cur_td++; |
695 | len-=tdlen; | 719 | len-=tdlen; |
696 | } | 720 | } |
697 | while(len>0 ); | 721 | while(len>0); |
698 | //logf("starting ep %d %s",endpoint,send?"send":"receive"); | 722 | //logf("starting ep %d %s",ep_num,send?"send":"receive"); |
699 | 723 | ||
700 | qh->dtd.next_td_ptr = (unsigned int)new_td; | 724 | qh->dtd.next_td_ptr = (unsigned int)new_td; |
701 | qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); | 725 | qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); |
702 | 726 | ||
703 | REG_ENDPTPRIME |= mask; | 727 | REG_ENDPTPRIME |= mask; |
704 | 728 | ||
705 | if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { | 729 | if(ep_num == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { |
706 | /* 32.14.3.2.2 */ | 730 | /* 32.14.3.2.2 */ |
707 | logf("new setup arrived"); | 731 | logf("new setup arrived"); |
708 | rc = -4; | 732 | rc = -4; |
@@ -724,11 +748,11 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait | |||
724 | } | 748 | } |
725 | 749 | ||
726 | if (!(REG_ENDPTSTATUS & mask)) { | 750 | if (!(REG_ENDPTSTATUS & mask)) { |
727 | logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff ); | 751 | logf("no prime! %d %d %x", ep_num, pipe, qh->dtd.size_ioc_sts & 0xff); |
728 | rc = -3; | 752 | rc = -3; |
729 | goto pt_error; | 753 | goto pt_error; |
730 | } | 754 | } |
731 | if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { | 755 | if(ep_num == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { |
732 | /* 32.14.3.2.2 */ | 756 | /* 32.14.3.2.2 */ |
733 | logf("new setup arrived"); | 757 | logf("new setup arrived"); |
734 | rc = -4; | 758 | rc = -4; |
@@ -780,17 +804,38 @@ void usb_drv_cancel_all_transfers(void) | |||
780 | } | 804 | } |
781 | } | 805 | } |
782 | 806 | ||
783 | int usb_drv_request_endpoint(int dir) | 807 | int usb_drv_request_endpoint(int type, int dir) |
784 | { | 808 | { |
785 | int i, bit; | 809 | int ep_num, ep_dir; |
810 | short ep_type; | ||
811 | |||
812 | /* Safety */ | ||
813 | ep_dir = EP_DIR(dir); | ||
814 | ep_type = type & USB_ENDPOINT_XFERTYPE_MASK; | ||
786 | 815 | ||
787 | bit=(dir & USB_DIR_IN)? 2:1; | 816 | logf("req: %s %s", XFER_DIR_STR(ep_dir), XFER_TYPE_STR(ep_type)); |
788 | 817 | ||
789 | for (i=1; i < USB_NUM_ENDPOINTS; i++) { | 818 | /* Find an available ep/dir pair */ |
790 | if((ep_allocation[i] & bit)!=0) | 819 | for (ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++) { |
820 | usb_endpoint_t* endpoint=&endpoints[ep_num]; | ||
821 | int other_dir=(ep_dir ? 0:1); | ||
822 | |||
823 | if (endpoint->allocated[ep_dir]) | ||
791 | continue; | 824 | continue; |
792 | ep_allocation[i] |= bit; | 825 | |
793 | return i | dir; | 826 | if (endpoint->allocated[other_dir] && |
827 | endpoint->type[other_dir] != ep_type) { | ||
828 | logf("ep of different type!"); | ||
829 | return -1; | ||
830 | } | ||
831 | |||
832 | log_ep(ep_num, ep_dir, "add"); | ||
833 | |||
834 | endpoint->allocated[ep_dir] = 1; | ||
835 | endpoint->type[ep_dir] = ep_type; | ||
836 | |||
837 | log_ep(ep_num, ep_dir, "got"); | ||
838 | return (ep_num | (dir & USB_ENDPOINT_DIR_MASK)); | ||
794 | } | 839 | } |
795 | 840 | ||
796 | return -1; | 841 | return -1; |
@@ -798,8 +843,11 @@ int usb_drv_request_endpoint(int dir) | |||
798 | 843 | ||
799 | void usb_drv_release_endpoint(int ep) | 844 | void usb_drv_release_endpoint(int ep) |
800 | { | 845 | { |
801 | int mask = (ep & USB_DIR_IN)? ~2:~1; | 846 | int ep_num = EP_NUM(ep); |
802 | ep_allocation[ep & 0x7f] &= mask; | 847 | int ep_dir = EP_DIR(ep); |
848 | |||
849 | log_ep(ep_num, ep_dir, "rel"); | ||
850 | endpoints[ep_num].allocated[ep_dir] = 0; | ||
803 | } | 851 | } |
804 | 852 | ||
805 | 853 | ||
@@ -870,11 +918,12 @@ static void transfer_completed(void) | |||
870 | struct transfer_descriptor* td=&td_array[pipe*NUM_TDS_PER_EP]; | 918 | struct transfer_descriptor* td=&td_array[pipe*NUM_TDS_PER_EP]; |
871 | while(td!=(struct transfer_descriptor*)DTD_NEXT_TERMINATE && td!=0) | 919 | while(td!=(struct transfer_descriptor*)DTD_NEXT_TERMINATE && td!=0) |
872 | { | 920 | { |
873 | length += ((td->reserved & DTD_RESERVED_LENGTH_MASK) - | 921 | length += ((td->reserved & DTD_RESERVED_LENGTH_MASK) - |
874 | ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS)); | 922 | ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS)); |
875 | td=(struct transfer_descriptor*) td->next_td_ptr; | 923 | td=(struct transfer_descriptor*) td->next_td_ptr; |
876 | } | 924 | } |
877 | usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, qh->status, length); | 925 | usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, |
926 | qh->status, length); | ||
878 | } | 927 | } |
879 | } | 928 | } |
880 | } | 929 | } |
@@ -906,7 +955,7 @@ static void bus_reset(void) | |||
906 | } | 955 | } |
907 | 956 | ||
908 | usb_drv_cancel_all_transfers(); | 957 | usb_drv_cancel_all_transfers(); |
909 | 958 | ||
910 | if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { | 959 | if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { |
911 | logf("usb: slow reset!"); | 960 | logf("usb: slow reset!"); |
912 | } | 961 | } |
@@ -926,39 +975,41 @@ static void init_control_queue_heads(void) | |||
926 | /* manual: 32.14.4.1 Queue Head Initialization */ | 975 | /* manual: 32.14.4.1 Queue Head Initialization */ |
927 | static void init_bulk_queue_heads(void) | 976 | static void init_bulk_queue_heads(void) |
928 | { | 977 | { |
929 | int tx_packetsize; | 978 | int packetsize = (usb_drv_port_speed() ? 512 : 64); |
930 | int rx_packetsize; | ||
931 | int i; | 979 | int i; |
932 | 980 | ||
933 | if (usb_drv_port_speed()) { | ||
934 | rx_packetsize = 512; | ||
935 | tx_packetsize = 512; | ||
936 | } | ||
937 | else { | ||
938 | rx_packetsize = 64; | ||
939 | tx_packetsize = 64; | ||
940 | } | ||
941 | /* TODO: this should take ep_allocation into account */ | 981 | /* TODO: this should take ep_allocation into account */ |
942 | 982 | for (i=1;i<USB_NUM_ENDPOINTS;i++) { | |
943 | /*** bulk ***/ | 983 | qh_array[i*2].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | |
944 | for(i=1;i<USB_NUM_ENDPOINTS;i++) { | 984 | QH_ZLT_SEL; |
945 | qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; | ||
946 | qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; | 985 | qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; |
947 | qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; | 986 | qh_array[i*2+1].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | |
987 | QH_ZLT_SEL; | ||
948 | qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; | 988 | qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; |
949 | } | 989 | } |
950 | } | 990 | } |
951 | 991 | ||
952 | static void init_endpoints(void) | 992 | static void init_endpoints(void) |
953 | { | 993 | { |
954 | int i; | 994 | int ep_num; |
955 | /* TODO: this should take ep_allocation into account */ | 995 | |
956 | /* bulk */ | 996 | logf("init_endpoints"); |
957 | for(i=1;i<USB_NUM_ENDPOINTS;i++) { | 997 | /* RX/TX from the device POV: OUT/IN, respectively */ |
958 | REG_ENDPTCTRL(i) = | 998 | for(ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++) { |
999 | usb_endpoint_t *endpoint = &endpoints[ep_num]; | ||
1000 | |||
1001 | /* manual: 32.9.5.18 (Caution) */ | ||
1002 | if (!endpoint->allocated[DIR_OUT]) { | ||
1003 | endpoint->type[DIR_OUT] = USB_ENDPOINT_XFER_BULK; | ||
1004 | } | ||
1005 | if (!endpoint->allocated[DIR_IN]) { | ||
1006 | endpoint->type[DIR_IN] = USB_ENDPOINT_XFER_BULK; | ||
1007 | } | ||
1008 | |||
1009 | REG_ENDPTCTRL(ep_num) = | ||
959 | EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | | 1010 | EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | |
960 | EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | | 1011 | EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | |
961 | (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) | | 1012 | (endpoint->type[DIR_OUT] << EPCTRL_RX_EP_TYPE_SHIFT) | |
962 | (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT); | 1013 | (endpoint->type[DIR_IN] << EPCTRL_TX_EP_TYPE_SHIFT); |
963 | } | 1014 | } |
964 | } | 1015 | } |
diff --git a/firmware/target/arm/usb-tcc.c b/firmware/target/arm/usb-tcc.c index 611e4be195..2538efd12e 100644 --- a/firmware/target/arm/usb-tcc.c +++ b/firmware/target/arm/usb-tcc.c | |||
@@ -94,12 +94,15 @@ static struct tcc_ep tcc_endpoints[] = { | |||
94 | static bool usb_drv_write_ep(struct tcc_ep *ep); | 94 | static bool usb_drv_write_ep(struct tcc_ep *ep); |
95 | static void usb_set_speed(int); | 95 | static void usb_set_speed(int); |
96 | 96 | ||
97 | int usb_drv_request_endpoint(int dir) | 97 | int usb_drv_request_endpoint(int type, int dir) |
98 | { | 98 | { |
99 | int flags = disable_irq_save(); | 99 | int flags = disable_irq_save(); |
100 | size_t ep; | 100 | size_t ep; |
101 | int ret = 0; | 101 | int ret = 0; |
102 | 102 | ||
103 | if (type != USB_ENDPOINT_XFER_BULK) | ||
104 | return -1; | ||
105 | |||
103 | if (dir == USB_DIR_IN) | 106 | if (dir == USB_DIR_IN) |
104 | ep = 1; | 107 | ep = 1; |
105 | else | 108 | else |