aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-24 02:14:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-24 02:14:30 -0500
commit36f20ee24b5dc510389394ed2bd36fbe23f8d962 (patch)
tree74b58927988c4a3a2a88ac5d131844a1a9dfbd53
parent06c944005bc3bfe21fd5706120a2cf8eeee76284 (diff)
parentc6f9288ee460565b94994aaf3261318199c2a674 (diff)
Merge tag 'platform-drivers-x86-v4.15-2' of git://git.infradead.org/linux-platform-drivers-x86
Pull x86 platform driver fixes from Darren Hart: "Fix two issues resulting from the dell-smbios refactoring and introduction of the dell-smbios-wmi dispatcher. The first ensures a proper error code is returned when kzalloc fails. The second avoids an issue in older Dell BIOS implementations which would fail if the more complex calls were made by limiting those platforms to the simple calls such as those used by the existing dell-laptop and dell-wmi drivers, preserving their functionality prior to the addition of the dell-smbios-wmi dispatcher" * tag 'platform-drivers-x86-v4.15-2' of git://git.infradead.org/linux-platform-drivers-x86: platform/x86: dell-laptop: fix error return code in dell_init() platform/x86: dell-smbios-wmi: Disable userspace interface if missing hotfix
-rw-r--r--drivers/platform/x86/dell-laptop.c4
-rw-r--r--drivers/platform/x86/dell-smbios-wmi.c13
-rw-r--r--drivers/platform/x86/dell-wmi-descriptor.c26
-rw-r--r--drivers/platform/x86/dell-wmi-descriptor.h1
4 files changed, 41 insertions, 3 deletions
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 2d704361f672..bf897b1832b1 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -2074,8 +2074,10 @@ static int __init dell_init(void)
2074 goto fail_platform_device2; 2074 goto fail_platform_device2;
2075 2075
2076 buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL); 2076 buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL);
2077 if (!buffer) 2077 if (!buffer) {
2078 ret = -ENOMEM;
2078 goto fail_buffer; 2079 goto fail_buffer;
2080 }
2079 2081
2080 2082
2081 ret = dell_setup_rfkill(); 2083 ret = dell_setup_rfkill();
diff --git a/drivers/platform/x86/dell-smbios-wmi.c b/drivers/platform/x86/dell-smbios-wmi.c
index 0cab1f9c35af..609557aa5868 100644
--- a/drivers/platform/x86/dell-smbios-wmi.c
+++ b/drivers/platform/x86/dell-smbios-wmi.c
@@ -147,7 +147,10 @@ fail_smbios_cmd:
147 147
148static int dell_smbios_wmi_probe(struct wmi_device *wdev) 148static int dell_smbios_wmi_probe(struct wmi_device *wdev)
149{ 149{
150 struct wmi_driver *wdriver =
151 container_of(wdev->dev.driver, struct wmi_driver, driver);
150 struct wmi_smbios_priv *priv; 152 struct wmi_smbios_priv *priv;
153 u32 hotfix;
151 int count; 154 int count;
152 int ret; 155 int ret;
153 156
@@ -164,6 +167,16 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev)
164 if (!dell_wmi_get_size(&priv->req_buf_size)) 167 if (!dell_wmi_get_size(&priv->req_buf_size))
165 return -EPROBE_DEFER; 168 return -EPROBE_DEFER;
166 169
170 /* some SMBIOS calls fail unless BIOS contains hotfix */
171 if (!dell_wmi_get_hotfix(&hotfix))
172 return -EPROBE_DEFER;
173 if (!hotfix) {
174 dev_warn(&wdev->dev,
175 "WMI SMBIOS userspace interface not supported(%u), try upgrading to a newer BIOS\n",
176 hotfix);
177 wdriver->filter_callback = NULL;
178 }
179
167 /* add in the length object we will use internally with ioctl */ 180 /* add in the length object we will use internally with ioctl */
168 priv->req_buf_size += sizeof(u64); 181 priv->req_buf_size += sizeof(u64);
169 ret = set_required_buffer_size(wdev, priv->req_buf_size); 182 ret = set_required_buffer_size(wdev, priv->req_buf_size);
diff --git a/drivers/platform/x86/dell-wmi-descriptor.c b/drivers/platform/x86/dell-wmi-descriptor.c
index 4dfef1f53481..072821aa47fc 100644
--- a/drivers/platform/x86/dell-wmi-descriptor.c
+++ b/drivers/platform/x86/dell-wmi-descriptor.c
@@ -27,6 +27,7 @@ struct descriptor_priv {
27 struct list_head list; 27 struct list_head list;
28 u32 interface_version; 28 u32 interface_version;
29 u32 size; 29 u32 size;
30 u32 hotfix;
30}; 31};
31static int descriptor_valid = -EPROBE_DEFER; 32static int descriptor_valid = -EPROBE_DEFER;
32static LIST_HEAD(wmi_list); 33static LIST_HEAD(wmi_list);
@@ -77,6 +78,24 @@ bool dell_wmi_get_size(u32 *size)
77} 78}
78EXPORT_SYMBOL_GPL(dell_wmi_get_size); 79EXPORT_SYMBOL_GPL(dell_wmi_get_size);
79 80
81bool dell_wmi_get_hotfix(u32 *hotfix)
82{
83 struct descriptor_priv *priv;
84 bool ret = false;
85
86 mutex_lock(&list_mutex);
87 priv = list_first_entry_or_null(&wmi_list,
88 struct descriptor_priv,
89 list);
90 if (priv) {
91 *hotfix = priv->hotfix;
92 ret = true;
93 }
94 mutex_unlock(&list_mutex);
95 return ret;
96}
97EXPORT_SYMBOL_GPL(dell_wmi_get_hotfix);
98
80/* 99/*
81 * Descriptor buffer is 128 byte long and contains: 100 * Descriptor buffer is 128 byte long and contains:
82 * 101 *
@@ -85,6 +104,7 @@ EXPORT_SYMBOL_GPL(dell_wmi_get_size);
85 * Object Signature 4 4 " WMI" 104 * Object Signature 4 4 " WMI"
86 * WMI Interface Version 8 4 <version> 105 * WMI Interface Version 8 4 <version>
87 * WMI buffer length 12 4 <length> 106 * WMI buffer length 12 4 <length>
107 * WMI hotfix number 16 4 <hotfix>
88 */ 108 */
89static int dell_wmi_descriptor_probe(struct wmi_device *wdev) 109static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
90{ 110{
@@ -144,15 +164,17 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
144 164
145 priv->interface_version = buffer[2]; 165 priv->interface_version = buffer[2];
146 priv->size = buffer[3]; 166 priv->size = buffer[3];
167 priv->hotfix = buffer[4];
147 ret = 0; 168 ret = 0;
148 dev_set_drvdata(&wdev->dev, priv); 169 dev_set_drvdata(&wdev->dev, priv);
149 mutex_lock(&list_mutex); 170 mutex_lock(&list_mutex);
150 list_add_tail(&priv->list, &wmi_list); 171 list_add_tail(&priv->list, &wmi_list);
151 mutex_unlock(&list_mutex); 172 mutex_unlock(&list_mutex);
152 173
153 dev_dbg(&wdev->dev, "Detected Dell WMI interface version %lu and buffer size %lu\n", 174 dev_dbg(&wdev->dev, "Detected Dell WMI interface version %lu, buffer size %lu, hotfix %lu\n",
154 (unsigned long) priv->interface_version, 175 (unsigned long) priv->interface_version,
155 (unsigned long) priv->size); 176 (unsigned long) priv->size,
177 (unsigned long) priv->hotfix);
156 178
157out: 179out:
158 kfree(obj); 180 kfree(obj);
diff --git a/drivers/platform/x86/dell-wmi-descriptor.h b/drivers/platform/x86/dell-wmi-descriptor.h
index 1e8cb96ffd78..a6123a4d06a7 100644
--- a/drivers/platform/x86/dell-wmi-descriptor.h
+++ b/drivers/platform/x86/dell-wmi-descriptor.h
@@ -23,5 +23,6 @@ int dell_wmi_get_descriptor_valid(void);
23 23
24bool dell_wmi_get_interface_version(u32 *version); 24bool dell_wmi_get_interface_version(u32 *version);
25bool dell_wmi_get_size(u32 *size); 25bool dell_wmi_get_size(u32 *size);
26bool dell_wmi_get_hotfix(u32 *hotfix);
26 27
27#endif 28#endif