All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michał Kępień" <kernel@kempniu.pl>
To: Andy Lutomirski <luto@kernel.org>
Cc: "Darren Hart" <dvhart@infradead.org>,
	"Matthew Garrett" <mjg59@srcf.ucam.org>,
	linux-acpi@vger.kernel.org, platform-driver-x86@vger.kernel.org,
	"Mario Limonciello" <mario_limonciello@dell.com>,
	"Pali Rohár" <pali.rohar@gmail.com>
Subject: Re: [PATCH 08/14] wmi: Probe data objects for read and write capabilities
Date: Sat, 16 Jan 2016 14:11:11 +0100	[thread overview]
Message-ID: <20160116131111.GB7816@eudyptula.hq.kempniu.pl> (raw)
In-Reply-To: <6027f0563e82e3ca5265c6b29777636a9b8dc244.1448931782.git.luto@kernel.org>

> My laptop has one RW data object, one RO data object, and one
> totally inaccessible data object.  Check for the existence of the
> accessor methods and report in sysfs.
> 
> The docs also permit WQxx getters for single-instance objects to
> take no parameters.  Probe for that as well to avoid ACPICA warnings
> about mismatched signatures.
> 
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
> ---
>  drivers/platform/x86/wmi.c | 94 ++++++++++++++++++++++++++++++++++++++++++++--
>  include/linux/wmi.h        |  6 +++
>  2 files changed, 96 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
> index 5571ae7354a1..49be61207c4a 100644
> --- a/drivers/platform/x86/wmi.c
> +++ b/drivers/platform/x86/wmi.c
> @@ -66,6 +66,8 @@ struct wmi_block {
>  	struct acpi_device *acpi_device;
>  	wmi_notify_handler handler;
>  	void *handler_data;
> +
> +	bool read_takes_no_args;	/* only defined if readable */
>  };
>  
>  
> @@ -216,6 +218,25 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
>  	return false;
>  }
>  
> +static int get_subobj_info(acpi_handle handle, const char *pathname,
> +			   struct acpi_device_info *info)
> +{
> +	acpi_handle subobj_handle;
> +	acpi_status status;
> +
> +	status = acpi_get_handle(handle, (char *)pathname, &subobj_handle);
> +	if (status == AE_NOT_FOUND)
> +		return -ENOENT;
> +	else if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	status = acpi_get_object_info(subobj_handle, &info);

acpi_get_object_info() allocates the returned buffer itself.  The latter
should then subsequently be freed by the caller.  One solution is to
change get_subobj_info() so that it takes a struct acpi_device_info **
as an argument, which should then be passed to acpi_get_object_info().
See also below.

> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
>  static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)
>  {
>  	struct guid_block *block = NULL;
> @@ -339,6 +360,9 @@ struct acpi_buffer *out)
>  	wq_params[0].type = ACPI_TYPE_INTEGER;
>  	wq_params[0].integer.value = instance;
>  
> +	if (instance == 0 && wblock->read_takes_no_args)
> +		input.count = 0;
> +
>  	/*
>  	 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method first to
>  	 * enable collection.
> @@ -706,11 +730,37 @@ static ssize_t object_id_show(struct device *dev, struct device_attribute *attr,
>  }
>  static DEVICE_ATTR_RO(object_id);
>  
> -static struct attribute *wmi_data_or_method_attrs[] = {
> +static ssize_t readable_show(struct device *dev, struct device_attribute *attr,
> +			     char *buf)
> +{
> +	struct wmi_device *wdev = dev_to_wdev(dev);
> +
> +	return sprintf(buf, "%d\n", (int)wdev->readable);
> +}
> +static DEVICE_ATTR_RO(readable);
> +
> +static ssize_t writeable_show(struct device *dev, struct device_attribute *attr,
> +			      char *buf)
> +{
> +	struct wmi_device *wdev = dev_to_wdev(dev);
> +
> +	return sprintf(buf, "%d\n", (int)wdev->writeable);
> +}
> +static DEVICE_ATTR_RO(writeable);
> +
> +static struct attribute *wmi_data_attrs[] = {
>  	&dev_attr_object_id.attr,
> +	&dev_attr_readable.attr,
> +	&dev_attr_writeable.attr,
>  	NULL,
>  };
> -ATTRIBUTE_GROUPS(wmi_data_or_method);
> +ATTRIBUTE_GROUPS(wmi_data);
> +
> +static struct attribute *wmi_method_attrs[] = {
> +	&dev_attr_object_id.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(wmi_method);
>  
>  static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
>  {
> @@ -809,13 +859,13 @@ static struct device_type wmi_type_event = {
>  
>  static struct device_type wmi_type_method = {
>  	.name = "method",
> -	.groups = wmi_data_or_method_groups,
> +	.groups = wmi_method_groups,
>  	.release = wmi_dev_release,
>  };
>  
>  static struct device_type wmi_type_data = {
>  	.name = "data",
> -	.groups = wmi_data_or_method_groups,
> +	.groups = wmi_data_groups,
>  	.release = wmi_dev_release,
>  };
>  
> @@ -834,7 +884,43 @@ static int wmi_create_device(struct device *wmi_bus_dev,
>  	} else if (gblock->flags & ACPI_WMI_METHOD) {
>  		wblock->dev.dev.type = &wmi_type_method;
>  	} else {
> +		struct acpi_device_info info;

struct acpi_device_info *info;

> +		char method[5];
> +		int result;
> +
>  		wblock->dev.dev.type = &wmi_type_data;
> +
> +		strcpy(method, "WQ");
> +		strncat(method, wblock->gblock.object_id, 2);
> +		result = get_subobj_info(device->handle, method, &info);
> +
> +		if (result == 0) {
> +			wblock->dev.readable = true;
> +
> +			/*
> +			 * The Microsoft documentation specifically states:
> +			 *
> +			 *   Data blocks registered with only a single instance
> +			 *   can ignore the parameter.
> +			 *
> +			 * ACPICA will get mad at us if we call the method
> +			 * with the wrong number of arguments, so check what
> +			 * our method expects.  (On some Dell laptops, WQxx
> +			 * may not be a method at all.)
> +			 */
> +			if (info.type != ACPI_TYPE_METHOD ||
> +			    info.param_count == 0)
> +				wblock->read_takes_no_args = true;

