4 * Copyright (C) 2010 SUSE Linux Products GmbH
6 * Thomas Renninger <trenn@suse.de>
8 * This work is licensed under the terms of the GNU GPL, version 2.
19 #include <sys/types.h>
23 #define EC_SPACE_SIZE 256
24 #define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io"
27 - Provide param for accessing different ECs (not supported by kernel yet)
30 static int read_mode = -1;
31 static int sleep_time;
32 static int write_byte_offset = -1;
33 static int read_byte_offset = -1;
34 static uint8_t write_value = -1;
36 void usage(char progname[], int exit_status)
39 printf("1) %s -r [-s sleep]\n", basename(progname));
40 printf("2) %s -b byte_offset\n", basename(progname));
41 printf("3) %s -w byte_offset -v value\n\n", basename(progname));
43 puts("\t-r [-s sleep] : Dump EC registers");
44 puts("\t If sleep is given, sleep x seconds,");
45 puts("\t re-read EC registers and show changes");
46 puts("\t-b offset : Read value at byte_offset (in hex)");
47 puts("\t-w offset -v value : Write value at byte_offset");
48 puts("\t-h : Print this help\n\n");
49 puts("Offsets and values are in hexadecimal number system.");
50 puts("The offset and value must be between 0 and 0xff.");
54 void parse_opts(int argc, char *argv[])
58 while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) {
63 usage(argv[0], EXIT_FAILURE);
67 if (read_mode != -1 && read_mode != 1)
68 usage(argv[0], EXIT_FAILURE);
70 sleep_time = atoi(optarg);
71 if (sleep_time <= 0) {
73 usage(argv[0], EXIT_FAILURE);
74 printf("Bad sleep time: %s\n", optarg);
79 usage(argv[0], EXIT_FAILURE);
81 read_byte_offset = strtoul(optarg, NULL, 16);
85 usage(argv[0], EXIT_FAILURE);
87 write_byte_offset = strtoul(optarg, NULL, 16);
90 write_value = strtoul(optarg, NULL, 16);
93 usage(argv[0], EXIT_SUCCESS);
95 fprintf(stderr, "Unknown option!\n");
96 usage(argv[0], EXIT_FAILURE);
100 if (write_byte_offset < 0 ||
101 write_byte_offset >= EC_SPACE_SIZE) {
102 fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
104 write_byte_offset, EC_SPACE_SIZE - 1);
105 usage(argv[0], EXIT_FAILURE);
107 if (write_value < 0 ||
108 write_value >= 255) {
109 fprintf(stderr, "Wrong byte offset 0x%.2x, valid:"
110 "[0-0xff]\n", write_byte_offset);
111 usage(argv[0], EXIT_FAILURE);
114 if (read_mode == 1 && read_byte_offset != -1) {
115 if (read_byte_offset < -1 ||
116 read_byte_offset >= EC_SPACE_SIZE) {
117 fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
119 read_byte_offset, EC_SPACE_SIZE - 1);
120 usage(argv[0], EXIT_FAILURE);
123 /* Add additional parameter checks here */
128 char buf[EC_SPACE_SIZE];
129 char buf2[EC_SPACE_SIZE];
130 int byte_off, bytes_read;
132 bytes_read = read(fd, buf, EC_SPACE_SIZE);
134 if (bytes_read == -1)
135 err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);
137 if (bytes_read != EC_SPACE_SIZE)
138 fprintf(stderr, "Could only read %d bytes\n", bytes_read);
140 printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
141 for (byte_off = 0; byte_off < bytes_read; byte_off++) {
142 if ((byte_off % 16) == 0)
143 printf("\n%.2X: ", byte_off);
144 printf(" %.2x ", (uint8_t)buf[byte_off]);
152 lseek(fd, 0, SEEK_SET);
155 bytes_read = read(fd, buf2, EC_SPACE_SIZE);
157 if (bytes_read == -1)
158 err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);
160 if (bytes_read != EC_SPACE_SIZE)
161 fprintf(stderr, "Could only read %d bytes\n", bytes_read);
163 printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
164 for (byte_off = 0; byte_off < bytes_read; byte_off++) {
165 if ((byte_off % 16) == 0)
166 printf("\n%.2X: ", byte_off);
168 if (buf[byte_off] == buf2[byte_off])
169 printf(" %.2x ", (uint8_t)buf2[byte_off]);
171 printf("*%.2x ", (uint8_t)buf2[byte_off]);
176 void read_ec_val(int fd, int byte_offset)
181 error = lseek(fd, byte_offset, SEEK_SET);
182 if (error != byte_offset)
183 err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);
185 error = read(fd, &buf, 1);
187 err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n",
188 byte_offset, SYSFS_PATH);
189 printf("0x%.2x\n", buf);
193 void write_ec_val(int fd, int byte_offset, uint8_t value)
197 error = lseek(fd, byte_offset, SEEK_SET);
198 if (error != byte_offset)
199 err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);
201 error = write(fd, &value, 1);
203 err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x",
207 int main(int argc, char *argv[])
209 int file_mode = O_RDONLY;
212 parse_opts(argc, argv);
215 file_mode = O_WRONLY;
216 else if (read_mode == 1)
217 file_mode = O_RDONLY;
219 usage(argv[0], EXIT_FAILURE);
221 fd = open(SYSFS_PATH, file_mode);
223 err(EXIT_FAILURE, "%s", SYSFS_PATH);
226 if (read_byte_offset == -1)
228 else if (read_byte_offset < 0 ||
229 read_byte_offset >= EC_SPACE_SIZE)
230 usage(argv[0], EXIT_FAILURE);
232 read_ec_val(fd, read_byte_offset);
234 write_ec_val(fd, write_byte_offset, write_value);