@@ -309,12 +309,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
309
309
static struct calling_interface_buffer * buffer ;
310
310
static DEFINE_MUTEX (buffer_mutex );
311
311
312
- static int hwswitch_state ;
312
+ static void clear_buffer (void )
313
+ {
314
+ memset (buffer , 0 , sizeof (struct calling_interface_buffer ));
315
+ }
313
316
314
317
static void get_buffer (void )
315
318
{
316
319
mutex_lock (& buffer_mutex );
317
- memset ( buffer , 0 , sizeof ( struct calling_interface_buffer ) );
320
+ clear_buffer ( );
318
321
}
319
322
320
323
static void release_buffer (void )
@@ -548,21 +551,41 @@ static int dell_rfkill_set(void *data, bool blocked)
548
551
int disable = blocked ? 1 : 0 ;
549
552
unsigned long radio = (unsigned long )data ;
550
553
int hwswitch_bit = (unsigned long )data - 1 ;
554
+ int hwswitch ;
555
+ int status ;
556
+ int ret ;
551
557
552
558
get_buffer ();
559
+
560
+ dell_send_request (buffer , 17 , 11 );
561
+ ret = buffer -> output [0 ];
562
+ status = buffer -> output [1 ];
563
+
564
+ if (ret != 0 )
565
+ goto out ;
566
+
567
+ clear_buffer ();
568
+
569
+ buffer -> input [0 ] = 0x2 ;
553
570
dell_send_request (buffer , 17 , 11 );
571
+ ret = buffer -> output [0 ];
572
+ hwswitch = buffer -> output [1 ];
554
573
555
574
/* If the hardware switch controls this radio, and the hardware
556
575
switch is disabled, always disable the radio */
557
- if (( hwswitch_state & BIT (hwswitch_bit )) &&
558
- !( buffer -> output [ 1 ] & BIT (16 )))
576
+ if (ret == 0 && ( hwswitch & BIT (hwswitch_bit )) &&
577
+ ( status & BIT ( 0 )) && !( status & BIT (16 )))
559
578
disable = 1 ;
560
579
580
+ clear_buffer ();
581
+
561
582
buffer -> input [0 ] = (1 | (radio <<8 ) | (disable << 16 ));
562
583
dell_send_request (buffer , 17 , 11 );
584
+ ret = buffer -> output [0 ];
563
585
586
+ out :
564
587
release_buffer ();
565
- return 0 ;
588
+ return dell_smi_error ( ret ) ;
566
589
}
567
590
568
591
/* Must be called with the buffer held */
@@ -572,6 +595,7 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
572
595
if (status & BIT (0 )) {
573
596
/* Has hw-switch, sync sw_state to BIOS */
574
597
int block = rfkill_blocked (rfkill );
598
+ clear_buffer ();
575
599
buffer -> input [0 ] = (1 | (radio << 8 ) | (block << 16 ));
576
600
dell_send_request (buffer , 17 , 11 );
577
601
} else {
@@ -581,23 +605,43 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
581
605
}
582
606
583
607
static void dell_rfkill_update_hw_state (struct rfkill * rfkill , int radio ,
584
- int status )
608
+ int status , int hwswitch )
585
609
{
586
- if (hwswitch_state & (BIT (radio - 1 )))
610
+ if (hwswitch & (BIT (radio - 1 )))
587
611
rfkill_set_hw_state (rfkill , !(status & BIT (16 )));
588
612
}
589
613
590
614
static void dell_rfkill_query (struct rfkill * rfkill , void * data )
591
615
{
616
+ int radio = ((unsigned long )data & 0xF );
617
+ int hwswitch ;
592
618
int status ;
619
+ int ret ;
593
620
594
621
get_buffer ();
622
+
595
623
dell_send_request (buffer , 17 , 11 );
624
+ ret = buffer -> output [0 ];
596
625
status = buffer -> output [1 ];
597
626
598
- dell_rfkill_update_hw_state (rfkill , (unsigned long )data , status );
627
+ if (ret != 0 || !(status & BIT (0 ))) {
628
+ release_buffer ();
629
+ return ;
630
+ }
631
+
632
+ clear_buffer ();
633
+
634
+ buffer -> input [0 ] = 0x2 ;
635
+ dell_send_request (buffer , 17 , 11 );
636
+ ret = buffer -> output [0 ];
637
+ hwswitch = buffer -> output [1 ];
599
638
600
639
release_buffer ();
640
+
641
+ if (ret != 0 )
642
+ return ;
643
+
644
+ dell_rfkill_update_hw_state (rfkill , radio , status , hwswitch );
601
645
}
602
646
603
647
static const struct rfkill_ops dell_rfkill_ops = {
@@ -609,13 +653,27 @@ static struct dentry *dell_laptop_dir;
609
653
610
654
static int dell_debugfs_show (struct seq_file * s , void * data )
611
655
{
656
+ int hwswitch_state ;
657
+ int hwswitch_ret ;
612
658
int status ;
659
+ int ret ;
613
660
614
661
get_buffer ();
662
+
615
663
dell_send_request (buffer , 17 , 11 );
664
+ ret = buffer -> output [0 ];
616
665
status = buffer -> output [1 ];
666
+
667
+ clear_buffer ();
668
+
669
+ buffer -> input [0 ] = 0x2 ;
670
+ dell_send_request (buffer , 17 , 11 );
671
+ hwswitch_ret = buffer -> output [0 ];
672
+ hwswitch_state = buffer -> output [1 ];
673
+
617
674
release_buffer ();
618
675
676
+ seq_printf (s , "return:\t%d\n" , ret );
619
677
seq_printf (s , "status:\t0x%X\n" , status );
620
678
seq_printf (s , "Bit 0 : Hardware switch supported: %lu\n" ,
621
679
status & BIT (0 ));
@@ -657,7 +715,8 @@ static int dell_debugfs_show(struct seq_file *s, void *data)
657
715
seq_printf (s , "Bit 21: WiGig is blocked: %lu\n" ,
658
716
(status & BIT (21 )) >> 21 );
659
717
660
- seq_printf (s , "\nhwswitch_state:\t0x%X\n" , hwswitch_state );
718
+ seq_printf (s , "\nhwswitch_return:\t%d\n" , hwswitch_ret );
719
+ seq_printf (s , "hwswitch_state:\t0x%X\n" , hwswitch_state );
661
720
seq_printf (s , "Bit 0 : Wifi controlled by switch: %lu\n" ,
662
721
hwswitch_state & BIT (0 ));
663
722
seq_printf (s , "Bit 1 : Bluetooth controlled by switch: %lu\n" ,
@@ -693,25 +752,43 @@ static const struct file_operations dell_debugfs_fops = {
693
752
694
753
static void dell_update_rfkill (struct work_struct * ignored )
695
754
{
755
+ int hwswitch = 0 ;
696
756
int status ;
757
+ int ret ;
697
758
698
759
get_buffer ();
760
+
699
761
dell_send_request (buffer , 17 , 11 );
762
+ ret = buffer -> output [0 ];
700
763
status = buffer -> output [1 ];
701
764
765
+ if (ret != 0 )
766
+ goto out ;
767
+
768
+ clear_buffer ();
769
+
770
+ buffer -> input [0 ] = 0x2 ;
771
+ dell_send_request (buffer , 17 , 11 );
772
+ ret = buffer -> output [0 ];
773
+
774
+ if (ret == 0 && (status & BIT (0 )))
775
+ hwswitch = buffer -> output [1 ];
776
+
702
777
if (wifi_rfkill ) {
703
- dell_rfkill_update_hw_state (wifi_rfkill , 1 , status );
778
+ dell_rfkill_update_hw_state (wifi_rfkill , 1 , status , hwswitch );
704
779
dell_rfkill_update_sw_state (wifi_rfkill , 1 , status );
705
780
}
706
781
if (bluetooth_rfkill ) {
707
- dell_rfkill_update_hw_state (bluetooth_rfkill , 2 , status );
782
+ dell_rfkill_update_hw_state (bluetooth_rfkill , 2 , status ,
783
+ hwswitch );
708
784
dell_rfkill_update_sw_state (bluetooth_rfkill , 2 , status );
709
785
}
710
786
if (wwan_rfkill ) {
711
- dell_rfkill_update_hw_state (wwan_rfkill , 3 , status );
787
+ dell_rfkill_update_hw_state (wwan_rfkill , 3 , status , hwswitch );
712
788
dell_rfkill_update_sw_state (wwan_rfkill , 3 , status );
713
789
}
714
790
791
+ out :
715
792
release_buffer ();
716
793
}
717
794
static DECLARE_DELAYED_WORK (dell_rfkill_work , dell_update_rfkill ) ;
@@ -773,21 +850,17 @@ static int __init dell_setup_rfkill(void)
773
850
774
851
get_buffer ();
775
852
dell_send_request (buffer , 17 , 11 );
853
+ ret = buffer -> output [0 ];
776
854
status = buffer -> output [1 ];
777
- buffer -> input [0 ] = 0x2 ;
778
- dell_send_request (buffer , 17 , 11 );
779
- hwswitch_state = buffer -> output [1 ];
780
855
release_buffer ();
781
856
782
- if (!(status & BIT (0 ))) {
783
- if (force_rfkill ) {
784
- /* No hwsitch, clear all hw-controlled bits */
785
- hwswitch_state &= ~7 ;
786
- } else {
787
- /* rfkill is only tested on laptops with a hwswitch */
788
- return 0 ;
789
- }
790
- }
857
+ /* dell wireless info smbios call is not supported */
858
+ if (ret != 0 )
859
+ return 0 ;
860
+
861
+ /* rfkill is only tested on laptops with a hwswitch */
862
+ if (!(status & BIT (0 )) && !force_rfkill )
863
+ return 0 ;
791
864
792
865
if ((status & (1 <<2 |1 <<8 )) == (1 <<2 |1 <<8 )) {
793
866
wifi_rfkill = rfkill_alloc ("dell-wifi" , & platform_device -> dev ,
@@ -932,47 +1005,50 @@ static void dell_cleanup_rfkill(void)
932
1005
933
1006
static int dell_send_intensity (struct backlight_device * bd )
934
1007
{
935
- int ret = 0 ;
1008
+ int token ;
1009
+ int ret ;
1010
+
1011
+ token = find_token_location (BRIGHTNESS_TOKEN );
1012
+ if (token == -1 )
1013
+ return - ENODEV ;
936
1014
937
1015
get_buffer ();
938
- buffer -> input [0 ] = find_token_location ( BRIGHTNESS_TOKEN ) ;
1016
+ buffer -> input [0 ] = token ;
939
1017
buffer -> input [1 ] = bd -> props .brightness ;
940
1018
941
- if (buffer -> input [0 ] == -1 ) {
942
- ret = - ENODEV ;
943
- goto out ;
944
- }
945
-
946
1019
if (power_supply_is_system_supplied () > 0 )
947
1020
dell_send_request (buffer , 1 , 2 );
948
1021
else
949
1022
dell_send_request (buffer , 1 , 1 );
950
1023
951
- out :
1024
+ ret = dell_smi_error (buffer -> output [0 ]);
1025
+
952
1026
release_buffer ();
953
1027
return ret ;
954
1028
}
955
1029
956
1030
static int dell_get_intensity (struct backlight_device * bd )
957
1031
{
958
- int ret = 0 ;
1032
+ int token ;
1033
+ int ret ;
959
1034
960
- get_buffer ();
961
- buffer -> input [0 ] = find_token_location (BRIGHTNESS_TOKEN );
1035
+ token = find_token_location (BRIGHTNESS_TOKEN );
1036
+ if (token == -1 )
1037
+ return - ENODEV ;
962
1038
963
- if (buffer -> input [0 ] == -1 ) {
964
- ret = - ENODEV ;
965
- goto out ;
966
- }
1039
+ get_buffer ();
1040
+ buffer -> input [0 ] = token ;
967
1041
968
1042
if (power_supply_is_system_supplied () > 0 )
969
1043
dell_send_request (buffer , 0 , 2 );
970
1044
else
971
1045
dell_send_request (buffer , 0 , 1 );
972
1046
973
- ret = buffer -> output [1 ];
1047
+ if (buffer -> output [0 ])
1048
+ ret = dell_smi_error (buffer -> output [0 ]);
1049
+ else
1050
+ ret = buffer -> output [1 ];
974
1051
975
- out :
976
1052
release_buffer ();
977
1053
return ret ;
978
1054
}
@@ -2036,6 +2112,7 @@ static void kbd_led_exit(void)
2036
2112
static int __init dell_init (void )
2037
2113
{
2038
2114
int max_intensity = 0 ;
2115
+ int token ;
2039
2116
int ret ;
2040
2117
2041
2118
if (!dmi_check_system (dell_device_table ))
@@ -2094,13 +2171,15 @@ static int __init dell_init(void)
2094
2171
if (acpi_video_get_backlight_type () != acpi_backlight_vendor )
2095
2172
return 0 ;
2096
2173
2097
- get_buffer ();
2098
- buffer -> input [0 ] = find_token_location (BRIGHTNESS_TOKEN );
2099
- if (buffer -> input [0 ] != -1 ) {
2174
+ token = find_token_location (BRIGHTNESS_TOKEN );
2175
+ if (token != -1 ) {
2176
+ get_buffer ();
2177
+ buffer -> input [0 ] = token ;
2100
2178
dell_send_request (buffer , 0 , 2 );
2101
- max_intensity = buffer -> output [3 ];
2179
+ if (buffer -> output [0 ] == 0 )
2180
+ max_intensity = buffer -> output [3 ];
2181
+ release_buffer ();
2102
2182
}
2103
- release_buffer ();
2104
2183
2105
2184
if (max_intensity ) {
2106
2185
struct backlight_properties props ;
0 commit comments