Skip to content

Commit 2e2a391

Browse files
Wer-Wolfij-intel
authored andcommitted
platform/wmi: Replace .no_notify_data with .min_event_size
WMI drivers using the buffer-based WMI API are expected to reject undersized event payloads. Extend the WMI driver core to allow such drivers to specify their minimum supported event payload size. Also remove the now redundant .no_notify_data field. Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://patch.msgid.link/20260406203237.2970-7-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>
1 parent 1aeded2 commit 2e2a391

13 files changed

Lines changed: 29 additions & 16 deletions

File tree

Documentation/wmi/driver-development-guide.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ to matching WMI devices using a struct wmi_device_id table:
7171
.remove = foo_remove, /* optional, devres is preferred */
7272
.shutdown = foo_shutdown, /* optional, called during shutdown */
7373
.notify_new = foo_notify, /* optional, for event handling */
74-
.no_notify_data = true, /* optional, enables events containing no additional data */
74+
.min_event_size = X, /* optional, simplifies event payload size verification */
7575
.no_singleton = true, /* required for new WMI drivers */
7676
};
7777
module_wmi_driver(foo_driver);
@@ -142,8 +142,10 @@ right before and after calling its remove() or shutdown() callback.
142142
However WMI driver developers should be aware that multiple WMI events can be received concurrently,
143143
so any locking (if necessary) needs to be provided by the WMI driver itself.
144144

145-
In order to be able to receive WMI events containing no additional event data,
146-
the ``no_notify_data`` flag inside struct wmi_driver should be set to ``true``.
145+
The WMI driver can furthermore instruct the WMI driver core to automatically reject WMI events
146+
that contain a undersized event payload by populating the ``min_event_size`` field inside
147+
struct wmi_driver. Setting this field to 0 will thus enable the WMI driver to receive WMI events
148+
without any event payload.
147149

148150
Take a look at drivers/platform/x86/xiaomi-wmi.c for an example WMI event driver.
149151

drivers/platform/wmi/core.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ static int wmi_dev_probe(struct device *dev)
10401040
}
10411041

10421042
if (wdriver->notify || wdriver->notify_new) {
1043-
if (test_bit(WMI_NO_EVENT_DATA, &wblock->flags) && !wdriver->no_notify_data)
1043+
if (test_bit(WMI_NO_EVENT_DATA, &wblock->flags) && wdriver->min_event_size)
10441044
return -ENODEV;
10451045
}
10461046

