source: drsdaq/VME/struck/sis1100/V2.02/test/test_3100.c@ 22

Last change on this file since 22 was 22, checked in by ogrimm, 16 years ago
First commit of drsdaq program
File size: 16.4 KB
Line 
1#define _GNU_SOURCE
2#define _LARGEFILE_SOURCE
3#define _LARGEFILE64_SOURCE
4#define _FILE_OFFSET_BITS 64
5#include <stdio.h>
6#include <errno.h>
7#include <string.h>
8#include <sys/types.h>
9#include <time.h>
10#include <unistd.h>
11#include <stdlib.h>
12#include <fcntl.h>
13#include <sys/mman.h>
14#include <sys/ioctl.h>
15
16#include "dev/pci/sis1100_var.h"
17#ifndef SIS3100_Version
18#define SIS3100_Version 100
19#endif
20
21
22#define VMESTART 0x84000000
23
24#if SIS3100_Version < 200
25enum sis1100_subdev {sis1100_subdev_vme, sis1100_subdev_ram,
26 sis1100_subdev_dsp};
27#endif
28
29struct path {
30 char* name;
31 enum sis1100_subdev type;
32 int p;
33 u_int32_t mapsize;
34 u_int32_t* map;
35 struct sis1100_ident ident;
36} *pathes;
37int numpathes;
38
39static void
40printusage(int argc, char* argv[])
41{
42 printf("usage: %s [-h] pathnames...\n",
43 argv[0]);
44}
45
46static void
47printhelp(int argc, char* argv[])
48{
49printf("printhelp not yet implemented\n");
50}
51
52static int
53getoptions(int argc, char* argv[])
54{
55 extern char *optarg;
56 extern int optind;
57 extern int opterr;
58 extern int optopt;
59 int errflag, c, i;
60 const char* args="h";
61
62 optarg=0; errflag=0;
63
64 while (!errflag && ((c=getopt(argc, argv, args))!=-1)) {
65 switch (c) {
66 case 'h': printhelp(argc, argv); break;
67 default: errflag++;
68 }
69 }
70
71 if (errflag || optind==argc) {
72 printusage(argc, argv);
73 return -1;
74 }
75
76 numpathes=argc-optind;
77 pathes=malloc(numpathes*sizeof(struct path));
78 for (i=0; i<numpathes; i++) {
79 pathes[i].name=argv[optind+i];
80 }
81
82 return 0;
83}
84
85static int
86init_path(struct path* path)
87{
88 path->type=-1;
89 path->p=-1;
90 path->mapsize=0;
91 path->map=0;
92
93 path->p=open(path->name, O_RDWR, 0);
94 if (path->p<0) {
95 printf("open \"%s\": %s\n", path->name, strerror(errno));
96 return -1;
97 }
98 if (ioctl(path->p, SIS1100_DEVTYPE, &path->type)<0) {
99 printf("ioctl(%s, SIS1100_DEVTYPE): %s\n",
100 path->name, strerror(errno));
101 return -1;
102 }
103 switch (path->type) {
104 case sis1100_subdev_vme:
105 printf("%s is VME\n", path->name);
106 break;
107 case sis1100_subdev_ram:
108 printf("%s is RAM\n", path->name);
109 break;
110#if SIS3100_Version >= 200
111 case sis1100_subdev_ctrl:
112 printf("%s is CTRL\n", path->name);
113 break;
114#endif
115 case sis1100_subdev_dsp:
116 printf("%s is DSP\n", path->name);
117 break;
118 default:
119 printf("init_path: %s has unknown type %d\n",
120 path->name, path->type);
121 return -1;
122 }
123 return 0;
124}
125
126static int
127done_path(struct path* path)
128{
129 if (path->map) {
130 if (munmap(path->map, path->mapsize)<0)
131 printf("munmap(%s): %s\n",
132 path->name, strerror(errno));
133 }
134 if (path->p) close(path->p);
135 return 0;
136}
137
138static int
139check_open(struct path* path)
140{
141 int p;
142
143 /* try to open the device a second time */
144 p=open(path->name, O_RDWR, 0);
145#if SIS3100_Version < 200
146 if (p<0) {
147 printf("open \"%s\" a second time: %s\n",
148 path->name, strerror(errno));
149 return -1;
150 }
151 close(p);
152#else
153 if (p>=0) {
154 printf("open \"%s\" a second time: success (but it should fail)\n",
155 path->name);
156 close(p);
157 return -1;
158 }
159 if (errno!=EBUSY) {
160 printf("open \"%s\" a second time returns \"%s\" "
161 "(but EBUSY is expected)\n",
162 path->name, strerror(errno));
163 return -1;
164 }
165#endif
166 return 0;
167}
168
169static int
170check_RESET(struct path* path)
171{
172 if (path->type!=sis1100_subdev_vme) return 0;
173 if (ioctl(path->p, SIS3100_RESET, &path->mapsize)<0) {
174 printf("ioctl(%s, SIS3100_RESET): %s\n",
175 path->name, strerror(errno));
176 return -1;
177 }
178 return 0;
179}
180
181static int
182check_MAPSIZE(struct path* path)
183{
184#if SIS3100_Version < 200
185 switch (path->type) {
186 case sis1100_subdev_vme: {
187 struct sis1100_mapinfo info;
188 info.space=2;
189 if (ioctl(path->p, SIS1100_MAPINFO, &info)<0) {
190 printf("ioctl(%s, SIS1100_MAPINFO, space=2): %s\n",
191 path->name, strerror(errno));
192 printf("sizeof off_t is %d\n", sizeof(off_t));
193 return -1;
194 }
195 path->mapsize=info.size;
196 if (info.offset!=0) {
197 printf("ioctl(%s, SIS1100_MAPINFO, space=2): "
198 "offset=0x%08llx (should be 0)\n",
199 path->name, info.offset);
200 return -1;
201 }
202 }
203 break;
204 case sis1100_subdev_ram: {
205 off_t max;
206 max=lseek(path->p, 0, SEEK_END);
207 if (max==(off_t)-1) {
208 printf("lseek(%s, 0, SEEK_END): %s\n", path->name, strerror(errno));
209 return -1;
210 }
211 path->mapsize=max;
212 }
213 break;
214 /* no default */
215 }
216#else
217 if (ioctl(path->p, SIS1100_MAPSIZE, &path->mapsize)<0) {
218 printf("ioctl(%s, SIS1100_MAPSIZE): %s\n",
219 path->name, strerror(errno));
220 return -1;
221 }
222#endif
223
224 printf("%s: mapsize=0x%x", path->name, path->mapsize);
225 if (path->mapsize>=(1<<20))
226 printf(" (%d MByte)", path->mapsize>>20);
227 else if (path->mapsize>=(1<<10))
228 printf(" (%d KByte)", path->mapsize>>10);
229 printf("\n");
230 switch (path->type) {
231 case sis1100_subdev_vme:
232 if (!path->mapsize)
233 printf("%s: no map available; but no real error\n", path->name);
234 else if (path->mapsize!=0x10000000) {
235 printf("%s: wrong mapsize 0x%x (should be 0x10000000)\n",
236 path->name, path->mapsize);
237 return -1;
238 }
239 break;
240 case sis1100_subdev_ram: break;
241#if SIS3100_Version >= 200
242 case sis1100_subdev_ctrl:
243 if (path->mapsize!=0x1000) {
244 printf("%s: unexpected mapsize 0x%x (should be 0x1000)\n",
245 path->name, path->mapsize);
246 return -1;
247 }
248 break;
249#endif
250 case sis1100_subdev_dsp:
251 if (path->mapsize) {
252 printf("%s: unexpected mapsize 0x%x (dsp can not be mapped (yet))\n",
253 path->name, path->mapsize);
254 return -1;
255 }
256 break;
257 default:
258 printf("check_MAPSIZE: %s has unknown type %d\n",
259 path->name, path->type);
260 return -1;
261 }
262
263 return 0;
264}
265
266static int
267check_mmap(struct path* path)
268{
269#if SIS3100_Version < 200
270 if (path->type!=sis1100_subdev_vme) return 0;
271#endif
272
273 if (!path->mapsize) return 0;
274 path->map=mmap(0, path->mapsize, PROT_READ|PROT_WRITE,
275 MAP_FILE|MAP_SHARED/*|MAP_VARIABLE*/, path->p, 0);
276
277 if (path->map==MAP_FAILED) {
278 printf("mmap(%s, 0x%x): %s\n", path->name, path->mapsize,
279 strerror(errno));
280 path->map=0;
281 } else
282 printf("%s: 0x%x Bytes mapped at %p\n", path->name, path->mapsize,
283 path->map);
284
285 switch (path->type) {
286 case sis1100_subdev_vme:
287 if (!path->map)
288 printf(" Not a real error.\n");
289 else
290 printf(" OK.\n");
291 break;
292 case sis1100_subdev_ram:
293 if (!path->map)
294 printf(" As expected.\n");
295 else {
296 printf(" But that is not possible (yet).\n");
297 return -1;
298 }
299 break;
300#if SIS3100_Version >= 200
301 case sis1100_subdev_ctrl:
302 if (!path->map) {
303 printf(" But it should work.\n");
304 return -1;
305 } else
306 printf(" OK.\n");
307 break;
308#endif
309 case sis1100_subdev_dsp:
310 if (!path->map)
311 printf(" OK.\n");
312 else {
313 printf(" But that is not possible (yet).\n");
314 return -1;
315 }
316 break;
317 default:
318 printf("check_mmap: %s has unknown type %d\n",
319 path->name, path->type);
320 return -1;
321 }
322 return 0;
323}
324
325static void
326print_ident(struct sis1100_ident_dev* ident)
327{
328 printf(" hw_type =%2d ", ident->hw_type);
329 switch (ident->hw_type) {
330 case 1: printf(" (PCI/PLX)"); break;
331 case 2: printf(" (VME)"); break;
332 case 3: printf(" (CAMAC/FERA)"); break;
333 case 4: printf(" (LVD/SCSI)"); break;
334 }
335 printf("\n");
336 printf(" hw_version=%2d\n", ident->hw_version);
337 printf(" fw_type =%2d\n", ident->fw_type);
338 printf(" fw_version=%2d\n", ident->fw_version);
339}
340
341static int
342check_IDENT(struct path* path)
343{
344struct sis1100_ident {
345 struct sis1100_ident_dev local;
346 struct sis1100_ident_dev remote;
347 int remote_ok;
348 int remote_online;
349};
350
351 if (ioctl(path->p, SIS1100_IDENT, &path->ident)<0) {
352 printf("ioctl(%s, SIS1100_IDENT): %s\n", path->name, strerror(errno));
353 return -1;
354 }
355 if (path->type==sis1100_subdev_vme) {
356 printf("Local Interface:\n");
357 print_ident(&path->ident.local);
358 if (path->ident.remote_ok) {
359 printf("Remote Interface:\n");
360 print_ident(&path->ident.remote);
361 printf(" remote interface o%sline\n",
362 path->ident.remote_online?"n":"ff");
363 } else
364 printf("no remote interface\n");
365 }
366 return 0;
367}
368
369static int
370check_rw_single(struct path* path, u_int32_t start, u_int32_t size)
371{
372 u_int32_t *in, *out;
373 int i, res, first, count;
374
375 in=calloc(size, 4);
376 out=calloc(size, 4);
377 if (!in || !out) {
378 printf("cannot allocate %d words for in- and output\n", size);
379 free(in); free(out);
380 return -1;
381 }
382
383 for (i=0; i<size; i++) {
384 out[i]=random();
385 in[i]=~out[i];
386 }
387 if (lseek(path->p, start, SEEK_SET)!=start) {
388 printf("check_rw_single: lseek(%s, 0x%08x, SEEK_SET): %s\n",
389 path->name, start, strerror(errno));
390 return -1;
391 }
392 for (i=0; i<size; i++) {
393 res=write(path->p, out+i, 4);
394 if (res!=4) {
395 printf("write(%s, ..., 4): %s\n", path->name, strerror(errno));
396 return -1;
397 }
398 }
399 if (lseek(path->p, start, SEEK_SET)!=start) {
400 printf("check_rw_single: lseek(%s, 0x%08x, SEEK_SET): %s\n",
401 path->name, start, strerror(errno));
402 return -1;
403 }
404 for (i=0; i<size; i++) {
405 res=read(path->p, in+i, 4);
406 if (res!=4) {
407 printf("read(%s, ..., 4): %s\n", path->name, strerror(errno));
408 return -1;
409 }
410 }
411 first=1; count=0;
412 for (i=0; i<size; i++) {
413 if (in[i]!=out[i]) {
414 if (first) {
415 printf("%s: rw error:", path->name);
416 first=0;
417 }
418 printf("[%3d]: %08x --> %08x\n", i, out[i], in[i]);
419 count++;
420 }
421 }
422 return count?-1:0;
423}
424
425static int
426check_rw_block(struct path* path, u_int32_t start, u_int32_t max)
427{
428 static u_int32_t *buf=0;
429 static int bufsize=0;
430
431 u_int32_t size;
432 int i, res, first, count;
433
434 printf("check_rw_block: max=0x%08x\n", max);
435 if (bufsize<max) {
436 free(buf);
437 bufsize=(((max-1)>>20)+1)<<20;
438 printf("\nmax=0x%x bufsize=0x%x\n", max, bufsize);
439 if (bufsize<max) {
440 printf("\nprogrammfehler.\n");
441 return -1;
442 }
443 buf=malloc(bufsize*4);
444 if (!buf) {
445 bufsize=0;
446 printf("\ncannot allocate %d words for in- and output\n", bufsize);
447 return -1;
448 }
449 }
450
451 for (i=0; i<max; i++) {
452 buf[i]=i;
453 }
454 if (lseek(path->p, start, SEEK_SET)!=start) {
455 printf("\nlseek(%s, 0x%08x, SEEK_SET): %s\n",
456 path->name, start, strerror(errno));
457 return -1;
458 }
459 res=write(path->p, buf, 4*max);
460 if (res!=4*max) {
461 printf("\nwrite(%s, ..., 4*%d): %s\n", path->name, max, strerror(errno));
462 return -1;
463 }
464 for (i=0; i<max; i++) {
465 buf[i]=~i;
466 }
467 for (size=1; size<=max; size++) {
468 if (lseek(path->p, start, SEEK_SET)!=start) {
469 printf("\nlseek(%s, 0x%08x, SEEK_SET): %s\n",
470 path->name, start, strerror(errno));
471 return -1;
472 }
473 res=read(path->p, buf, 4*size);
474 if (res!=4*size) {
475 u_int32_t err;
476 printf("\nread(%s, ..., 4*%d): ", path->name, size);
477 if (res&3) printf("res=%d\n", res);
478 if (res>=0) {
479 printf("res=%d (%4d)\n", res/4, size-res/4);
480 } else {
481 printf("%s\n", strerror(errno));
482 }
483 if (ioctl(path->p, SIS1100_LAST_ERROR, &err)<0) {
484 printf("\nioctl(%s, LAST_ERROR): %s\n",
485 path->name, strerror(errno));
486 } else {
487 if (err==0x211)
488 return 0;
489 else
490 printf("prot_err: 0x%x\n", err);
491 }
492 return -1;
493 }
494 first=1; count=0;
495 for (i=0; i<size; i++) {
496 if (buf[i]!=i) {
497 if (first) {
498 printf("\n%s: block rw error:", path->name);
499 first=0;
500 }
501 printf("[%3d]: %08x --> %08x\n", i, i, buf[i]);
502 count++;
503 }
504 }
505 if (count) return -1;
506 }
507 return 0;
508}
509
510static int
511vme_probe(struct path* path, u_int32_t addr)
512{
513 struct vmespace space;
514 int res;
515
516 space.am=0x9;
517 space.datasize=4;
518 space.swap=1;
519 space.mapit=0;
520 space.mindmalen=-1;
521 res=ioctl(path->p, SIS1100_SETVMESPACE, &space);
522 if (res) {
523 printf("SETVMESPACE(%s): %s\n", path->name, strerror(errno));
524 return -1;
525 }
526 res=ioctl(path->p, SIS3100_VME_PROBE, &addr);
527 if (res) {
528 printf("VME_PROBE(%s, 0x%08x): %s\n", path->name, addr, strerror(errno));
529 }
530 return res;
531}
532
533static int
534check_rw_vme(struct path* path)
535{
536 struct vmespace space;
537 int res, size;
538
539 printf("testing sdram over VME\n");
540 if (vme_probe(path, VMESTART)) return 0;
541
542 space.am=0x9;
543 space.datasize=4;
544 space.swap=1;
545 space.mapit=0;
546 space.mindmalen=-1;
547 res=ioctl(path->p, SIS1100_SETVMESPACE, &space);
548 if (res) {
549 printf("SETVMESPACE(%s): %s\n", path->name, strerror(errno));
550 return -1;
551 }
552 if (check_rw_single(path, VMESTART, 10000)<0) return -1;
553
554 space.am=0xb;
555 res=ioctl(path->p, SIS1100_SETVMESPACE, &space);
556 if (res) {
557 printf("SETVMESPACE(%s): %s\n", path->name, strerror(errno));
558 return -1;
559 }
560 size=1;
561 while (check_rw_block(path, VMESTART, size)>=0) {
562 printf(".");
563 fflush(stdout);
564 size<<=4;
565 }
566 printf("OK.\n");
567 return 0;
568}
569
570static int
571check_rw_ram(struct path* path)
572{
573 printf("testing sdram\n");
574 if (check_rw_single(path, 0, 1000)<0) return -1;
575 if (check_rw_block(path, 0, 1024)<0) return -1;
576 printf("OK.\n");
577 return 0;
578}
579
580static int
581check_rw_ctrl(struct path* path)
582{
583 return 0;
584}
585
586static int
587check_rw_dsp(struct path* path)
588{
589 return 0;
590}
591
592static int
593check_rw(struct path* path)
594{
595 switch (path->type) {
596 case sis1100_subdev_vme: return check_rw_vme(path); break;
597 case sis1100_subdev_ram: return check_rw_ram(path); break;
598#if SIS3100_Version >= 200
599 case sis1100_subdev_ctrl: return check_rw_ctrl(path); break;
600#endif
601 case sis1100_subdev_dsp: return check_rw_dsp(path); break;
602 default:
603 printf("check_rw: %s has unknown type %d\n",
604 path->name, path->type);
605 return -1;
606 }
607}
608
609typedef int(*testfunc)(struct path*);
610testfunc funcs[]={
611 init_path,
612 check_open,
613 /*check_RESET,*/
614 check_MAPSIZE,
615 check_mmap, /* requires check_MAPSIZE */
616 check_IDENT, /* can use check_mmap */
617 check_rw,
618
619#if 0
620 check_SETVMESPACE,
621 check_VME_PROBE,
622 check_VME_READ,
623 check_VME_WRITE,
624 check_VME_BLOCK_READ,
625 check_VME_BLOCK_WRITE,
626 check_CONTROL_READ,
627 check_CONTROL_WRITE,
628 check_CONTROL_READ,
629 check_CONTROL_WRITE,
630 check_PIPE,
631 check_LAST_ERROR,
632 check_FIFOMODE,
633
634 check_BIGENDIAN,
635
636 check_IRQ_CTL,
637 check_IRQ_GET,
638 check_IRQ_ACK,
639 check_IRQ_WAIT,
640
641 check_MINDMALEN,
642
643 check_FRONT_IO,
644 check_FRONT_PULSE,
645 check_FRONT_LATCH,
646
647 check_VME_SUPER_BLOCK_READ,
648 check_WRITE_PIPE,
649
650 check_DMA_ALLOC,
651 check_DMA_FREE,
652
653 check_DUMP,
654#endif
655};
656int numfuncs=sizeof(funcs)/sizeof(testfunc);
657
658int main(int argc, char* argv[])
659{
660 int res=0, i, j;
661
662 printf("==== SIS1100/3100 Test; V1.0 ====\n\n");
663
664 if (getoptions(argc, argv)<0) return 1;
665
666 srandom(17);
667
668 for (i=0; i<numfuncs; i++) {
669 for (j=0; j<numpathes; j++) {
670 if (funcs[i](pathes+j)<0) {res=i+3; goto raus;}
671 }
672 }
673
674raus:
675 for (j=0; j<numpathes; j++) done_path(pathes+j);
676 return res;
677}
Note: See TracBrowser for help on using the repository browser.