@@ -200,6 +200,7 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
200
200
201
201
sch_ep -> sch_tt = tt ;
202
202
sch_ep -> ep = ep ;
203
+ INIT_LIST_HEAD (& sch_ep -> tt_endpoint );
203
204
204
205
return sch_ep ;
205
206
}
@@ -583,6 +584,8 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
583
584
584
585
mtk -> sch_array = sch_array ;
585
586
587
+ INIT_LIST_HEAD (& mtk -> bw_ep_list_new );
588
+
586
589
return 0 ;
587
590
}
588
591
EXPORT_SYMBOL_GPL (xhci_mtk_sch_init );
@@ -601,19 +604,14 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
601
604
struct xhci_ep_ctx * ep_ctx ;
602
605
struct xhci_slot_ctx * slot_ctx ;
603
606
struct xhci_virt_device * virt_dev ;
604
- struct mu3h_sch_bw_info * sch_bw ;
605
607
struct mu3h_sch_ep_info * sch_ep ;
606
- struct mu3h_sch_bw_info * sch_array ;
607
608
unsigned int ep_index ;
608
- int bw_index ;
609
- int ret = 0 ;
610
609
611
610
xhci = hcd_to_xhci (hcd );
612
611
virt_dev = xhci -> devs [udev -> slot_id ];
613
612
ep_index = xhci_get_endpoint_index (& ep -> desc );
614
613
slot_ctx = xhci_get_slot_ctx (xhci , virt_dev -> in_ctx );
615
614
ep_ctx = xhci_get_ep_ctx (xhci , virt_dev -> in_ctx , ep_index );
616
- sch_array = mtk -> sch_array ;
617
615
618
616
xhci_dbg (xhci , "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n" ,
619
617
__func__ , usb_endpoint_type (& ep -> desc ), udev -> speed ,
@@ -632,39 +630,34 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
632
630
return 0 ;
633
631
}
634
632
635
- bw_index = get_bw_index (xhci , udev , ep );
636
- sch_bw = & sch_array [bw_index ];
637
-
638
633
sch_ep = create_sch_ep (udev , ep , ep_ctx );
639
634
if (IS_ERR_OR_NULL (sch_ep ))
640
635
return - ENOMEM ;
641
636
642
637
setup_sch_info (udev , ep_ctx , sch_ep );
643
638
644
- ret = check_sch_bw (udev , sch_bw , sch_ep );
645
- if (ret ) {
646
- xhci_err (xhci , "Not enough bandwidth!\n" );
647
- if (is_fs_or_ls (udev -> speed ))
648
- drop_tt (udev );
649
-
650
- kfree (sch_ep );
651
- return - ENOSPC ;
652
- }
639
+ list_add_tail (& sch_ep -> endpoint , & mtk -> bw_ep_list_new );
653
640
654
- list_add_tail (& sch_ep -> endpoint , & sch_bw -> bw_ep_list );
641
+ return 0 ;
642
+ }
643
+ EXPORT_SYMBOL_GPL (xhci_mtk_add_ep_quirk );
655
644
656
- ep_ctx -> reserved [0 ] |= cpu_to_le32 (EP_BPKTS (sch_ep -> pkts )
657
- | EP_BCSCOUNT (sch_ep -> cs_count ) | EP_BBM (sch_ep -> burst_mode ));
658
- ep_ctx -> reserved [1 ] |= cpu_to_le32 (EP_BOFFSET (sch_ep -> offset )
659
- | EP_BREPEAT (sch_ep -> repeat ));
645
+ static void xhci_mtk_drop_ep (struct xhci_hcd_mtk * mtk , struct usb_device * udev ,
646
+ struct mu3h_sch_ep_info * sch_ep )
647
+ {
648
+ struct xhci_hcd * xhci = hcd_to_xhci (mtk -> hcd );
649
+ int bw_index = get_bw_index (xhci , udev , sch_ep -> ep );
650
+ struct mu3h_sch_bw_info * sch_bw = & mtk -> sch_array [bw_index ];
660
651
661
- xhci_dbg (xhci , " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n" ,
662
- sch_ep -> pkts , sch_ep -> cs_count , sch_ep -> burst_mode ,
663
- sch_ep -> offset , sch_ep -> repeat );
652
+ update_bus_bw (sch_bw , sch_ep , 0 );
653
+ list_del (& sch_ep -> endpoint );
664
654
665
- return 0 ;
655
+ if (sch_ep -> sch_tt ) {
656
+ list_del (& sch_ep -> tt_endpoint );
657
+ drop_tt (udev );
658
+ }
659
+ kfree (sch_ep );
666
660
}
667
- EXPORT_SYMBOL_GPL (xhci_mtk_add_ep_quirk );
668
661
669
662
void xhci_mtk_drop_ep_quirk (struct usb_hcd * hcd , struct usb_device * udev ,
670
663
struct usb_host_endpoint * ep )
@@ -675,7 +668,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
675
668
struct xhci_virt_device * virt_dev ;
676
669
struct mu3h_sch_bw_info * sch_array ;
677
670
struct mu3h_sch_bw_info * sch_bw ;
678
- struct mu3h_sch_ep_info * sch_ep ;
671
+ struct mu3h_sch_ep_info * sch_ep , * tmp ;
679
672
int bw_index ;
680
673
681
674
xhci = hcd_to_xhci (hcd );
@@ -694,17 +687,73 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
694
687
bw_index = get_bw_index (xhci , udev , ep );
695
688
sch_bw = & sch_array [bw_index ];
696
689
697
- list_for_each_entry (sch_ep , & sch_bw -> bw_ep_list , endpoint ) {
690
+ list_for_each_entry_safe (sch_ep , tmp , & sch_bw -> bw_ep_list , endpoint ) {
698
691
if (sch_ep -> ep == ep ) {
699
- update_bus_bw (sch_bw , sch_ep , 0 );
700
- list_del (& sch_ep -> endpoint );
701
- if (is_fs_or_ls (udev -> speed )) {
702
- list_del (& sch_ep -> tt_endpoint );
703
- drop_tt (udev );
704
- }
705
- kfree (sch_ep );
706
- break ;
692
+ xhci_mtk_drop_ep (mtk , udev , sch_ep );
707
693
}
708
694
}
709
695
}
710
696
EXPORT_SYMBOL_GPL (xhci_mtk_drop_ep_quirk );
697
+
698
+ int xhci_mtk_check_bandwidth (struct usb_hcd * hcd , struct usb_device * udev )
699
+ {
700
+ struct xhci_hcd_mtk * mtk = hcd_to_mtk (hcd );
701
+ struct xhci_hcd * xhci = hcd_to_xhci (hcd );
702
+ struct xhci_virt_device * virt_dev = xhci -> devs [udev -> slot_id ];
703
+ struct mu3h_sch_bw_info * sch_bw ;
704
+ struct mu3h_sch_ep_info * sch_ep , * tmp ;
705
+ int bw_index , ret ;
706
+
707
+ dev_dbg (& udev -> dev , "%s\n" , __func__ );
708
+
709
+ list_for_each_entry (sch_ep , & mtk -> bw_ep_list_new , endpoint ) {
710
+ bw_index = get_bw_index (xhci , udev , sch_ep -> ep );
711
+ sch_bw = & mtk -> sch_array [bw_index ];
712
+
713
+ ret = check_sch_bw (udev , sch_bw , sch_ep );
714
+ if (ret ) {
715
+ xhci_err (xhci , "Not enough bandwidth!\n" );
716
+ return - ENOSPC ;
717
+ }
718
+ }
719
+
720
+ list_for_each_entry_safe (sch_ep , tmp , & mtk -> bw_ep_list_new , endpoint ) {
721
+ struct xhci_ep_ctx * ep_ctx ;
722
+ struct usb_host_endpoint * ep = sch_ep -> ep ;
723
+ unsigned int ep_index = xhci_get_endpoint_index (& ep -> desc );
724
+
725
+ bw_index = get_bw_index (xhci , udev , ep );
726
+ sch_bw = & mtk -> sch_array [bw_index ];
727
+
728
+ list_move_tail (& sch_ep -> endpoint , & sch_bw -> bw_ep_list );
729
+
730
+ ep_ctx = xhci_get_ep_ctx (xhci , virt_dev -> in_ctx , ep_index );
731
+ ep_ctx -> reserved [0 ] |= cpu_to_le32 (EP_BPKTS (sch_ep -> pkts )
732
+ | EP_BCSCOUNT (sch_ep -> cs_count )
733
+ | EP_BBM (sch_ep -> burst_mode ));
734
+ ep_ctx -> reserved [1 ] |= cpu_to_le32 (EP_BOFFSET (sch_ep -> offset )
735
+ | EP_BREPEAT (sch_ep -> repeat ));
736
+
737
+ xhci_dbg (xhci , " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n" ,
738
+ sch_ep -> pkts , sch_ep -> cs_count , sch_ep -> burst_mode ,
739
+ sch_ep -> offset , sch_ep -> repeat );
740
+ }
741
+
742
+ return xhci_check_bandwidth (hcd , udev );
743
+ }
744
+ EXPORT_SYMBOL_GPL (xhci_mtk_check_bandwidth );
745
+
746
+ void xhci_mtk_reset_bandwidth (struct usb_hcd * hcd , struct usb_device * udev )
747
+ {
748
+ struct xhci_hcd_mtk * mtk = hcd_to_mtk (hcd );
749
+ struct mu3h_sch_ep_info * sch_ep , * tmp ;
750
+
751
+ dev_dbg (& udev -> dev , "%s\n" , __func__ );
752
+
753
+ list_for_each_entry_safe (sch_ep , tmp , & mtk -> bw_ep_list_new , endpoint ) {
754
+ xhci_mtk_drop_ep (mtk , udev , sch_ep );
755
+ }
756
+
757
+ xhci_reset_bandwidth (hcd , udev );
758
+ }
759
+ EXPORT_SYMBOL_GPL (xhci_mtk_reset_bandwidth );
0 commit comments