提交 868b8d33 编写于 作者: M Mario Limonciello 提交者: Darren Hart (VMware)

platform/x86: dell-*wmi*: Relay failed initial probe to dependent drivers

dell-wmi and dell-smbios-wmi are dependent upon dell-wmi-descriptor
finishing probe successfully to probe themselves.

Currently if dell-wmi-descriptor fails probing in a non-recoverable way
(such as invalid header) dell-wmi and dell-smbios-wmi will continue to
try to redo probing due to deferred probing.

To solve this have the dependent drivers query the dell-wmi-descriptor
driver whether the descriptor has been determined valid. The possible
results are:
-ENODEV: Descriptor GUID missing from WMI bus
-EPROBE_DEFER: Descriptor not yet probed, dependent driver should wait
 and use deferred probing
< 0: Descriptor probed, invalid.  Dependent driver should return an
 error.
0: Successful descriptor probe, dependent driver can continue

Successful descriptor probe still doesn't mean that the descriptor driver
is necessarily bound at the time of initialization of dependent driver.
Userspace can unbind the driver, so all methods used from driver
should still be verified to return success values otherwise deferred
probing be used.
Signed-off-by: NMario Limonciello <mario.limonciello@dell.com>
Reviewed-by: NPali Rohár <pali.rohar@gmail.com>
Signed-off-by: NDarren Hart (VMware) <dvhart@infradead.org>
上级 8b9528a6
...@@ -151,8 +151,9 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev) ...@@ -151,8 +151,9 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev)
int count; int count;
int ret; int ret;
if (!wmi_has_guid(DELL_WMI_DESCRIPTOR_GUID)) ret = dell_wmi_get_descriptor_valid();
return -ENODEV; if (ret)
return ret;
priv = devm_kzalloc(&wdev->dev, sizeof(struct wmi_smbios_priv), priv = devm_kzalloc(&wdev->dev, sizeof(struct wmi_smbios_priv),
GFP_KERNEL); GFP_KERNEL);
......
...@@ -21,14 +21,26 @@ ...@@ -21,14 +21,26 @@
#include <linux/wmi.h> #include <linux/wmi.h>
#include "dell-wmi-descriptor.h" #include "dell-wmi-descriptor.h"
#define DELL_WMI_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492"
struct descriptor_priv { struct descriptor_priv {
struct list_head list; struct list_head list;
u32 interface_version; u32 interface_version;
u32 size; u32 size;
}; };
static int descriptor_valid = -EPROBE_DEFER;
static LIST_HEAD(wmi_list); static LIST_HEAD(wmi_list);
static DEFINE_MUTEX(list_mutex); static DEFINE_MUTEX(list_mutex);
int dell_wmi_get_descriptor_valid(void)
{
if (!wmi_has_guid(DELL_WMI_DESCRIPTOR_GUID))
return -ENODEV;
return descriptor_valid;
}
EXPORT_SYMBOL_GPL(dell_wmi_get_descriptor_valid);
bool dell_wmi_get_interface_version(u32 *version) bool dell_wmi_get_interface_version(u32 *version)
{ {
struct descriptor_priv *priv; struct descriptor_priv *priv;
...@@ -91,6 +103,7 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev) ...@@ -91,6 +103,7 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
if (obj->type != ACPI_TYPE_BUFFER) { if (obj->type != ACPI_TYPE_BUFFER) {
dev_err(&wdev->dev, "Dell descriptor has wrong type\n"); dev_err(&wdev->dev, "Dell descriptor has wrong type\n");
ret = -EINVAL; ret = -EINVAL;
descriptor_valid = ret;
goto out; goto out;
} }
...@@ -102,6 +115,7 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev) ...@@ -102,6 +115,7 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
"Dell descriptor buffer has unexpected length (%d)\n", "Dell descriptor buffer has unexpected length (%d)\n",
obj->buffer.length); obj->buffer.length);
ret = -EINVAL; ret = -EINVAL;
descriptor_valid = ret;
goto out; goto out;
} }
...@@ -111,8 +125,10 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev) ...@@ -111,8 +125,10 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
dev_err(&wdev->dev, "Dell descriptor buffer has invalid signature (%8ph)\n", dev_err(&wdev->dev, "Dell descriptor buffer has invalid signature (%8ph)\n",
buffer); buffer);
ret = -EINVAL; ret = -EINVAL;
descriptor_valid = ret;
goto out; goto out;
} }
descriptor_valid = 0;
if (buffer[2] != 0 && buffer[2] != 1) if (buffer[2] != 0 && buffer[2] != 1)
dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%lu)\n", dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%lu)\n",
......
...@@ -13,7 +13,13 @@ ...@@ -13,7 +13,13 @@
#include <linux/wmi.h> #include <linux/wmi.h>
#define DELL_WMI_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492" /* possible return values:
* -ENODEV: Descriptor GUID missing from WMI bus
* -EPROBE_DEFER: probing for dell-wmi-descriptor not yet run
* 0: valid descriptor, successfully probed
* < 0: invalid descriptor, don't probe dependent devices
*/
int dell_wmi_get_descriptor_valid(void);
bool dell_wmi_get_interface_version(u32 *version); bool dell_wmi_get_interface_version(u32 *version);
bool dell_wmi_get_size(u32 *size); bool dell_wmi_get_size(u32 *size);
......
...@@ -655,9 +655,11 @@ static int dell_wmi_events_set_enabled(bool enable) ...@@ -655,9 +655,11 @@ static int dell_wmi_events_set_enabled(bool enable)
static int dell_wmi_probe(struct wmi_device *wdev) static int dell_wmi_probe(struct wmi_device *wdev)
{ {
struct dell_wmi_priv *priv; struct dell_wmi_priv *priv;
int ret;
if (!wmi_has_guid(DELL_WMI_DESCRIPTOR_GUID)) ret = dell_wmi_get_descriptor_valid();
return -ENODEV; if (ret)
return ret;
priv = devm_kzalloc( priv = devm_kzalloc(
&wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL); &wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册