AlcapDAQ  1
hyt1331.c
Go to the documentation of this file.
1 /********************************************************************
2 
3  Name: hyt1331.c
4  Created by: Stefan Ritt
5 
6  Contents: Device driver for HYTEC 1331 Turbo CAMAC controller
7  either via IS PC card or via 5331 PCI interface card
8  following the MIDAS CAMAC Standard under DIRECTIO
9 
10  27-May-2008 Volodya:
11  added #include <sys/io.h>
12 
13  $Log: hyt1331.c,v $
14  Revision 1.1.1.1 2005/06/20 23:37:07 mucap
15  Importing release 1.9.5 of the MIDAS source code as distributed by PSI.
16  (Next, I'll commit our local customizations.)
17 
18  Revision 1.24 2004/04/20 13:27:22 midas
19  Fixed bug with PCI interface
20 
21  Revision 1.23 2004/01/08 08:40:08 midas
22  Implemented standard indentation
23 
24  Revision 1.22 2003/10/30 12:21:45 midas
25  Fixed bug with pci_scan under linux
26 
27  Revision 1.21 2003/10/29 13:08:15 midas
28  Stop after one PCI device found
29 
30  Revision 1.20 2003/10/06 15:01:33 midas
31  Removed tabs
32 
33  Revision 1.19 2002/03/12 22:28:50 pierre
34  fix gbl_sw1d, cam16i_sa for sw1d
35 
36  Revision 1.18 2002/02/12 14:56:04 midas
37  Opened port 0x80 for delayed write
38 
39  Revision 1.17 2002/01/16 14:54:52 midas
40  Removed debugging printf()
41 
42  Revision 1.16 2002/01/16 14:40:45 midas
43  Fixed bug with gbl_sw1d
44 
45  Revision 1.15 2001/09/04 12:53:41 midas
46  Fixed small bug
47 
48  Revision 1.14 2001/08/22 13:53:32 midas
49  Fixed small bug
50 
51  Revision 1.13 2001/08/16 09:39:12 midas
52  Changed comments
53 
54  Revision 1.12 2001/08/14 10:27:40 midas
55  Restore signal handler on error
56 
57  Revision 1.11 2001/08/14 10:15:43 midas
58  Removed debugging statements
59 
60  Revision 1.10 2001/08/14 09:42:42 midas
61  Added autodetection of ISA and PCI cards
62 
63 
64 \********************************************************************/
65 
66 #include <stdio.h>
67 #include <string.h>
68 #include "mcstd.h"
69 
70 /*------------------------------------------------------------------*/
71 
72 #if defined( __MSDOS__ )
73 #include <dos.h>
74 #define OUTP(_p, _d) outportb(_p, _d)
75 #define OUTPW(_p, _d) outport(_p, _d)
76 #define INP(_p) inportb(_p)
77 #define INPW(_p) inport(_p)
78 #define OUTP_P(_p, _d) outportb(_p, _d)
79 #define OUTPW_P(_p, _d) outport(_p, _d)
80 #define INP_P(_p) inportb(_p)
81 #define INPW_P(_p) inport(_p)
82 #elif defined( _MSC_VER )
83 #include <windows.h>
84 #include <conio.h>
85 #include <signal.h>
86 #define OUTP(_p, _d) _outp((WORD) (_p), (BYTE) (_d))
87 #define OUTPW(_p, _d) _outpw((WORD) (_p), (WORD) (_d))
88 #define OUTPD(_p, _d) _outpd((WORD) (_p), (unsigned int) (_d))
89 #define INP(_p) _inp((WORD) (_p))
90 #define INPW(_p) _inpw((WORD) (_p))
91 #define INPD(_p) _inpd((WORD) (_p))
92 #define OUTP_P(_p, _d) {_outp((WORD) (_p), (int) (_d)); _outp((WORD)0x80,0);}
93 #define OUTPW_P(_p, _d) {_outpw((WORD) (_p), (WORD) (_d)); _outp((WORD)0x80,0);}
94 #define INP_P(_p) _inp((WORD) (_p)); _outp((WORD)0x80,0);
95 #define INPW_P(_p) _inpw((WORD) (_p));_outp((WORD)0x80,0);
96 #elif defined( __linux__ )
97 #if !defined(__OPTIMIZE__)
98 #error Please compile hyt1331.c with the -O flag to make port access possible
99 #endif
100 //#include <asm/io.h>
101 #include <sys/io.h>
102 #include <unistd.h>
103 #include <signal.h>
104 #define OUTP(_p, _d) outb(_d, _p)
105 #define OUTPW(_p, _d) outw(_d, _p)
106 #define INP(_p) inb(_p)
107 #define INPW(_p) inw(_p)
108 #define OUTP_P(_p, _d) outb_p(_d, _p)
109 #define OUTPW_P(_p, _d) outw_p(_d, _p)
110 #define INP_P(_p) inb_p(_p)
111 #define INPW_P(_p) inw_p(_p)
112 #endif
113 
114 /*---- global variables -------------------------------------------*/
115 
116 #define MAX_DEVICES 4 /* Maximal 4 PC cards */
117 
118 WORD io_base[MAX_DEVICES]; /* IO base addrress for PC interfaces */
119 BYTE irq[MAX_DEVICES]; /* IRQ for PC interfaces */
120 
121 int gbl_sw1d[MAX_DEVICES]; /* Switch 1D on HYT1331 controlelr */
122 
123 /*------------------------------------------------------------------*/
124 
125 INLINE void cam8i(const int c, const int n, const int a, const int f, BYTE * d)
126 {
127  WORD adr, status;
128 
129  adr = io_base[c >> 2] + ((c % 3) << 4);
130  OUTP(adr + 8, n);
131  OUTP(adr + 6, a);
132  OUTP(adr + 10, f);
133 
134  status = (BYTE) INP(adr + 6);
135  *((BYTE *) d) = INP(adr);
136 }
137 
138 /*------------------------------------------------------------------*/
139 
140 INLINE void cami(const int c, const int n, const int a, const int f, WORD * d)
141 {
142  WORD adr, status;
143 
144  adr = io_base[c >> 2] + ((c % 3) << 4);
145  OUTP(adr + 8, n);
146  OUTP(adr + 6, a);
147  OUTP(adr + 10, f);
148 
149  status = (BYTE) INP(adr + 6);
150  *((BYTE *) d) = INP(adr);
151  *(((BYTE *) d) + 1) = INP(adr + 2);
152 }
153 
154 /*------------------------------------------------------------------*/
155 
156 INLINE void cam16i(const int c, const int n, const int a, const int f, WORD * d)
157 {
158  cami(c, n, a, f, d);
159 }
160 
161 /*------------------------------------------------------------------*/
162 
163 INLINE void cam24i(const int c, const int n, const int a, const int f, DWORD * d)
164 {
165  WORD adr;
166  BYTE status;
167 
168  adr = io_base[c >> 2] + ((c % 3) << 4);
169  OUTP(adr + 8, n);
170  OUTP(adr + 6, a);
171  OUTP(adr + 10, f);
172 
173  status = (BYTE) INP(adr + 6);
174  *((BYTE *) d) = INP(adr);
175  *(((BYTE *) d) + 1) = INP(adr + 2);
176  *(((BYTE *) d) + 2) = INP(adr + 4);
177  *(((BYTE *) d) + 3) = 0;
178 }
179 
180 /*------------------------------------------------------------------*/
181 
182 INLINE void cam8i_q(const int c, const int n, const int a, const int f,
183  BYTE * d, int *x, int *q)
184 {
185  WORD adr;
186  BYTE status;
187 
188  adr = io_base[c >> 2] + ((c % 3) << 4);
189  OUTP(adr + 8, n);
190  OUTP(adr + 6, a);
191  OUTP(adr + 10, f);
192 
193  status = (BYTE) INP(adr + 6);
194  *((BYTE *) d) = INP(adr);
195 
196  *q = status & 1;
197  *x = status >> 7;
198 }
199 
200 /*------------------------------------------------------------------*/
201 
202 INLINE void cam16i_q(const int c, const int n, const int a, const int f,
203  WORD * d, int *x, int *q)
204 {
205  WORD adr;
206  BYTE status;
207 
208  adr = io_base[c >> 2] + ((c % 3) << 4);
209  OUTP(adr + 8, n);
210  OUTP(adr + 6, a);
211  OUTP(adr + 10, f);
212 
213  status = (BYTE) INP(adr + 6);
214  *((BYTE *) d) = INP(adr);
215  *(((BYTE *) d) + 1) = INP(adr + 2);
216 
217  *q = status & 1;
218  *x = status >> 7;
219 }
220 
221 /*------------------------------------------------------------------*/
222 
223 INLINE void cam24i_q(const int c, const int n, const int a, const int f,
224  DWORD * d, int *x, int *q)
225 {
226  WORD adr, status;
227 
228  adr = io_base[c >> 2] + ((c % 3) << 4);
229  OUTP(adr + 8, n);
230  OUTP(adr + 6, a);
231  OUTP(adr + 10, f);
232 
233  status = (BYTE) INP(adr + 6);
234  *((BYTE *) d) = INP(adr);
235  *(((BYTE *) d) + 1) = INP(adr + 2);
236  *(((BYTE *) d) + 2) = INP(adr + 4);
237  *(((BYTE *) d) + 3) = 0;
238 
239  *q = status & 1;
240  *x = status >> 7;
241 }
242 
243 /*------------------------------------------------------------------*/
244 
245 INLINE void cam16i_r(const int c, const int n, const int a, const int f,
246  WORD ** d, const int r)
247 {
248  WORD adr, i, status;
249 
250  adr = io_base[c >> 2] + ((c % 3) << 4);
251 
252  OUTP(adr + 8, n);
253  OUTP(adr + 6, a);
254  OUTP_P(adr + 10, f);
255 
256  status = (BYTE) INP(adr + 6);
257  *((BYTE *) * d) = INP(adr);
258  *(((BYTE *) * d) + 1) = INP(adr + 2); /* read the first word */
259  (*d)++;
260 
261  INPW_P(adr + 12); /* trigger first cycle */
262 
263  for (i = 0; i < (r - 1); i++)
264  *((*d)++) = INPW(adr + 12); /* read data and trigger next cycle */
265 }
266 
267 /*------------------------------------------------------------------*/
268 
269 INLINE void cam24i_r(const int c, const int n, const int a, const int f,
270  DWORD ** d, const int r)
271 {
272  WORD adr, i, status;
273 
274  adr = io_base[c >> 2] + ((c % 3) << 4);
275  OUTP(adr + 8, n);
276  OUTP(adr + 6, a);
277 
278  for (i = 0; i < r; i++) {
279  OUTP(adr + 10, f);
280  status = (BYTE) INP(adr + 6);
281  *((BYTE *) * d) = INP(adr);
282  *(((BYTE *) * d) + 1) = INP(adr + 2);
283  *(((BYTE *) * d) + 2) = INP(adr + 4);
284  *(((BYTE *) * d) + 3) = 0;
285  (*d)++;
286  }
287 
288  /*
289  gives unrealiable results, SR 6.4.00
290 
291  adr = io_base[c >> 2]+((c % 3)<<4);
292 
293  OUTP(adr+8, n);
294  OUTP(adr+6, a);
295  OUTP_P(adr+10,f);
296 
297  status = (BYTE) INP(adr+6);
298  *((BYTE *) *d) = INP(adr);
299  *(((BYTE *) *d)+1) = INP(adr+2); // read the first word
300  *(((BYTE *) *d)+2) = INP(adr+4);
301  *(((BYTE *) *d)+3) = 0;
302  (*d)++;
303 
304  INPW_P(adr+12); // trigger first cycle
305 
306  for (i=0 ; i<(r-1) ; i++)
307  {
308  *(((BYTE *) *d)+2) = INP_P(adr+4);
309  *(((BYTE *) *d)+3) = 0;
310  *((WORD *) *d) = INPW_P(adr+12);
311  (*d)++;
312  }
313  */
314 }
315 
316 /*------------------------------------------------------------------*/
317 
318 INLINE void cam16i_rq(const int c, const int n, const int a, const int f,
319  WORD ** d, const int r)
320 {
321  WORD adr, i;
322  int fail;
323 
324  /* following code is disabled by above code */
325  adr = io_base[c >> 2] + ((c % 3) << 4);
326 
327  OUTP(adr + 8, n);
328  OUTP(adr + 6, a);
329  /* Turn on the Q-mode for repeat until Q=1 in the INPW(adr+12) */
330  OUTP(adr + 1, 0x10);
331  OUTP_P(adr + 10, f);
332  INPW_P(adr + 12); /* trigger first cycle */
333 
334  for (i = 0; i < r; i++) {
335  /* read data and trigger next cycle fail = no valid Q within 12usec */
336  **d = INPW_P(adr + 12);
337  fail = ((BYTE) INP(adr + 6)) & 0x20; // going to test!
338  if (fail)
339  break;
340  (*d)++;
341  }
342  /* Turn off the Q-mode for repeat until Q=1 in the INPW(adr+12) */
343  OUTP(adr + 1, 0x0);
344 }
345 
346 /*------------------------------------------------------------------*/
347 
348 INLINE void cam24i_rq(const int c, const int n, const int a, const int f,
349  DWORD ** d, const int r)
350 {
351  WORD adr;
352  int i, fail;
353 
354  adr = io_base[c >> 2] + ((c % 3) << 4);
355 
356  OUTP(adr + 8, n);
357  OUTP(adr + 6, a);
358  /* Turn on the Q-mode for repeat until Q=1 in the INPW(adr+12) */
359  OUTP(adr + 1, 0x10);
360  OUTP_P(adr + 10, f);
361  INPW_P(adr + 12); /* trigger first cycle */
362 
363  for (i = 0; i < r; i++) {
364  /* read data and trigger next cycle fail = no valid Q within 12usec */
365  *(((BYTE *) * d) + 2) = INP(adr + 4);
366  *(((BYTE *) * d) + 3) = 0;
367  *((WORD *) * d) = INPW_P(adr + 12);
368  fail = ((BYTE) INP(adr + 6)) & 0x20; // going to test!
369  if (fail)
370  break;
371  (*d)++;
372  }
373  /* Turn off the Q-mode for repeat until Q=1 in the INPW(adr+12) */
374  OUTP(adr + 1, 0x0);
375 }
376 
377 /*------------------------------------------------------------------*/
378 
379 INLINE void cam16i_sa(const int c, const int n, const int a, const int f,
380  WORD ** d, const int r)
381 {
382  WORD adr, i;
383 
384  if (gbl_sw1d[c]) {
385  adr = io_base[c >> 2] + ((c % 3) << 4);
386  /* enable auto increment */
387  OUTP_P(adr + 10, 49);
388  OUTP(adr + 8, n);
389  OUTP(adr + 6, a - 1);
390  OUTP_P(adr + 10, f);
391  INPW_P(adr + 12);
392 
393  for (i = 0; i < r; i++)
394  *((*d)++) = INPW_P(adr + 12); /* read data and trigger next cycle */
395 
396  /* disable auto increment */
397  OUTP_P(adr + 10, 48);
398  } else
399  for (i = 0; i < r; i++)
400  cami(c, n, a + i, f, (*d)++);
401 }
402 
403 /*------------------------------------------------------------------*/
404 
405 INLINE void cam24i_sa(const int c, const int n, const int a, const int f,
406  DWORD ** d, const int r)
407 {
408  WORD adr, i;
409 
410  if (gbl_sw1d[c]) {
411  adr = io_base[c >> 2] + ((c % 3) << 4);
412 
413  /* enable auto increment */
414  OUTP_P(adr + 10, 49);
415  OUTP(adr + 8, n);
416  OUTP(adr + 6, a - 1);
417  OUTP_P(adr + 10, f);
418  INPW_P(adr + 12);
419  for (i = 0; i < r; i++) {
420  /* read data and trigger next cycle */
421  *(((BYTE *) * d) + 2) = INP(adr + 4);
422  *(((BYTE *) * d) + 3) = 0;
423  *((WORD *) * d) = INPW_P(adr + 12);
424  (*d)++;
425  }
426 
427  /* disable auto increment */
428  OUTP_P(adr + 10, 48);
429  } else
430  for (i = 0; i < r; i++)
431  cam24i(c, n, a + i, f, (*d)++);
432 }
433 
434 /*------------------------------------------------------------------*/
435 
436 INLINE void cam16i_sn(const int c, const int n, const int a, const int f,
437  WORD ** d, const int r)
438 {
439  int i;
440 
441  for (i = 0; i < r; i++)
442  cam16i(c, n + i, a, f, (*d)++);
443 }
444 
445 /*------------------------------------------------------------------*/
446 
447 INLINE void cam24i_sn(const int c, const int n, const int a, const int f,
448  DWORD ** d, const int r)
449 {
450  int i;
451 
452  for (i = 0; i < r; i++)
453  cam24i(c, n + i, a, f, (*d)++);
454 }
455 
456 /*------------------------------------------------------------------*/
457 
458 INLINE void cam8o(const int c, const int n, const int a, const int f, BYTE d)
459 {
460  unsigned int adr;
461 
462  adr = io_base[c >> 2] + ((c % 3) << 4);
463  OUTP(adr + 8, n);
464  OUTP(adr, d);
465  OUTP(adr + 6, a);
466  OUTP(adr + 10, f);
467 }
468 
469 /*------------------------------------------------------------------*/
470 
471 INLINE void camo(const int c, const int n, const int a, const int f, WORD d)
472 {
473  unsigned int adr;
474 
475  adr = io_base[c >> 2] + ((c % 3) << 4);
476 
477  OUTP(adr + 8, n);
478  OUTP(adr, (BYTE) d);
479  OUTP(adr + 2, *(((BYTE *) & d) + 1));
480  OUTP(adr + 6, a);
481  OUTP(adr + 10, f);
482 }
483 
484 /*------------------------------------------------------------------*/
485 
486 INLINE void cam16o(const int c, const int n, const int a, const int f, WORD d)
487 {
488  camo(c, n, a, f, d);
489 }
490 
491 /*------------------------------------------------------------------*/
492 
493 INLINE void cam24o(const int c, const int n, const int a, const int f, DWORD d)
494 {
495  unsigned int adr;
496 
497  adr = io_base[c >> 2] + ((c % 3) << 4);
498  OUTP(adr + 8, n);
499  OUTP(adr, (BYTE) d);
500  OUTP(adr + 2, *(((BYTE *) & d) + 1));
501  OUTP(adr + 4, *(((BYTE *) & d) + 2));
502  OUTP(adr + 6, a);
503  OUTP(adr + 10, f);
504 }
505 
506 /*------------------------------------------------------------------*/
507 
508 INLINE void cam16o_q(const int c, const int n, const int a, const int f,
509  WORD d, int *x, int *q)
510 {
511  unsigned int adr, status;
512 
513  adr = io_base[c >> 2] + ((c % 3) << 4);
514  OUTP(adr + 8, n);
515  OUTP(adr, (BYTE) d);
516  OUTP(adr + 2, *(((BYTE *) & d) + 1));
517  OUTP(adr + 6, a);
518  OUTP(adr + 10, f);
519 
520  status = (BYTE) INP(adr + 6);
521  *q = status & 1;
522  *x = status >> 7;
523 }
524 
525 /*------------------------------------------------------------------*/
526 
527 INLINE void cam24o_q(const int c, const int n, const int a, const int f,
528  DWORD d, int *x, int *q)
529 {
530  unsigned int adr, status;
531 
532  adr = io_base[c >> 2] + ((c % 3) << 4);
533  OUTP(adr + 8, n);
534  OUTP(adr, (BYTE) d);
535  OUTP(adr + 2, *(((BYTE *) & d) + 1));
536  OUTP(adr + 4, *(((BYTE *) & d) + 2));
537  OUTP(adr + 6, a);
538  OUTP(adr + 10, f);
539 
540  status = (BYTE) INP(adr + 6);
541  *q = status & 1;
542  *x = status >> 7;
543 }
544 
545 /*------------------------------------------------------------------*/
546 
547 INLINE void cam8o_r(const int c, const int n, const int a, const int f,
548  BYTE * d, const int r)
549 {
550  WORD adr, i;
551 
552  adr = io_base[c >> 2] + ((c % 3) << 4);
553 
554  /* trigger first cycle */
555  OUTP(adr + 8, n);
556  OUTP(adr, *((BYTE *) d));
557  OUTP(adr + 6, a);
558  OUTP(adr + 10, f);
559 
560  for (i = 0; i < r - 1; i++)
561  OUTPW(adr + 12, (BYTE) * (++d)); /* write data and trigger next cycle */
562 }
563 
564 /*------------------------------------------------------------------*/
565 
566 INLINE void cam16o_r(const int c, const int n, const int a, const int f,
567  WORD * d, const int r)
568 {
569  WORD adr, i;
570 
571  adr = io_base[c >> 2] + ((c % 3) << 4);
572 
573  /* trigger first cycle */
574  OUTP(adr + 8, n);
575  OUTP(adr, *((BYTE *) d));
576  OUTP(adr + 2, *(((BYTE *) d) + 1));
577  OUTP(adr + 6, a);
578  OUTP(adr + 10, f);
579 
580  for (i = 0; i < r - 1; i++)
581  OUTPW(adr + 12, *(++d)); /* write data and trigger next cycle */
582 }
583 
584 /*------------------------------------------------------------------*/
585 
586 INLINE void cam24o_r(const int c, const int n, const int a, const int f,
587  DWORD * d, const int r)
588 {
589  WORD adr, i;
590 
591  adr = io_base[c >> 2] + ((c % 3) << 4);
592 
593  /* trigger first cycle */
594  OUTP(adr + 8, n);
595  OUTP(adr, *((BYTE *) d));
596  OUTP(adr + 2, *(((BYTE *) d) + 1));
597  OUTP(adr + 4, *(((BYTE *) d) + 2));
598  OUTP(adr + 6, a);
599  OUTP(adr + 10, f);
600 
601  for (i = 0; i < r - 1; i++) {
602  d++;
603  OUTP(adr + 4, *(((BYTE *) d) + 2));
604  OUTPW(adr + 12, (WORD) * d); /* write data and trigger next cycle */
605  }
606 }
607 
608 /*------------------------------------------------------------------*/
609 
610 INLINE int camc_chk(const int c)
611 {
612  unsigned int adr, n, a, f;
613 
614  /* clear inhibit */
615  camc(c, 1, 2, 32);
616 
617  /* read back naf */
618  adr = io_base[c >> 2] + ((c % 3) << 4);
619  a = (BYTE) INP(adr + 10);
620  n = (BYTE) INP(adr + 10);
621  f = (BYTE) INP(adr + 10);
622 
623  if (n != 1 || a != 2 || f != 32)
624  return -1;
625 
626  return 0;
627 }
628 
629 /*------------------------------------------------------------------*/
630 
631 INLINE void camc(const int c, const int n, const int a, const int f)
632 {
633  unsigned int adr;
634 
635  adr = io_base[c >> 2] + ((c % 3) << 4);
636  OUTP(adr + 8, n);
637  OUTP(adr + 6, a);
638  OUTP(adr + 10, f);
639 }
640 
641 /*------------------------------------------------------------------*/
642 
643 INLINE void camc_q(const int c, const int n, const int a, const int f, int *q)
644 {
645  unsigned int adr, status;
646 
647  adr = io_base[c >> 2] + ((c % 3) << 4);
648  OUTP(adr + 8, n);
649  OUTP(adr + 6, a);
650  OUTP(adr + 10, f);
651 
652  status = (BYTE) INP(adr + 6);
653  *q = status & 1;
654 }
655 
656 /*------------------------------------------------------------------*/
657 
658 INLINE void camc_sa(const int c, const int n, const int a, const int f, const int r)
659 {
660  int i;
661 
662  for (i = 0; i < r; i++)
663  camc(c, n, a + i, f);
664 }
665 
666 /*------------------------------------------------------------------*/
667 
668 INLINE void camc_sn(const int c, const int n, const int a, const int f, const int r)
669 {
670  int i;
671 
672  for (i = 0; i < r; i++)
673  camc(c, n + i, a, f);
674 }
675 
676 /*------------------------------------------------------------------*/
677 
678 INLINE void cam_inhibit_set(const int c)
679 {
680  unsigned int adr;
681 
682  adr = io_base[c >> 2] + ((c % 3) << 4);
683  OUTP(adr + 10, 33);
684 }
685 
686 /*------------------------------------------------------------------*/
687 
688 INLINE void cam_inhibit_clear(const int c)
689 {
690  unsigned int adr;
691 
692  adr = io_base[c >> 2] + ((c % 3) << 4);
693  OUTP(adr + 10, 32);
694 }
695 
696 /*------------------------------------------------------------------*/
697 
698 INLINE int cam_inhibit_test(const int c)
699 {
700  unsigned int adr;
701  BYTE status;
702 
703  adr = io_base[c >> 2] + ((c % 3) << 4);
704  status = (BYTE) INP(adr + 6);
705  return (status & 1) > 0;
706 }
707 
708 /*------------------------------------------------------------------*/
709 
710 INLINE void cam_crate_clear(const int c)
711 {
712  unsigned int adr;
713 
714  adr = io_base[c >> 2] + ((c % 3) << 4);
715  OUTP(adr + 10, 36);
716 }
717 
718 /*------------------------------------------------------------------*/
719 
720 INLINE void cam_crate_zinit(const int c)
721 {
722  unsigned int adr;
723 
724  adr = io_base[c >> 2] + ((c % 3) << 4);
725  OUTP(adr + 10, 34);
726 }
727 
728 /*------------------------------------------------------------------*/
729 
730 INLINE void cam_lam_enable(const int c, const int n)
731 {
732  /* enable the station number */
733  unsigned int adr;
734 
735  /* enable LAM in controller */
736  adr = io_base[c >> 2] + ((c % 3) << 4);
737  OUTP(adr + 10, 64 + n);
738 }
739 
740 /*------------------------------------------------------------------*/
741 
742 INLINE void cam_lam_disable(const int c, const int n)
743 {
744  /* disable the station number */
745  unsigned int adr;
746 
747  /* disable LAM in controller */
748  adr = io_base[c >> 2] + ((c % 3) << 4);
749  OUTP(adr + 10, 128 + n);
750 }
751 
752 /*------------------------------------------------------------------*/
753 
754 INLINE void cam_interrupt_enable(const int c)
755 {
756  unsigned int adr;
757 
758  /* enable interrupts in controller */
759  adr = io_base[c >> 2] + ((c % 3) << 4);
760  OUTP(adr + 10, 41);
761 }
762 
763 /*------------------------------------------------------------------*/
764 
765 INLINE void cam_interrupt_disable(const int c)
766 {
767  unsigned int adr;
768 
769  /* disable interrupts in controller */
770  adr = io_base[c >> 2] + ((c % 3) << 4);
771  OUTP(adr + 10, 40);
772 }
773 
774 /*------------------------------------------------------------------*/
775 
776 INLINE int cam_interrupt_test(const int c)
777 {
778  unsigned int adr;
779  BYTE status;
780 
781  adr = io_base[c >> 2] + ((c % 3) << 4);
782  status = (BYTE) INP(adr + 6);
783  return (status & (1 << 2)) > 0;
784 }
785 
786 /*------------------------------------------------------------------*/
787 
788 INLINE void cam_lam_read(const int c, DWORD * lam)
789 {
790  /*
791  return a BITWISE coded station NOT the station number
792  i.e.: n = 5 ==> lam = 0x10
793  */
794  unsigned int adr, csr;
795 
796  adr = io_base[c >> 2] + ((c % 3) << 4);
797  csr = (BYTE) INP(adr + 6);
798  if (csr & (1 << 3)) {
799  *lam = ((BYTE) INP(adr + 8)) & 0x1F; // mask upper 3 bits
800  *lam = 1 << (*lam - 1);
801  } else
802  *lam = 0;
803 }
804 
805 /*------------------------------------------------------------------*/
806 
807 INLINE void cam_lam_clear(const int c, const int n)
808 {
809  unsigned int adr;
810 
811  /*
812  note that the LAM flip-flop in unit must be cleared via
813 
814  camc(c, n, 0, 10);
815 
816  in the user code prior to the call of cam_lam_clear()
817  */
818 
819  /* restart LAM scanner in controller */
820  adr = io_base[c >> 2] + ((c % 3) << 4);
821  INP(adr + 8);
822 }
823 
824 /*------------------------------------------------------------------*/
825 
826 INLINE int cam_init_rpc(char *host_name, char *exp_name, char *fe_name,
827  char *client_name, char *rpc_server)
828 {
829  /* dummy routine for compatibility */
830  return 1;
831 }
832 
833 /*---- DirectIO functions ------------------------------------------*/
834 
836 {
837 #ifdef _MSC_VER
838 
839  /* under Windows NT, use DirectIO driver to open ports */
840 
841  OSVERSIONINFO vi;
842  HANDLE hdio = 0;
843  DWORD buffer[] = { 6, 0, 0, 0 };
844  DWORD size;
845 
846  vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
847  GetVersionEx(&vi);
848 
849  /* use DirectIO driver under NT to gain port access */
850  if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
851  hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL,
852  OPEN_EXISTING, 0, NULL);
853  if (hdio == INVALID_HANDLE_VALUE) {
854  printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
855  return -1;
856  }
857 
858  /* open ports */
859  buffer[1] = start;
860  buffer[2] = end;
861  if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer),
862  NULL, 0, &size, NULL))
863  return -1;
864  }
865 
866  return 0;
867 
868 #elif defined(__linux__)
869 
870  /*
871  In order to access the IO ports of the CAMAC interface, one needs
872  to call the ioperm() function for those ports. This requires root
873  privileges. For normal operation, this is performed by the "dio"
874  program, which is a "setuid" program having temporarily root privi-
875  lege. So the user program is started with "dio <program>". Since the
876  program cannot be debugged through the dio program, we suplly here
877  the direct ioperm call which requires the program to be run as root,
878  making it possible to debug it. The program has then to be compiled
879  with "gcc -DDO_IOPERM -o <program> <program>.c hyt1331.c ..."
880  */
881 
882 #ifdef DO_IOPERM
883 
884  if (end <= 0x3FF) {
885  if (ioperm(start, end - start + 1, 1) < 0) {
886  printf("hyt1331.c: Cannot call ioperm() (no root privileges)\n");
887  return -1;
888  }
889  } else {
890  if (iopl(3) < 0) {
891  printf("hyt1331.c: Cannot call iopl() (no root privileges)\n");
892  return -1;
893  }
894  }
895 
896 #endif
897 
898  return 0;
899 
900 #else
901 #error This driver cannot be compiled under this operating system
902 #endif
903 }
904 
905 /*------------------------------------------------------------------*/
906 
908 {
909 #ifdef _MSC_VER
910 
911  /* under Windows NT, use DirectIO driver to lock ports */
912 
913  OSVERSIONINFO vi;
914  HANDLE hdio;
915  DWORD buffer[] = { 7, 0, 0, 0 };
916  DWORD size;
917 
918  vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
919  GetVersionEx(&vi);
920 
921  /* use DirectIO driver under NT to gain port access */
922  if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
923  hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL,
924  OPEN_EXISTING, 0, NULL);
925  if (hdio == INVALID_HANDLE_VALUE) {
926  printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
927  return -1;
928  }
929 
930  /* lock ports */
931  buffer[1] = start;
932  buffer[2] = end;
933  if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer),
934  NULL, 0, &size, NULL))
935  return -1;
936  }
937 
938  return 0;
939 
940 #elif defined(__linux__)
941 
942 #ifdef DO_IOPERM
943 
944  if (end <= 0x3FF) {
945  if (ioperm(start, end - start + 0, 0) < 0) {
946  printf("hyt1331.c: Cannot call ioperm() (no root privileges)\n");
947  return -1;
948  }
949  } else {
950  if (iopl(0) < 0) {
951  printf("hyt1331.c: Cannot call iopl() (no root privileges)\n");
952  return -1;
953  }
954  }
955 
956 #endif
957 
958  return 0;
959 
960 #endif
961 }
962 
963 /*---- PCI Scan ----------------------------------------------------*/
964 
965 int pci_scan(int vendor_id, int device_id, int n_dev, BYTE * pirq, DWORD * ba)
966 {
967 #ifdef __linux__
968 
969  FILE *f;
970  char line[1000];
971  int n;
972  DWORD base_addr[6], irq, dfn, vend, vend_id, dev_id;
973 
974  f = fopen("/proc/bus/pci/devices", "r");
975  if (f == NULL)
976  return 0;
977 
978  n = 0;
979  while (fgets(line, sizeof(line), f)) {
980  sscanf(line, "%x %x %x %lx %lx %lx %lx %lx %lx",
981  &dfn,
982  &vend,
983  &irq,
984  &base_addr[0],
985  &base_addr[1], &base_addr[2], &base_addr[3], &base_addr[4], &base_addr[5]);
986 
987  vend_id = vend >> 16U;
988  dev_id = vend & 0xFFFF;
989 
990  /*
991  printf("%x:%x %d %x %x %x %x\n", vend_id, dev_id, *irq, base_addr[0], base_addr[1],
992  base_addr[2], base_addr[3]);
993  */
994 
995  if (vend_id == vendor_id && dev_id == device_id)
996  n++;
997 
998  if (n == n_dev)
999  break;
1000  }
1001 
1002  fclose(f);
1003 
1004  if (n == n_dev) {
1005  *pirq = irq;
1006  memcpy(ba, base_addr, sizeof(base_addr));
1007  return 1;
1008  }
1009 
1010  return 0;
1011 
1012 #elif defined(_MSC_VER)
1013 
1014  DWORD buffer[] = { 8, 0, 0, 0 };
1015  DWORD retbuf[7];
1016  HANDLE hdio;
1017  int size;
1018 
1019  hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL,
1020  OPEN_EXISTING, 0, NULL);
1021  if (hdio == INVALID_HANDLE_VALUE) {
1022  printf("hyt1331.c: Cannot access DirectIO driver\n");
1023  return -1;
1024  }
1025 
1026  buffer[1] = vendor_id;
1027  buffer[2] = device_id;
1028  buffer[3] = n_dev + 1;
1029  if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer),
1030  retbuf, sizeof(retbuf), &size, NULL))
1031  return 0;
1032 
1033  if (size == 0)
1034  return 0;
1035 
1036  *pirq = (BYTE) retbuf[0];
1037  memcpy(ba, retbuf + 1, sizeof(DWORD) * 6);
1038  return 1;
1039 
1040 #endif
1041 }
1042 
1043 /*------------------------------------------------------------------*/
1044 
1045 void catch_sigsegv(int signo)
1046 {
1047  printf
1048  ("Cannot access ports. Please run with \"dio <prog>\" or compile with \"-DDO_IOPERM\"\n");
1049  signal(SIGSEGV, SIG_DFL);
1050 }
1051 
1052 /*------------------------------------------------------------------*/
1053 
1054 INLINE int cam_init(void)
1055 {
1056  BYTE status, n_dev, i, n, a, f;
1057  WORD isa_io_base[] = { 0x200, 0x280, 0x300, 0x380 };
1058  WORD base_test;
1059  DWORD base_addr[6];
1060 
1061  /* set signal handler for segmet violation */
1062  signal(SIGSEGV, catch_sigsegv);
1063 
1064  /* scan PCI cards */
1065  for (n_dev = 0;; n_dev++) {
1066  if (!pci_scan(0x1196, 0x5331, n_dev + 1, irq + n_dev, base_addr))
1067  break;
1068 
1069  io_base[n_dev] = (WORD) (base_addr[3] & (~0x3UL));
1070 
1071  printf("hyt1331.c: Found PCI card at 0x%X, IRQ %d\n", io_base[n_dev], irq[n_dev]);
1072 
1073  if (directio_give_port(io_base[n_dev], io_base[n_dev] + 4 * 0x10) < 0) {
1074  signal(SIGSEGV, SIG_DFL);
1075  return 0;
1076  } else {
1077  n_dev++;
1078  break; // currently only supports one PCI interface
1079  }
1080  }
1081 
1082  /* scan ISA cards */
1083  for (i = 0; i < 4; i++) {
1084  base_test = isa_io_base[i];
1085 
1086  if (directio_give_port(base_test, base_test + 4 * 0x10) < 0) {
1087  signal(SIGSEGV, SIG_DFL);
1088  return 0;
1089  }
1090 
1091  /* Test if address is writable */
1092  OUTP(base_test, 0);
1093  status = INP(base_test);
1094  if (status != 0) {
1095  directio_lock_port(base_test, base_test + 4 * 0x10);
1096  continue;
1097  }
1098 
1099  /* Test A,N,F readback of ISA card */
1100  OUTP(base_test + 8, 1);
1101  OUTP(base_test + 6, 2);
1102  OUTP(base_test + 10, 32);
1103 
1104  a = (BYTE) INP(base_test + 10);
1105  n = (BYTE) INP(base_test + 10);
1106  f = (BYTE) INP(base_test + 10);
1107 
1108  if (n != 1 || a != 2 || f != 32) {
1109  directio_lock_port(base_test, base_test + 4 * 0x10);
1110  continue;
1111  }
1112 
1113  /* ISA card found */
1114  printf("hyt1331.c: Found ISA card at 0x%X\n", base_test);
1115 
1116  io_base[n_dev++] = base_test;
1117  }
1118 
1119  if (n_dev == 0) {
1120  printf("hyt1331.c: No PCI or ISA cards found\n");
1121  signal(SIGSEGV, SIG_DFL);
1122  return 0;
1123  }
1124 
1125  /* open port 80 for delayed write */
1126  directio_give_port(0x80, 0x80);
1127 
1128  /* check if we have access */
1129  OUTP(io_base[0], 0);
1130  signal(SIGSEGV, SIG_DFL);
1131 
1132  /* test auto increment switch SW1D */
1133  for (i = 0; i < n_dev; i++) {
1134  status = INP(io_base[i] + 6);
1135  if (!(status & (1 << 6))) {
1136  gbl_sw1d[i] = 0;
1137  } else {
1138  gbl_sw1d[i] = 1;
1139  }
1140  }
1141 
1142  return SUCCESS;
1143 }
1144 
1145 /*------------------------------------------------------------------*/
1146 
1147 INLINE void cam_exit(void)
1148 {
1149  int i;
1150 
1151  /* lock IO ports */
1152  for (i = 0; i < MAX_DEVICES; i++)
1153  if (io_base[i])
1154  directio_lock_port(io_base[i], io_base[i] + 4 * 0x10);
1155 }
1156 
1157 /*------------------------------------------------------------------*/