@@ -1398,10 +1398,14 @@ static int wmi_get_notify_data(struct wmi_block *wblock, union acpi_object **obj
13981398
static void wmi_notify_driver(struct wmi_block *wblock, union acpi_object *obj)
13991399
{
14001400
struct wmi_driver *driver = to_wmi_driver(wblock->dev.dev.driver);
1401+
struct wmi_buffer dummy = {
1402+
.length = 0,
1403+
.data = ZERO_SIZE_PTR,
1404+
};
14011405
struct wmi_buffer buffer;
14021406
int ret;
14031407

1404-
if (!obj && !driver->no_notify_data) {
1408+
if (!obj && driver->min_event_size) {
14051409
dev_warn(&wblock->dev.dev, "Event contains no event data\n");
14061410
return;
14071411
}
@@ -1411,11 +1415,11 @@ static void wmi_notify_driver(struct wmi_block *wblock, union acpi_object *obj)
14111415

14121416
if (driver->notify_new) {
14131417
if (!obj) {
1414-
driver->notify_new(&wblock->dev, NULL);
1418+
driver->notify_new(&wblock->dev, &dummy);
14151419
return;
14161420
}
14171421

1418-
ret = wmi_unmarshal_acpi_object(obj, &buffer, 0);
1422+
ret = wmi_unmarshal_acpi_object(obj, &buffer, driver->min_event_size);
14191423
if (ret < 0) {
14201424
dev_warn(&wblock->dev.dev, "Failed to unmarshal event data: %d\n", ret);
14211425
return;

drivers/platform/x86/bitland-mifs-wmi.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -734,15 +734,10 @@ static void bitland_mifs_wmi_notify(struct wmi_device *wdev,
734734
const struct wmi_buffer *buffer)
735735
{
736736
struct bitland_mifs_wmi_data *data = dev_get_drvdata(&wdev->dev);
737-
const struct bitland_mifs_event *event;
737+
const struct bitland_mifs_event *event = buffer->data;
738738
struct bitland_fan_notify_data fan_data;
739739
u8 brightness;
740740

741-
if (buffer->length < sizeof(*event))
742-
return;
743-
744-
event = buffer->data;
745-
746741
/* Validate event type */
747742
if (event->event_type != WMI_EVENT_TYPE_HOTKEY)
748743
return;
@@ -830,6 +825,7 @@ static struct wmi_driver bitland_mifs_wmi_driver = {
830825
.pm = pm_sleep_ptr(&bitland_mifs_wmi_pm_ops),
831826
},
832827
.id_table = bitland_mifs_wmi_id_table,
828+
.min_event_size = sizeof(struct bitland_mifs_event),
833829
.probe = bitland_mifs_wmi_probe,
834830
.notify_new = bitland_mifs_wmi_notify,
835831
};

drivers/platform/x86/dell/dell-wmi-base.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ static struct wmi_driver dell_wmi_driver = {
825825
.name = "dell-wmi",
826826
},
827827
.id_table = dell_wmi_id_table,
828+
.min_event_size = sizeof(u16),
828829
.probe = dell_wmi_probe,
829830
.remove = dell_wmi_remove,
830831
.notify = dell_wmi_notify,

drivers/platform/x86/lenovo/ideapad-laptop.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,6 +2340,7 @@ static struct wmi_driver ideapad_wmi_driver = {
23402340
.name = "ideapad_wmi",
23412341
},
23422342
.id_table = ideapad_wmi_ids,
2343+
.min_event_size = sizeof(u32),
23432344
.probe = ideapad_wmi_probe,
23442345
.notify = ideapad_wmi_notify,
23452346
};

drivers/platform/x86/lenovo/wmi-camera.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ static struct wmi_driver lenovo_wmi_driver = {
134134
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
135135
},
136136
.id_table = lenovo_wmi_id_table,
137+
.min_event_size = sizeof(u8),
137138
.no_singleton = true,
138139
.probe = lenovo_wmi_probe,
139140
.notify = lenovo_wmi_notify,

drivers/platform/x86/lenovo/wmi-events.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ static struct wmi_driver lwmi_events_driver = {
183183
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
184184
},
185185
.id_table = lwmi_events_id_table,
186+
.min_event_size = sizeof(u32),
186187
.probe = lwmi_events_probe,
187188
.notify = lwmi_events_notify,
188189
.no_singleton = true,

drivers/platform/x86/lenovo/ymc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ static struct wmi_driver lenovo_ymc_driver = {
153153
.name = "lenovo-ymc",
154154
},
155155
.id_table = lenovo_ymc_wmi_id_table,
156+
.min_event_size = sizeof(u32),
156157
.probe = lenovo_ymc_probe,
157158
.notify = lenovo_ymc_notify,
158159
};

drivers/platform/x86/lenovo/yogabook.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ static struct wmi_driver yogabook_wmi_driver = {
411411
.name = "yogabook-wmi",
412412
.pm = pm_sleep_ptr(&yogabook_pm_ops),
413413
},
414-
.no_notify_data = true,
415414
.id_table = yogabook_wmi_id_table,
415+
.min_event_size = 0,
416416
.probe = yogabook_wmi_probe,
417417
.remove = yogabook_wmi_remove,
418418
.notify = yogabook_wmi_notify,

drivers/platform/x86/redmi-wmi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static struct wmi_driver redmi_wmi_driver = {
141141
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
142142
},
143143
.id_table = redmi_wmi_id_table,
144+
.min_event_size = 32,
144145
.probe = redmi_wmi_probe,
145146
.notify = redmi_wmi_notify,
146147
.no_singleton = true,

0 commit comments

Comments
 (0)