@@ -341,12 +341,14 @@ static const struct usb_device_id blacklist_table[] = {
341
341
#define BTUSB_FIRMWARE_FAILED 8
342
342
#define BTUSB_BOOTING 9
343
343
#define BTUSB_RESET_RESUME 10
344
+ #define BTUSB_DIAG_RUNNING 11
344
345
345
346
struct btusb_data {
346
347
struct hci_dev * hdev ;
347
348
struct usb_device * udev ;
348
349
struct usb_interface * intf ;
349
350
struct usb_interface * isoc ;
351
+ struct usb_interface * diag ;
350
352
351
353
unsigned long flags ;
352
354
@@ -361,6 +363,7 @@ struct btusb_data {
361
363
struct usb_anchor intr_anchor ;
362
364
struct usb_anchor bulk_anchor ;
363
365
struct usb_anchor isoc_anchor ;
366
+ struct usb_anchor diag_anchor ;
364
367
spinlock_t rxlock ;
365
368
366
369
struct sk_buff * evt_skb ;
@@ -372,6 +375,8 @@ struct btusb_data {
372
375
struct usb_endpoint_descriptor * bulk_rx_ep ;
373
376
struct usb_endpoint_descriptor * isoc_tx_ep ;
374
377
struct usb_endpoint_descriptor * isoc_rx_ep ;
378
+ struct usb_endpoint_descriptor * diag_tx_ep ;
379
+ struct usb_endpoint_descriptor * diag_rx_ep ;
375
380
376
381
__u8 cmdreq_type ;
377
382
__u8 cmdreq ;
@@ -869,6 +874,92 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
869
874
return err ;
870
875
}
871
876
877
+ static void btusb_diag_complete (struct urb * urb )
878
+ {
879
+ struct hci_dev * hdev = urb -> context ;
880
+ struct btusb_data * data = hci_get_drvdata (hdev );
881
+ int err ;
882
+
883
+ BT_DBG ("%s urb %p status %d count %d" , hdev -> name , urb , urb -> status ,
884
+ urb -> actual_length );
885
+
886
+ if (urb -> status == 0 ) {
887
+ struct sk_buff * skb ;
888
+
889
+ skb = bt_skb_alloc (urb -> actual_length , GFP_ATOMIC );
890
+ if (skb ) {
891
+ memcpy (skb_put (skb , urb -> actual_length ),
892
+ urb -> transfer_buffer , urb -> actual_length );
893
+ hci_recv_diag (hdev , skb );
894
+ }
895
+ } else if (urb -> status == - ENOENT ) {
896
+ /* Avoid suspend failed when usb_kill_urb */
897
+ return ;
898
+ }
899
+
900
+ if (!test_bit (BTUSB_DIAG_RUNNING , & data -> flags ))
901
+ return ;
902
+
903
+ usb_anchor_urb (urb , & data -> diag_anchor );
904
+ usb_mark_last_busy (data -> udev );
905
+
906
+ err = usb_submit_urb (urb , GFP_ATOMIC );
907
+ if (err < 0 ) {
908
+ /* -EPERM: urb is being killed;
909
+ * -ENODEV: device got disconnected */
910
+ if (err != - EPERM && err != - ENODEV )
911
+ BT_ERR ("%s urb %p failed to resubmit (%d)" ,
912
+ hdev -> name , urb , - err );
913
+ usb_unanchor_urb (urb );
914
+ }
915
+ }
916
+
917
+ static int btusb_submit_diag_urb (struct hci_dev * hdev , gfp_t mem_flags )
918
+ {
919
+ struct btusb_data * data = hci_get_drvdata (hdev );
920
+ struct urb * urb ;
921
+ unsigned char * buf ;
922
+ unsigned int pipe ;
923
+ int err , size = HCI_MAX_FRAME_SIZE ;
924
+
925
+ BT_DBG ("%s" , hdev -> name );
926
+
927
+ if (!data -> diag_rx_ep )
928
+ return - ENODEV ;
929
+
930
+ urb = usb_alloc_urb (0 , mem_flags );
931
+ if (!urb )
932
+ return - ENOMEM ;
933
+
934
+ buf = kmalloc (size , mem_flags );
935
+ if (!buf ) {
936
+ usb_free_urb (urb );
937
+ return - ENOMEM ;
938
+ }
939
+
940
+ pipe = usb_rcvbulkpipe (data -> udev , data -> diag_rx_ep -> bEndpointAddress );
941
+
942
+ usb_fill_bulk_urb (urb , data -> udev , pipe , buf , size ,
943
+ btusb_diag_complete , hdev );
944
+
945
+ urb -> transfer_flags |= URB_FREE_BUFFER ;
946
+
947
+ usb_mark_last_busy (data -> udev );
948
+ usb_anchor_urb (urb , & data -> diag_anchor );
949
+
950
+ err = usb_submit_urb (urb , mem_flags );
951
+ if (err < 0 ) {
952
+ if (err != - EPERM && err != - ENODEV )
953
+ BT_ERR ("%s urb %p submission failed (%d)" ,
954
+ hdev -> name , urb , - err );
955
+ usb_unanchor_urb (urb );
956
+ }
957
+
958
+ usb_free_urb (urb );
959
+
960
+ return err ;
961
+ }
962
+
872
963
static void btusb_tx_complete (struct urb * urb )
873
964
{
874
965
struct sk_buff * skb = urb -> context ;
@@ -956,6 +1047,11 @@ static int btusb_open(struct hci_dev *hdev)
956
1047
set_bit (BTUSB_BULK_RUNNING , & data -> flags );
957
1048
btusb_submit_bulk_urb (hdev , GFP_KERNEL );
958
1049
1050
+ if (data -> diag ) {
1051
+ if (!btusb_submit_diag_urb (hdev , GFP_KERNEL ))
1052
+ set_bit (BTUSB_DIAG_RUNNING , & data -> flags );
1053
+ }
1054
+
959
1055
done :
960
1056
usb_autopm_put_interface (data -> intf );
961
1057
return 0 ;
@@ -971,6 +1067,7 @@ static void btusb_stop_traffic(struct btusb_data *data)
971
1067
usb_kill_anchored_urbs (& data -> intr_anchor );
972
1068
usb_kill_anchored_urbs (& data -> bulk_anchor );
973
1069
usb_kill_anchored_urbs (& data -> isoc_anchor );
1070
+ usb_kill_anchored_urbs (& data -> diag_anchor );
974
1071
}
975
1072
976
1073
static int btusb_close (struct hci_dev * hdev )
@@ -986,6 +1083,7 @@ static int btusb_close(struct hci_dev *hdev)
986
1083
clear_bit (BTUSB_ISOC_RUNNING , & data -> flags );
987
1084
clear_bit (BTUSB_BULK_RUNNING , & data -> flags );
988
1085
clear_bit (BTUSB_INTR_RUNNING , & data -> flags );
1086
+ clear_bit (BTUSB_DIAG_RUNNING , & data -> flags );
989
1087
990
1088
btusb_stop_traffic (data );
991
1089
btusb_free_frags (data );
@@ -2547,6 +2645,95 @@ static int btusb_setup_qca(struct hci_dev *hdev)
2547
2645
return 0 ;
2548
2646
}
2549
2647
2648
+ #ifdef CONFIG_BT_HCIBTUSB_BCM
2649
+ static inline int __set_diag_interface (struct hci_dev * hdev )
2650
+ {
2651
+ struct btusb_data * data = hci_get_drvdata (hdev );
2652
+ struct usb_interface * intf = data -> diag ;
2653
+ int i ;
2654
+
2655
+ if (!data -> diag )
2656
+ return - ENODEV ;
2657
+
2658
+ data -> diag_tx_ep = NULL ;
2659
+ data -> diag_rx_ep = NULL ;
2660
+
2661
+ for (i = 0 ; i < intf -> cur_altsetting -> desc .bNumEndpoints ; i ++ ) {
2662
+ struct usb_endpoint_descriptor * ep_desc ;
2663
+
2664
+ ep_desc = & intf -> cur_altsetting -> endpoint [i ].desc ;
2665
+
2666
+ if (!data -> diag_tx_ep && usb_endpoint_is_bulk_out (ep_desc )) {
2667
+ data -> diag_tx_ep = ep_desc ;
2668
+ continue ;
2669
+ }
2670
+
2671
+ if (!data -> diag_rx_ep && usb_endpoint_is_bulk_in (ep_desc )) {
2672
+ data -> diag_rx_ep = ep_desc ;
2673
+ continue ;
2674
+ }
2675
+ }
2676
+
2677
+ if (!data -> diag_tx_ep || !data -> diag_rx_ep ) {
2678
+ BT_ERR ("%s invalid diagnostic descriptors" , hdev -> name );
2679
+ return - ENODEV ;
2680
+ }
2681
+
2682
+ return 0 ;
2683
+ }
2684
+
2685
+ static struct urb * alloc_diag_urb (struct hci_dev * hdev , bool enable )
2686
+ {
2687
+ struct btusb_data * data = hci_get_drvdata (hdev );
2688
+ struct sk_buff * skb ;
2689
+ struct urb * urb ;
2690
+ unsigned int pipe ;
2691
+
2692
+ if (!data -> diag_tx_ep )
2693
+ return ERR_PTR (- ENODEV );
2694
+
2695
+ urb = usb_alloc_urb (0 , GFP_KERNEL );
2696
+ if (!urb )
2697
+ return ERR_PTR (- ENOMEM );
2698
+
2699
+ skb = bt_skb_alloc (2 , GFP_KERNEL );
2700
+ if (!skb ) {
2701
+ usb_free_urb (urb );
2702
+ return ERR_PTR (- ENOMEM );
2703
+ }
2704
+
2705
+ * skb_put (skb , 1 ) = 0xf0 ;
2706
+ * skb_put (skb , 1 ) = enable ;
2707
+
2708
+ pipe = usb_sndbulkpipe (data -> udev , data -> diag_tx_ep -> bEndpointAddress );
2709
+
2710
+ usb_fill_bulk_urb (urb , data -> udev , pipe ,
2711
+ skb -> data , skb -> len , btusb_tx_complete , skb );
2712
+
2713
+ skb -> dev = (void * )hdev ;
2714
+
2715
+ return urb ;
2716
+ }
2717
+
2718
+ static int btusb_bcm_set_diag (struct hci_dev * hdev , bool enable )
2719
+ {
2720
+ struct btusb_data * data = hci_get_drvdata (hdev );
2721
+ struct urb * urb ;
2722
+
2723
+ if (!data -> diag )
2724
+ return - ENODEV ;
2725
+
2726
+ if (!test_bit (HCI_RUNNING , & hdev -> flags ))
2727
+ return - ENETDOWN ;
2728
+
2729
+ urb = alloc_diag_urb (hdev , enable );
2730
+ if (IS_ERR (urb ))
2731
+ return PTR_ERR (urb );
2732
+
2733
+ return submit_or_queue_tx_urb (hdev , urb );
2734
+ }
2735
+ #endif
2736
+
2550
2737
static int btusb_probe (struct usb_interface * intf ,
2551
2738
const struct usb_device_id * id )
2552
2739
{
@@ -2627,6 +2814,7 @@ static int btusb_probe(struct usb_interface *intf,
2627
2814
init_usb_anchor (& data -> intr_anchor );
2628
2815
init_usb_anchor (& data -> bulk_anchor );
2629
2816
init_usb_anchor (& data -> isoc_anchor );
2817
+ init_usb_anchor (& data -> diag_anchor );
2630
2818
spin_lock_init (& data -> rxlock );
2631
2819
2632
2820
if (id -> driver_info & BTUSB_INTEL_NEW ) {
@@ -2666,11 +2854,20 @@ static int btusb_probe(struct usb_interface *intf,
2666
2854
#ifdef CONFIG_BT_HCIBTUSB_BCM
2667
2855
if (id -> driver_info & BTUSB_BCM_PATCHRAM ) {
2668
2856
hdev -> setup = btbcm_setup_patchram ;
2857
+ hdev -> set_diag = btusb_bcm_set_diag ;
2669
2858
hdev -> set_bdaddr = btbcm_set_bdaddr ;
2859
+
2860
+ /* Broadcom LM_DIAG Interface numbers are hardcoded */
2861
+ data -> diag = usb_ifnum_to_if (data -> udev , 2 );
2670
2862
}
2671
2863
2672
- if (id -> driver_info & BTUSB_BCM_APPLE )
2864
+ if (id -> driver_info & BTUSB_BCM_APPLE ) {
2673
2865
hdev -> setup = btbcm_setup_apple ;
2866
+ hdev -> set_diag = btusb_bcm_set_diag ;
2867
+
2868
+ /* Broadcom LM_DIAG Interface numbers are hardcoded */
2869
+ data -> diag = usb_ifnum_to_if (data -> udev , 2 );
2870
+ }
2674
2871
#endif
2675
2872
2676
2873
if (id -> driver_info & BTUSB_INTEL ) {
@@ -2791,6 +2988,16 @@ static int btusb_probe(struct usb_interface *intf,
2791
2988
}
2792
2989
}
2793
2990
2991
+ #ifdef CONFIG_BT_HCIBTUSB_BCM
2992
+ if (data -> diag ) {
2993
+ if (!usb_driver_claim_interface (& btusb_driver ,
2994
+ data -> diag , data ))
2995
+ __set_diag_interface (hdev );
2996
+ else
2997
+ data -> diag = NULL ;
2998
+ }
2999
+ #endif
3000
+
2794
3001
err = hci_register_dev (hdev );
2795
3002
if (err < 0 ) {
2796
3003
hci_free_dev (hdev );
@@ -2818,12 +3025,25 @@ static void btusb_disconnect(struct usb_interface *intf)
2818
3025
if (data -> isoc )
2819
3026
usb_set_intfdata (data -> isoc , NULL );
2820
3027
3028
+ if (data -> diag )
3029
+ usb_set_intfdata (data -> diag , NULL );
3030
+
2821
3031
hci_unregister_dev (hdev );
2822
3032
2823
- if (intf == data -> isoc )
3033
+ if (intf == data -> intf ) {
3034
+ if (data -> isoc )
3035
+ usb_driver_release_interface (& btusb_driver , data -> isoc );
3036
+ if (data -> diag )
3037
+ usb_driver_release_interface (& btusb_driver , data -> diag );
3038
+ } else if (intf == data -> isoc ) {
3039
+ if (data -> diag )
3040
+ usb_driver_release_interface (& btusb_driver , data -> diag );
2824
3041
usb_driver_release_interface (& btusb_driver , data -> intf );
2825
- else if (data -> isoc )
2826
- usb_driver_release_interface (& btusb_driver , data -> isoc );
3042
+ } else if (intf == data -> diag ) {
3043
+ usb_driver_release_interface (& btusb_driver , data -> intf );
3044
+ if (data -> isoc )
3045
+ usb_driver_release_interface (& btusb_driver , data -> isoc );
3046
+ }
2827
3047
2828
3048
hci_free_dev (hdev );
2829
3049
}
0 commit comments