Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* 
  2  * inp.c -- read all the ports specified in hex on the command line.
  3  *     The program uses the faster ioperm/iopl calls on x86, /dev/port
  4  *     on other platforms. The program acts as inb/inw/inl according
  5  *     to its own name
  6  *
  7  * Copyright (C) 1998,2000,2001 Alessandro Rubini
  8  * 
  9  *   This program is free software; you can redistribute it and/or modify
 10  *   it under the terms of the GNU General Public License as published by
 11  *   the Free Software Foundation; either version 2 of the License, or
 12  *   (at your option) any later version.
 13  *
 14  *   This program is distributed in the hope that it will be useful,
 15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17  *   GNU General Public License for more details.
 18  *
 19  *   You should have received a copy of the GNU General Public License
 20  *   along with this program; if not, write to the Free Software
 21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 22  */
 23 
 24 #include <stdio.h>
 25 #include <stdlib.h>
 26 #include <string.h>
 27 #include <unistd.h>
 28 #include <errno.h>
 29 #include <fcntl.h>
 30 #include <sys/types.h>
 31 #include <sys/stat.h>
 32 
 33 #include <asm/io.h> /* linux-specific */
 34 
 35 #ifdef __GLIBC__
 36 #  include <sys/perm.h>
 37 #endif
 38 
 39 #define PORT_FILE "/dev/port"
 40 
 41 char *prgname;
 42 
 43 #ifdef __i386__
 44 static int read_and_print_one(unsigned int port,int size)
 45 {
 46     static int iopldone = 0;
 47 
 48     if (port > 1024) {
 49         if (!iopldone && iopl(3)) {
 50             fprintf(stderr, "%s: iopl(): %s\n", prgname, strerror(errno));
 51             return 1;
 52         }
 53         iopldone++;
 54     } else if (ioperm(port,size,1)) {
 55         fprintf(stderr, "%s: ioperm(%x): %s\n", prgname,
 56                 port, strerror(errno));
 57         return 1;
 58     }
 59 
 60     if (size == 4)
 61         printf("%04x: %08x\n", port, inl(port));
 62     else if (size == 2)
 63         printf("%04x: %04x\n", port, inw(port));
 64     else
 65         printf("%04x: %02x\n", port, inb(port));
 66     return 0;
 67 }
 68 #else /* not i386 */
 69 
 70 static int read_and_print_one(unsigned int port,int size)
 71 {
 72     static int fd = -1;
 73     unsigned char b; unsigned short w; unsigned int l;
 74 
 75     if (fd < 0)
 76         fd = open(PORT_FILE, O_RDONLY);
 77     if (fd < 0) {
 78         fprintf(stderr, "%s: %s: %s\n", prgname, PORT_FILE, strerror(errno));
 79         return 1;
 80     }
 81     lseek(fd, port, SEEK_SET);
 82     
 83     if (size == 4) {
 84         read(fd, &l, 4);
 85         printf("%04x: 0x%08x\n", port, l);
 86     } else if (size == 2) {
 87         read(fd, &w, 2);
 88         printf("%04x: 0x%04x\n", port, w & 0xffff);
 89     } else {
 90         read(fd, &b, 1);
 91         printf("%04x: 0x%02x\n", port, b & 0xff);
 92     }
 93     return 0;
 94 }
 95 
 96 #endif /* i386 */
 97 
 98 
 99 int main(int argc, char **argv)
100 {
101     unsigned int i, n, port, size, error = 0;
102     
103     prgname = argv[0];
104     /* find the data size */
105     switch (prgname[strlen(prgname)-1]) {
106         case 'w': size = 2; break;
107         case 'l': size = 4; break;
108         case 'b': case 'p': default:
109             size = 1;
110     }
111 
112     setuid(0); /* if we're setuid, force it on */
113     for (i = 1; i < argc; i++) {
114         if ( sscanf(argv[i], "%x%n", &port, &n) < 1
115               || n != strlen(argv[i]) ) {
116             fprintf(stderr, "%s: argument \"%s\" is not a hex number\n",
117                     argv[0], argv[i]);
118             error++; continue;
119         }
120         if (port & (size-1)) {
121             fprintf(stderr, "%s: argument \"%s\" is not properly aligned\n",
122                     argv[0], argv[i]);
123             error++; continue;
124         }
125         error += read_and_print_one(port, size);
126     }
127     exit (error ? 1 : 0);
128 }
129 
130 
  This page was automatically generated by the LXR engine.