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

TOMOYO Linux Cross Reference
Linux/tools/power/acpi/tools/ec/ec_access.c

Version: ~ [ linux-5.11 ] ~ [ linux-5.10.17 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.99 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.176 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.221 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.257 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.257 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ 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-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 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * ec_access.c
  4  *
  5  * Copyright (C) 2010 SUSE Linux Products GmbH
  6  * Author:
  7  *      Thomas Renninger <trenn@suse.de>
  8  */
  9 
 10 #include <fcntl.h>
 11 #include <err.h>
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <libgen.h>
 15 #include <unistd.h>
 16 #include <getopt.h>
 17 #include <stdint.h>
 18 #include <sys/types.h>
 19 #include <sys/stat.h>
 20 
 21 
 22 #define EC_SPACE_SIZE 256
 23 #define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io"
 24 
 25 /* TBD/Enhancements:
 26    - Provide param for accessing different ECs (not supported by kernel yet)
 27 */
 28 
 29 static int read_mode = -1;
 30 static int sleep_time;
 31 static int write_byte_offset = -1;
 32 static int read_byte_offset = -1;
 33 static uint8_t write_value = -1;
 34 
 35 void usage(char progname[], int exit_status)
 36 {
 37         printf("Usage:\n");
 38         printf("1) %s -r [-s sleep]\n", basename(progname));
 39         printf("2) %s -b byte_offset\n", basename(progname));
 40         printf("3) %s -w byte_offset -v value\n\n", basename(progname));
 41 
 42         puts("\t-r [-s sleep]      : Dump EC registers");
 43         puts("\t                     If sleep is given, sleep x seconds,");
 44         puts("\t                     re-read EC registers and show changes");
 45         puts("\t-b offset          : Read value at byte_offset (in hex)");
 46         puts("\t-w offset -v value : Write value at byte_offset");
 47         puts("\t-h                 : Print this help\n\n");
 48         puts("Offsets and values are in hexadecimal number system.");
 49         puts("The offset and value must be between 0 and 0xff.");
 50         exit(exit_status);
 51 }
 52 
 53 void parse_opts(int argc, char *argv[])
 54 {
 55         int c;
 56 
 57         while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) {
 58 
 59                 switch (c) {
 60                 case 'r':
 61                         if (read_mode != -1)
 62                                 usage(argv[0], EXIT_FAILURE);
 63                         read_mode = 1;
 64                         break;
 65                 case 's':
 66                         if (read_mode != -1 && read_mode != 1)
 67                                 usage(argv[0], EXIT_FAILURE);
 68 
 69                         sleep_time = atoi(optarg);
 70                         if (sleep_time <= 0) {
 71                                 sleep_time = 0;
 72                                 usage(argv[0], EXIT_FAILURE);
 73                                 printf("Bad sleep time: %s\n", optarg);
 74                         }
 75                         break;
 76                 case 'b':
 77                         if (read_mode != -1)
 78                                 usage(argv[0], EXIT_FAILURE);
 79                         read_mode = 1;
 80                         read_byte_offset = strtoul(optarg, NULL, 16);
 81                         break;
 82                 case 'w':
 83                         if (read_mode != -1)
 84                                 usage(argv[0], EXIT_FAILURE);
 85                         read_mode = 0;
 86                         write_byte_offset = strtoul(optarg, NULL, 16);
 87                         break;
 88                 case 'v':
 89                         write_value = strtoul(optarg, NULL, 16);
 90                         break;
 91                 case 'h':
 92                         usage(argv[0], EXIT_SUCCESS);
 93                 default:
 94                         fprintf(stderr, "Unknown option!\n");
 95                         usage(argv[0], EXIT_FAILURE);
 96                 }
 97         }
 98         if (read_mode == 0) {
 99                 if (write_byte_offset < 0 ||
100                     write_byte_offset >= EC_SPACE_SIZE) {
101                         fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
102                                 "[0-0x%.2x]\n",
103                                 write_byte_offset, EC_SPACE_SIZE - 1);
104                         usage(argv[0], EXIT_FAILURE);
105                 }
106                 if (write_value < 0 ||
107                     write_value >= 255) {
108                         fprintf(stderr, "Wrong byte offset 0x%.2x, valid:"
109                                 "[0-0xff]\n", write_byte_offset);
110                         usage(argv[0], EXIT_FAILURE);
111                 }
112         }
113         if (read_mode == 1 && read_byte_offset != -1) {
114                 if (read_byte_offset < -1 ||
115                     read_byte_offset >= EC_SPACE_SIZE) {
116                         fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
117                                 "[0-0x%.2x]\n",
118                                 read_byte_offset, EC_SPACE_SIZE - 1);
119                         usage(argv[0], EXIT_FAILURE);
120                 }
121         }
122         /* Add additional parameter checks here */
123 }
124 
125 void dump_ec(int fd)
126 {
127         char buf[EC_SPACE_SIZE];
128         char buf2[EC_SPACE_SIZE];
129         int byte_off, bytes_read;
130 
131         bytes_read = read(fd, buf, EC_SPACE_SIZE);
132 
133         if (bytes_read == -1)
134                 err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);
135 
136         if (bytes_read != EC_SPACE_SIZE)
137                 fprintf(stderr, "Could only read %d bytes\n", bytes_read);
138 
139         printf("     00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F");
140         for (byte_off = 0; byte_off < bytes_read; byte_off++) {
141                 if ((byte_off % 16) == 0)
142                         printf("\n%.2X: ", byte_off);
143                 printf(" %.2x ", (uint8_t)buf[byte_off]);
144         }
145         printf("\n");
146 
147         if (!sleep_time)
148                 return;
149 
150         printf("\n");
151         lseek(fd, 0, SEEK_SET);
152         sleep(sleep_time);
153 
154         bytes_read = read(fd, buf2, EC_SPACE_SIZE);
155 
156         if (bytes_read == -1)
157                 err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);
158 
159         if (bytes_read != EC_SPACE_SIZE)
160                 fprintf(stderr, "Could only read %d bytes\n", bytes_read);
161 
162         printf("     00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F");
163         for (byte_off = 0; byte_off < bytes_read; byte_off++) {
164                 if ((byte_off % 16) == 0)
165                         printf("\n%.2X: ", byte_off);
166 
167                 if (buf[byte_off] == buf2[byte_off])
168                         printf(" %.2x ", (uint8_t)buf2[byte_off]);
169                 else
170                         printf("*%.2x ", (uint8_t)buf2[byte_off]);
171         }
172         printf("\n");
173 }
174 
175 void read_ec_val(int fd, int byte_offset)
176 {
177         uint8_t buf;
178         int error;
179 
180         error = lseek(fd, byte_offset, SEEK_SET);
181         if (error != byte_offset)
182                 err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);
183 
184         error = read(fd, &buf, 1);
185         if (error != 1)
186                 err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n",
187                     byte_offset, SYSFS_PATH);
188         printf("0x%.2x\n", buf);
189         return;
190 }
191 
192 void write_ec_val(int fd, int byte_offset, uint8_t value)
193 {
194         int error;
195 
196         error = lseek(fd, byte_offset, SEEK_SET);
197         if (error != byte_offset)
198                 err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);
199 
200         error = write(fd, &value, 1);
201         if (error != 1)
202                 err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x",
203                     value, byte_offset);
204 }
205 
206 int main(int argc, char *argv[])
207 {
208         int file_mode = O_RDONLY;
209         int fd;
210 
211         parse_opts(argc, argv);
212 
213         if (read_mode == 0)
214                 file_mode = O_WRONLY;
215         else if (read_mode == 1)
216                 file_mode = O_RDONLY;
217         else
218                 usage(argv[0], EXIT_FAILURE);
219 
220         fd = open(SYSFS_PATH, file_mode);
221         if (fd == -1)
222                 err(EXIT_FAILURE, "%s", SYSFS_PATH);
223 
224         if (read_mode)
225                 if (read_byte_offset == -1)
226                         dump_ec(fd);
227                 else if (read_byte_offset < 0 ||
228                          read_byte_offset >= EC_SPACE_SIZE)
229                         usage(argv[0], EXIT_FAILURE);
230                 else
231                         read_ec_val(fd, read_byte_offset);
232         else
233                 write_ec_val(fd, write_byte_offset, write_value);
234         close(fd);
235 
236         exit(EXIT_SUCCESS);
237 }
238 

~ [ 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