Pull osi-now into release branch
[sfrench/cifs-2.6.git] / Documentation / ia64 / aliasing-test.c
1 /*
2  * Exercise /dev/mem mmap cases that have been troublesome in the past
3  *
4  * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
5  *      Bjorn Helgaas <bjorn.helgaas@hp.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <sys/types.h>
15 #include <dirent.h>
16 #include <fcntl.h>
17 #include <fnmatch.h>
18 #include <string.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 int sum;
24
25 int map_mem(char *path, off_t offset, size_t length, int touch)
26 {
27         int fd, rc;
28         void *addr;
29         int *c;
30
31         fd = open(path, O_RDWR);
32         if (fd == -1) {
33                 perror(path);
34                 return -1;
35         }
36
37         addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
38         if (addr == MAP_FAILED)
39                 return 1;
40
41         if (touch) {
42                 c = (int *) addr;
43                 while (c < (int *) (offset + length))
44                         sum += *c++;
45         }
46
47         rc = munmap(addr, length);
48         if (rc == -1) {
49                 perror("munmap");
50                 return -1;
51         }
52
53         close(fd);
54         return 0;
55 }
56
57 int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
58 {
59         struct dirent **namelist;
60         char *name, *path2;
61         int i, n, r, rc, result = 0;
62         struct stat buf;
63
64         n = scandir(path, &namelist, 0, alphasort);
65         if (n < 0) {
66                 perror("scandir");
67                 return -1;
68         }
69
70         for (i = 0; i < n; i++) {
71                 name = namelist[i]->d_name;
72
73                 if (fnmatch(".", name, 0) == 0)
74                         goto skip;
75                 if (fnmatch("..", name, 0) == 0)
76                         goto skip;
77
78                 path2 = malloc(strlen(path) + strlen(name) + 3);
79                 strcpy(path2, path);
80                 strcat(path2, "/");
81                 strcat(path2, name);
82
83                 if (fnmatch(file, name, 0) == 0) {
84                         rc = map_mem(path2, offset, length, touch);
85                         if (rc == 0)
86                                 fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
87                         else if (rc > 0)
88                                 fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
89                         else {
90                                 fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
91                                 return rc;
92                         }
93                 } else {
94                         r = lstat(path2, &buf);
95                         if (r == 0 && S_ISDIR(buf.st_mode)) {
96                                 rc = scan_sysfs(path2, file, offset, length, touch);
97                                 if (rc < 0)
98                                         return rc;
99                         }
100                 }
101
102                 result |= rc;
103                 free(path2);
104
105 skip:
106                 free(namelist[i]);
107         }
108         free(namelist);
109         return rc;
110 }
111
112 char buf[1024];
113
114 int read_rom(char *path)
115 {
116         int fd, rc;
117         size_t size = 0;
118
119         fd = open(path, O_RDWR);
120         if (fd == -1) {
121                 perror(path);
122                 return -1;
123         }
124
125         rc = write(fd, "1", 2);
126         if (rc <= 0) {
127                 perror("write");
128                 return -1;
129         }
130
131         do {
132                 rc = read(fd, buf, sizeof(buf));
133                 if (rc > 0)
134                         size += rc;
135         } while (rc > 0);
136
137         close(fd);
138         return size;
139 }
140
141 int scan_rom(char *path, char *file)
142 {
143         struct dirent **namelist;
144         char *name, *path2;
145         int i, n, r, rc, result = 0;
146         struct stat buf;
147
148         n = scandir(path, &namelist, 0, alphasort);
149         if (n < 0) {
150                 perror("scandir");
151                 return -1;
152         }
153
154         for (i = 0; i < n; i++) {
155                 name = namelist[i]->d_name;
156
157                 if (fnmatch(".", name, 0) == 0)
158                         goto skip;
159                 if (fnmatch("..", name, 0) == 0)
160                         goto skip;
161
162                 path2 = malloc(strlen(path) + strlen(name) + 3);
163                 strcpy(path2, path);
164                 strcat(path2, "/");
165                 strcat(path2, name);
166
167                 if (fnmatch(file, name, 0) == 0) {
168                         rc = read_rom(path2);
169
170                         /*
171                          * It's OK if the ROM is unreadable.  Maybe there
172                          * is no ROM, or some other error ocurred.  The
173                          * important thing is that no MCA happened.
174                          */
175                         if (rc > 0)
176                                 fprintf(stderr, "PASS: %s read %ld bytes\n", path2, rc);
177                         else {
178                                 fprintf(stderr, "PASS: %s not readable\n", path2);
179                                 return rc;
180                         }
181                 } else {
182                         r = lstat(path2, &buf);
183                         if (r == 0 && S_ISDIR(buf.st_mode)) {
184                                 rc = scan_rom(path2, file);
185                                 if (rc < 0)
186                                         return rc;
187                         }
188                 }
189
190                 result |= rc;
191                 free(path2);
192
193 skip:
194                 free(namelist[i]);
195         }
196         free(namelist);
197         return rc;
198 }
199
200 int main()
201 {
202         int rc;
203
204         if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
205                 fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
206         else
207                 fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
208
209         /*
210          * It's not safe to blindly read the VGA frame buffer.  If you know
211          * how to poke the card the right way, it should respond, but it's
212          * not safe in general.  Many machines, e.g., Intel chipsets, cover
213          * up a non-responding card by just returning -1, but others will
214          * report the failure as a machine check.
215          */
216         if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
217                 fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
218         else
219                 fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
220
221         if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
222                 fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
223         else
224                 fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
225
226         /*
227          * Often you can map all the individual pieces above (0-0xA0000,
228          * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
229          * thing at once.  This is because the individual pieces use different
230          * attributes, and there's no single attribute supported over the
231          * whole region.
232          */
233         rc = map_mem("/dev/mem", 0, 1024*1024, 0);
234         if (rc == 0)
235                 fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
236         else if (rc > 0)
237                 fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
238         else
239                 fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
240
241         scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
242         scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
243         scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
244         scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
245
246         scan_rom("/sys/devices", "rom");
247 }