kfree(info)

> +		}
> +
> +		strcpy(method, "WS");
> +		strncat(method, wblock->gblock.object_id, 2);
> +		result = get_subobj_info(device->handle, method, &info);
> +
> +		if (result == 0) {
> +			wblock->dev.writeable = true;

kfree(info)

-- 
Best regards,
Michał Kępień
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2016-01-16 13:11 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-01  1:05 [PATCH 00/14] Big WMI driver rework Andy Lutomirski
2015-12-01  1:05 ` [PATCH 01/14] wmi: Drop "Mapper (un)loaded" messages Andy Lutomirski
2015-12-01  1:05 ` [PATCH 02/14] wmi: Pass the acpi_device through to parse_wdg Andy Lutomirski
2015-12-01  1:05 ` [PATCH 03/14] wmi: Clean up acpi_wmi_add Andy Lutomirski
2015-12-01  1:05 ` [PATCH 04/14] wmi: Track wmi devices per ACPI device Andy Lutomirski
2015-12-01  1:05 ` [PATCH 05/14] wmi: Turn WMI into a bus driver Andy Lutomirski
2016-01-16 12:56   ` Michał Kępień
2016-01-16 16:19     ` Andy Lutomirski
2015-12-01  1:05 ` [PATCH 06/14] wmi: Fix error handling when creating devices Andy Lutomirski
2015-12-01  1:05 ` [PATCH 07/14] wmi: Split devices into types and add basic sysfs attributes Andy Lutomirski
2015-12-01  1:05 ` [PATCH 08/14] wmi: Probe data objects for read and write capabilities Andy Lutomirski
2016-01-16 13:11   ` Michał Kępień [this message]
2016-01-16 16:14     ` Andy Lutomirski
2017-01-10  5:56       ` Michał Kępień
2017-01-10 10:05         ` Andy Lutomirski
2017-01-12  5:01           ` Michał Kępień
2017-01-13  1:42             ` Andy Lutomirski
2015-12-01  1:05 ` [PATCH 09/14] wmi: Instantiate all devices before adding them Andy Lutomirski
2016-01-17 14:06   ` Michał Kępień
2015-12-01  1:06 ` [PATCH 10/14] wmi: Add a driver .notify function Andy Lutomirski
2015-12-01  1:06 ` [PATCH 11/14] wmi: Add a new interface to read block data Andy Lutomirski
2015-12-01  1:06 ` [PATCH 12/14] wmi: Switch from acpi_driver.notify to acpi_install_notify_handler Andy Lutomirski
2015-12-01  1:06 ` [PATCH 13/14] wmi: Bind the platform device, not the ACPI node Andy Lutomirski
2015-12-01  1:06 ` [PATCH 14/14] dell-wmi: Convert to the WMI bus infrastructure Andy Lutomirski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160116131111.GB7816@eudyptula.hq.kempniu.pl \
    --to=kernel@kempniu.pl \
    --cc=dvhart@infradead.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mario_limonciello@dell.com \
    --cc=mjg59@srcf.ucam.org \
    --cc=pali.rohar@gmail.com \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.