1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * hwmon driver for HP (and some HP Compaq) business-class computers that
4   * report numeric sensor data via Windows Management Instrumentation (WMI).
5   *
6   * Copyright (C) 2023 James Seo <james@equiv.tech>
7   *
8   * References:
9   * [1] Hewlett-Packard Development Company, L.P.,
10   *     "HP Client Management Interface Technical White Paper", 2005. [Online].
11   *     Available: https://h20331.www2.hp.com/hpsub/downloads/cmi_whitepaper.pdf
12   * [2] Hewlett-Packard Development Company, L.P.,
13   *     "HP Retail Manageability", 2012. [Online].
14   *     Available: http://h10032.www1.hp.com/ctg/Manual/c03291135.pdf
15   * [3] Linux Hardware Project, A. Ponomarenko et al.,
16   *     "linuxhw/ACPI - Collect ACPI table dumps", 2018. [Online].
17   *     Available: https://github.com/linuxhw/ACPI
18   * [4] P. Rohár, "bmfdec - Decompile binary MOF file (BMF) from WMI buffer",
19   *     2017. [Online]. Available: https://github.com/pali/bmfdec
20   * [5] Microsoft Corporation, "Driver-Defined WMI Data Items", 2017. [Online].
21   *     Available: https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/driver-defined-wmi-data-items
22   */
23  
24  #include <linux/acpi.h>
25  #include <linux/debugfs.h>
26  #include <linux/hwmon.h>
27  #include <linux/jiffies.h>
28  #include <linux/mutex.h>
29  #include <linux/nls.h>
30  #include <linux/units.h>
31  #include <linux/wmi.h>
32  
33  #define HP_WMI_EVENT_NAMESPACE		"root\\WMI"
34  #define HP_WMI_EVENT_CLASS		"HPBIOS_BIOSEvent"
35  #define HP_WMI_EVENT_GUID		"95F24279-4D7B-4334-9387-ACCDC67EF61C"
36  #define HP_WMI_NUMERIC_SENSOR_GUID	"8F1F6435-9F42-42C8-BADC-0E9424F20C9A"
37  #define HP_WMI_PLATFORM_EVENTS_GUID	"41227C2D-80E1-423F-8B8E-87E32755A0EB"
38  
39  /* Patterns for recognizing sensors and matching events to channels. */
40  
41  #define HP_WMI_PATTERN_SYS_TEMP		"Chassis Thermal Index"
42  #define HP_WMI_PATTERN_SYS_TEMP2	"System Ambient Temperature"
43  #define HP_WMI_PATTERN_CPU_TEMP		"CPU Thermal Index"
44  #define HP_WMI_PATTERN_CPU_TEMP2	"CPU Temperature"
45  #define HP_WMI_PATTERN_TEMP_SENSOR	"Thermal Index"
46  #define HP_WMI_PATTERN_TEMP_ALARM	"Thermal Critical"
47  #define HP_WMI_PATTERN_INTRUSION_ALARM	"Hood Intrusion"
48  #define HP_WMI_PATTERN_FAN_ALARM	"Stall"
49  #define HP_WMI_PATTERN_TEMP		"Temperature"
50  #define HP_WMI_PATTERN_CPU		"CPU"
51  
52  /* These limits are arbitrary. The WMI implementation may vary by system. */
53  
54  #define HP_WMI_MAX_STR_SIZE		128U
55  #define HP_WMI_MAX_PROPERTIES		32U
56  #define HP_WMI_MAX_INSTANCES		32U
57  
58  enum hp_wmi_type {
59  	HP_WMI_TYPE_OTHER			= 1,
60  	HP_WMI_TYPE_TEMPERATURE			= 2,
61  	HP_WMI_TYPE_VOLTAGE			= 3,
62  	HP_WMI_TYPE_CURRENT			= 4,
63  	HP_WMI_TYPE_AIR_FLOW			= 12,
64  	HP_WMI_TYPE_INTRUSION			= 0xabadb01, /* Custom. */
65  };
66  
67  enum hp_wmi_category {
68  	HP_WMI_CATEGORY_SENSOR			= 3,
69  };
70  
71  enum hp_wmi_severity {
72  	HP_WMI_SEVERITY_UNKNOWN			= 0,
73  	HP_WMI_SEVERITY_OK			= 5,
74  	HP_WMI_SEVERITY_DEGRADED_WARNING	= 10,
75  	HP_WMI_SEVERITY_MINOR_FAILURE		= 15,
76  	HP_WMI_SEVERITY_MAJOR_FAILURE		= 20,
77  	HP_WMI_SEVERITY_CRITICAL_FAILURE	= 25,
78  	HP_WMI_SEVERITY_NON_RECOVERABLE_ERROR	= 30,
79  };
80  
81  enum hp_wmi_status {
82  	HP_WMI_STATUS_OK			= 2,
83  	HP_WMI_STATUS_DEGRADED			= 3,
84  	HP_WMI_STATUS_STRESSED			= 4,
85  	HP_WMI_STATUS_PREDICTIVE_FAILURE	= 5,
86  	HP_WMI_STATUS_ERROR			= 6,
87  	HP_WMI_STATUS_NON_RECOVERABLE_ERROR	= 7,
88  	HP_WMI_STATUS_NO_CONTACT		= 12,
89  	HP_WMI_STATUS_LOST_COMMUNICATION	= 13,
90  	HP_WMI_STATUS_ABORTED			= 14,
91  	HP_WMI_STATUS_SUPPORTING_ENTITY_IN_ERROR = 16,
92  
93  	/* Occurs combined with one of "OK", "Degraded", and "Error" [1]. */
94  	HP_WMI_STATUS_COMPLETED			= 17,
95  };
96  
97  enum hp_wmi_units {
98  	HP_WMI_UNITS_OTHER			= 1,
99  	HP_WMI_UNITS_DEGREES_C			= 2,
100  	HP_WMI_UNITS_DEGREES_F			= 3,
101  	HP_WMI_UNITS_DEGREES_K			= 4,
102  	HP_WMI_UNITS_VOLTS			= 5,
103  	HP_WMI_UNITS_AMPS			= 6,
104  	HP_WMI_UNITS_RPM			= 19,
105  };
106  
107  enum hp_wmi_property {
108  	HP_WMI_PROPERTY_NAME			= 0,
109  	HP_WMI_PROPERTY_DESCRIPTION		= 1,
110  	HP_WMI_PROPERTY_SENSOR_TYPE		= 2,
111  	HP_WMI_PROPERTY_OTHER_SENSOR_TYPE	= 3,
112  	HP_WMI_PROPERTY_OPERATIONAL_STATUS	= 4,
113  	HP_WMI_PROPERTY_SIZE			= 5,
114  	HP_WMI_PROPERTY_POSSIBLE_STATES		= 6,
115  	HP_WMI_PROPERTY_CURRENT_STATE		= 7,
116  	HP_WMI_PROPERTY_BASE_UNITS		= 8,
117  	HP_WMI_PROPERTY_UNIT_MODIFIER		= 9,
118  	HP_WMI_PROPERTY_CURRENT_READING		= 10,
119  	HP_WMI_PROPERTY_RATE_UNITS		= 11,
120  };
121  
122  static const acpi_object_type hp_wmi_property_map[] = {
123  	[HP_WMI_PROPERTY_NAME]			= ACPI_TYPE_STRING,
124  	[HP_WMI_PROPERTY_DESCRIPTION]		= ACPI_TYPE_STRING,
125  	[HP_WMI_PROPERTY_SENSOR_TYPE]		= ACPI_TYPE_INTEGER,
126  	[HP_WMI_PROPERTY_OTHER_SENSOR_TYPE]	= ACPI_TYPE_STRING,
127  	[HP_WMI_PROPERTY_OPERATIONAL_STATUS]	= ACPI_TYPE_INTEGER,
128  	[HP_WMI_PROPERTY_SIZE]			= ACPI_TYPE_INTEGER,
129  	[HP_WMI_PROPERTY_POSSIBLE_STATES]	= ACPI_TYPE_STRING,
130  	[HP_WMI_PROPERTY_CURRENT_STATE]		= ACPI_TYPE_STRING,
131  	[HP_WMI_PROPERTY_BASE_UNITS]		= ACPI_TYPE_INTEGER,
132  	[HP_WMI_PROPERTY_UNIT_MODIFIER]		= ACPI_TYPE_INTEGER,
133  	[HP_WMI_PROPERTY_CURRENT_READING]	= ACPI_TYPE_INTEGER,
134  	[HP_WMI_PROPERTY_RATE_UNITS]		= ACPI_TYPE_INTEGER,
135  };
136  
137  enum hp_wmi_platform_events_property {
138  	HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME		    = 0,
139  	HP_WMI_PLATFORM_EVENTS_PROPERTY_DESCRIPTION	    = 1,
140  	HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_NAMESPACE    = 2,
141  	HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_CLASS	    = 3,
142  	HP_WMI_PLATFORM_EVENTS_PROPERTY_CATEGORY	    = 4,
143  	HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_SEVERITY   = 5,
144  	HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS	    = 6,
145  };
146  
147  static const acpi_object_type hp_wmi_platform_events_property_map[] = {
148  	[HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME]		    = ACPI_TYPE_STRING,
149  	[HP_WMI_PLATFORM_EVENTS_PROPERTY_DESCRIPTION]	    = ACPI_TYPE_STRING,
150  	[HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_NAMESPACE]  = ACPI_TYPE_STRING,
151  	[HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_CLASS]	    = ACPI_TYPE_STRING,
152  	[HP_WMI_PLATFORM_EVENTS_PROPERTY_CATEGORY]	    = ACPI_TYPE_INTEGER,
153  	[HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_SEVERITY] = ACPI_TYPE_INTEGER,
154  	[HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS]   = ACPI_TYPE_INTEGER,
155  };
156  
157  enum hp_wmi_event_property {
158  	HP_WMI_EVENT_PROPERTY_NAME		= 0,
159  	HP_WMI_EVENT_PROPERTY_DESCRIPTION	= 1,
160  	HP_WMI_EVENT_PROPERTY_CATEGORY		= 2,
161  	HP_WMI_EVENT_PROPERTY_SEVERITY		= 3,
162  	HP_WMI_EVENT_PROPERTY_STATUS		= 4,
163  };
164  
165  static const acpi_object_type hp_wmi_event_property_map[] = {
166  	[HP_WMI_EVENT_PROPERTY_NAME]		= ACPI_TYPE_STRING,
167  	[HP_WMI_EVENT_PROPERTY_DESCRIPTION]	= ACPI_TYPE_STRING,
168  	[HP_WMI_EVENT_PROPERTY_CATEGORY]	= ACPI_TYPE_INTEGER,
169  	[HP_WMI_EVENT_PROPERTY_SEVERITY]	= ACPI_TYPE_INTEGER,
170  	[HP_WMI_EVENT_PROPERTY_STATUS]		= ACPI_TYPE_INTEGER,
171  };
172  
173  static const enum hwmon_sensor_types hp_wmi_hwmon_type_map[] = {
174  	[HP_WMI_TYPE_TEMPERATURE]		= hwmon_temp,
175  	[HP_WMI_TYPE_VOLTAGE]			= hwmon_in,
176  	[HP_WMI_TYPE_CURRENT]			= hwmon_curr,
177  	[HP_WMI_TYPE_AIR_FLOW]			= hwmon_fan,
178  };
179  
180  static const u32 hp_wmi_hwmon_attributes[hwmon_max] = {
181  	[hwmon_chip]	  = HWMON_C_REGISTER_TZ,
182  	[hwmon_temp]	  = HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_FAULT,
183  	[hwmon_in]	  = HWMON_I_INPUT | HWMON_I_LABEL,
184  	[hwmon_curr]	  = HWMON_C_INPUT | HWMON_C_LABEL,
185  	[hwmon_fan]	  = HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_FAULT,
186  	[hwmon_intrusion] = HWMON_INTRUSION_ALARM,
187  };
188  
189  /*
190   * struct hp_wmi_numeric_sensor - a HPBIOS_BIOSNumericSensor instance
191   *
192   * Two variants of HPBIOS_BIOSNumericSensor are known. The first is specified
193   * in [1] and appears to be much more widespread. The second was discovered by
194   * decoding BMOF blobs [4], seems to be found only in some newer ZBook systems
195   * [3], and has two new properties and a slightly different property order.
196   *
197   * These differences don't matter on Windows, where WMI object properties are
198   * accessed by name. For us, supporting both variants gets ugly and hacky at
199   * times. The fun begins now; this struct is defined as per the new variant.
200   *
201   * Effective MOF definition:
202   *
203   *   #pragma namespace("\\\\.\\root\\HP\\InstrumentedBIOS");
204   *   class HPBIOS_BIOSNumericSensor {
205   *     [read] string Name;
206   *     [read] string Description;
207   *     [read, ValueMap {"0","1","2","3","4","5","6","7","8","9",
208   *      "10","11","12"}, Values {"Unknown","Other","Temperature",
209   *      "Voltage","Current","Tachometer","Counter","Switch","Lock",
210   *      "Humidity","Smoke Detection","Presence","Air Flow"}]
211   *     uint32 SensorType;
212   *     [read] string OtherSensorType;
213   *     [read, ValueMap {"0","1","2","3","4","5","6","7","8","9",
214   *      "10","11","12","13","14","15","16","17","18","..",
215   *      "0x8000.."}, Values {"Unknown","Other","OK","Degraded",
216   *      "Stressed","Predictive Failure","Error",
217   *      "Non-Recoverable Error","Starting","Stopping","Stopped",
218   *      "In Service","No Contact","Lost Communication","Aborted",
219   *      "Dormant","Supporting Entity in Error","Completed",
220   *      "Power Mode","DMTF Reserved","Vendor Reserved"}]
221   *     uint32 OperationalStatus;
222   *     [read] uint32 Size;
223   *     [read] string PossibleStates[];
224   *     [read] string CurrentState;
225   *     [read, ValueMap {"0","1","2","3","4","5","6","7","8","9",
226   *      "10","11","12","13","14","15","16","17","18","19","20",
227   *      "21","22","23","24","25","26","27","28","29","30","31",
228   *      "32","33","34","35","36","37","38","39","40","41","42",
229   *      "43","44","45","46","47","48","49","50","51","52","53",
230   *      "54","55","56","57","58","59","60","61","62","63","64",
231   *      "65"}, Values {"Unknown","Other","Degrees C","Degrees F",
232   *      "Degrees K","Volts","Amps","Watts","Joules","Coulombs",
233   *      "VA","Nits","Lumens","Lux","Candelas","kPa","PSI",
234   *      "Newtons","CFM","RPM","Hertz","Seconds","Minutes",
235   *      "Hours","Days","Weeks","Mils","Inches","Feet",
236   *      "Cubic Inches","Cubic Feet","Meters","Cubic Centimeters",
237   *      "Cubic Meters","Liters","Fluid Ounces","Radians",
238   *      "Steradians","Revolutions","Cycles","Gravities","Ounces",
239   *      "Pounds","Foot-Pounds","Ounce-Inches","Gauss","Gilberts",
240   *      "Henries","Farads","Ohms","Siemens","Moles","Becquerels",
241   *      "PPM (parts/million)","Decibels","DbA","DbC","Grays",
242   *      "Sieverts","Color Temperature Degrees K","Bits","Bytes",
243   *      "Words (data)","DoubleWords","QuadWords","Percentage"}]
244   *     uint32 BaseUnits;
245   *     [read] sint32 UnitModifier;
246   *     [read] uint32 CurrentReading;
247   *     [read] uint32 RateUnits;
248   *   };
249   *
250   * Effective MOF definition of old variant [1] (sans redundant info):
251   *
252   *   class HPBIOS_BIOSNumericSensor {
253   *     [read] string Name;
254   *     [read] string Description;
255   *     [read] uint32 SensorType;
256   *     [read] string OtherSensorType;
257   *     [read] uint32 OperationalStatus;
258   *     [read] string CurrentState;
259   *     [read] string PossibleStates[];
260   *     [read] uint32 BaseUnits;
261   *     [read] sint32 UnitModifier;
262   *     [read] uint32 CurrentReading;
263   *   };
264   */
265  struct hp_wmi_numeric_sensor {
266  	const char *name;
267  	const char *description;
268  	u32 sensor_type;
269  	const char *other_sensor_type;	/* Explains "Other" SensorType. */
270  	u32 operational_status;
271  	u8 size;			/* Count of PossibleStates[]. */
272  	const char **possible_states;
273  	const char *current_state;
274  	u32 base_units;
275  	s32 unit_modifier;
276  	u32 current_reading;
277  	u32 rate_units;
278  };
279  
280  /*
281   * struct hp_wmi_platform_events - a HPBIOS_PlatformEvents instance
282   *
283   * Instances of this object reveal the set of possible HPBIOS_BIOSEvent
284   * instances for the current system, but it may not always be present.
285   *
286   * Effective MOF definition:
287   *
288   *   #pragma namespace("\\\\.\\root\\HP\\InstrumentedBIOS");
289   *   class HPBIOS_PlatformEvents {
290   *     [read] string Name;
291   *     [read] string Description;
292   *     [read] string SourceNamespace;
293   *     [read] string SourceClass;
294   *     [read, ValueMap {"0","1","2","3","4",".."}, Values {
295   *      "Unknown","Configuration Change","Button Pressed",
296   *      "Sensor","BIOS Settings","Reserved"}]
297   *     uint32 Category;
298   *     [read, ValueMap{"0","5","10","15","20","25","30",".."},
299   *      Values{"Unknown","OK","Degraded/Warning","Minor Failure",
300   *      "Major Failure","Critical Failure","Non-recoverable Error",
301   *      "DMTF Reserved"}]
302   *     uint32 PossibleSeverity;
303   *     [read, ValueMap {"0","1","2","3","4","5","6","7","8","9",
304   *      "10","11","12","13","14","15","16","17","18","..",
305   *      "0x8000.."}, Values {"Unknown","Other","OK","Degraded",
306   *      "Stressed","Predictive Failure","Error",
307   *      "Non-Recoverable Error","Starting","Stopping","Stopped",
308   *      "In Service","No Contact","Lost Communication","Aborted",
309   *      "Dormant","Supporting Entity in Error","Completed",
310   *      "Power Mode","DMTF Reserved","Vendor Reserved"}]
311   *     uint32 PossibleStatus;
312   *   };
313   */
314  struct hp_wmi_platform_events {
315  	const char *name;
316  	const char *description;
317  	const char *source_namespace;
318  	const char *source_class;
319  	u32 category;
320  	u32 possible_severity;
321  	u32 possible_status;
322  };
323  
324  /*
325   * struct hp_wmi_event - a HPBIOS_BIOSEvent instance
326   *
327   * Effective MOF definition [1] (corrected below from original):
328   *
329   *   #pragma namespace("\\\\.\\root\\WMI");
330   *   class HPBIOS_BIOSEvent : WMIEvent {
331   *     [read] string Name;
332   *     [read] string Description;
333   *     [read ValueMap {"0","1","2","3","4"}, Values {"Unknown",
334   *      "Configuration Change","Button Pressed","Sensor",
335   *      "BIOS Settings"}]
336   *     uint32 Category;
337   *     [read, ValueMap {"0","5","10","15","20","25","30"},
338   *      Values {"Unknown","OK","Degraded/Warning",
339   *      "Minor Failure","Major Failure","Critical Failure",
340   *      "Non-recoverable Error"}]
341   *     uint32 Severity;
342   *     [read, ValueMap {"0","1","2","3","4","5","6","7","8",
343   *      "9","10","11","12","13","14","15","16","17","18","..",
344   *      "0x8000.."}, Values {"Unknown","Other","OK","Degraded",
345   *      "Stressed","Predictive Failure","Error",
346   *      "Non-Recoverable Error","Starting","Stopping","Stopped",
347   *      "In Service","No Contact","Lost Communication","Aborted",
348   *      "Dormant","Supporting Entity in Error","Completed",
349   *      "Power Mode","DMTF Reserved","Vendor Reserved"}]
350   *     uint32 Status;
351   *   };
352   */
353  struct hp_wmi_event {
354  	const char *name;
355  	const char *description;
356  	u32 category;
357  };
358  
359  /*
360   * struct hp_wmi_info - sensor info
361   * @nsensor: numeric sensor properties
362   * @instance: its WMI instance number
363   * @state: pointer to driver state
364   * @has_alarm: whether sensor has an alarm flag
365   * @alarm: alarm flag
366   * @type: its hwmon sensor type
367   * @cached_val: current sensor reading value, scaled for hwmon
368   * @last_updated: when these readings were last updated
369   */
370  struct hp_wmi_info {
371  	struct hp_wmi_numeric_sensor nsensor;
372  	u8 instance;
373  	void *state;			/* void *: Avoid forward declaration. */
374  	bool has_alarm;
375  	bool alarm;
376  	enum hwmon_sensor_types type;
377  	long cached_val;
378  	unsigned long last_updated;	/* In jiffies. */
379  
380  };
381  
382  /*
383   * struct hp_wmi_sensors - driver state
384   * @wdev: pointer to the parent WMI device
385   * @info_map: sensor info structs by hwmon type and channel number
386   * @channel_count: count of hwmon channels by hwmon type
387   * @has_intrusion: whether an intrusion sensor is present
388   * @intrusion: intrusion flag
389   * @lock: mutex to lock polling WMI and changes to driver state
390   */
391  struct hp_wmi_sensors {
392  	struct wmi_device *wdev;
393  	struct hp_wmi_info **info_map[hwmon_max];
394  	u8 channel_count[hwmon_max];
395  	bool has_intrusion;
396  	bool intrusion;
397  
398  	struct mutex lock;	/* Lock polling WMI and driver state changes. */
399  };
400  
is_raw_wmi_string(const u8 * pointer,u32 length)401  static bool is_raw_wmi_string(const u8 *pointer, u32 length)
402  {
403  	const u16 *ptr;
404  	u16 len;
405  
406  	/* WMI strings are length-prefixed UTF-16 [5]. */
407  	if (length <= sizeof(*ptr))
408  		return false;
409  
410  	length -= sizeof(*ptr);
411  	ptr = (const u16 *)pointer;
412  	len = *ptr;
413  
414  	return len <= length && !(len & 1);
415  }
416  
convert_raw_wmi_string(const u8 * buf)417  static char *convert_raw_wmi_string(const u8 *buf)
418  {
419  	const wchar_t *src;
420  	unsigned int cps;
421  	unsigned int len;
422  	char *dst;
423  	int i;
424  
425  	src = (const wchar_t *)buf;
426  
427  	/* Count UTF-16 code points. Exclude trailing null padding. */
428  	cps = *src / sizeof(*src);
429  	while (cps && !src[cps])
430  		cps--;
431  
432  	/* Each code point becomes up to 3 UTF-8 characters. */
433  	len = min(cps * 3, HP_WMI_MAX_STR_SIZE - 1);
434  
435  	dst = kmalloc((len + 1) * sizeof(*dst), GFP_KERNEL);
436  	if (!dst)
437  		return NULL;
438  
439  	i = utf16s_to_utf8s(++src, cps, UTF16_LITTLE_ENDIAN, dst, len);
440  	dst[i] = '\0';
441  
442  	return dst;
443  }
444  
445  /* hp_wmi_strdup - devm_kstrdup, but length-limited */
hp_wmi_strdup(struct device * dev,const char * src)446  static char *hp_wmi_strdup(struct device *dev, const char *src)
447  {
448  	char *dst;
449  	size_t len;
450  
451  	len = strnlen(src, HP_WMI_MAX_STR_SIZE - 1);
452  
453  	dst = devm_kmalloc(dev, (len + 1) * sizeof(*dst), GFP_KERNEL);
454  	if (!dst)
455  		return NULL;
456  
457  	strscpy(dst, src, len + 1);
458  
459  	return dst;
460  }
461  
462  /* hp_wmi_wstrdup - hp_wmi_strdup, but for a raw WMI string */
hp_wmi_wstrdup(struct device * dev,const u8 * buf)463  static char *hp_wmi_wstrdup(struct device *dev, const u8 *buf)
464  {
465  	char *src;
466  	char *dst;
467  
468  	src = convert_raw_wmi_string(buf);
469  	if (!src)
470  		return NULL;
471  
472  	dst = hp_wmi_strdup(dev, strim(src));	/* Note: Copy is trimmed. */
473  
474  	kfree(src);
475  
476  	return dst;
477  }
478  
479  /*
480   * hp_wmi_get_wobj - poll WMI for a WMI object instance
481   * @guid: WMI object GUID
482   * @instance: WMI object instance number
483   *
484   * Returns a new WMI object instance on success, or NULL on error.
485   * Caller must kfree() the result.
486   */
hp_wmi_get_wobj(const char * guid,u8 instance)487  static union acpi_object *hp_wmi_get_wobj(const char *guid, u8 instance)
488  {
489  	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
490  	acpi_status err;
491  
492  	err = wmi_query_block(guid, instance, &out);
493  	if (ACPI_FAILURE(err))
494  		return NULL;
495  
496  	return out.pointer;
497  }
498  
499  /* hp_wmi_wobj_instance_count - find count of WMI object instances */
hp_wmi_wobj_instance_count(const char * guid)500  static u8 hp_wmi_wobj_instance_count(const char *guid)
501  {
502  	int count;
503  
504  	count = wmi_instance_count(guid);
505  
506  	return clamp(count, 0, (int)HP_WMI_MAX_INSTANCES);
507  }
508  
check_wobj(const union acpi_object * wobj,const acpi_object_type property_map[],int last_prop)509  static int check_wobj(const union acpi_object *wobj,
510  		      const acpi_object_type property_map[], int last_prop)
511  {
512  	acpi_object_type type = wobj->type;
513  	acpi_object_type valid_type;
514  	union acpi_object *elements;
515  	u32 elem_count;
516  	int prop;
517  
518  	if (type != ACPI_TYPE_PACKAGE)
519  		return -EINVAL;
520  
521  	elem_count = wobj->package.count;
522  	if (elem_count != last_prop + 1)
523  		return -EINVAL;
524  
525  	elements = wobj->package.elements;
526  	for (prop = 0; prop <= last_prop; prop++) {
527  		type = elements[prop].type;
528  		valid_type = property_map[prop];
529  		if (type != valid_type) {
530  			if (type == ACPI_TYPE_BUFFER &&
531  			    valid_type == ACPI_TYPE_STRING &&
532  			    is_raw_wmi_string(elements[prop].buffer.pointer,
533  					      elements[prop].buffer.length))
534  				continue;
535  			return -EINVAL;
536  		}
537  	}
538  
539  	return 0;
540  }
541  
extract_acpi_value(struct device * dev,union acpi_object * element,acpi_object_type type,u32 * out_value,char ** out_string)542  static int extract_acpi_value(struct device *dev,
543  			      union acpi_object *element,
544  			      acpi_object_type type,
545  			      u32 *out_value, char **out_string)
546  {
547  	switch (type) {
548  	case ACPI_TYPE_INTEGER:
549  		*out_value = element->integer.value;
550  		break;
551  
552  	case ACPI_TYPE_STRING:
553  		*out_string = element->type == ACPI_TYPE_BUFFER ?
554  			hp_wmi_wstrdup(dev, element->buffer.pointer) :
555  			hp_wmi_strdup(dev, strim(element->string.pointer));
556  		if (!*out_string)
557  			return -ENOMEM;
558  		break;
559  
560  	default:
561  		return -EINVAL;
562  	}
563  
564  	return 0;
565  }
566  
567  /*
568   * check_numeric_sensor_wobj - validate a HPBIOS_BIOSNumericSensor instance
569   * @wobj: pointer to WMI object instance to check
570   * @out_size: out pointer to count of possible states
571   * @out_is_new: out pointer to whether this is a "new" variant object
572   *
573   * Returns 0 on success, or a negative error code on error.
574   */
check_numeric_sensor_wobj(const union acpi_object * wobj,u8 * out_size,bool * out_is_new)575  static int check_numeric_sensor_wobj(const union acpi_object *wobj,
576  				     u8 *out_size, bool *out_is_new)
577  {
578  	acpi_object_type type = wobj->type;
579  	int prop = HP_WMI_PROPERTY_NAME;
580  	acpi_object_type valid_type;
581  	union acpi_object *elements;
582  	u32 elem_count;
583  	int last_prop;
584  	bool is_new;
585  	u8 count;
586  	u32 j;
587  	u32 i;
588  
589  	if (type != ACPI_TYPE_PACKAGE)
590  		return -EINVAL;
591  
592  	/*
593  	 * elements is a variable-length array of ACPI objects, one for
594  	 * each property of the WMI object instance, except that the
595  	 * strings in PossibleStates[] are flattened into this array
596  	 * as if each individual string were a property by itself.
597  	 */
598  	elements = wobj->package.elements;
599  
600  	elem_count = wobj->package.count;
601  	if (elem_count <= HP_WMI_PROPERTY_SIZE ||
602  	    elem_count > HP_WMI_MAX_PROPERTIES)
603  		return -EINVAL;
604  
605  	type = elements[HP_WMI_PROPERTY_SIZE].type;
606  	switch (type) {
607  	case ACPI_TYPE_INTEGER:
608  		is_new = true;
609  		last_prop = HP_WMI_PROPERTY_RATE_UNITS;
610  		break;
611  
612  	case ACPI_TYPE_STRING:
613  		is_new = false;
614  		last_prop = HP_WMI_PROPERTY_CURRENT_READING;
615  		break;
616  
617  	default:
618  		return -EINVAL;
619  	}
620  
621  	/*
622  	 * In general, the count of PossibleStates[] must be > 0.
623  	 * Also, the old variant lacks the Size property, so we may need to
624  	 * reduce the value of last_prop by 1 when doing arithmetic with it.
625  	 */
626  	if (elem_count < last_prop - !is_new + 1)
627  		return -EINVAL;
628  
629  	count = elem_count - (last_prop - !is_new);
630  
631  	for (i = 0; i < elem_count && prop <= last_prop; i++, prop++) {
632  		type = elements[i].type;
633  		valid_type = hp_wmi_property_map[prop];
634  		if (type != valid_type)
635  			return -EINVAL;
636  
637  		switch (prop) {
638  		case HP_WMI_PROPERTY_OPERATIONAL_STATUS:
639  			/* Old variant: CurrentState follows OperationalStatus. */
640  			if (!is_new)
641  				prop = HP_WMI_PROPERTY_CURRENT_STATE - 1;
642  			break;
643  
644  		case HP_WMI_PROPERTY_SIZE:
645  			/* New variant: Size == count of PossibleStates[]. */
646  			if (count != elements[i].integer.value)
647  				return -EINVAL;
648  			break;
649  
650  		case HP_WMI_PROPERTY_POSSIBLE_STATES:
651  			/* PossibleStates[0] has already been type-checked. */
652  			for (j = 0; i + 1 < elem_count && j + 1 < count; j++) {
653  				type = elements[++i].type;
654  				if (type != valid_type)
655  					return -EINVAL;
656  			}
657  
658  			/* Old variant: BaseUnits follows PossibleStates[]. */
659  			if (!is_new)
660  				prop = HP_WMI_PROPERTY_BASE_UNITS - 1;
661  			break;
662  
663  		case HP_WMI_PROPERTY_CURRENT_STATE:
664  			/* Old variant: PossibleStates[] follows CurrentState. */
665  			if (!is_new)
666  				prop = HP_WMI_PROPERTY_POSSIBLE_STATES - 1;
667  			break;
668  		}
669  	}
670  
671  	if (prop != last_prop + 1)
672  		return -EINVAL;
673  
674  	*out_size = count;
675  	*out_is_new = is_new;
676  
677  	return 0;
678  }
679  
680  static int
numeric_sensor_is_connected(const struct hp_wmi_numeric_sensor * nsensor)681  numeric_sensor_is_connected(const struct hp_wmi_numeric_sensor *nsensor)
682  {
683  	u32 operational_status = nsensor->operational_status;
684  
685  	return operational_status != HP_WMI_STATUS_NO_CONTACT;
686  }
687  
numeric_sensor_has_fault(const struct hp_wmi_numeric_sensor * nsensor)688  static int numeric_sensor_has_fault(const struct hp_wmi_numeric_sensor *nsensor)
689  {
690  	u32 operational_status = nsensor->operational_status;
691  
692  	switch (operational_status) {
693  	case HP_WMI_STATUS_DEGRADED:
694  	case HP_WMI_STATUS_STRESSED:		/* e.g. Overload, overtemp. */
695  	case HP_WMI_STATUS_PREDICTIVE_FAILURE:	/* e.g. Fan removed. */
696  	case HP_WMI_STATUS_ERROR:
697  	case HP_WMI_STATUS_NON_RECOVERABLE_ERROR:
698  	case HP_WMI_STATUS_NO_CONTACT:
699  	case HP_WMI_STATUS_LOST_COMMUNICATION:
700  	case HP_WMI_STATUS_ABORTED:
701  	case HP_WMI_STATUS_SUPPORTING_ENTITY_IN_ERROR:
702  
703  	/* Assume combination by addition; bitwise OR doesn't make sense. */
704  	case HP_WMI_STATUS_COMPLETED + HP_WMI_STATUS_DEGRADED:
705  	case HP_WMI_STATUS_COMPLETED + HP_WMI_STATUS_ERROR:
706  		return true;
707  	}
708  
709  	return false;
710  }
711  
712  /* scale_numeric_sensor - scale sensor reading for hwmon */
scale_numeric_sensor(const struct hp_wmi_numeric_sensor * nsensor)713  static long scale_numeric_sensor(const struct hp_wmi_numeric_sensor *nsensor)
714  {
715  	u32 current_reading = nsensor->current_reading;
716  	s32 unit_modifier = nsensor->unit_modifier;
717  	u32 sensor_type = nsensor->sensor_type;
718  	u32 base_units = nsensor->base_units;
719  	s32 target_modifier;
720  	long val;
721  
722  	/* Fan readings are in RPM units; others are in milliunits. */
723  	target_modifier = sensor_type == HP_WMI_TYPE_AIR_FLOW ? 0 : -3;
724  
725  	val = current_reading;
726  
727  	for (; unit_modifier < target_modifier; unit_modifier++)
728  		val = DIV_ROUND_CLOSEST(val, 10);
729  
730  	for (; unit_modifier > target_modifier; unit_modifier--) {
731  		if (val > LONG_MAX / 10) {
732  			val = LONG_MAX;
733  			break;
734  		}
735  		val *= 10;
736  	}
737  
738  	if (sensor_type == HP_WMI_TYPE_TEMPERATURE) {
739  		switch (base_units) {
740  		case HP_WMI_UNITS_DEGREES_F:
741  			val -= MILLI * 32;
742  			val = val <= LONG_MAX / 5 ?
743  				      DIV_ROUND_CLOSEST(val * 5, 9) :
744  				      DIV_ROUND_CLOSEST(val, 9) * 5;
745  			break;
746  
747  		case HP_WMI_UNITS_DEGREES_K:
748  			val = milli_kelvin_to_millicelsius(val);
749  			break;
750  		}
751  	}
752  
753  	return val;
754  }
755  
756  /*
757   * classify_numeric_sensor - classify a numeric sensor
758   * @nsensor: pointer to numeric sensor struct
759   *
760   * Returns an enum hp_wmi_type value on success,
761   * or a negative value if the sensor type is unsupported.
762   */
classify_numeric_sensor(const struct hp_wmi_numeric_sensor * nsensor)763  static int classify_numeric_sensor(const struct hp_wmi_numeric_sensor *nsensor)
764  {
765  	u32 sensor_type = nsensor->sensor_type;
766  	u32 base_units = nsensor->base_units;
767  	const char *name = nsensor->name;
768  
769  	switch (sensor_type) {
770  	case HP_WMI_TYPE_TEMPERATURE:
771  		/*
772  		 * Some systems have sensors named "X Thermal Index" in "Other"
773  		 * units. Tested CPU sensor examples were found to be in °C,
774  		 * albeit perhaps "differently" accurate; e.g. readings were
775  		 * reliably -6°C vs. coretemp on a HP Compaq Elite 8300, and
776  		 * +8°C on an EliteOne G1 800. But this is still within the
777  		 * realm of plausibility for cheaply implemented motherboard
778  		 * sensors, and chassis readings were about as expected.
779  		 */
780  		if ((base_units == HP_WMI_UNITS_OTHER &&
781  		     strstr(name, HP_WMI_PATTERN_TEMP_SENSOR)) ||
782  		    base_units == HP_WMI_UNITS_DEGREES_C ||
783  		    base_units == HP_WMI_UNITS_DEGREES_F ||
784  		    base_units == HP_WMI_UNITS_DEGREES_K)
785  			return HP_WMI_TYPE_TEMPERATURE;
786  		break;
787  
788  	case HP_WMI_TYPE_VOLTAGE:
789  		if (base_units == HP_WMI_UNITS_VOLTS)
790  			return HP_WMI_TYPE_VOLTAGE;
791  		break;
792  
793  	case HP_WMI_TYPE_CURRENT:
794  		if (base_units == HP_WMI_UNITS_AMPS)
795  			return HP_WMI_TYPE_CURRENT;
796  		break;
797  
798  	case HP_WMI_TYPE_AIR_FLOW:
799  		/*
800  		 * Strangely, HP considers fan RPM sensor type to be
801  		 * "Air Flow" instead of the more intuitive "Tachometer".
802  		 */
803  		if (base_units == HP_WMI_UNITS_RPM)
804  			return HP_WMI_TYPE_AIR_FLOW;
805  		break;
806  	}
807  
808  	return -EINVAL;
809  }
810  
811  static int
populate_numeric_sensor_from_wobj(struct device * dev,struct hp_wmi_numeric_sensor * nsensor,union acpi_object * wobj,bool * out_is_new)812  populate_numeric_sensor_from_wobj(struct device *dev,
813  				  struct hp_wmi_numeric_sensor *nsensor,
814  				  union acpi_object *wobj, bool *out_is_new)
815  {
816  	int last_prop = HP_WMI_PROPERTY_RATE_UNITS;
817  	int prop = HP_WMI_PROPERTY_NAME;
818  	const char **possible_states;
819  	union acpi_object *element;
820  	acpi_object_type type;
821  	char *string;
822  	bool is_new;
823  	u32 value;
824  	u8 size;
825  	int err;
826  
827  	err = check_numeric_sensor_wobj(wobj, &size, &is_new);
828  	if (err)
829  		return err;
830  
831  	possible_states = devm_kcalloc(dev, size, sizeof(*possible_states),
832  				       GFP_KERNEL);
833  	if (!possible_states)
834  		return -ENOMEM;
835  
836  	element = wobj->package.elements;
837  	nsensor->possible_states = possible_states;
838  	nsensor->size = size;
839  
840  	if (!is_new)
841  		last_prop = HP_WMI_PROPERTY_CURRENT_READING;
842  
843  	for (; prop <= last_prop; prop++) {
844  		type = hp_wmi_property_map[prop];
845  
846  		err = extract_acpi_value(dev, element, type, &value, &string);
847  		if (err)
848  			return err;
849  
850  		element++;
851  
852  		switch (prop) {
853  		case HP_WMI_PROPERTY_NAME:
854  			nsensor->name = string;
855  			break;
856  
857  		case HP_WMI_PROPERTY_DESCRIPTION:
858  			nsensor->description = string;
859  			break;
860  
861  		case HP_WMI_PROPERTY_SENSOR_TYPE:
862  			if (value > HP_WMI_TYPE_AIR_FLOW)
863  				return -EINVAL;
864  
865  			nsensor->sensor_type = value;
866  			break;
867  
868  		case HP_WMI_PROPERTY_OTHER_SENSOR_TYPE:
869  			nsensor->other_sensor_type = string;
870  			break;
871  
872  		case HP_WMI_PROPERTY_OPERATIONAL_STATUS:
873  			nsensor->operational_status = value;
874  
875  			/* Old variant: CurrentState follows OperationalStatus. */
876  			if (!is_new)
877  				prop = HP_WMI_PROPERTY_CURRENT_STATE - 1;
878  			break;
879  
880  		case HP_WMI_PROPERTY_SIZE:
881  			break;			/* Already set. */
882  
883  		case HP_WMI_PROPERTY_POSSIBLE_STATES:
884  			*possible_states++ = string;
885  			if (--size)
886  				prop--;
887  
888  			/* Old variant: BaseUnits follows PossibleStates[]. */
889  			if (!is_new && !size)
890  				prop = HP_WMI_PROPERTY_BASE_UNITS - 1;
891  			break;
892  
893  		case HP_WMI_PROPERTY_CURRENT_STATE:
894  			nsensor->current_state = string;
895  
896  			/* Old variant: PossibleStates[] follows CurrentState. */
897  			if (!is_new)
898  				prop = HP_WMI_PROPERTY_POSSIBLE_STATES - 1;
899  			break;
900  
901  		case HP_WMI_PROPERTY_BASE_UNITS:
902  			nsensor->base_units = value;
903  			break;
904  
905  		case HP_WMI_PROPERTY_UNIT_MODIFIER:
906  			/* UnitModifier is signed. */
907  			nsensor->unit_modifier = (s32)value;
908  			break;
909  
910  		case HP_WMI_PROPERTY_CURRENT_READING:
911  			nsensor->current_reading = value;
912  			break;
913  
914  		case HP_WMI_PROPERTY_RATE_UNITS:
915  			nsensor->rate_units = value;
916  			break;
917  
918  		default:
919  			return -EINVAL;
920  		}
921  	}
922  
923  	*out_is_new = is_new;
924  
925  	return 0;
926  }
927  
928  /* update_numeric_sensor_from_wobj - update fungible sensor properties */
929  static void
update_numeric_sensor_from_wobj(struct device * dev,struct hp_wmi_numeric_sensor * nsensor,const union acpi_object * wobj)930  update_numeric_sensor_from_wobj(struct device *dev,
931  				struct hp_wmi_numeric_sensor *nsensor,
932  				const union acpi_object *wobj)
933  {
934  	const union acpi_object *elements;
935  	const union acpi_object *element;
936  	const char *new_string;
937  	char *trimmed;
938  	char *string;
939  	bool is_new;
940  	int offset;
941  	u8 size;
942  	int err;
943  
944  	err = check_numeric_sensor_wobj(wobj, &size, &is_new);
945  	if (err)
946  		return;
947  
948  	elements = wobj->package.elements;
949  
950  	element = &elements[HP_WMI_PROPERTY_OPERATIONAL_STATUS];
951  	nsensor->operational_status = element->integer.value;
952  
953  	/*
954  	 * In general, an index offset is needed after PossibleStates[0].
955  	 * On a new variant, CurrentState is after PossibleStates[]. This is
956  	 * not the case on an old variant, but we still need to offset the
957  	 * read because CurrentState is where Size would be on a new variant.
958  	 */
959  	offset = is_new ? size - 1 : -2;
960  
961  	element = &elements[HP_WMI_PROPERTY_CURRENT_STATE + offset];
962  	string = element->type == ACPI_TYPE_BUFFER ?
963  		convert_raw_wmi_string(element->buffer.pointer) :
964  		element->string.pointer;
965  
966  	if (string) {
967  		trimmed = strim(string);
968  		if (strcmp(trimmed, nsensor->current_state)) {
969  			new_string = hp_wmi_strdup(dev, trimmed);
970  			if (new_string) {
971  				devm_kfree(dev, nsensor->current_state);
972  				nsensor->current_state = new_string;
973  			}
974  		}
975  		if (element->type == ACPI_TYPE_BUFFER)
976  			kfree(string);
977  	}
978  
979  	/* Old variant: -2 (not -1) because it lacks the Size property. */
980  	if (!is_new)
981  		offset = (int)size - 2;	/* size is > 0, i.e. may be 1. */
982  
983  	element = &elements[HP_WMI_PROPERTY_UNIT_MODIFIER + offset];
984  	nsensor->unit_modifier = (s32)element->integer.value;
985  
986  	element = &elements[HP_WMI_PROPERTY_CURRENT_READING + offset];
987  	nsensor->current_reading = element->integer.value;
988  }
989  
990  /*
991   * check_platform_events_wobj - validate a HPBIOS_PlatformEvents instance
992   * @wobj: pointer to WMI object instance to check
993   *
994   * Returns 0 on success, or a negative error code on error.
995   */
check_platform_events_wobj(const union acpi_object * wobj)996  static int check_platform_events_wobj(const union acpi_object *wobj)
997  {
998  	return check_wobj(wobj, hp_wmi_platform_events_property_map,
999  			  HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS);
1000  }
1001  
1002  static int
populate_platform_events_from_wobj(struct device * dev,struct hp_wmi_platform_events * pevents,union acpi_object * wobj)1003  populate_platform_events_from_wobj(struct device *dev,
1004  				   struct hp_wmi_platform_events *pevents,
1005  				   union acpi_object *wobj)
1006  {
1007  	int last_prop = HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS;
1008  	int prop = HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME;
1009  	union acpi_object *element;
1010  	acpi_object_type type;
1011  	char *string;
1012  	u32 value;
1013  	int err;
1014  
1015  	err = check_platform_events_wobj(wobj);
1016  	if (err)
1017  		return err;
1018  
1019  	element = wobj->package.elements;
1020  
1021  	for (; prop <= last_prop; prop++, element++) {
1022  		type = hp_wmi_platform_events_property_map[prop];
1023  
1024  		err = extract_acpi_value(dev, element, type, &value, &string);
1025  		if (err)
1026  			return err;
1027  
1028  		switch (prop) {
1029  		case HP_WMI_PLATFORM_EVENTS_PROPERTY_NAME:
1030  			pevents->name = string;
1031  			break;
1032  
1033  		case HP_WMI_PLATFORM_EVENTS_PROPERTY_DESCRIPTION:
1034  			pevents->description = string;
1035  			break;
1036  
1037  		case HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_NAMESPACE:
1038  			if (strcasecmp(HP_WMI_EVENT_NAMESPACE, string))
1039  				return -EINVAL;
1040  
1041  			pevents->source_namespace = string;
1042  			break;
1043  
1044  		case HP_WMI_PLATFORM_EVENTS_PROPERTY_SOURCE_CLASS:
1045  			if (strcasecmp(HP_WMI_EVENT_CLASS, string))
1046  				return -EINVAL;
1047  
1048  			pevents->source_class = string;
1049  			break;
1050  
1051  		case HP_WMI_PLATFORM_EVENTS_PROPERTY_CATEGORY:
1052  			pevents->category = value;
1053  			break;
1054  
1055  		case HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_SEVERITY:
1056  			pevents->possible_severity = value;
1057  			break;
1058  
1059  		case HP_WMI_PLATFORM_EVENTS_PROPERTY_POSSIBLE_STATUS:
1060  			pevents->possible_status = value;
1061  			break;
1062  
1063  		default:
1064  			return -EINVAL;
1065  		}
1066  	}
1067  
1068  	return 0;
1069  }
1070  
1071  /*
1072   * check_event_wobj - validate a HPBIOS_BIOSEvent instance
1073   * @wobj: pointer to WMI object instance to check
1074   *
1075   * Returns 0 on success, or a negative error code on error.
1076   */
check_event_wobj(const union acpi_object * wobj)1077  static int check_event_wobj(const union acpi_object *wobj)
1078  {
1079  	return check_wobj(wobj, hp_wmi_event_property_map,
1080  			  HP_WMI_EVENT_PROPERTY_STATUS);
1081  }
1082  
populate_event_from_wobj(struct device * dev,struct hp_wmi_event * event,union acpi_object * wobj)1083  static int populate_event_from_wobj(struct device *dev,
1084  				    struct hp_wmi_event *event,
1085  				    union acpi_object *wobj)
1086  {
1087  	int prop = HP_WMI_EVENT_PROPERTY_NAME;
1088  	union acpi_object *element;
1089  	acpi_object_type type;
1090  	char *string;
1091  	u32 value;
1092  	int err;
1093  
1094  	err = check_event_wobj(wobj);
1095  	if (err)
1096  		return err;
1097  
1098  	element = wobj->package.elements;
1099  
1100  	for (; prop <= HP_WMI_EVENT_PROPERTY_CATEGORY; prop++, element++) {
1101  		type = hp_wmi_event_property_map[prop];
1102  
1103  		err = extract_acpi_value(dev, element, type, &value, &string);
1104  		if (err)
1105  			return err;
1106  
1107  		switch (prop) {
1108  		case HP_WMI_EVENT_PROPERTY_NAME:
1109  			event->name = string;
1110  			break;
1111  
1112  		case HP_WMI_EVENT_PROPERTY_DESCRIPTION:
1113  			event->description = string;
1114  			break;
1115  
1116  		case HP_WMI_EVENT_PROPERTY_CATEGORY:
1117  			event->category = value;
1118  			break;
1119  
1120  		default:
1121  			return -EINVAL;
1122  		}
1123  	}
1124  
1125  	return 0;
1126  }
1127  
1128  /*
1129   * classify_event - classify an event
1130   * @name: event name
1131   * @category: event category
1132   *
1133   * Classify instances of both HPBIOS_PlatformEvents and HPBIOS_BIOSEvent from
1134   * property values. Recognition criteria are based on multiple ACPI dumps [3].
1135   *
1136   * Returns an enum hp_wmi_type value on success,
1137   * or a negative value if the event type is unsupported.
1138   */
classify_event(const char * event_name,u32 category)1139  static int classify_event(const char *event_name, u32 category)
1140  {
1141  	if (category != HP_WMI_CATEGORY_SENSOR)
1142  		return -EINVAL;
1143  
1144  	/* Fan events have Name "X Stall". */
1145  	if (strstr(event_name, HP_WMI_PATTERN_FAN_ALARM))
1146  		return HP_WMI_TYPE_AIR_FLOW;
1147  
1148  	/* Intrusion events have Name "Hood Intrusion". */
1149  	if (!strcmp(event_name, HP_WMI_PATTERN_INTRUSION_ALARM))
1150  		return HP_WMI_TYPE_INTRUSION;
1151  
1152  	/*
1153  	 * Temperature events have Name either "Thermal Caution" or
1154  	 * "Thermal Critical". Deal only with "Thermal Critical" events.
1155  	 *
1156  	 * "Thermal Caution" events have Status "Stressed", informing us that
1157  	 * the OperationalStatus of the related sensor has become "Stressed".
1158  	 * However, this is already a fault condition that will clear itself
1159  	 * when the sensor recovers, so we have no further interest in them.
1160  	 */
1161  	if (!strcmp(event_name, HP_WMI_PATTERN_TEMP_ALARM))
1162  		return HP_WMI_TYPE_TEMPERATURE;
1163  
1164  	return -EINVAL;
1165  }
1166  
1167  /*
1168   * interpret_info - interpret sensor for hwmon
1169   * @info: pointer to sensor info struct
1170   *
1171   * Should be called after the numeric sensor member has been updated.
1172   */
interpret_info(struct hp_wmi_info * info)1173  static void interpret_info(struct hp_wmi_info *info)
1174  {
1175  	const struct hp_wmi_numeric_sensor *nsensor = &info->nsensor;
1176  
1177  	info->cached_val = scale_numeric_sensor(nsensor);
1178  	info->last_updated = jiffies;
1179  }
1180  
1181  /*
1182   * hp_wmi_update_info - poll WMI to update sensor info
1183   * @state: pointer to driver state
1184   * @info: pointer to sensor info struct
1185   *
1186   * Returns 0 on success, or a negative error code on error.
1187   */
hp_wmi_update_info(struct hp_wmi_sensors * state,struct hp_wmi_info * info)1188  static int hp_wmi_update_info(struct hp_wmi_sensors *state,
1189  			      struct hp_wmi_info *info)
1190  {
1191  	struct hp_wmi_numeric_sensor *nsensor = &info->nsensor;
1192  	struct device *dev = &state->wdev->dev;
1193  	const union acpi_object *wobj;
1194  	u8 instance = info->instance;
1195  	int ret = 0;
1196  
1197  	if (time_after(jiffies, info->last_updated + HZ)) {
1198  		mutex_lock(&state->lock);
1199  
1200  		wobj = hp_wmi_get_wobj(HP_WMI_NUMERIC_SENSOR_GUID, instance);
1201  		if (!wobj) {
1202  			ret = -EIO;
1203  			goto out_unlock;
1204  		}
1205  
1206  		update_numeric_sensor_from_wobj(dev, nsensor, wobj);
1207  
1208  		interpret_info(info);
1209  
1210  		kfree(wobj);
1211  
1212  out_unlock:
1213  		mutex_unlock(&state->lock);
1214  	}
1215  
1216  	return ret;
1217  }
1218  
basic_string_show(struct seq_file * seqf,void * ignored)1219  static int basic_string_show(struct seq_file *seqf, void *ignored)
1220  {
1221  	const char *str = seqf->private;
1222  
1223  	seq_printf(seqf, "%s\n", str);
1224  
1225  	return 0;
1226  }
1227  DEFINE_SHOW_ATTRIBUTE(basic_string);
1228  
fungible_show(struct seq_file * seqf,enum hp_wmi_property prop)1229  static int fungible_show(struct seq_file *seqf, enum hp_wmi_property prop)
1230  {
1231  	struct hp_wmi_numeric_sensor *nsensor;
1232  	struct hp_wmi_sensors *state;
1233  	struct hp_wmi_info *info;
1234  	int err;
1235  
1236  	info = seqf->private;
1237  	state = info->state;
1238  	nsensor = &info->nsensor;
1239  
1240  	err = hp_wmi_update_info(state, info);
1241  	if (err)
1242  		return err;
1243  
1244  	switch (prop) {
1245  	case HP_WMI_PROPERTY_OPERATIONAL_STATUS:
1246  		seq_printf(seqf, "%u\n", nsensor->operational_status);
1247  		break;
1248  
1249  	case HP_WMI_PROPERTY_CURRENT_STATE:
1250  		seq_printf(seqf, "%s\n", nsensor->current_state);
1251  		break;
1252  
1253  	case HP_WMI_PROPERTY_UNIT_MODIFIER:
1254  		seq_printf(seqf, "%d\n", nsensor->unit_modifier);
1255  		break;
1256  
1257  	case HP_WMI_PROPERTY_CURRENT_READING:
1258  		seq_printf(seqf, "%u\n", nsensor->current_reading);
1259  		break;
1260  
1261  	default:
1262  		return -EOPNOTSUPP;
1263  	}
1264  
1265  	return 0;
1266  }
1267  
operational_status_show(struct seq_file * seqf,void * ignored)1268  static int operational_status_show(struct seq_file *seqf, void *ignored)
1269  {
1270  	return fungible_show(seqf, HP_WMI_PROPERTY_OPERATIONAL_STATUS);
1271  }
1272  DEFINE_SHOW_ATTRIBUTE(operational_status);
1273  
current_state_show(struct seq_file * seqf,void * ignored)1274  static int current_state_show(struct seq_file *seqf, void *ignored)
1275  {
1276  	return fungible_show(seqf, HP_WMI_PROPERTY_CURRENT_STATE);
1277  }
1278  DEFINE_SHOW_ATTRIBUTE(current_state);
1279  
possible_states_show(struct seq_file * seqf,void * ignored)1280  static int possible_states_show(struct seq_file *seqf, void *ignored)
1281  {
1282  	struct hp_wmi_numeric_sensor *nsensor = seqf->private;
1283  	u8 i;
1284  
1285  	for (i = 0; i < nsensor->size; i++)
1286  		seq_printf(seqf, "%s%s", i ? "," : "",
1287  			   nsensor->possible_states[i]);
1288  
1289  	seq_puts(seqf, "\n");
1290  
1291  	return 0;
1292  }
1293  DEFINE_SHOW_ATTRIBUTE(possible_states);
1294  
unit_modifier_show(struct seq_file * seqf,void * ignored)1295  static int unit_modifier_show(struct seq_file *seqf, void *ignored)
1296  {
1297  	return fungible_show(seqf, HP_WMI_PROPERTY_UNIT_MODIFIER);
1298  }
1299  DEFINE_SHOW_ATTRIBUTE(unit_modifier);
1300  
current_reading_show(struct seq_file * seqf,void * ignored)1301  static int current_reading_show(struct seq_file *seqf, void *ignored)
1302  {
1303  	return fungible_show(seqf, HP_WMI_PROPERTY_CURRENT_READING);
1304  }
1305  DEFINE_SHOW_ATTRIBUTE(current_reading);
1306  
1307  /* hp_wmi_devm_debugfs_remove - devm callback for debugfs cleanup */
hp_wmi_devm_debugfs_remove(void * res)1308  static void hp_wmi_devm_debugfs_remove(void *res)
1309  {
1310  	debugfs_remove_recursive(res);
1311  }
1312  
1313  /* hp_wmi_debugfs_init - create and populate debugfs directory tree */
hp_wmi_debugfs_init(struct device * dev,struct hp_wmi_info * info,struct hp_wmi_platform_events * pevents,u8 icount,u8 pcount,bool is_new)1314  static void hp_wmi_debugfs_init(struct device *dev, struct hp_wmi_info *info,
1315  				struct hp_wmi_platform_events *pevents,
1316  				u8 icount, u8 pcount, bool is_new)
1317  {
1318  	struct hp_wmi_numeric_sensor *nsensor;
1319  	char buf[HP_WMI_MAX_STR_SIZE];
1320  	struct dentry *debugfs;
1321  	struct dentry *entries;
1322  	struct dentry *dir;
1323  	int err;
1324  	u8 i;
1325  
1326  	/* dev_name() gives a not-very-friendly GUID for WMI devices. */
1327  	scnprintf(buf, sizeof(buf), "hp-wmi-sensors-%u", dev->id);
1328  
1329  	debugfs = debugfs_create_dir(buf, NULL);
1330  	if (IS_ERR(debugfs))
1331  		return;
1332  
1333  	err = devm_add_action_or_reset(dev, hp_wmi_devm_debugfs_remove,
1334  				       debugfs);
1335  	if (err)
1336  		return;
1337  
1338  	entries = debugfs_create_dir("sensor", debugfs);
1339  
1340  	for (i = 0; i < icount; i++, info++) {
1341  		nsensor = &info->nsensor;
1342  
1343  		scnprintf(buf, sizeof(buf), "%u", i);
1344  		dir = debugfs_create_dir(buf, entries);
1345  
1346  		debugfs_create_file("name", 0444, dir,
1347  				    (void *)nsensor->name,
1348  				    &basic_string_fops);
1349  
1350  		debugfs_create_file("description", 0444, dir,
1351  				    (void *)nsensor->description,
1352  				    &basic_string_fops);
1353  
1354  		debugfs_create_u32("sensor_type", 0444, dir,
1355  				   &nsensor->sensor_type);
1356  
1357  		debugfs_create_file("other_sensor_type", 0444, dir,
1358  				    (void *)nsensor->other_sensor_type,
1359  				    &basic_string_fops);
1360  
1361  		debugfs_create_file("operational_status", 0444, dir,
1362  				    info, &operational_status_fops);
1363  
1364  		debugfs_create_file("possible_states", 0444, dir,
1365  				    nsensor, &possible_states_fops);
1366  
1367  		debugfs_create_file("current_state", 0444, dir,
1368  				    info, &current_state_fops);
1369  
1370  		debugfs_create_u32("base_units", 0444, dir,
1371  				   &nsensor->base_units);
1372  
1373  		debugfs_create_file("unit_modifier", 0444, dir,
1374  				    info, &unit_modifier_fops);
1375  
1376  		debugfs_create_file("current_reading", 0444, dir,
1377  				    info, &current_reading_fops);
1378  
1379  		if (is_new)
1380  			debugfs_create_u32("rate_units", 0444, dir,
1381  					   &nsensor->rate_units);
1382  	}
1383  
1384  	if (!pcount)
1385  		return;
1386  
1387  	entries = debugfs_create_dir("platform_events", debugfs);
1388  
1389  	for (i = 0; i < pcount; i++, pevents++) {
1390  		scnprintf(buf, sizeof(buf), "%u", i);
1391  		dir = debugfs_create_dir(buf, entries);
1392  
1393  		debugfs_create_file("name", 0444, dir,
1394  				    (void *)pevents->name,
1395  				    &basic_string_fops);
1396  
1397  		debugfs_create_file("description", 0444, dir,
1398  				    (void *)pevents->description,
1399  				    &basic_string_fops);
1400  
1401  		debugfs_create_file("source_namespace", 0444, dir,
1402  				    (void *)pevents->source_namespace,
1403  				    &basic_string_fops);
1404  
1405  		debugfs_create_file("source_class", 0444, dir,
1406  				    (void *)pevents->source_class,
1407  				    &basic_string_fops);
1408  
1409  		debugfs_create_u32("category", 0444, dir,
1410  				   &pevents->category);
1411  
1412  		debugfs_create_u32("possible_severity", 0444, dir,
1413  				   &pevents->possible_severity);
1414  
1415  		debugfs_create_u32("possible_status", 0444, dir,
1416  				   &pevents->possible_status);
1417  	}
1418  }
1419  
hp_wmi_hwmon_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)1420  static umode_t hp_wmi_hwmon_is_visible(const void *drvdata,
1421  				       enum hwmon_sensor_types type,
1422  				       u32 attr, int channel)
1423  {
1424  	const struct hp_wmi_sensors *state = drvdata;
1425  	const struct hp_wmi_info *info;
1426  
1427  	if (type == hwmon_intrusion)
1428  		return state->has_intrusion ? 0644 : 0;
1429  
1430  	if (!state->info_map[type] || !state->info_map[type][channel])
1431  		return 0;
1432  
1433  	info = state->info_map[type][channel];
1434  
1435  	if ((type == hwmon_temp && attr == hwmon_temp_alarm) ||
1436  	    (type == hwmon_fan  && attr == hwmon_fan_alarm))
1437  		return info->has_alarm ? 0444 : 0;
1438  
1439  	return 0444;
1440  }
1441  
hp_wmi_hwmon_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * out_val)1442  static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
1443  			     u32 attr, int channel, long *out_val)
1444  {
1445  	struct hp_wmi_sensors *state = dev_get_drvdata(dev);
1446  	const struct hp_wmi_numeric_sensor *nsensor;
1447  	struct hp_wmi_info *info;
1448  	int err;
1449  
1450  	if (type == hwmon_intrusion) {
1451  		*out_val = state->intrusion ? 1 : 0;
1452  
1453  		return 0;
1454  	}
1455  
1456  	info = state->info_map[type][channel];
1457  
1458  	if ((type == hwmon_temp && attr == hwmon_temp_alarm) ||
1459  	    (type == hwmon_fan  && attr == hwmon_fan_alarm)) {
1460  		*out_val = info->alarm ? 1 : 0;
1461  		info->alarm = false;
1462  
1463  		return 0;
1464  	}
1465  
1466  	nsensor = &info->nsensor;
1467  
1468  	err = hp_wmi_update_info(state, info);
1469  	if (err)
1470  		return err;
1471  
1472  	if ((type == hwmon_temp && attr == hwmon_temp_fault) ||
1473  	    (type == hwmon_fan  && attr == hwmon_fan_fault))
1474  		*out_val = numeric_sensor_has_fault(nsensor);
1475  	else
1476  		*out_val = info->cached_val;
1477  
1478  	return 0;
1479  }
1480  
hp_wmi_hwmon_read_string(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,const char ** out_str)1481  static int hp_wmi_hwmon_read_string(struct device *dev,
1482  				    enum hwmon_sensor_types type, u32 attr,
1483  				    int channel, const char **out_str)
1484  {
1485  	const struct hp_wmi_sensors *state = dev_get_drvdata(dev);
1486  	const struct hp_wmi_info *info;
1487  
1488  	info = state->info_map[type][channel];
1489  	*out_str = info->nsensor.name;
1490  
1491  	return 0;
1492  }
1493  
hp_wmi_hwmon_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long val)1494  static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
1495  			      u32 attr, int channel, long val)
1496  {
1497  	struct hp_wmi_sensors *state = dev_get_drvdata(dev);
1498  
1499  	if (val)
1500  		return -EINVAL;
1501  
1502  	mutex_lock(&state->lock);
1503  
1504  	state->intrusion = false;
1505  
1506  	mutex_unlock(&state->lock);
1507  
1508  	return 0;
1509  }
1510  
1511  static const struct hwmon_ops hp_wmi_hwmon_ops = {
1512  	.is_visible  = hp_wmi_hwmon_is_visible,
1513  	.read	     = hp_wmi_hwmon_read,
1514  	.read_string = hp_wmi_hwmon_read_string,
1515  	.write	     = hp_wmi_hwmon_write,
1516  };
1517  
1518  static struct hwmon_chip_info hp_wmi_chip_info = {
1519  	.ops         = &hp_wmi_hwmon_ops,
1520  	.info        = NULL,
1521  };
1522  
match_fan_event(struct hp_wmi_sensors * state,const char * event_description)1523  static struct hp_wmi_info *match_fan_event(struct hp_wmi_sensors *state,
1524  					   const char *event_description)
1525  {
1526  	struct hp_wmi_info **ptr_info = state->info_map[hwmon_fan];
1527  	u8 fan_count = state->channel_count[hwmon_fan];
1528  	struct hp_wmi_info *info;
1529  	const char *name;
1530  	u8 i;
1531  
1532  	/* Fan event has Description "X Speed". Sensor has Name "X[ Speed]". */
1533  
1534  	for (i = 0; i < fan_count; i++, ptr_info++) {
1535  		info = *ptr_info;
1536  		name = info->nsensor.name;
1537  
1538  		if (strstr(event_description, name))
1539  			return info;
1540  	}
1541  
1542  	return NULL;
1543  }
1544  
match_temp_events(struct hp_wmi_sensors * state,const char * event_description,struct hp_wmi_info * temp_info[])1545  static u8 match_temp_events(struct hp_wmi_sensors *state,
1546  			    const char *event_description,
1547  			    struct hp_wmi_info *temp_info[])
1548  {
1549  	struct hp_wmi_info **ptr_info = state->info_map[hwmon_temp];
1550  	u8 temp_count = state->channel_count[hwmon_temp];
1551  	struct hp_wmi_info *info;
1552  	const char *name;
1553  	u8 count = 0;
1554  	bool is_cpu;
1555  	bool is_sys;
1556  	u8 i;
1557  
1558  	/* Description is either "CPU Thermal Index" or "Chassis Thermal Index". */
1559  
1560  	is_cpu = !strcmp(event_description, HP_WMI_PATTERN_CPU_TEMP);
1561  	is_sys = !strcmp(event_description, HP_WMI_PATTERN_SYS_TEMP);
1562  	if (!is_cpu && !is_sys)
1563  		return 0;
1564  
1565  	/*
1566  	 * CPU event: Match one sensor with Name either "CPU Thermal Index" or
1567  	 * "CPU Temperature", or multiple with Name(s) "CPU[#] Temperature".
1568  	 *
1569  	 * Chassis event: Match one sensor with Name either
1570  	 * "Chassis Thermal Index" or "System Ambient Temperature".
1571  	 */
1572  
1573  	for (i = 0; i < temp_count; i++, ptr_info++) {
1574  		info = *ptr_info;
1575  		name = info->nsensor.name;
1576  
1577  		if ((is_cpu && (!strcmp(name, HP_WMI_PATTERN_CPU_TEMP) ||
1578  				!strcmp(name, HP_WMI_PATTERN_CPU_TEMP2))) ||
1579  		    (is_sys && (!strcmp(name, HP_WMI_PATTERN_SYS_TEMP) ||
1580  				!strcmp(name, HP_WMI_PATTERN_SYS_TEMP2)))) {
1581  			temp_info[0] = info;
1582  			return 1;
1583  		}
1584  
1585  		if (is_cpu && (strstr(name, HP_WMI_PATTERN_CPU) &&
1586  			       strstr(name, HP_WMI_PATTERN_TEMP)))
1587  			temp_info[count++] = info;
1588  	}
1589  
1590  	return count;
1591  }
1592  
1593  /* hp_wmi_devm_debugfs_remove - devm callback for WMI event handler removal */
hp_wmi_devm_notify_remove(void * ignored)1594  static void hp_wmi_devm_notify_remove(void *ignored)
1595  {
1596  	wmi_remove_notify_handler(HP_WMI_EVENT_GUID);
1597  }
1598  
1599  /* hp_wmi_notify - WMI event notification handler */
hp_wmi_notify(union acpi_object * wobj,void * context)1600  static void hp_wmi_notify(union acpi_object *wobj, void *context)
1601  {
1602  	struct hp_wmi_info *temp_info[HP_WMI_MAX_INSTANCES] = {};
1603  	struct hp_wmi_sensors *state = context;
1604  	struct device *dev = &state->wdev->dev;
1605  	struct hp_wmi_event event = {};
1606  	struct hp_wmi_info *fan_info;
1607  	acpi_status err;
1608  	int event_type;
1609  	u8 count;
1610  
1611  	/*
1612  	 * The following warning may occur in the kernel log:
1613  	 *
1614  	 *   ACPI Warning: \_SB.WMID._WED: Return type mismatch -
1615  	 *     found Package, expected Integer/String/Buffer
1616  	 *
1617  	 * After using [4] to decode BMOF blobs found in [3], careless copying
1618  	 * of BIOS code seems the most likely explanation for this warning.
1619  	 * HP_WMI_EVENT_GUID refers to \\.\root\WMI\HPBIOS_BIOSEvent on
1620  	 * business-class systems, but it refers to \\.\root\WMI\hpqBEvnt on
1621  	 * non-business-class systems. Per the existing hp-wmi driver, it
1622  	 * looks like an instance of hpqBEvnt delivered as event data may
1623  	 * indeed take the form of a raw ACPI_BUFFER on non-business-class
1624  	 * systems ("may" because ASL shows some BIOSes do strange things).
1625  	 *
1626  	 * In any case, we can ignore this warning, because we always validate
1627  	 * the event data to ensure it is an ACPI_PACKAGE containing a
1628  	 * HPBIOS_BIOSEvent instance.
1629  	 */
1630  
1631  	if (!wobj)
1632  		return;
1633  
1634  	mutex_lock(&state->lock);
1635  
1636  	err = populate_event_from_wobj(dev, &event, wobj);
1637  	if (err) {
1638  		dev_warn(dev, "Bad event data (ACPI type %d)\n", wobj->type);
1639  		goto out_free;
1640  	}
1641  
1642  	event_type = classify_event(event.name, event.category);
1643  	switch (event_type) {
1644  	case HP_WMI_TYPE_AIR_FLOW:
1645  		fan_info = match_fan_event(state, event.description);
1646  		if (fan_info)
1647  			fan_info->alarm = true;
1648  		break;
1649  
1650  	case HP_WMI_TYPE_INTRUSION:
1651  		state->intrusion = true;
1652  		break;
1653  
1654  	case HP_WMI_TYPE_TEMPERATURE:
1655  		count = match_temp_events(state, event.description, temp_info);
1656  		while (count)
1657  			temp_info[--count]->alarm = true;
1658  		break;
1659  
1660  	default:
1661  		break;
1662  	}
1663  
1664  out_free:
1665  	devm_kfree(dev, event.name);
1666  	devm_kfree(dev, event.description);
1667  
1668  	mutex_unlock(&state->lock);
1669  }
1670  
init_platform_events(struct device * dev,struct hp_wmi_platform_events ** out_pevents,u8 * out_pcount)1671  static int init_platform_events(struct device *dev,
1672  				struct hp_wmi_platform_events **out_pevents,
1673  				u8 *out_pcount)
1674  {
1675  	struct hp_wmi_platform_events *pevents_arr;
1676  	struct hp_wmi_platform_events *pevents;
1677  	union acpi_object *wobj;
1678  	u8 count;
1679  	int err;
1680  	u8 i;
1681  
1682  	count = hp_wmi_wobj_instance_count(HP_WMI_PLATFORM_EVENTS_GUID);
1683  	if (!count) {
1684  		*out_pcount = 0;
1685  
1686  		dev_dbg(dev, "No platform events\n");
1687  
1688  		return 0;
1689  	}
1690  
1691  	pevents_arr = devm_kcalloc(dev, count, sizeof(*pevents), GFP_KERNEL);
1692  	if (!pevents_arr)
1693  		return -ENOMEM;
1694  
1695  	for (i = 0, pevents = pevents_arr; i < count; i++, pevents++) {
1696  		wobj = hp_wmi_get_wobj(HP_WMI_PLATFORM_EVENTS_GUID, i);
1697  		if (!wobj)
1698  			return -EIO;
1699  
1700  		err = populate_platform_events_from_wobj(dev, pevents, wobj);
1701  
1702  		kfree(wobj);
1703  
1704  		if (err)
1705  			return err;
1706  	}
1707  
1708  	*out_pevents = pevents_arr;
1709  	*out_pcount = count;
1710  
1711  	dev_dbg(dev, "Found %u platform events\n", count);
1712  
1713  	return 0;
1714  }
1715  
init_numeric_sensors(struct hp_wmi_sensors * state,struct hp_wmi_info * connected[],struct hp_wmi_info ** out_info,u8 * out_icount,u8 * out_count,bool * out_is_new)1716  static int init_numeric_sensors(struct hp_wmi_sensors *state,
1717  				struct hp_wmi_info *connected[],
1718  				struct hp_wmi_info **out_info,
1719  				u8 *out_icount, u8 *out_count,
1720  				bool *out_is_new)
1721  {
1722  	struct hp_wmi_info ***info_map = state->info_map;
1723  	u8 *channel_count = state->channel_count;
1724  	struct device *dev = &state->wdev->dev;
1725  	struct hp_wmi_numeric_sensor *nsensor;
1726  	u8 channel_index[hwmon_max] = {};
1727  	enum hwmon_sensor_types type;
1728  	struct hp_wmi_info *info_arr;
1729  	struct hp_wmi_info *info;
1730  	union acpi_object *wobj;
1731  	u8 count = 0;
1732  	bool is_new;
1733  	u8 icount;
1734  	int wtype;
1735  	int err;
1736  	u8 c;
1737  	u8 i;
1738  
1739  	icount = hp_wmi_wobj_instance_count(HP_WMI_NUMERIC_SENSOR_GUID);
1740  	if (!icount)
1741  		return -ENODATA;
1742  
1743  	info_arr = devm_kcalloc(dev, icount, sizeof(*info), GFP_KERNEL);
1744  	if (!info_arr)
1745  		return -ENOMEM;
1746  
1747  	for (i = 0, info = info_arr; i < icount; i++, info++) {
1748  		wobj = hp_wmi_get_wobj(HP_WMI_NUMERIC_SENSOR_GUID, i);
1749  		if (!wobj)
1750  			return -EIO;
1751  
1752  		info->instance = i;
1753  		info->state = state;
1754  		nsensor = &info->nsensor;
1755  
1756  		err = populate_numeric_sensor_from_wobj(dev, nsensor, wobj,
1757  							&is_new);
1758  
1759  		kfree(wobj);
1760  
1761  		if (err)
1762  			return err;
1763  
1764  		if (!numeric_sensor_is_connected(nsensor))
1765  			continue;
1766  
1767  		wtype = classify_numeric_sensor(nsensor);
1768  		if (wtype < 0)
1769  			continue;
1770  
1771  		type = hp_wmi_hwmon_type_map[wtype];
1772  
1773  		channel_count[type]++;
1774  
1775  		info->type = type;
1776  
1777  		interpret_info(info);
1778  
1779  		connected[count++] = info;
1780  	}
1781  
1782  	dev_dbg(dev, "Found %u sensors (%u connected)\n", i, count);
1783  
1784  	for (i = 0; i < count; i++) {
1785  		info = connected[i];
1786  		type = info->type;
1787  		c = channel_index[type]++;
1788  
1789  		if (!info_map[type]) {
1790  			info_map[type] = devm_kcalloc(dev, channel_count[type],
1791  						      sizeof(*info_map),
1792  						      GFP_KERNEL);
1793  			if (!info_map[type])
1794  				return -ENOMEM;
1795  		}
1796  
1797  		info_map[type][c] = info;
1798  	}
1799  
1800  	*out_info = info_arr;
1801  	*out_icount = icount;
1802  	*out_count = count;
1803  	*out_is_new = is_new;
1804  
1805  	return 0;
1806  }
1807  
find_event_attributes(struct hp_wmi_sensors * state,struct hp_wmi_platform_events * pevents,u8 pevents_count)1808  static bool find_event_attributes(struct hp_wmi_sensors *state,
1809  				  struct hp_wmi_platform_events *pevents,
1810  				  u8 pevents_count)
1811  {
1812  	/*
1813  	 * The existence of this HPBIOS_PlatformEvents instance:
1814  	 *
1815  	 *   {
1816  	 *     Name = "Rear Chassis Fan0 Stall";
1817  	 *     Description = "Rear Chassis Fan0 Speed";
1818  	 *     Category = 3;           // "Sensor"
1819  	 *     PossibleSeverity = 25;  // "Critical Failure"
1820  	 *     PossibleStatus = 5;     // "Predictive Failure"
1821  	 *     [...]
1822  	 *   }
1823  	 *
1824  	 * means that this HPBIOS_BIOSEvent instance may occur:
1825  	 *
1826  	 *   {
1827  	 *     Name = "Rear Chassis Fan0 Stall";
1828  	 *     Description = "Rear Chassis Fan0 Speed";
1829  	 *     Category = 3;           // "Sensor"
1830  	 *     Severity = 25;          // "Critical Failure"
1831  	 *     Status = 5;             // "Predictive Failure"
1832  	 *   }
1833  	 *
1834  	 * After the event occurs (e.g. because the fan was unplugged),
1835  	 * polling the related HPBIOS_BIOSNumericSensor instance gives:
1836  	 *
1837  	 *   {
1838  	 *      Name = "Rear Chassis Fan0";
1839  	 *      Description = "Reports rear chassis fan0 speed";
1840  	 *      OperationalStatus = 5; // "Predictive Failure", was 3 ("OK")
1841  	 *      CurrentReading = 0;
1842  	 *      [...]
1843  	 *   }
1844  	 *
1845  	 * In this example, the hwmon fan channel for "Rear Chassis Fan0"
1846  	 * should support the alarm flag and have it be set if the related
1847  	 * HPBIOS_BIOSEvent instance occurs.
1848  	 *
1849  	 * In addition to fan events, temperature (CPU/chassis) and intrusion
1850  	 * events are relevant to hwmon [2]. Note that much information in [2]
1851  	 * is unreliable; it is referenced in addition to ACPI dumps [3] merely
1852  	 * to support the conclusion that sensor and event names/descriptions
1853  	 * are systematic enough to allow this driver to match them.
1854  	 *
1855  	 * Complications and limitations:
1856  	 *
1857  	 * - Strings are freeform and may vary, cf. sensor Name "CPU0 Fan"
1858  	 *   on a Z420 vs. "CPU Fan Speed" on an EliteOne 800 G1.
1859  	 * - Leading/trailing whitespace is a rare but real possibility [3].
1860  	 * - The HPBIOS_PlatformEvents object may not exist or its instances
1861  	 *   may show that the system only has e.g. BIOS setting-related
1862  	 *   events (cf. the ProBook 4540s and ProBook 470 G0 [3]).
1863  	 */
1864  
1865  	struct hp_wmi_info *temp_info[HP_WMI_MAX_INSTANCES] = {};
1866  	const char *event_description;
1867  	struct hp_wmi_info *fan_info;
1868  	bool has_events = false;
1869  	const char *event_name;
1870  	u32 event_category;
1871  	int event_type;
1872  	u8 count;
1873  	u8 i;
1874  
1875  	for (i = 0; i < pevents_count; i++, pevents++) {
1876  		event_name = pevents->name;
1877  		event_description = pevents->description;
1878  		event_category = pevents->category;
1879  
1880  		event_type = classify_event(event_name, event_category);
1881  		switch (event_type) {
1882  		case HP_WMI_TYPE_AIR_FLOW:
1883  			fan_info = match_fan_event(state, event_description);
1884  			if (!fan_info)
1885  				break;
1886  
1887  			fan_info->has_alarm = true;
1888  			has_events = true;
1889  			break;
1890  
1891  		case HP_WMI_TYPE_INTRUSION:
1892  			state->has_intrusion = true;
1893  			has_events = true;
1894  			break;
1895  
1896  		case HP_WMI_TYPE_TEMPERATURE:
1897  			count = match_temp_events(state, event_description,
1898  						  temp_info);
1899  			if (!count)
1900  				break;
1901  
1902  			while (count)
1903  				temp_info[--count]->has_alarm = true;
1904  			has_events = true;
1905  			break;
1906  
1907  		default:
1908  			break;
1909  		}
1910  	}
1911  
1912  	return has_events;
1913  }
1914  
make_chip_info(struct hp_wmi_sensors * state,bool has_events)1915  static int make_chip_info(struct hp_wmi_sensors *state, bool has_events)
1916  {
1917  	const struct hwmon_channel_info **ptr_channel_info;
1918  	struct hp_wmi_info ***info_map = state->info_map;
1919  	u8 *channel_count = state->channel_count;
1920  	struct hwmon_channel_info *channel_info;
1921  	struct device *dev = &state->wdev->dev;
1922  	enum hwmon_sensor_types type;
1923  	u8 type_count = 0;
1924  	u32 *config;
1925  	u32 attr;
1926  	u8 count;
1927  	u8 i;
1928  
1929  	if (channel_count[hwmon_temp])
1930  		channel_count[hwmon_chip] = 1;
1931  
1932  	if (has_events && state->has_intrusion)
1933  		channel_count[hwmon_intrusion] = 1;
1934  
1935  	for (type = hwmon_chip; type < hwmon_max; type++)
1936  		if (channel_count[type])
1937  			type_count++;
1938  
1939  	channel_info = devm_kcalloc(dev, type_count,
1940  				    sizeof(*channel_info), GFP_KERNEL);
1941  	if (!channel_info)
1942  		return -ENOMEM;
1943  
1944  	ptr_channel_info = devm_kcalloc(dev, type_count + 1,
1945  					sizeof(*ptr_channel_info), GFP_KERNEL);
1946  	if (!ptr_channel_info)
1947  		return -ENOMEM;
1948  
1949  	hp_wmi_chip_info.info = ptr_channel_info;
1950  
1951  	for (type = hwmon_chip; type < hwmon_max; type++) {
1952  		count = channel_count[type];
1953  		if (!count)
1954  			continue;
1955  
1956  		config = devm_kcalloc(dev, count + 1,
1957  				      sizeof(*config), GFP_KERNEL);
1958  		if (!config)
1959  			return -ENOMEM;
1960  
1961  		attr = hp_wmi_hwmon_attributes[type];
1962  		channel_info->type = type;
1963  		channel_info->config = config;
1964  		memset32(config, attr, count);
1965  
1966  		*ptr_channel_info++ = channel_info++;
1967  
1968  		if (!has_events || (type != hwmon_temp && type != hwmon_fan))
1969  			continue;
1970  
1971  		attr = type == hwmon_temp ? HWMON_T_ALARM : HWMON_F_ALARM;
1972  
1973  		for (i = 0; i < count; i++)
1974  			if (info_map[type][i]->has_alarm)
1975  				config[i] |= attr;
1976  	}
1977  
1978  	return 0;
1979  }
1980  
add_event_handler(struct hp_wmi_sensors * state)1981  static bool add_event_handler(struct hp_wmi_sensors *state)
1982  {
1983  	struct device *dev = &state->wdev->dev;
1984  	int err;
1985  
1986  	err = wmi_install_notify_handler(HP_WMI_EVENT_GUID,
1987  					 hp_wmi_notify, state);
1988  	if (err) {
1989  		dev_info(dev, "Failed to subscribe to WMI event\n");
1990  		return false;
1991  	}
1992  
1993  	err = devm_add_action_or_reset(dev, hp_wmi_devm_notify_remove, NULL);
1994  	if (err)
1995  		return false;
1996  
1997  	return true;
1998  }
1999  
hp_wmi_sensors_init(struct hp_wmi_sensors * state)2000  static int hp_wmi_sensors_init(struct hp_wmi_sensors *state)
2001  {
2002  	struct hp_wmi_info *connected[HP_WMI_MAX_INSTANCES];
2003  	struct hp_wmi_platform_events *pevents = NULL;
2004  	struct device *dev = &state->wdev->dev;
2005  	struct hp_wmi_info *info;
2006  	struct device *hwdev;
2007  	bool has_events;
2008  	bool is_new;
2009  	u8 icount;
2010  	u8 pcount;
2011  	u8 count;
2012  	int err;
2013  
2014  	err = init_platform_events(dev, &pevents, &pcount);
2015  	if (err)
2016  		return err;
2017  
2018  	err = init_numeric_sensors(state, connected, &info,
2019  				   &icount, &count, &is_new);
2020  	if (err)
2021  		return err;
2022  
2023  	if (IS_ENABLED(CONFIG_DEBUG_FS))
2024  		hp_wmi_debugfs_init(dev, info, pevents, icount, pcount, is_new);
2025  
2026  	if (!count)
2027  		return 0;	/* No connected sensors; debugfs only. */
2028  
2029  	has_events = find_event_attributes(state, pevents, pcount);
2030  
2031  	/* Survive failure to install WMI event handler. */
2032  	if (has_events && !add_event_handler(state))
2033  		has_events = false;
2034  
2035  	err = make_chip_info(state, has_events);
2036  	if (err)
2037  		return err;
2038  
2039  	hwdev = devm_hwmon_device_register_with_info(dev, "hp_wmi_sensors",
2040  						     state, &hp_wmi_chip_info,
2041  						     NULL);
2042  	return PTR_ERR_OR_ZERO(hwdev);
2043  }
2044  
hp_wmi_sensors_probe(struct wmi_device * wdev,const void * context)2045  static int hp_wmi_sensors_probe(struct wmi_device *wdev, const void *context)
2046  {
2047  	struct device *dev = &wdev->dev;
2048  	struct hp_wmi_sensors *state;
2049  
2050  	state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
2051  	if (!state)
2052  		return -ENOMEM;
2053  
2054  	state->wdev = wdev;
2055  
2056  	mutex_init(&state->lock);
2057  
2058  	dev_set_drvdata(dev, state);
2059  
2060  	return hp_wmi_sensors_init(state);
2061  }
2062  
2063  static const struct wmi_device_id hp_wmi_sensors_id_table[] = {
2064  	{ HP_WMI_NUMERIC_SENSOR_GUID, NULL },
2065  	{},
2066  };
2067  
2068  static struct wmi_driver hp_wmi_sensors_driver = {
2069  	.driver   = { .name = "hp-wmi-sensors" },
2070  	.id_table = hp_wmi_sensors_id_table,
2071  	.probe    = hp_wmi_sensors_probe,
2072  };
2073  module_wmi_driver(hp_wmi_sensors_driver);
2074  
2075  MODULE_AUTHOR("James Seo <james@equiv.tech>");
2076  MODULE_DESCRIPTION("HP WMI Sensors driver");
2077  MODULE_LICENSE("GPL");
2078