add warning to 6711 calibration if driver version might be too old
[comedilib.git] / testing / mmap.c
1
2 #include <stdio.h>
3 #include <comedilib.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <sys/ioctl.h>
7 #include <errno.h>
8 #include <getopt.h>
9 #include <ctype.h>
10 #include <math.h>
11 #include <sys/time.h>
12 #include <string.h>
13 #include <sys/mman.h>
14 #include <signal.h>
15 #include <setjmp.h>
16 #include <stdlib.h>
17
18 #include "comedi_test.h"
19
20 /* XXX this should come from elsewhere */
21 #define PAGE_SIZE 4096
22
23 #define N_SAMPLES 10000
24
25 #define BUFSZ N_SAMPLES*sizeof(sampl_t)
26
27 #define MAPLEN 20480
28
29 jmp_buf jump_env;
30
31 void segv_handler(int num)
32 {
33         longjmp(jump_env,1);
34 }
35
36 int test_segfault(void *memptr)
37 {
38         volatile char tmp;
39         int ret;
40
41         ret=setjmp(jump_env);
42         if(!ret) tmp = *((char *)(memptr));
43         return ret;
44 }
45
46 void setup_segfaulter(void)
47 {
48         struct sigaction act;
49
50         memset(&act,0,sizeof(act));
51         act.sa_handler=&segv_handler;
52         sigaction(SIGSEGV,&act,NULL);
53 }
54
55 int test_mmap(void)
56 {
57         comedi_cmd cmd;
58         unsigned char *buf;
59         unsigned int chanlist[1];
60         int go;
61         int fails;
62         int total=0;
63         int ret;
64         void *b;
65         unsigned char *adr;
66         unsigned char *map;
67         unsigned int flags;
68         int i;
69
70         flags = comedi_get_subdevice_flags(device,subdevice);
71
72         if(!(flags&SDF_CMD) || flags&SDF_WRITEABLE){
73                 printf("not applicable\n");
74                 return 0;
75         }
76
77         if(comedi_get_cmd_generic_timed(device,subdevice,&cmd,1)<0){
78                 printf("E: comedi_get_cmd_generic_timed failed\n");
79                 return 0;
80         }
81
82         setup_segfaulter();
83
84         buf=malloc(BUFSZ);
85
86         map=mmap(NULL,MAPLEN,PROT_READ,MAP_SHARED,comedi_fileno(device),0);
87         if(!map){
88                 printf("E: mmap() failed\n");
89                 return 0;
90         }
91
92         /* test readability */
93         for(adr=map;adr<map+MAPLEN;adr+=PAGE_SIZE){
94                 ret=test_segfault(adr);
95                 if(ret){
96                         printf("E: %p failed\n",adr);
97                 }else{
98                         printf("%p ok\n",adr);
99                 }
100         }
101
102         if(realtime)cmd.flags |= TRIG_RT;
103
104         cmd.chanlist = chanlist;
105         cmd.scan_end_arg = 1;
106         cmd.stop_arg = N_SAMPLES;
107         cmd.chanlist_len = 1;
108         chanlist[0] = CR_PACK(0,0,0);
109
110         comedi_command(device,&cmd);
111
112         go=1;
113         b=buf;
114         while(go){
115                 ret = read(comedi_fileno(device),b,BUFSZ);
116                 if(ret<0){
117                         if(errno==EAGAIN){
118                                 usleep(10000);
119                         }else{
120                                 go = 0;
121                                 perror("read");
122                         }
123                 }else if(ret==0){
124                         go = 0;
125                 }else{
126                         total += ret;
127                         b += ret;
128                         if(verbose) printf("read %d %d\n",ret,total);
129                 }
130         }
131
132         fails = 0;
133         for(i=0;i<total;i++){
134                 if(buf[i]!=map[i]){
135                         if(fails==0)printf("E: mmap compare failed\n");
136                         printf("offset %d (read=%02x mmap=%02x)\n",i,
137                                 buf[i], map[i]);
138                         go = 0;
139                         fails++;
140                         if(fails>10)break;
141                 }
142         }
143         if(fails==0) printf("compare ok\n");
144
145         munmap(map,MAPLEN);
146
147         /* test if area is really unmapped */
148         for(adr=map;adr<map+MAPLEN;adr+=PAGE_SIZE){
149                 ret=test_segfault(adr);
150                 if(ret){
151                         printf("%p segfaulted (ok)\n",adr);
152                 }else{
153                         printf("E: %p still mapped\n",adr);
154                 }
155         }
156
157         free(buf);
158
159         return 0;
160 }
161