@@ -309,12 +309,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
309309static struct calling_interface_buffer * buffer ;
310310static DEFINE_MUTEX (buffer_mutex );
311311
312- static int hwswitch_state ;
312+ static void clear_buffer (void )
313+ {
314+ memset (buffer , 0 , sizeof (struct calling_interface_buffer ));
315+ }
313316
314317static void get_buffer (void )
315318{
316319 mutex_lock (& buffer_mutex );
317- memset ( buffer , 0 , sizeof ( struct calling_interface_buffer ) );
320+ clear_buffer ( );
318321}
319322
320323static void release_buffer (void )
@@ -548,21 +551,41 @@ static int dell_rfkill_set(void *data, bool blocked)
548551 int disable = blocked ? 1 : 0 ;
549552 unsigned long radio = (unsigned long )data ;
550553 int hwswitch_bit = (unsigned long )data - 1 ;
554+ int hwswitch ;
555+ int status ;
556+ int ret ;
551557
552558 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 ;
553570 dell_send_request (buffer , 17 , 11 );
571+ ret = buffer -> output [0 ];
572+ hwswitch = buffer -> output [1 ];
554573
555574 /* If the hardware switch controls this radio, and the hardware
556575 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 )))
559578 disable = 1 ;
560579
580+ clear_buffer ();
581+
561582 buffer -> input [0 ] = (1 | (radio <<8 ) | (disable << 16 ));
562583 dell_send_request (buffer , 17 , 11 );
584+ ret = buffer -> output [0 ];
563585
586+ out :
564587 release_buffer ();
565- return 0 ;
588+ return dell_smi_error ( ret ) ;
566589}
567590
568591/* Must be called with the buffer held */
@@ -572,6 +595,7 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
572595 if (status & BIT (0 )) {
573596 /* Has hw-switch, sync sw_state to BIOS */
574597 int block = rfkill_blocked (rfkill );
598+ clear_buffer ();
575599 buffer -> input [0 ] = (1 | (radio << 8 ) | (block << 16 ));
576600 dell_send_request (buffer , 17 , 11 );
577601 } else {
@@ -581,23 +605,43 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
581605}
582606
583607static void dell_rfkill_update_hw_state (struct rfkill * rfkill , int radio ,
584- int status )
608+ int status , int hwswitch )
585609{
586- if (hwswitch_state & (BIT (radio - 1 )))
610+ if (hwswitch & (BIT (radio - 1 )))
587611 rfkill_set_hw_state (rfkill , !(status & BIT (16 )));
588612}
589613
590614static void dell_rfkill_query (struct rfkill * rfkill , void * data )
591615{
616+ int radio = ((unsigned long )data & 0xF );
617+ int hwswitch ;
592618 int status ;
619+ int ret ;
593620
594621 get_buffer ();
622+
595623 dell_send_request (buffer , 17 , 11 );
624+ ret = buffer -> output [0 ];
596625 status = buffer -> output [1 ];
597626
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 ];
599638
600639 release_buffer ();
640+
641+ if (ret != 0 )
642+ return ;
643+
644+ dell_rfkill_update_hw_state (rfkill , radio , status , hwswitch );
601645}
602646
603647static const struct rfkill_ops dell_rfkill_ops = {
@@ -609,13 +653,27 @@ static struct dentry *dell_laptop_dir;
609653
610654static int dell_debugfs_show (struct seq_file * s , void * data )
611655{
656+ int hwswitch_state ;
657+ int hwswitch_ret ;
612658 int status ;
659+ int ret ;
613660
614661 get_buffer ();
662+
615663 dell_send_request (buffer , 17 , 11 );
664+ ret = buffer -> output [0 ];
616665 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+
617674 release_buffer ();
618675
676+ seq_printf (s , "return:\t%d\n" , ret );
619677 seq_printf (s , "status:\t0x%X\n" , status );
620678 seq_printf (s , "Bit 0 : Hardware switch supported: %lu\n" ,
621679 status & BIT (0 ));
@@ -657,7 +715,8 @@ static int dell_debugfs_show(struct seq_file *s, void *data)
657715 seq_printf (s , "Bit 21: WiGig is blocked: %lu\n" ,
658716 (status & BIT (21 )) >> 21 );
659717
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 );
661720 seq_printf (s , "Bit 0 : Wifi controlled by switch: %lu\n" ,
662721 hwswitch_state & BIT (0 ));
663722 seq_printf (s , "Bit 1 : Bluetooth controlled by switch: %lu\n" ,
@@ -693,25 +752,43 @@ static const struct file_operations dell_debugfs_fops = {
693752
694753static void dell_update_rfkill (struct work_struct * ignored )
695754{
755+ int hwswitch = 0 ;
696756 int status ;
757+ int ret ;
697758
698759 get_buffer ();
760+
699761 dell_send_request (buffer , 17 , 11 );
762+ ret = buffer -> output [0 ];
700763 status = buffer -> output [1 ];
701764
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+
702777 if (wifi_rfkill ) {
703- dell_rfkill_update_hw_state (wifi_rfkill , 1 , status );
778+ dell_rfkill_update_hw_state (wifi_rfkill , 1 , status , hwswitch );
704779 dell_rfkill_update_sw_state (wifi_rfkill , 1 , status );
705780 }
706781 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 );
708784 dell_rfkill_update_sw_state (bluetooth_rfkill , 2 , status );
709785 }
710786 if (wwan_rfkill ) {
711- dell_rfkill_update_hw_state (wwan_rfkill , 3 , status );
787+ dell_rfkill_update_hw_state (wwan_rfkill , 3 , status , hwswitch );
712788 dell_rfkill_update_sw_state (wwan_rfkill , 3 , status );
713789 }
714790
791+ out :
715792 release_buffer ();
716793}
717794static DECLARE_DELAYED_WORK (dell_rfkill_work , dell_update_rfkill ) ;
@@ -773,21 +850,17 @@ static int __init dell_setup_rfkill(void)
773850
774851 get_buffer ();
775852 dell_send_request (buffer , 17 , 11 );
853+ ret = buffer -> output [0 ];
776854 status = buffer -> output [1 ];
777- buffer -> input [0 ] = 0x2 ;
778- dell_send_request (buffer , 17 , 11 );
779- hwswitch_state = buffer -> output [1 ];
780855 release_buffer ();
781856
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 ;
791864
792865 if ((status & (1 <<2 |1 <<8 )) == (1 <<2 |1 <<8 )) {
793866 wifi_rfkill = rfkill_alloc ("dell-wifi" , & platform_device -> dev ,
@@ -932,47 +1005,50 @@ static void dell_cleanup_rfkill(void)
9321005
9331006static int dell_send_intensity (struct backlight_device * bd )
9341007{
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 ;
9361014
9371015 get_buffer ();
938- buffer -> input [0 ] = find_token_location ( BRIGHTNESS_TOKEN ) ;
1016+ buffer -> input [0 ] = token ;
9391017 buffer -> input [1 ] = bd -> props .brightness ;
9401018
941- if (buffer -> input [0 ] == -1 ) {
942- ret = - ENODEV ;
943- goto out ;
944- }
945-
9461019 if (power_supply_is_system_supplied () > 0 )
9471020 dell_send_request (buffer , 1 , 2 );
9481021 else
9491022 dell_send_request (buffer , 1 , 1 );
9501023
951- out :
1024+ ret = dell_smi_error (buffer -> output [0 ]);
1025+
9521026 release_buffer ();
9531027 return ret ;
9541028}
9551029
9561030static int dell_get_intensity (struct backlight_device * bd )
9571031{
958- int ret = 0 ;
1032+ int token ;
1033+ int ret ;
9591034
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 ;
9621038
963- if (buffer -> input [0 ] == -1 ) {
964- ret = - ENODEV ;
965- goto out ;
966- }
1039+ get_buffer ();
1040+ buffer -> input [0 ] = token ;
9671041
9681042 if (power_supply_is_system_supplied () > 0 )
9691043 dell_send_request (buffer , 0 , 2 );
9701044 else
9711045 dell_send_request (buffer , 0 , 1 );
9721046
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 ];
9741051
975- out :
9761052 release_buffer ();
9771053 return ret ;
9781054}
@@ -2036,6 +2112,7 @@ static void kbd_led_exit(void)
20362112static int __init dell_init (void )
20372113{
20382114 int max_intensity = 0 ;
2115+ int token ;
20392116 int ret ;
20402117
20412118 if (!dmi_check_system (dell_device_table ))
@@ -2094,13 +2171,15 @@ static int __init dell_init(void)
20942171 if (acpi_video_get_backlight_type () != acpi_backlight_vendor )
20952172 return 0 ;
20962173
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 ;
21002178 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 ();
21022182 }
2103- release_buffer ();
21042183
21052184 if (max_intensity ) {
21062185 struct backlight_properties props ;
0 commit comments