@@ -156,9 +156,6 @@ static inline ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
156
156
static void qhd_init (ehci_qhd_t * p_qhd , uint8_t dev_addr , tusb_desc_endpoint_t const * ep_desc );
157
157
158
158
static inline ehci_qtd_t * qtd_find_free (void );
159
- static inline ehci_qtd_t * qtd_next (ehci_qtd_t const * p_qtd );
160
- static inline void qtd_insert_to_qhd (ehci_qhd_t * p_qhd , ehci_qtd_t * p_qtd_new );
161
- static inline void qtd_remove_1st_from_qhd (ehci_qhd_t * p_qhd );
162
159
static void qtd_init (ehci_qtd_t * qtd , void const * buffer , uint16_t total_bytes );
163
160
164
161
static inline void list_insert (ehci_link_t * current , ehci_link_t * new , uint8_t new_type );
@@ -473,11 +470,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
473
470
hcd_dcache_clean ((void * ) setup_packet , 8 );
474
471
hcd_dcache_clean_invalidate (td , sizeof (ehci_qtd_t ));
475
472
476
- // sw region
477
- qhd -> p_qtd_list_head = td ;
478
- qhd -> p_qtd_list_tail = td ;
479
-
480
473
// attach TD
474
+ qhd -> p_attached_qtd = td ; // software management
481
475
qhd -> qtd_overlay .next .address = (uint32_t ) td ;
482
476
483
477
hcd_dcache_clean_invalidate (qhd , sizeof (ehci_qhd_t ));
@@ -501,7 +495,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
501
495
502
496
qtd_init (qtd , buffer , buflen );
503
497
504
- // first first data toggle is always 1 (data & setup stage)
498
+ // first data toggle is always 1 (data & setup stage)
505
499
qtd -> data_toggle = 1 ;
506
500
qtd -> pid = dir ? EHCI_PID_IN : EHCI_PID_OUT ;
507
501
} else {
@@ -521,11 +515,8 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
521
515
}
522
516
hcd_dcache_clean_invalidate (qtd , sizeof (ehci_qtd_t ));
523
517
524
- // Software: assign TD to QHD
525
- qhd -> p_qtd_list_head = qtd ;
526
- qhd -> p_qtd_list_tail = qtd ;
527
-
528
518
// attach TD to QHD start transferring
519
+ qhd -> p_attached_qtd = qtd ; // software management
529
520
qhd -> qtd_overlay .next .address = (uint32_t ) qtd ;
530
521
531
522
hcd_dcache_clean_invalidate (qhd , sizeof (ehci_qhd_t ));
@@ -580,27 +571,25 @@ void port_connect_status_change_isr(uint8_t rhport)
580
571
TU_ATTR_ALWAYS_INLINE static inline
581
572
void qhd_xfer_complete_isr (ehci_qhd_t * p_qhd )
582
573
{
583
- // free all TDs from the head td to the first active TD
584
- while (p_qhd -> p_qtd_list_head != NULL && !p_qhd -> p_qtd_list_head -> active )
585
- {
586
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) p_qhd -> p_qtd_list_head ;
587
- hcd_dcache_invalidate (qtd , sizeof (ehci_qtd_t ));
574
+ // examine TD attached to queue head
575
+ ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) p_qhd -> p_attached_qtd ;
576
+ if (qtd == NULL ) return ; // no TD attached
577
+ hcd_dcache_invalidate (qtd , sizeof (ehci_qtd_t ));
588
578
589
- bool const is_ioc = (qtd -> int_on_complete != 0 );
590
- uint8_t const ep_addr = tu_edpt_addr (p_qhd -> ep_number , qtd -> pid == EHCI_PID_IN ? 1 : 0 );
579
+ // TD is still active, no need to process
580
+ if (qtd -> active ) {
581
+ return ;
582
+ }
591
583
592
- p_qhd -> total_xferred_bytes += qtd -> expected_bytes - qtd -> total_bytes ;
584
+ uint32_t const xferred_bytes = qtd -> expected_bytes - qtd -> total_bytes ;
585
+ uint8_t const ep_addr = tu_edpt_addr (p_qhd -> ep_number , qtd -> pid == EHCI_PID_IN ? 1 : 0 );
593
586
594
- // TD need to be freed and removed from qhd, before invoking callback
595
- qtd -> used = 0 ; // free QTD
596
- qtd_remove_1st_from_qhd ( p_qhd );
587
+ // remove and free TD before invoking callback
588
+ p_qhd -> p_attached_qtd = NULL ;
589
+ qtd -> used = 0 ; // free QTD
597
590
598
- if (is_ioc )
599
- {
600
- hcd_event_xfer_complete (p_qhd -> dev_addr , ep_addr , p_qhd -> total_xferred_bytes , XFER_RESULT_SUCCESS , true);
601
- p_qhd -> total_xferred_bytes = 0 ;
602
- }
603
- }
591
+ // IOC is always set
592
+ hcd_event_xfer_complete (p_qhd -> dev_addr , ep_addr , xferred_bytes , XFER_RESULT_SUCCESS , true);
604
593
}
605
594
606
595
TU_ATTR_ALWAYS_INLINE static inline
@@ -685,20 +674,17 @@ void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
685
674
// while(1){}
686
675
// }
687
676
688
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) p_qhd -> p_qtd_list_head ;
677
+ ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) p_qhd -> p_attached_qtd ;
689
678
TU_ASSERT (qtd , ); // No TD yet, probably a race condition or cache issue !?
690
679
691
680
hcd_dcache_invalidate (qtd , sizeof (ehci_qtd_t ));
692
- p_qhd -> total_xferred_bytes + = qtd -> expected_bytes - qtd -> total_bytes ;
681
+ uint32_t const xferred_bytes = qtd -> expected_bytes - qtd -> total_bytes ;
693
682
683
+ p_qhd -> p_attached_qtd = NULL ;
694
684
qtd -> used = 0 ; // free QTD
695
- qtd_remove_1st_from_qhd (p_qhd );
696
685
697
686
if ( 0 == p_qhd -> ep_number ) {
698
- // control cannot be halted --> clear all qtd list
699
- p_qhd -> p_qtd_list_head = NULL ;
700
- p_qhd -> p_qtd_list_tail = NULL ;
701
-
687
+ // control cannot be halted
702
688
p_qhd -> qtd_overlay .next .terminate = 1 ;
703
689
p_qhd -> qtd_overlay .alternate .terminate = 1 ;
704
690
p_qhd -> qtd_overlay .halted = 0 ;
@@ -707,19 +693,17 @@ void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
707
693
p_setup -> used = 0 ;
708
694
}
709
695
710
- // call USBH callback
696
+ // notify usbh
711
697
uint8_t const ep_addr = tu_edpt_addr (p_qhd -> ep_number , p_qhd -> pid == EHCI_PID_IN ? 1 : 0 );
712
- hcd_event_xfer_complete (p_qhd -> dev_addr , ep_addr , p_qhd -> total_xferred_bytes , xfer_result , true);
713
-
714
- p_qhd -> total_xferred_bytes = 0 ;
698
+ hcd_event_xfer_complete (p_qhd -> dev_addr , ep_addr , xferred_bytes , xfer_result , true);
715
699
}
716
700
}
717
701
718
702
TU_ATTR_ALWAYS_INLINE static inline
719
- void xfer_error_isr (uint8_t hostid )
703
+ void xfer_error_isr (uint8_t rhport )
720
704
{
721
705
//------------- async list -------------//
722
- ehci_qhd_t * const async_head = qhd_async_head (hostid );
706
+ ehci_qhd_t * const async_head = qhd_async_head (rhport );
723
707
ehci_qhd_t * p_qhd = async_head ;
724
708
do
725
709
{
@@ -729,10 +713,10 @@ void xfer_error_isr(uint8_t hostid)
729
713
}while (p_qhd != async_head ); // async list traversal, stop if loop around
730
714
731
715
//------------- TODO refractor period list -------------//
732
- uint32_t const period_1ms_addr = (uint32_t ) get_period_head (hostid , 1u );
716
+ uint32_t const period_1ms_addr = (uint32_t ) get_period_head (rhport , 1u );
733
717
for (uint32_t interval_ms = 1 ; interval_ms <= FRAMELIST_SIZE ; interval_ms *= 2 )
734
718
{
735
- ehci_link_t next_item = * get_period_head (hostid , interval_ms );
719
+ ehci_link_t next_item = * get_period_head (rhport , interval_ms );
736
720
737
721
// TODO abstract max loop guard for period
738
722
while ( !next_item .terminate &&
@@ -873,34 +857,6 @@ static inline ehci_qtd_t* qtd_find_free(void)
873
857
return NULL ;
874
858
}
875
859
876
- static inline ehci_qtd_t * qtd_next (ehci_qtd_t const * p_qtd )
877
- {
878
- return (ehci_qtd_t * ) tu_align32 (p_qtd -> next .address );
879
- }
880
-
881
- static inline void qtd_remove_1st_from_qhd (ehci_qhd_t * p_qhd )
882
- {
883
- if (p_qhd -> p_qtd_list_head == p_qhd -> p_qtd_list_tail ) // last TD --> make it NULL
884
- {
885
- p_qhd -> p_qtd_list_head = p_qhd -> p_qtd_list_tail = NULL ;
886
- }else
887
- {
888
- p_qhd -> p_qtd_list_head = qtd_next ( p_qhd -> p_qtd_list_head );
889
- }
890
- }
891
-
892
- static inline void qtd_insert_to_qhd (ehci_qhd_t * p_qhd , ehci_qtd_t * p_qtd_new )
893
- {
894
- if (p_qhd -> p_qtd_list_head == NULL ) // empty list
895
- {
896
- p_qhd -> p_qtd_list_head = p_qhd -> p_qtd_list_tail = p_qtd_new ;
897
- }else
898
- {
899
- p_qhd -> p_qtd_list_tail -> next .address = (uint32_t ) p_qtd_new ;
900
- p_qhd -> p_qtd_list_tail = p_qtd_new ;
901
- }
902
- }
903
-
904
860
static void qhd_init (ehci_qhd_t * p_qhd , uint8_t dev_addr , tusb_desc_endpoint_t const * ep_desc )
905
861
{
906
862
// address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise)
@@ -955,15 +911,14 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
955
911
p_qhd -> int_smask = p_qhd -> fl_int_cmask = 0 ;
956
912
}
957
913
958
- p_qhd -> fl_hub_addr = devtree_info .hub_addr ;
959
- p_qhd -> fl_hub_port = devtree_info .hub_port ;
960
- p_qhd -> mult = 1 ; // TODO not use high bandwidth/park mode yet
914
+ p_qhd -> fl_hub_addr = devtree_info .hub_addr ;
915
+ p_qhd -> fl_hub_port = devtree_info .hub_port ;
916
+ p_qhd -> mult = 1 ; // TODO not use high bandwidth/park mode yet
961
917
962
918
//------------- HCD Management Data -------------//
963
- p_qhd -> used = 1 ;
964
- p_qhd -> removing = 0 ;
965
- p_qhd -> p_qtd_list_head = NULL ;
966
- p_qhd -> p_qtd_list_tail = NULL ;
919
+ p_qhd -> used = 1 ;
920
+ p_qhd -> removing = 0 ;
921
+ p_qhd -> p_attached_qtd = NULL ;
967
922
p_qhd -> pid = tu_edpt_dir (ep_desc -> bEndpointAddress ) ? EHCI_PID_IN : EHCI_PID_OUT ; // PID for TD under this endpoint
968
923
969
924
//------------- active, but no TD list -------------//
0 commit comments