Merge tag 'pinctrl-v3.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[platform/adaptation/renesas_rcar/renesas_kernel.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/ioctl.h>
20 #include <sys/mman.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <linux/pci.h>
24
25 int sum;
26
27 static int map_mem(char *path, off_t offset, size_t length, int touch)
28 {
29         int fd, rc;
30         void *addr;
31         int *c;
32
33         fd = open(path, O_RDWR);
34         if (fd == -1) {
35                 perror(path);
36                 return -1;
37         }
38
39         if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
40                 rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
41                 if (rc == -1)
42                         perror("PCIIOC_MMAP_IS_MEM ioctl");
43         }
44
45         addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
46         if (addr == MAP_FAILED)
47                 return 1;
48
49         if (touch) {
50                 c = (int *) addr;
51                 while (c < (int *) (addr + length))
52                         sum += *c++;
53         }
54
55         rc = munmap(addr, length);
56         if (rc == -1) {
57                 perror("munmap");
58                 return -1;
59         }
60
61         close(fd);
62         return 0;
63 }
64
65 static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
66 {
67         struct dirent **namelist;
68         char *name, *path2;
69         int i, n, r, rc = 0, result = 0;
70         struct stat buf;
71
72         n = scandir(path, &namelist, 0, alphasort);
73         if (n < 0) {
74                 perror("scandir");
75                 return -1;
76         }
77
78         for (i = 0; i < n; i++) {
79                 name = namelist[i]->d_name;
80
81                 if (fnmatch(".", name, 0) == 0)
82                         goto skip;
83                 if (fnmatch("..", name, 0) == 0)
84                         goto skip;
85
86                 path2 = malloc(strlen(path) + strlen(name) + 3);
87                 strcpy(path2, path);
88                 strcat(path2, "/");
89                 strcat(path2, name);
90
91                 if (fnmatch(file, name, 0) == 0) {
92                         rc = map_mem(path2, offset, length, touch);
93                         if (rc == 0)
94                                 fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
95                         else if (rc > 0)
96                                 fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
97                         else {
98                                 fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
99                                 return rc;
100                         }
101                 } else {
102                         r = lstat(path2, &buf);
103                         if (r == 0 && S_ISDIR(buf.st_mode)) {
104                                 rc = scan_tree(path2, file, offset, length, touch);
105                                 if (rc < 0)
106                                         return rc;
107                         }
108                 }
109
110                 result |= rc;
111                 free(path2);
112
113 skip:
114                 free(namelist[i]);
115         }
116         free(namelist);
117         return result;
118 }
119
120 char buf[1024];
121
122 static int read_rom(char *path)
123 {
124         int fd, rc;
125         size_t size = 0;
126
127         fd = open(path, O_RDWR);
128         if (fd == -1) {
129                 perror(path);
130                 return -1;
131         }
132
133         rc = write(fd, "1", 2);
134         if (rc <= 0) {
135                 close(fd);
136                 perror("write");
137                 return -1;
138         }
139
140         do {
141                 rc = read(fd, buf, sizeof(buf));
142                 if (rc > 0)
143                         size += rc;
144         } while (rc > 0);
145
146         close(fd);
147         return size;
148 }
149
150 static int scan_rom(char *path, char *file)
151 {
152         struct dirent **namelist;
153         char *name, *path2;
154         int i, n, r, rc = 0, result = 0;
155         struct stat buf;
156
157         n = scandir(path, &namelist, 0, alphasort);
158         if (n < 0) {
159                 perror("scandir");
160                 return -1;
161         }
162
163         for (i = 0; i < n; i++) {
164                 name = namelist[i]->d_name;
165
166                 if (fnmatch(".", name, 0) == 0)
167                         goto skip;
168                 if (fnmatch("..", name, 0) == 0)
169                         goto skip;
170
171                 path2 = malloc(strlen(path) + strlen(name) + 3);
172                 strcpy(path2, path);
173                 strcat(path2, "/");
174                 strcat(path2, name);
175
176                 if (fnmatch(file, name, 0) == 0) {
177                         rc = read_rom(path2);
178
179                         /*
180                          * It's OK if the ROM is unreadable.  Maybe there
181                          * is no ROM, or some other error occurred.  The
182                          * important thing is that no MCA happened.
183                          */
184                         if (rc > 0)
185                                 fprintf(stderr, "PASS: %s read %d bytes\n", path2, rc);
186                         else {
187                                 fprintf(stderr, "PASS: %s not readable\n", path2);
188                                 return rc;
189                         }
190                 } else {
191                         r = lstat(path2, &buf);
192                         if (r == 0 && S_ISDIR(buf.st_mode)) {
193                                 rc = scan_rom(path2, file);
194                                 if (rc < 0)
195                                         return rc;
196                         }
197                 }
198
199                 result |= rc;
200                 free(path2);
201
202 skip:
203                 free(namelist[i]);
204         }
205         free(namelist);
206         return result;
207 }
208
209 int main(void)
210 {
211         int rc;
212
213         if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
214                 fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
215         else
216                 fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
217
218         /*
219          * It's not safe to blindly read the VGA frame buffer.  If you know
220          * how to poke the card the right way, it should respond, but it's
221          * not safe in general.  Many machines, e.g., Intel chipsets, cover
222          * up a non-responding card by just returning -1, but others will
223          * report the failure as a machine check.
224          */
225         if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
226                 fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
227         else
228                 fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
229
230         if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
231                 fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
232         else
233                 fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
234
235         /*
236          * Often you can map all the individual pieces above (0-0xA0000,
237          * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
238          * thing at once.  This is because the individual pieces use different
239          * attributes, and there's no single attribute supported over the
240          * whole region.
241          */
242         rc = map_mem("/dev/mem", 0, 1024*1024, 0);
243         if (rc == 0)
244                 fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
245         else if (rc > 0)
246                 fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
247         else
248                 fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
249
250         scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
251         scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
252         scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
253         scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
254
255         scan_rom("/sys/devices", "rom");
256
257         scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
258         scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
259         scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
260         scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
261
262         return rc;
263 }