[Lucid SRU] UBUNTU: SAUCE: dell-laptop: fire SMI when toggling hardware killswitch

Keng-Yu Lin keng-yu.lin at canonical.com
Wed Jun 9 07:44:39 UTC 2010


SRU Justification:

Impact:
A type of Dell Inspiron Mini does not turn off bluetooth physically when
pressing F2 (rfkill hotkey). 

Fix: 
Current kernel code expects hardware to handle the hard-rfkill switching
spontaneously and only notify rfkill subsystem with the status change.
This patch makes kernel to explicitly fire a SMI to switch on/off
rfkill devices if BIOS reports that the hardware switch is not supported.

This patch depends on the following sauce patch in lucid kernel so is not going upstream:
	UBUNTU: SAUCE: dell-laptop: Store the HW switch status internally rather than requerying every time

Testcase: 
I tested the patch on a Dell Mini 10. It works smoothly.

--
>From b17359e833677297d4d5daf78e4d9dc460e51285 Mon Sep 17 00:00:00 2001
From: Keng-Yu Lin <keng-yu.lin at canonical.com>
Date: Thu, 3 Jun 2010 10:31:56 +0800
Subject: [PATCH] UBUNTU: SAUCE: dell-laptop: fire SMI when toggling hardware killswitch

When BIOS reports hardware switch is not supported, it does not turn on/off all
devices spontaneously. So it is neccessary to fire an SMI to switch the rfkill
status explicitly when toggling the hardware killswitch.

BugLink: http://bugs.launchpad.net/bugs/590607

Signed-off-by: Keng-Yu Lin <keng-yu.lin at canonical.com>
---
 drivers/platform/x86/dell-laptop.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 15d96a0..e54ab12 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -29,6 +29,7 @@
 #define WLAN_SWITCH_MASK 0
 #define BT_SWITCH_MASK 1
 #define WWAN_SWITCH_MASK 2
+#define HW_SWITCH_SUPPORT 3
 #define HW_SWITCH_MASK 16
 
 /* This structure will be modified by the firmware when we enter
@@ -240,7 +241,7 @@ static int dell_rfkill_set(void *data, bool blocked)
 	int disable = blocked ? 1 : 0;
 	unsigned long radio = (unsigned long)data;
 
-	if (!(hw_switch_status & BIT(radio-1)) || !(hw_switch_status & BIT(HW_SWITCH_MASK))) {
+	if (!(hw_switch_status & BIT(radio-1)) || !(hw_switch_status & BIT(HW_SWITCH_MASK)) || !(hw_switch_status & BIT(HW_SWITCH_SUPPORT))) {
 		memset(&buffer, 0, sizeof(struct calling_interface_buffer));
 		buffer.input[0] = (1 | (radio<<8) | (disable << 16));
 		dell_send_request(&buffer, 17, 11);
@@ -258,6 +259,7 @@ static void dell_rfkill_query(struct rfkill *rfkill, void *data)
 	dell_send_request(&buffer, 17, 11);
 	status = buffer.output[1];
 
+	hw_switch_status |= (status & BIT(0)) << BIT(HW_SWITCH_SUPPORT);
 	hw_switch_status |= (status & BIT(HW_SWITCH_MASK)) ^ BIT(HW_SWITCH_MASK);
 
 	/* HW switch control not supported
-- 
1.7.0.4





More information about the kernel-team mailing list