~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/wmi/dell-smbios-example.c

Version: ~ [ linux-5.1-rc5 ] ~ [ linux-5.0.7 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.34 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.111 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.168 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.178 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.138 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.65 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  Sample application for SMBIOS communication over WMI interface
  3  *  Performs the following:
  4  *  - Simple cmd_class/cmd_select lookup for TPM information
  5  *  - Simple query of known tokens and their values
  6  *  - Simple activation of a token
  7  *
  8  *  Copyright (C) 2017 Dell, Inc.
  9  *
 10  *  This program is free software; you can redistribute it and/or modify
 11  *  it under the terms of the GNU General Public License version 2 as
 12  *  published by the Free Software Foundation.
 13  */
 14 
 15 #include <errno.h>
 16 #include <fcntl.h>
 17 #include <stdio.h>
 18 #include <stdlib.h>
 19 #include <sys/ioctl.h>
 20 #include <unistd.h>
 21 
 22 /* if uapi header isn't installed, this might not yet exist */
 23 #ifndef __packed
 24 #define __packed __attribute__((packed))
 25 #endif
 26 #include <linux/wmi.h>
 27 
 28 /* It would be better to discover these using udev, but for a simple
 29  * application they're hardcoded
 30  */
 31 static const char *ioctl_devfs = "/dev/wmi/dell-smbios";
 32 static const char *token_sysfs =
 33                         "/sys/bus/platform/devices/dell-smbios.0/tokens";
 34 
 35 static void show_buffer(struct dell_wmi_smbios_buffer *buffer)
 36 {
 37         printf("Call: %x/%x [%x,%x,%x,%x]\nResults: [%8x,%8x,%8x,%8x]\n",
 38         buffer->std.cmd_class, buffer->std.cmd_select,
 39         buffer->std.input[0], buffer->std.input[1],
 40         buffer->std.input[2], buffer->std.input[3],
 41         buffer->std.output[0], buffer->std.output[1],
 42         buffer->std.output[2], buffer->std.output[3]);
 43 }
 44 
 45 static int run_wmi_smbios_cmd(struct dell_wmi_smbios_buffer *buffer)
 46 {
 47         int fd;
 48         int ret;
 49 
 50         fd = open(ioctl_devfs, O_NONBLOCK);
 51         ret = ioctl(fd, DELL_WMI_SMBIOS_CMD, buffer);
 52         close(fd);
 53         return ret;
 54 }
 55 
 56 static int find_token(__u16 token, __u16 *location, __u16 *value)
 57 {
 58         char location_sysfs[60];
 59         char value_sysfs[57];
 60         char buf[4096];
 61         FILE *f;
 62         int ret;
 63 
 64         ret = sprintf(value_sysfs, "%s/%04x_value", token_sysfs, token);
 65         if (ret < 0) {
 66                 printf("sprintf value failed\n");
 67                 return 2;
 68         }
 69         f = fopen(value_sysfs, "rb");
 70         if (!f) {
 71                 printf("failed to open %s\n", value_sysfs);
 72                 return 2;
 73         }
 74         fread(buf, 1, 4096, f);
 75         fclose(f);
 76         *value = (__u16) strtol(buf, NULL, 16);
 77 
 78         ret = sprintf(location_sysfs, "%s/%04x_location", token_sysfs, token);
 79         if (ret < 0) {
 80                 printf("sprintf location failed\n");
 81                 return 1;
 82         }
 83         f = fopen(location_sysfs, "rb");
 84         if (!f) {
 85                 printf("failed to open %s\n", location_sysfs);
 86                 return 2;
 87         }
 88         fread(buf, 1, 4096, f);
 89         fclose(f);
 90         *location = (__u16) strtol(buf, NULL, 16);
 91 
 92         if (*location)
 93                 return 0;
 94         return 2;
 95 }
 96 
 97 static int token_is_active(__u16 *location, __u16 *cmpvalue,
 98                            struct dell_wmi_smbios_buffer *buffer)
 99 {
100         int ret;
101 
102         buffer->std.cmd_class = CLASS_TOKEN_READ;
103         buffer->std.cmd_select = SELECT_TOKEN_STD;
104         buffer->std.input[0] = *location;
105         ret = run_wmi_smbios_cmd(buffer);
106         if (ret != 0 || buffer->std.output[0] != 0)
107                 return ret;
108         ret = (buffer->std.output[1] == *cmpvalue);
109         return ret;
110 }
111 
112 static int query_token(__u16 token, struct dell_wmi_smbios_buffer *buffer)
113 {
114         __u16 location;
115         __u16 value;
116         int ret;
117 
118         ret = find_token(token, &location, &value);
119         if (ret != 0) {
120                 printf("unable to find token %04x\n", token);
121                 return 1;
122         }
123         return token_is_active(&location, &value, buffer);
124 }
125 
126 static int activate_token(struct dell_wmi_smbios_buffer *buffer,
127                    __u16 token)
128 {
129         __u16 location;
130         __u16 value;
131         int ret;
132 
133         ret = find_token(token, &location, &value);
134         if (ret != 0) {
135                 printf("unable to find token %04x\n", token);
136                 return 1;
137         }
138         buffer->std.cmd_class = CLASS_TOKEN_WRITE;
139         buffer->std.cmd_select = SELECT_TOKEN_STD;
140         buffer->std.input[0] = location;
141         buffer->std.input[1] = 1;
142         ret = run_wmi_smbios_cmd(buffer);
143         return ret;
144 }
145 
146 static int query_buffer_size(__u64 *buffer_size)
147 {
148         FILE *f;
149 
150         f = fopen(ioctl_devfs, "rb");
151         if (!f)
152                 return -EINVAL;
153         fread(buffer_size, sizeof(__u64), 1, f);
154         fclose(f);
155         return EXIT_SUCCESS;
156 }
157 
158 int main(void)
159 {
160         struct dell_wmi_smbios_buffer *buffer;
161         int ret;
162         __u64 value = 0;
163 
164         ret = query_buffer_size(&value);
165         if (ret == EXIT_FAILURE || !value) {
166                 printf("Unable to read buffer size\n");
167                 goto out;
168         }
169         printf("Detected required buffer size %lld\n", value);
170 
171         buffer = malloc(value);
172         if (buffer == NULL) {
173                 printf("failed to alloc memory for ioctl\n");
174                 ret = -ENOMEM;
175                 goto out;
176         }
177         buffer->length = value;
178 
179         /* simple SMBIOS call for looking up TPM info */
180         buffer->std.cmd_class = CLASS_FLASH_INTERFACE;
181         buffer->std.cmd_select = SELECT_FLASH_INTERFACE;
182         buffer->std.input[0] = 2;
183         ret = run_wmi_smbios_cmd(buffer);
184         if (ret) {
185                 printf("smbios ioctl failed: %d\n", ret);
186                 ret = EXIT_FAILURE;
187                 goto out;
188         }
189         show_buffer(buffer);
190 
191         /* query some tokens */
192         ret = query_token(CAPSULE_EN_TOKEN, buffer);
193         printf("UEFI Capsule enabled token is: %d\n", ret);
194         ret = query_token(CAPSULE_DIS_TOKEN, buffer);
195         printf("UEFI Capsule disabled token is: %d\n", ret);
196 
197         /* activate UEFI capsule token if disabled */
198         if (ret) {
199                 printf("Enabling UEFI capsule token");
200                 if (activate_token(buffer, CAPSULE_EN_TOKEN)) {
201                         printf("activate failed\n");
202                         ret = -1;
203                         goto out;
204                 }
205         }
206         ret = EXIT_SUCCESS;
207 out:
208         free(buffer);
209         return ret;
210 }
211 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp