2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 static int op = 0; /* Operation, 0 = read, 1 = write. */
32 static int size = 1; /* Operation size in bytes. */
33 static int rcode = 0; /* If set, inX exits with return value. */
34 static int rhex = 0; /* If set, print result in hex. */
36 static struct option long_options[] = {
37 { "code", 0, 0, 'c' },
38 { "read", 0, 0, 'r' },
39 { "size", 1, 0, 's' },
40 { "write", 0, 0, 'w' },
44 static const char *options = "crs:w";
51 inb|inw|inl [--options] address\n\
52 outb|outw|outl [--options] address data\n\
54 --code Exit with status code instead of printing value (inX only).\n\
55 --hex Print hex instead of decimal (inX only).\n\
56 --read Perform a read (in) operation.\n\
57 --write Perform a write (out) operation.\n\
58 --size N Set size to N bytes where N = 1, 2 or 4.\n\
60 For detailed information, see the manual page inb(1).\n\
64 static unsigned get_int_or_die (const char *);
67 main (int argc, char *argv[])
74 /* Find out how the program was invoked. */
75 p = strrchr (argv[0], '/');
76 if (p == NULL) p = argv[0]; else p++;
78 if (strncasecmp (p, "inb", 3) == 0) {
80 } else if (strncasecmp (p, "outb", 4) == 0) {
82 } else if (strncasecmp (p, "inw", 3) == 0) {
84 } else if (strncasecmp (p, "outw", 4) == 0) {
86 } else if (strncasecmp (p, "inl", 3) == 0) {
88 } else if (strncasecmp (p, "outl", 4) == 0) {
92 /* Parse command line arguments. */
95 c = getopt_long (argc, argv, options, long_options, &option_index);
108 size = get_int_or_die (optarg);
109 if (!(size == 1 || size == 2 || size == 4)) {
110 fprintf (stderr, "%s: size can only be 1, 2 or 4.\n", optarg);
124 fprintf (stderr, "internal error in getopt_long\n");
133 /* Parse the address (for read/write) and data (for writes). */
134 if (optind >= argc) {
136 fprintf (stderr, "%s: missing parameter, see --help or man page\n",
141 addr = get_int_or_die (argv[optind++]);
144 if (optind >= argc) goto missing;
145 data = get_int_or_die (argv[optind++]);
148 if (optind != argc) {
150 "%s: extra parameters on command line, see --help or man page\n",
155 /* Raise our privilege level. */
156 if (iopl (3) == -1) {
157 fprintf (stderr, "iopl failed: You may need to run as root or give the process the CAP_SYS_RAWIO\ncapability. On non-x86 architectures, this operation probably isn't possible.\n");
162 /* Perform the operation. */
166 case 1: data = inb (addr); break;
167 case 2: data = inw (addr); break;
168 case 4: data = inl (addr); break;
173 case 1: outb (data, addr); break;
174 case 2: outw (data, addr); break;
175 case 4: outl (data, addr); break;
183 printf ("%d\n", data);
185 printf ("%x\n", data);
193 get_int_or_die (const char *str)
199 r = strtoul (str, &endp, 0);
200 if ((errno == ERANGE && r == ULONG_MAX)
201 || (errno != 0 && r == 0)) {
207 fprintf (stderr, "expecting a number, but found an empty string\n");
211 fprintf (stderr, "%s: trailing garbage after number\n", str);