Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp2298448rdb; Fri, 8 Dec 2023 04:26:08 -0800 (PST) X-Google-Smtp-Source: AGHT+IFIPnCyuglBuc9oWzXMj9A3RwTMzrYm8uXcIUwIje0mrUyNVYeceqUtr8ZK3hl4Mci6AE55 X-Received: by 2002:a05:6a20:7d84:b0:18f:fdc8:f402 with SMTP id v4-20020a056a207d8400b0018ffdc8f402mr2431146pzj.96.1702038367819; Fri, 08 Dec 2023 04:26:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702038367; cv=none; d=google.com; s=arc-20160816; b=YXpE/9qynhb5urHXVFmXigWsUXnGTNtVfolOfD+WE7JRvEbGGB3vQlI9Pm7BJI9T// VjBaBeyX4aCJ7fEzGcjOWFl9bnL+Eugpyba39Aub6BeoeFUCTbbBvkQuQdytsWHdyH/e RqCD2cCjdsZPOiBeYMyJA3ipJK6KaX+uZqMTCDy7UWGzqy4xskh1hgmUO0TuliuF3XCm 1+3z+CaaDmOD4Xjhpj677vfan5kngkCwlnV2YyuaAhqT8F7gLSBc/IijRrJ7SInbhO8y 14rW4FadlcvnmL13c6q3npKhY8x91WDRgpI2HBJWU97jQLUFmE69go40UwNGQMos0r+k r+cg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:message-id:in-reply-to :subject:cc:to:from:date:dkim-signature; bh=NSWwsBvRSS9gCMwAb4AMI2NYJuagjLsxqY33pGYAYZo=; fh=v1AieQ6xn19PAQ8VnNUwelkjh2ysSSLsP24Jxpc5b64=; b=lFiqPlt+i/cB/tz0/Tsxsq3kCh+p24+4l/IxCAbykuec0xGbaVOZifgSsdWfIiLRHK X8hNvY87QAuaeCxBGQMBYcwcmS6cvMg45O7Jr1PyEzuubJf6yWdEfVlgz8qpI7kkS6Qm CZ820r7T60ClGwjTh+OJPkTJ2e/Tx5VjWnq72uWKhmCdmxCSJ1RZmg3IhBWFUFQczQT8 h1XkEu5DuwGBJzRkb9PBXR+vC2MuOCUiuX5Kd+AIXEEaWrCe9QEAvHIgauJG8sQdwlJy KKPArG5p27kx1W3TXHINUjzv8Nf3PYG/4vXtlny4a89eN4TlGpsWZPJhSzLIoPUsU2DH +NUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=RjRs9rRT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from groat.vger.email (groat.vger.email. [2620:137:e000::3:5]) by mx.google.com with ESMTPS id n15-20020a170902d2cf00b001d005527017si1519587plc.313.2023.12.08.04.26.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 08 Dec 2023 04:26:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) client-ip=2620:137:e000::3:5; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=RjRs9rRT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id E53D6824686A; Fri, 8 Dec 2023 04:26:03 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233428AbjLHMZ3 (ORCPT + 99 others); Fri, 8 Dec 2023 07:25:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36446 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229844AbjLHMZ1 (ORCPT ); Fri, 8 Dec 2023 07:25:27 -0500 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.9]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FA15AD; Fri, 8 Dec 2023 04:25:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1702038333; x=1733574333; h=date:from:to:cc:subject:in-reply-to:message-id: references:mime-version; bh=iFM6QWXztFxAu/wiWgDOnvUc9r/V18pkQZWgPrB80Jo=; b=RjRs9rRTqJ0c1zBpBt34zYD3HAxG8d/nS6V6Vn2s+44yLtIiGIMNo6Hn hyfzGvn2CwMNIHZRsr8ahE82xLLlYkWUPxXH7W139zJjUGvdJdTtApfZe +5HR8BTODYLA8rdxir2Tkm3gacZs1HD+P90nwAQUBSx0TfwdIRhmq8mCa 99kxtYIW09XKy+znW0JJtewBZVYN4ifPJu6eF/6m4NMbLuVwwCGv5CCQj Xw4Ib3NOnfGCb3h44Zhii+cwHP+LmS7WJW68SZmNLdhkoozft2I7KRYvh F+oOXAWMsE7QV3U0Mcp6YKuxE670KTq5HESZ0W4WGQQzUcFCifzn1Ya97 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10917"; a="1278028" X-IronPort-AV: E=Sophos;i="6.04,260,1695711600"; d="scan'208";a="1278028" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Dec 2023 04:25:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10917"; a="765476120" X-IronPort-AV: E=Sophos;i="6.04,260,1695711600"; d="scan'208";a="765476120" Received: from smatua-mobl.ger.corp.intel.com ([10.251.223.110]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Dec 2023 04:25:30 -0800 Date: Fri, 8 Dec 2023 14:25:27 +0200 (EET) From: =?ISO-8859-15?Q?Ilpo_J=E4rvinen?= To: Armin Wolf cc: Hans de Goede , corbet@lwn.net, Dell.Client.Kernel@dell.com, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, LKML Subject: Re: [PATCH 5/5] platform/x86: wmi: Add driver development guide In-Reply-To: <20231207222623.232074-6-W_Armin@gmx.de> Message-ID: References: <20231207222623.232074-1-W_Armin@gmx.de> <20231207222623.232074-6-W_Armin@gmx.de> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Fri, 08 Dec 2023 04:26:04 -0800 (PST) On Thu, 7 Dec 2023, Armin Wolf wrote: > Since 2010, an LWN article covering WMI drivers exists: > > https://lwn.net/Articles/391230/ > > Since the introduction of the modern bus-based interface > and other userspace tooling (fwts wmi, bmfdec, ...), this > article is outdated and causes people to still submit new > WMI drivers using the deprecated GUID-based interface. > Fix this by adding a short guid on how to develop WMI drivers Too used to typing guid(?), here you want "guide" instead. :-D (I know that feeling when my fingers type something else than I think). > using the modern bus-based interface. > > Signed-off-by: Armin Wolf > --- > .../wmi/driver-development-guide.rst | 126 ++++++++++++++++++ > Documentation/wmi/index.rst | 1 + > 2 files changed, 127 insertions(+) > create mode 100644 Documentation/wmi/driver-development-guide.rst > > diff --git a/Documentation/wmi/driver-development-guide.rst b/Documentation/wmi/driver-development-guide.rst > new file mode 100644 > index 000000000000..a831e2728d25 > --- /dev/null > +++ b/Documentation/wmi/driver-development-guide.rst > @@ -0,0 +1,126 @@ > +.. SPDX-License-Identifier: GPL-2.0-or-later > + > +============================ > +WMI driver development guide > +============================ > + > +The WMI subsystem provides a rich driver api for implementing WMI drivers, API > +documented at Documentation/driver-api/wmi.rst. This document will serve > +as an introductory guide for WMI driver writers using this API. It is supposed > +t be an successor to the original `LWN article `_ t -> to > +which deals with WMI drivers using the deprecated GUID-based WMI interface. > + > +Optaining WMI device information Obtaining > +-------------------------------- > + > +Before developing an WMI driver, information about the WMI device in question > +must be optained. The `lswmi `_ utility can be obtained > +used to display detailed WMI device information using the following command: > + > +:: > + > + lswmi -V > + > +The resulting output will contain information about all WMI devices inside a given > +machine, plus some extra information. > + > +In order to find out more about the interface used to communicate with a WMI device, > +the `bmfdec `_ utilities can be used to decode > +the Binary MOF information used to describe WMI devices. The ``wmi-bmof`` driver (Managed Object Format) > +exposes this information to userspace, see Documentation/ABI/stable/sysfs-platform-wmi-bmof. This should use a true link to the file. > +In order to retrieve the decoded Binary MOF information, use the following command (requires root): > + > +:: > + > + ./bmf2mof /sys/bus/wmi/devices/05901221-D566-11D1-B2F0-00A0C9062910[-X]/bmof > + > +Sometimes, looking at the disassembled ACPI tables used to describe the WMI device > +helps in understanding how the WMI device is supposed to work. To find out which > +ACPI method handles which WMI device, the `fwts `_ > +program can be used with the following command (requires root): > + > +:: > + > + fwts wmi - > + > +Basic WMI driver structure > +-------------------------- > + > +The basic WMI driver is build around the struct wmi_driver, which is then bound > +to matching WMI devices using an struct wmi_device_id table. Please note that each an struct -> a struct > +WMI driver should be able to be instantiated multiple times. > + > +:: > + > + static const struct wmi_device_id foo_id_table[] = { > + { "936DA01F-9ABD-4D9D-80C7-02AF85C822A8", NULL }, > + { } > + }; > + MODULE_DEVICE_TABLE(wmi, foo_id_table); > + > + static struct wmi_driver foo_driver = { > + .driver = { > + .name = "foo", > + .probe_type = PROBE_PREFER_ASYNCHRONOUS, /* optional */ > + .pm = pm_sleep_ptr(&foo_dev_pm_ops), /* optional */ > + }, > + .id_table = foo_id_table, > + .probe = foo_probe, > + .remove = foo_remove, /* optional, devres is preferred */ > + .notify = foo_notify, /* optional, for event handling */ > + }; > + module_wmi_driver(foo_driver); > + > +If your WMI driver is not using any deprecated GUID-based WMI functions and is > +able to be instantiated multiple times, please add its GUID to ``allow_duplicates`` > +inside drivers/platform/x86/wmi.c, so that the WMI subsystem does not block duplicate > +GUIDs for it. Just voicing wouldn't it be more useful to not burden new stuff with this at all and construct the opposite list instead with the GUIDs that have a driver that don't support duplicates? It's the existing set of GUIDs we have in-tree minus those currently on the list, correct? > +WMI method drivers > +------------------ > + > +WMI drivers can call WMI device methods using wmidev_evaluate_method(), the > +structure of the ACPI buffer passed to this function is device-specific and usually > +needs some tinkering to get right. Looking at the ACPI tables containing the WMI > +device usually helps here. The method id and instance number passed to this function > +are also device-specific, looking at the decoded Binary MOF is usually enough to > +find the right values. > +The maximum instance number can be retrieved during runtime using wmidev_instance_count(). > + > +Take a look at drivers/platform/x86/inspur_platform_profile.c for an example WMI method driver. > + > +WMI data block drivers > +---------------------- > + > +WMI drivers can query WMI device data blocks using wmidev_block_query(), the > +structure of the returned ACPI object is again device-specific. Some WMI devices > +also allow for setting data blocks using wmidev_block_set(). > +The maximum instance number can also be retrieved using wmidev_instance_count(). > + > +Take a look at drivers/platform/x86/intel/wmi/sbl-fw-update.c for an example > +WMI data block driver. > + > +WMI event drivers > +----------------- > + > +WMI drivers can receive WMI event notifications by providing the notify() callback > +inside the struct wmi_driver. The WMI subsystem will then take care of setting > +up the WMI event accordingly. Plase note that the ACPI object passed to this callback Plase -> Please > +is optional and its structure device-specific. It also does not need to be freed, structure is device-specific. > +the WMI subsystem takes care of that. I'd state the freeing part more strongly: Releasing the ACPI object is handled by the WMI subsystem, not the driver. > + > +Take a look at drivers/platform/x86/xiaomi-wmi.c for an example WMI event driver. > + > +Things to avoid > +--------------- > + > +When developing WMI drivers, there are a couple of things which should be avoid > +if feasible: > + > +- usage of the deprecated GUID-based WMI interface It would be nice to be more specific because it's far from obvious at this point how to differentiate. So perhaps adding something like this would help: (avoid functions with wmi_ prefix that input GUID converting it into a wmi_device using wmi_find_device_by_guid()). > +- bypassing of the WMI subsystem when talking to WMI devices > +- WMI drivers which cannot be instantiated multiple times. > + > +Many older WMI drivers violate one or more points from this list. The reason for > +this is that the WMI subsystem evolved significantly over the last two decades, > +so there is a lot of legacy cruft inside older WMI drivers. -- i.