Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1169541

[PATCH 2/4] dell-laptop: Check return value of all SMBIOS calls

From Pali Rohár <pali.rohar@gmail.com>
Newsgroups linux.kernel
Subject [PATCH 2/4] dell-laptop: Check return value of all SMBIOS calls
Date 2015-06-21 10:50 +0200
Message-ID <pDJ6W-8tH-11@gated-at.bofh.it> (permalink)
References <pDJ6W-8tH-1@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


Make sure that return value of all SMBIOS calls are properly checked and
do not continue of processing (received) information if call failed.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
 drivers/platform/x86/dell-laptop.c |   61 +++++++++++++++++++++++++++++++-----
 1 file changed, 54 insertions(+), 7 deletions(-)

diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index ab89103..aaef335 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -548,21 +548,27 @@ static int dell_rfkill_set(void *data, bool blocked)
 	int disable = blocked ? 1 : 0;
 	unsigned long radio = (unsigned long)data;
 	int hwswitch_bit = (unsigned long)data - 1;
+	int status;
+	int ret;
 
 	get_buffer();
 	dell_send_request(buffer, 17, 11);
+	ret = buffer->output[0];
+	status = buffer->output[1];
 
 	/* If the hardware switch controls this radio, and the hardware
 	   switch is disabled, always disable the radio */
-	if ((hwswitch_state & BIT(hwswitch_bit)) &&
-	    !(buffer->output[1] & BIT(16)))
+	if (ret == 0 &&
+	    (hwswitch_state & BIT(hwswitch_bit)) &&
+	    !(status & BIT(16)))
 		disable = 1;
 
 	buffer->input[0] = (1 | (radio<<8) | (disable << 16));
 	dell_send_request(buffer, 17, 11);
+	ret = buffer->output[0];
 
 	release_buffer();
-	return 0;
+	return dell_smi_error(ret);
 }
 
 /* Must be called with the buffer held */
@@ -590,14 +596,18 @@ static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,
 static void dell_rfkill_query(struct rfkill *rfkill, void *data)
 {
 	int status;
+	int ret;
 
 	get_buffer();
 	dell_send_request(buffer, 17, 11);
+	ret = buffer->output[0];
 	status = buffer->output[1];
+	release_buffer();
 
-	dell_rfkill_update_hw_state(rfkill, (unsigned long)data, status);
+	if (ret != 0)
+		return;
 
-	release_buffer();
+	dell_rfkill_update_hw_state(rfkill, (unsigned long)data, status);
 }
 
 static const struct rfkill_ops dell_rfkill_ops = {
@@ -610,12 +620,15 @@ static struct dentry *dell_laptop_dir;
 static int dell_debugfs_show(struct seq_file *s, void *data)
 {
 	int status;
+	int ret;
 
 	get_buffer();
 	dell_send_request(buffer, 17, 11);
+	ret = buffer->output[0];
 	status = buffer->output[1];
 	release_buffer();
 
+	seq_printf(s, "return:\t%d\n", ret);
 	seq_printf(s, "status:\t0x%X\n", status);
 	seq_printf(s, "Bit 0 : Hardware switch supported:   %lu\n",
 		   status & BIT(0));
@@ -677,11 +690,16 @@ static const struct file_operations dell_debugfs_fops = {
 static void dell_update_rfkill(struct work_struct *ignored)
 {
 	int status;
+	int ret;
 
 	get_buffer();
 	dell_send_request(buffer, 17, 11);
+	ret = buffer->output[0];
 	status = buffer->output[1];
 
+	if (ret != 0)
+		goto out;
+
 	if (wifi_rfkill) {
 		dell_rfkill_update_hw_state(wifi_rfkill, 1, status);
 		dell_rfkill_update_sw_state(wifi_rfkill, 1, status);
@@ -695,6 +713,7 @@ static void dell_update_rfkill(struct work_struct *ignored)
 		dell_rfkill_update_sw_state(wwan_rfkill, 3, status);
 	}
 
+ out:
 	release_buffer();
 }
 static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
@@ -755,13 +774,35 @@ static int __init dell_setup_rfkill(void)
 		return 0;
 
 	get_buffer();
+
 	dell_send_request(buffer, 17, 11);
+	ret = buffer->output[0];
 	status = buffer->output[1];
+	if (ret != 0) {
+		/* dell wireless info smbios call is not working */
+		/* so there is no support for rfkill */
+		release_buffer();
+		return 0;
+	}
+
 	buffer->input[0] = 0x2;
 	dell_send_request(buffer, 17, 11);
+	ret = buffer->output[0];
 	hwswitch_state = buffer->output[1];
+
 	release_buffer();
 
+	if (ret != 0) {
+		/* dell wireless switch smbios call is not working */
+		if (force_rfkill) {
+			/* clear all hw-controlled bits */
+			hwswitch_state &= ~7;
+		} else {
+			/* rfkill is only tested on laptops with a hwswitch */
+			return 0;
+		}
+	}
+
 	if (!(status & BIT(0))) {
 		if (force_rfkill) {
 			/* No hwsitch, clear all hw-controlled bits */
@@ -931,6 +972,8 @@ static int dell_send_intensity(struct backlight_device *bd)
 	else
 		dell_send_request(buffer, 1, 1);
 
+	ret = dell_smi_error(buffer->output[0]);
+
  out:
 	release_buffer();
 	return ret;
@@ -953,7 +996,10 @@ static int dell_get_intensity(struct backlight_device *bd)
 	else
 		dell_send_request(buffer, 0, 1);
 
-	ret = buffer->output[1];
+	if (buffer->output[0])
+		ret = dell_smi_error(buffer->output[0]);
+	else
+		ret = buffer->output[1];
 
  out:
 	release_buffer();
@@ -2087,7 +2133,8 @@ static int __init dell_init(void)
 	buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN);
 	if (buffer->input[0] != -1) {
 		dell_send_request(buffer, 0, 2);
-		max_intensity = buffer->output[3];
+		if (buffer->output[0] == 0)
+			max_intensity = buffer->output[3];
 	}
 	release_buffer();
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 0/4] Fixes for dell-laptop.c driver Pali Rohár <pali.rohar@gmail.com> - 2015-06-21 10:50 +0200
  [PATCH 2/4] dell-laptop: Check return value of all SMBIOS calls Pali Rohár <pali.rohar@gmail.com> - 2015-06-21 10:50 +0200
    [PATCH v2] dell-laptop: Check return value of all SMBIOS calls and do not cache hwswitch state Pali Rohár <pali.rohar@gmail.com> - 2015-06-27 09:40 +0200
      Re: [PATCH v2] dell-laptop: Check return value of all SMBIOS calls  and do not cache hwswitch state Darren Hart <dvhart@infradead.org> - 2015-06-30 01:10 +0200
  [PATCH 3/4] dell-laptop: Fix allocating & freeing SMI buffer page Pali Rohár <pali.rohar@gmail.com> - 2015-06-21 10:50 +0200
  [PATCH 4/4] dell-laptop: Show info about WiGig and UWB in debugfs Pali Rohár <pali.rohar@gmail.com> - 2015-06-21 10:50 +0200
  [PATCH 1/4] dell-laptop: Update information about wireless control Pali Rohár <pali.rohar@gmail.com> - 2015-06-21 10:50 +0200

csiph-web