Re: [PATCH v2 1/2] platform/x86: wmi: Disambiguate WMI event data on some ACPI tables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 2022-11-13 at 21:30 +0100, Armin Wolf wrote:
> Am 13.11.22 um 13:12 schrieb Philipp Jungkamp:
> 
> > The ACPI DSDT table includes multiple WMI blocks which emit events
> > with
> > the same notify_id. The wmi_get_event_data() function chooses the
> > wmi_block with the _WED handler to call based on the notify_id.
> > This
> > function may call the wrong _WED event handler based on the order
> > the
> > WMI blocks are parsed.
> > 
> > This introduces wmi_get_event_data_with_guid() to diambiguate the
> > _WED
> > call to get metadata for an event. The GUID here is the one of the
> > containing WMI block, not the one of the WMI event itself.
> 
> Hello,
> 
> maybe it would be better to instead rewrite the driver to utilize the
> WMI bus infrastructure?
> Because a GUID is not guaranteed to be unique inside a system, there
> would still be a chance
> to call the wrong _WED handler.
> AFAIK only utilizing the WMI bus infrastructure would fully
> disambiguate the WMI event data.
> 
> Armin Wolf
> 
Hello,

I thought the same, so I implemented the bare minimum to support the
GUID on my hardware using the WMI bus in the v1 patch.

But I also agree with Hans in that it should probably reside in the
ideapad-laptop driver, so there aren't two modules for the same
hardware.

Therefore I'd need to change the WMI handling part of ideapad-laptop in
a way that does not break other hardware.

I don't know how to write a driver which connects on two buses.
The driver is currently for a platform device with the corresponding
probe and remove hooks. How would I coordinate the private data
allocation/deletion between the  platform-probe/-remove and wmi-probe/-
remove in a way that is established by other drivers.

Do you have a recommendation on how to setup a module to register on
two buses or another driver that is good to learn from?

Greetings,
Philipp Jungkamp

> > Signed-off-by: Philipp Jungkamp <p.jungkamp@xxxxxxx>
> > ---
> > Was separating this change into it's own commit correct?
> > 
> >   drivers/platform/x86/wmi.c | 30 ++++++++++++++++++++++++++++++
> >   include/linux/acpi.h       |  3 +++
> >   2 files changed, 33 insertions(+)
> > 
> > diff --git a/drivers/platform/x86/wmi.c
> > b/drivers/platform/x86/wmi.c
> > index 223550a10d4d..56b666f4b40b 100644
> > --- a/drivers/platform/x86/wmi.c
> > +++ b/drivers/platform/x86/wmi.c
> > @@ -659,6 +659,36 @@ acpi_status wmi_get_event_data(u32 event,
> > struct acpi_buffer *out)
> >   }
> >   EXPORT_SYMBOL_GPL(wmi_get_event_data);
> > 
> > +/**
> > + * wmi_get_event_data_with_guid - Get WMI data associated with an
> > event by guid
> > + *
> > + * Consider using this instead of wmi_get_event_data() when the
> > notify_id
> > + * of the WMI event may not be unique among all WMI blocks of a
> > device.
> > + *
> > + * @guid: GUID of the WMI block for this event
> > + * @event: Event to find
> > + * @out: Buffer to hold event data. out->pointer should be freed
> > with kfree()
> > + *
> > + * Returns extra data associated with an event in WMI.
> > + */
> > +acpi_status wmi_get_event_data_with_guid(const char *guid, u32
> > event, struct acpi_buffer *out)
> > +{
> > +       struct wmi_block *wblock = NULL;
> > +       struct guid_block *gblock;
> > +       acpi_status status;
> > +
> > +       status = find_guid(guid, &wblock);
> > +       if (ACPI_FAILURE(status))
> > +               return AE_NOT_FOUND;
> > +
> > +       gblock = &wblock->gblock;
> > +       if ((gblock->flags & ACPI_WMI_EVENT) && gblock->notify_id
> > == event)
> > +               return get_event_data(wblock, out);
> > +
> > +       return AE_NOT_FOUND;
> > +}
> > +EXPORT_SYMBOL_GPL(wmi_get_event_data_with_guid);
> > +
> >   /**
> >    * wmi_has_guid - Check if a GUID is available
> >    * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-
> > 83fa-65417f2f49ba
> > diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> > index 3015235d65e3..51ac4d6bcae1 100644
> > --- a/include/linux/acpi.h
> > +++ b/include/linux/acpi.h
> > @@ -423,6 +423,9 @@ extern acpi_status wmi_set_block(const char
> > *guid, u8 instance,
> >   extern acpi_status wmi_install_notify_handler(const char *guid,
> >                                         wmi_notify_handler handler,
> > void *data);
> >   extern acpi_status wmi_remove_notify_handler(const char *guid);
> > +extern acpi_status wmi_get_event_data_with_guid(const char *guid,
> > +                                               u32 event,
> > +                                               struct acpi_buffer
> > *out);
> >   extern acpi_status wmi_get_event_data(u32 event, struct
> > acpi_buffer *out);
> >   extern bool wmi_has_guid(const char *guid);
> >   extern char *wmi_get_acpi_device_uid(const char *guid);
> > --
> > 2.38.1
> > 





[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux