platform/x86: wmi: Fix probe failure when failing to register WMI devices
authorArmin Wolf <W_Armin@gmx.de>
Fri, 20 Oct 2023 21:10:03 +0000 (23:10 +0200)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Wed, 25 Oct 2023 09:46:38 +0000 (12:46 +0300)
When a WMI device besides the first one somehow fails to register,
retval is returned while still containing a negative error code. This
causes the ACPI device fail to probe, leaving behind zombie WMI devices
leading to various errors later.

Handle the single error path separately and return 0 unconditionally
after trying to register all WMI devices to solve the issue. Also
continue to register WMI devices even if some fail to allocate memory.

Fixes: 6ee50aaa9a20 ("platform/x86: wmi: Instantiate all devices before adding them")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20231020211005.38216-4-W_Armin@gmx.de
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/wmi.c

index e3984801883afa003c9cbbd77eb624c1a26677a2..ab24ea9ffc9a8c6aeac32fa55ca512a30679ec46 100644 (file)
@@ -1338,8 +1338,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev)
        struct wmi_block *wblock;
        union acpi_object *obj;
        acpi_status status;
-       int retval = 0;
        u32 i, total;
+       int retval;
 
        status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out);
        if (ACPI_FAILURE(status))
@@ -1350,8 +1350,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev)
                return -ENXIO;
 
        if (obj->type != ACPI_TYPE_BUFFER) {
-               retval = -ENXIO;
-               goto out_free_pointer;
+               kfree(obj);
+               return -ENXIO;
        }
 
        gblock = (const struct guid_block *)obj->buffer.pointer;
@@ -1366,8 +1366,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev)
 
                wblock = kzalloc(sizeof(*wblock), GFP_KERNEL);
                if (!wblock) {
-                       retval = -ENOMEM;
-                       break;
+                       dev_err(wmi_bus_dev, "Failed to allocate %pUL\n", &gblock[i].guid);
+                       continue;
                }
 
                wblock->acpi_device = device;
@@ -1398,9 +1398,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev)
                }
        }
 
-out_free_pointer:
-       kfree(out.pointer);
-       return retval;
+       kfree(obj);
+
+       return 0;
 }
 
 /*