1 // SPDX-License-Identifier: GPL-2.0
3 * Functions corresponding to enumeration type attributes under
4 * BIOS Enumeration GUID for use with dell-wmi-sysman
6 * Copyright (c) 2020 Dell Inc.
9 #include "dell-wmi-sysman.h"
11 get_instance_id(enumeration
);
13 static ssize_t
current_value_show(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
15 int instance_id
= get_enumeration_instance_id(kobj
);
16 union acpi_object
*obj
;
22 /* need to use specific instance_id and guid combination to get right data */
23 obj
= get_wmiobj_pointer(instance_id
, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID
);
26 if (obj
->package
.elements
[CURRENT_VAL
].type
!= ACPI_TYPE_STRING
) {
30 ret
= snprintf(buf
, PAGE_SIZE
, "%s\n", obj
->package
.elements
[CURRENT_VAL
].string
.pointer
);
36 * validate_enumeration_input() - Validate input of current_value against possible values
37 * @instance_id: The instance on which input is validated
40 static int validate_enumeration_input(int instance_id
, const char *buf
)
42 char *options
, *tmp
, *p
;
45 options
= tmp
= kstrdup(wmi_priv
.enumeration_data
[instance_id
].possible_values
,
50 while ((p
= strsep(&options
, ";")) != NULL
) {
53 if (!strcasecmp(p
, buf
)) {
63 attribute_s_property_show(display_name_language_code
, enumeration
);
64 static struct kobj_attribute displ_langcode
=
65 __ATTR_RO(display_name_language_code
);
67 attribute_s_property_show(display_name
, enumeration
);
68 static struct kobj_attribute displ_name
=
69 __ATTR_RO(display_name
);
71 attribute_s_property_show(default_value
, enumeration
);
72 static struct kobj_attribute default_val
=
73 __ATTR_RO(default_value
);
75 attribute_property_store(current_value
, enumeration
);
76 static struct kobj_attribute current_val
=
77 __ATTR_RW_MODE(current_value
, 0600);
79 attribute_s_property_show(dell_modifier
, enumeration
);
80 static struct kobj_attribute modifier
=
81 __ATTR_RO(dell_modifier
);
83 attribute_s_property_show(dell_value_modifier
, enumeration
);
84 static struct kobj_attribute value_modfr
=
85 __ATTR_RO(dell_value_modifier
);
87 attribute_s_property_show(possible_values
, enumeration
);
88 static struct kobj_attribute poss_val
=
89 __ATTR_RO(possible_values
);
91 static ssize_t
type_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
94 return sprintf(buf
, "enumeration\n");
96 static struct kobj_attribute type
=
99 static struct attribute
*enumeration_attrs
[] = {
100 &displ_langcode
.attr
,
111 static const struct attribute_group enumeration_attr_group
= {
112 .attrs
= enumeration_attrs
,
115 int alloc_enum_data(void)
119 wmi_priv
.enumeration_instances_count
=
120 get_instance_count(DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID
);
121 wmi_priv
.enumeration_data
= kcalloc(wmi_priv
.enumeration_instances_count
,
122 sizeof(struct enumeration_data
), GFP_KERNEL
);
123 if (!wmi_priv
.enumeration_data
) {
124 wmi_priv
.enumeration_instances_count
= 0;
131 * populate_enum_data() - Populate all properties of an instance under enumeration attribute
132 * @enumeration_obj: ACPI object with enumeration data
133 * @instance_id: The instance to enumerate
134 * @attr_name_kobj: The parent kernel object
136 int populate_enum_data(union acpi_object
*enumeration_obj
, int instance_id
,
137 struct kobject
*attr_name_kobj
)
139 int i
, next_obj
, value_modifier_count
, possible_values_count
;
141 wmi_priv
.enumeration_data
[instance_id
].attr_name_kobj
= attr_name_kobj
;
142 strlcpy_attr(wmi_priv
.enumeration_data
[instance_id
].attribute_name
,
143 enumeration_obj
[ATTR_NAME
].string
.pointer
);
144 strlcpy_attr(wmi_priv
.enumeration_data
[instance_id
].display_name_language_code
,
145 enumeration_obj
[DISPL_NAME_LANG_CODE
].string
.pointer
);
146 strlcpy_attr(wmi_priv
.enumeration_data
[instance_id
].display_name
,
147 enumeration_obj
[DISPLAY_NAME
].string
.pointer
);
148 strlcpy_attr(wmi_priv
.enumeration_data
[instance_id
].default_value
,
149 enumeration_obj
[DEFAULT_VAL
].string
.pointer
);
150 strlcpy_attr(wmi_priv
.enumeration_data
[instance_id
].dell_modifier
,
151 enumeration_obj
[MODIFIER
].string
.pointer
);
153 next_obj
= MODIFIER
+ 1;
155 value_modifier_count
= (uintptr_t)enumeration_obj
[next_obj
].string
.pointer
;
157 for (i
= 0; i
< value_modifier_count
; i
++) {
158 strcat(wmi_priv
.enumeration_data
[instance_id
].dell_value_modifier
,
159 enumeration_obj
[++next_obj
].string
.pointer
);
160 strcat(wmi_priv
.enumeration_data
[instance_id
].dell_value_modifier
, ";");
163 possible_values_count
= (uintptr_t) enumeration_obj
[++next_obj
].string
.pointer
;
165 for (i
= 0; i
< possible_values_count
; i
++) {
166 strcat(wmi_priv
.enumeration_data
[instance_id
].possible_values
,
167 enumeration_obj
[++next_obj
].string
.pointer
);
168 strcat(wmi_priv
.enumeration_data
[instance_id
].possible_values
, ";");
171 return sysfs_create_group(attr_name_kobj
, &enumeration_attr_group
);
175 * exit_enum_attributes() - Clear all attribute data
177 * Clears all data allocated for this group of attributes
179 void exit_enum_attributes(void)
183 for (instance_id
= 0; instance_id
< wmi_priv
.enumeration_instances_count
; instance_id
++) {
184 if (wmi_priv
.enumeration_data
[instance_id
].attr_name_kobj
)
185 sysfs_remove_group(wmi_priv
.enumeration_data
[instance_id
].attr_name_kobj
,
186 &enumeration_attr_group
);
188 kfree(wmi_priv
.enumeration_data
);