1 | #ifdef __linux__
|
---|
2 | #define _LARGEFILE_SOURCE
|
---|
3 | #define _LARGEFILE64_SOURCE
|
---|
4 | #define _FILE_OFFSET_BITS 64
|
---|
5 | #define LINUX_LARGEFILE O_LARGEFILE
|
---|
6 | #else
|
---|
7 | #define LINUX_LARGEFILE 0
|
---|
8 | #endif
|
---|
9 |
|
---|
10 | #define _GNU_SOURCE
|
---|
11 | #include <stdio.h>
|
---|
12 | #include <errno.h>
|
---|
13 | #include <string.h>
|
---|
14 | #include <sys/types.h>
|
---|
15 | #include <unistd.h>
|
---|
16 | #include <stdlib.h>
|
---|
17 | #include <fcntl.h>
|
---|
18 | #include <sys/ioctl.h>
|
---|
19 |
|
---|
20 | #include "dev/pci/sis1100_var.h"
|
---|
21 |
|
---|
22 | struct caen_type {
|
---|
23 | int typ;
|
---|
24 | char* name;
|
---|
25 | char* descr;
|
---|
26 | };
|
---|
27 |
|
---|
28 | struct caen_type caen_types[]={
|
---|
29 | {0x003, "V259", "multihit pattern/NIM"},
|
---|
30 | {0x004, "V259E", "multihit pattern/ECL"},
|
---|
31 | {0x001, "V262", "IO reg"},
|
---|
32 | {0x01a, "V512", "Logic"},
|
---|
33 | {0x018, "V560", "counter"},
|
---|
34 | {0x034, "V550", "C-RAMS"}, /* 64k */
|
---|
35 | {0x03c, "V551B", "C-RAMS Sequencer"},
|
---|
36 | {0x048, "V729A", "40 MHz ADC"},
|
---|
37 | {0x12e, "V693", "Multihit TDC"},
|
---|
38 | {0x2ff, "V767", "tdc"},
|
---|
39 | {0x307, "V775", "tdc"},
|
---|
40 | {0x311, "V785", "Peak Sensing ADC"},
|
---|
41 | {0x318, "V792", "qdc"},
|
---|
42 | {0, 0, 0}
|
---|
43 | };
|
---|
44 |
|
---|
45 | /****************************************************************************/
|
---|
46 | static int find_caen_name(int typ)
|
---|
47 | {
|
---|
48 | int i;
|
---|
49 | for (i=0; caen_types[i].name && caen_types[i].typ!=typ; i++);
|
---|
50 | if (caen_types[i].typ==typ)
|
---|
51 | return i;
|
---|
52 | else
|
---|
53 | return -1;
|
---|
54 | }
|
---|
55 | /****************************************************************************/
|
---|
56 | static int check_caen_new(int p, u_int32_t addr, u_int32_t offs)
|
---|
57 | {
|
---|
58 | u_int32_t _addr;
|
---|
59 | u_int16_t oui_msb, oui, oui_lsb;
|
---|
60 | u_int16_t ver;
|
---|
61 | u_int16_t id_msb, id, id_lsb;
|
---|
62 | u_int16_t rev;
|
---|
63 | u_int16_t ser_msb, ser_lsb;
|
---|
64 | u_int32_t manu, board_id, serial;
|
---|
65 | int res, idx;
|
---|
66 | struct vmespace space;
|
---|
67 |
|
---|
68 | space.am=0x39;
|
---|
69 | space.datasize=2;
|
---|
70 | space.swap=1;
|
---|
71 | space.mapit=0;
|
---|
72 | space.mindmalen=-1;
|
---|
73 |
|
---|
74 | _addr=addr+offs;
|
---|
75 |
|
---|
76 | if (ioctl(p, SIS1100_SETVMESPACE, &space)<0) {
|
---|
77 | perror("SETVMESPACE");
|
---|
78 | return -1;
|
---|
79 | }
|
---|
80 |
|
---|
81 | if (ioctl(p, VME_PROBE, &_addr+0x26)<0) return 0;
|
---|
82 |
|
---|
83 | res=pread(p, &oui_msb, 2, _addr+0x26);
|
---|
84 | if (res!=2) return 0;
|
---|
85 |
|
---|
86 | res=pread(p, &oui, 2, _addr+0x2a);
|
---|
87 | if (res!=2) return 0;
|
---|
88 |
|
---|
89 | res=pread(p, &oui_lsb, 2, _addr+0x2e);
|
---|
90 | if (res!=2) return 0;
|
---|
91 |
|
---|
92 | manu=((oui_msb&0xff)<<12)|((oui&0xff)<<8)|(oui_lsb&0xff);
|
---|
93 | if (manu!=0x40e6) return 0;
|
---|
94 |
|
---|
95 | res=pread(p, &ver, 2, _addr+0x32);
|
---|
96 | if (res!=2) return 0;
|
---|
97 |
|
---|
98 | res=pread(p, &id_msb, 2, _addr+0x36);
|
---|
99 | if (res!=2) return 0;
|
---|
100 |
|
---|
101 | res=pread(p, &id, 2, _addr+0x3a);
|
---|
102 | if (res!=2) return 0;
|
---|
103 |
|
---|
104 | res=pread(p, &id_lsb, 2, _addr+0x3e);
|
---|
105 | if (res!=2) return 0;
|
---|
106 |
|
---|
107 | board_id=((id_msb&0xff)<<12)|((id&0xff)<<8)|(id_lsb&0xff);
|
---|
108 | res=pread(p, &rev, 2, _addr+0x4e);
|
---|
109 | if (res!=2) return 0;
|
---|
110 |
|
---|
111 | res=pread(p, &ser_msb, 2, _addr+0xf02);
|
---|
112 | if (res!=2) return 0;
|
---|
113 |
|
---|
114 | res=pread(p, &ser_lsb, 2, _addr+0xf06);
|
---|
115 | if (res!=2) return 0;
|
---|
116 |
|
---|
117 | serial=((ser_msb&0xff)<<8)|(ser_lsb&0xff);
|
---|
118 | idx=find_caen_name(board_id);
|
---|
119 | if (idx>=0)
|
---|
120 | printf("0x%08x: %03x CAEN %-6s; version=%2d; serial=%3d; revision=%d (%s)\n",
|
---|
121 | addr, board_id, caen_types[idx].name, ver, serial, rev, caen_types[idx].descr);
|
---|
122 | else
|
---|
123 | printf("0x%08x: %03x CAEN unknown type 0x%x; version=%2d; serial=%3d; revision=%d\n",
|
---|
124 | addr, board_id, board_id, ver, serial, rev);
|
---|
125 | return 1;
|
---|
126 | }
|
---|
127 | /****************************************************************************/
|
---|
128 | static int check_caen_old(int p, u_int32_t addr)
|
---|
129 | {
|
---|
130 | u_int16_t v[3];
|
---|
131 | int res;
|
---|
132 | struct vmespace space;
|
---|
133 |
|
---|
134 | space.am=0x39;
|
---|
135 | space.datasize=2;
|
---|
136 | space.swap=1;
|
---|
137 | space.mapit=0;
|
---|
138 | space.mindmalen=-1;
|
---|
139 |
|
---|
140 | if (ioctl(p, SIS1100_SETVMESPACE, &space)<0) {
|
---|
141 | perror("SETVMESPACE");
|
---|
142 | return -1;
|
---|
143 | }
|
---|
144 |
|
---|
145 | res=pread(p, v, 6, addr+0xfa);
|
---|
146 | if (res!=6) {
|
---|
147 | /*fprintf(stderr, "read 0x%x+0xfa: %s\n", addr, strerror(errno));*/
|
---|
148 | return 0;
|
---|
149 | }
|
---|
150 |
|
---|
151 | if (v[0]==0xfaf5) {
|
---|
152 | int typ, manf, ser, ver, idx;
|
---|
153 |
|
---|
154 | typ=v[1]&0x3ff;
|
---|
155 | manf=(v[1]>>10)&0x3f;
|
---|
156 | ser=v[2]&0xfff;
|
---|
157 | ver=(v[2])>12&0xf;
|
---|
158 | idx=find_caen_name(typ);
|
---|
159 | if (idx>=0)
|
---|
160 | printf("0x%08x: %03x CAEN %-6s; version=%2d; serial=%3d (%s)\n",
|
---|
161 | addr, typ, caen_types[idx].name, ver, ser, caen_types[idx].descr);
|
---|
162 | else
|
---|
163 | printf("0x%08x: %03x CAEN; unknown type 0x%x; version=%2d; serial=%3d\n",
|
---|
164 | addr, typ, typ, ver, ser);
|
---|
165 | return 1;
|
---|
166 | }
|
---|
167 | return 0;
|
---|
168 | }
|
---|
169 | /****************************************************************************/
|
---|
170 | static int check_caen(int p, u_int32_t addr)
|
---|
171 | {
|
---|
172 | volatile int res;
|
---|
173 | res=check_caen_old(p, addr);
|
---|
174 | /*printf("check_caen_old(0x%08x): %d\n", addr, res);*/
|
---|
175 | if (res) return res;
|
---|
176 | res=check_caen_new(p, addr, 0x1000);
|
---|
177 | /*printf("check_caen_new1(0x%08x): %d\n", addr, res);*/
|
---|
178 | if (res) return res;
|
---|
179 | res=check_caen_new(p, addr, 0x8000);
|
---|
180 | /*printf("check_caen_new2(0x%08x): %d\n", addr, res);*/
|
---|
181 | if (res) return res;
|
---|
182 | return res;
|
---|
183 | }
|
---|
184 | /****************************************************************************/
|
---|
185 | int main(int argc, char* argv[])
|
---|
186 | {
|
---|
187 | u_int32_t addr;
|
---|
188 | int p, num, idx, n, res;
|
---|
189 |
|
---|
190 | if (argc<2) {
|
---|
191 | fprintf(stderr, "usage: %s path [num]\n", argv[0]);
|
---|
192 | return 1;
|
---|
193 | }
|
---|
194 | num=argc>2?atoi(argv[2]):65536;
|
---|
195 |
|
---|
196 | if ((p=open(argv[1], O_RDWR, 0))<0) {
|
---|
197 | fprintf(stderr, "open %s: %s\n", argv[1], strerror(errno));
|
---|
198 | return 1;
|
---|
199 | }
|
---|
200 |
|
---|
201 | for (addr=0, idx=0, n=0; idx<num; idx++, addr+=0x10000) {
|
---|
202 | res=check_caen(p, addr);
|
---|
203 | if (res<0) return 0;
|
---|
204 | if (res>0) n++;
|
---|
205 | }
|
---|
206 |
|
---|
207 | printf("%d module%s found\n", n, n==1?"":"s");
|
---|
208 | close(p);
|
---|
209 | return 0;
|
---|
210 | }
|
---|