Commit ef343491db1770a3af5010ba007167c348cdbe1a
Committed by
Matthew Garrett
1 parent
46dbca871d
Exists in
master
and in
4 other branches
asus-wmi: allow debugfs interface to call arbitrary method
Also add some # format flags to debugfs output. Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Showing 1 changed file with 45 additions and 2 deletions Side-by-side Diff
drivers/platform/x86/asus-wmi.c
... | ... | @@ -112,11 +112,14 @@ |
112 | 112 | * <platform>/ - debugfs root directory |
113 | 113 | * dev_id - current dev_id |
114 | 114 | * ctrl_param - current ctrl_param |
115 | + * method_id - current method_id | |
115 | 116 | * devs - call DEVS(dev_id, ctrl_param) and print result |
116 | 117 | * dsts - call DSTS(dev_id) and print result |
118 | + * call - call method_id(dev_id, ctrl_param) and print result | |
117 | 119 | */ |
118 | 120 | struct asus_wmi_debug { |
119 | 121 | struct dentry *root; |
122 | + u32 method_id; | |
120 | 123 | u32 dev_id; |
121 | 124 | u32 ctrl_param; |
122 | 125 | }; |
... | ... | @@ -1138,7 +1141,7 @@ |
1138 | 1141 | if (err < 0) |
1139 | 1142 | return err; |
1140 | 1143 | |
1141 | - seq_printf(m, "DSTS(%x) = %x\n", asus->debug.dev_id, retval); | |
1144 | + seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval); | |
1142 | 1145 | |
1143 | 1146 | return 0; |
1144 | 1147 | } |
1145 | 1148 | |
1146 | 1149 | |
... | ... | @@ -1155,15 +1158,50 @@ |
1155 | 1158 | if (err < 0) |
1156 | 1159 | return err; |
1157 | 1160 | |
1158 | - seq_printf(m, "DEVS(%x, %x) = %x\n", asus->debug.dev_id, | |
1161 | + seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id, | |
1159 | 1162 | asus->debug.ctrl_param, retval); |
1160 | 1163 | |
1161 | 1164 | return 0; |
1162 | 1165 | } |
1163 | 1166 | |
1167 | +static int show_call(struct seq_file *m, void *data) | |
1168 | +{ | |
1169 | + struct asus_wmi *asus = m->private; | |
1170 | + struct bios_args args = { | |
1171 | + .arg0 = asus->debug.dev_id, | |
1172 | + .arg1 = asus->debug.ctrl_param, | |
1173 | + }; | |
1174 | + struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; | |
1175 | + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | |
1176 | + union acpi_object *obj; | |
1177 | + acpi_status status; | |
1178 | + | |
1179 | + status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, | |
1180 | + 1, asus->debug.method_id, | |
1181 | + &input, &output); | |
1182 | + | |
1183 | + if (ACPI_FAILURE(status)) | |
1184 | + return -EIO; | |
1185 | + | |
1186 | + obj = (union acpi_object *)output.pointer; | |
1187 | + if (obj && obj->type == ACPI_TYPE_INTEGER) | |
1188 | + seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id, | |
1189 | + asus->debug.dev_id, asus->debug.ctrl_param, | |
1190 | + (u32) obj->integer.value); | |
1191 | + else | |
1192 | + seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id, | |
1193 | + asus->debug.dev_id, asus->debug.ctrl_param, | |
1194 | + obj->type); | |
1195 | + | |
1196 | + kfree(obj); | |
1197 | + | |
1198 | + return 0; | |
1199 | +} | |
1200 | + | |
1164 | 1201 | static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = { |
1165 | 1202 | {NULL, "devs", show_devs}, |
1166 | 1203 | {NULL, "dsts", show_dsts}, |
1204 | + {NULL, "call", show_call}, | |
1167 | 1205 | }; |
1168 | 1206 | |
1169 | 1207 | static int asus_wmi_debugfs_open(struct inode *inode, struct file *file) |
... | ... | @@ -1196,6 +1234,11 @@ |
1196 | 1234 | pr_err("failed to create debugfs directory"); |
1197 | 1235 | goto error_debugfs; |
1198 | 1236 | } |
1237 | + | |
1238 | + dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR, | |
1239 | + asus->debug.root, &asus->debug.method_id); | |
1240 | + if (!dent) | |
1241 | + goto error_debugfs; | |
1199 | 1242 | |
1200 | 1243 | dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR, |
1201 | 1244 | asus->debug.root, &asus->debug.dev_id); |