Merge from vendor branch ATHEROS:
[games.git] / sys / dev / misc / gpib / gpib.c
1
2 /*
3  * GPIB driver for FreeBSD.
4  * Version 0.1 (No interrupts, no DMA)
5  * Supports National Instruments AT-GPIB and AT-GPIB/TNT boards.
6  * (AT-GPIB not tested, but it should work)
7  *
8  * Written by Fred Cawthorne (fcawth@delphi.umd.edu)
9  * Some sections were based partly on the lpt driver.
10  *  (some remnants may remain)
11  *
12  * This software is distributed with NO WARRANTIES, not even the implied
13  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  *
15  * The author grants any other persons or organizations permission to use
16  * or modify this software as long as this message is kept with the software,
17  * all derivative works or modified versions.
18  *
19  * $FreeBSD: src/sys/i386/isa/gpib.c,v 1.29 2000/01/29 16:17:32 peter Exp $
20  * $DragonFly: src/sys/dev/misc/gpib/gpib.c,v 1.10 2005/12/11 01:54:08 swildner Exp $
21  *
22  */
23 /*Please read the README file for usage information*/
24
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/conf.h>
28 #include <sys/uio.h>
29 #include <sys/malloc.h>
30 #include "gpibreg.h"
31 #include "gpib.h"
32 #include <bus/isa/i386/isa_device.h>
33
34 #define GPIBPRI  PCATCH
35 #define SLEEP_MAX 1000
36 #define SLEEP_MIN 4
37
38
39
40 static int initgpib(void);
41 static void closegpib(void);
42 static int sendgpibfifo(unsigned char device,char *data,int count);
43 static int sendrawgpibfifo(unsigned char device,char *data,int count);
44 static int readgpibfifo(unsigned char device,char *data,int count);
45 #if 0
46 static void showregs(void);
47 #endif
48 static void enableremote(unsigned char device);
49 static void gotolocal(unsigned char device);
50 static void menableremote(unsigned char *device);
51 static void mgotolocal(unsigned char *device);
52 static void mtrigger(unsigned char *device);
53 static void trigger(unsigned char device);
54 static char spoll(unsigned char device);
55
56 static int gpprobe(struct isa_device *dvp);
57 static int gpattach(struct isa_device *dvp);
58
59 struct   isa_driver gpdriver = {gpprobe, gpattach, "gp"};
60
61 static  d_open_t        gpopen;
62 static  d_close_t       gpclose;
63 static  d_write_t       gpwrite;
64 static  d_ioctl_t       gpioctl;
65
66 #define CDEV_MAJOR 44
67 static struct cdevsw gp_cdevsw = {
68         /* name */      "gp",
69         /* maj */       CDEV_MAJOR,
70         /* flags */     0,
71         /* port */      NULL,
72         /* clone */     NULL,
73
74         /* open */      gpopen,
75         /* close */     gpclose,
76         /* read */      noread,
77         /* write */     gpwrite,
78         /* ioctl */     gpioctl,
79         /* poll */      nopoll,
80         /* mmap */      nommap,
81         /* strategy */  nostrategy,
82         /* dump */      nodump,
83         /* psize */     nopsize
84 };
85
86 #define   BUFSIZE      1024
87 #define   ATTACHED     0x08
88 #define   OPEN         0x04
89 #define   INIT         0x02
90
91
92 static struct gpib_softc {
93         char    *sc_cp;         /* current data to send         */
94         int     sc_count;       /* bytes queued in sc_inbuf     */
95         int     sc_type;        /* Type of gpib controller      */
96         u_char  sc_flags;       /* flags (open and internal)    */
97         char    sc_unit;        /* gpib device number           */
98         char    *sc_inbuf;      /* buffer for data              */
99 } gpib_sc; /* only support one of these? */
100 static int oldcount;
101 static char oldbytes[2];
102 /*Probe routine*/
103 /*This needs to be changed to be a bit more robust*/
104 static int
105 gpprobe(struct isa_device *dvp)
106 {
107         int     status;
108         struct gpib_softc *sc = &gpib_sc;
109
110         gpib_port = dvp->id_iobase;
111         status=1;
112         sc->sc_type=3;
113 if ((inb(KSR)&0xF7)==0x34) sc->sc_type=3;
114 else if ((inb(KSR)&0xF7)==0x24) sc->sc_type=2;
115 else if ((inb(KSR)&0xF7)==0x14) sc->sc_type=1;
116           else status=0;
117
118         return (status);
119 }
120
121 /*
122  * gpattach()
123  *  Attach device and print the type of card to the screen.
124  */
125 static int
126 gpattach(struct isa_device *isdp)
127 {
128         struct   gpib_softc   *sc = &gpib_sc;
129
130         sc->sc_unit = isdp->id_unit;
131         if (sc->sc_type==3)
132            printf ("gp%d: type AT-GPIB/TNT\n",sc->sc_unit);
133         if (sc->sc_type==2)
134            printf ("gp%d: type AT-GPIB chip NAT4882B\n",sc->sc_unit);
135         if (sc->sc_type==1)
136            printf ("gp%d: type AT-GPIB chip NAT4882A\n",sc->sc_unit);
137         sc->sc_flags |=ATTACHED;
138
139         cdevsw_add(&gp_cdevsw, -1, sc->sc_unit);
140         make_dev(&gp_cdevsw, sc->sc_unit, 0, 0, 0600, "gp");
141         return (1);
142 }
143
144 /*
145  * gpopen()
146  *      New open on device.
147  *
148  * More than 1 open is not allowed on the entire device.
149  * i.e. even if gpib5 is open, we can't open another minor device
150  */
151 static  int
152 gpopen(dev_t dev, int flags, int fmt, struct thread *td)
153 {
154         struct gpib_softc *sc = &gpib_sc;
155         u_char unit;
156         int status;
157
158        unit= minor(dev);
159
160         /* minor number out of limits ? */
161         if (unit >= 32)
162                 return (ENXIO);
163
164         /* Attached ? */
165         if (!(sc->sc_flags&ATTACHED)) { /* not attached */
166                 return(ENXIO);
167         }
168
169         /* Already open  */
170         if (sc->sc_flags&OPEN) { /* too late .. */
171                 return(EBUSY);
172         }
173
174         /* Have memory for buffer? */
175         sc->sc_inbuf = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
176         if (sc->sc_inbuf == 0)
177                 return(ENOMEM);
178
179         if (initgpib()) return(EBUSY);
180         sc->sc_flags |= OPEN;
181         sc->sc_count = 0;
182         oldcount=0;
183 if (unit!=0) {  /*Someone is trying to access an actual device*/
184                 /*So.. we'll address it to listen*/
185 enableremote(unit);
186  do {
187  status=inb(ISR2);
188  }
189  while (!(status&8)&&tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1)==EWOULDBLOCK);
190
191  outb(CDOR,(unit&31)+32);/*address device to listen*/
192
193  do
194  status=inb(ISR2);
195  while (!(status&8)&&tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1)==EWOULDBLOCK);
196  outb (CDOR,64); /*Address controller (me) to talk*/
197  do status=inb(ISR2);
198
199  while (!(status&8)&&tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1)==EWOULDBLOCK);
200  outb(AUXMR,gts); /*Set to Standby (Controller)*/
201
202
203  do
204  status=inb(ISR1);
205  while (!(status&2)&&tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1)==EWOULDBLOCK);
206 /*Set up the TURBO488 registers*/
207  outb(IMR2,0x30); /*we have to enable DMA (0x30) for turbo488 to work*/
208  outb(CNT0,0);   /*NOTE this does not enable DMA to the host computer!!*/
209  outb(CNT1,0);
210  outb(CNT2,0);
211  outb(CNT3,0);
212  outb(CMDR,0x20);
213  outb(CFG,0x47); /* 16 bit, write, fifo B first, TMOE TIM */
214  outb(CMDR,0x10); /*RESET fifos*/
215  outb(CMDR,0x04); /*Tell TURBO488 to GO*/
216 }
217         return(0);
218 }
219
220
221 /*
222  * gpclose()
223  *      Close gpib device.
224  */
225 static  int
226 gpclose(dev_t dev, int flags, int fmt, struct thread *td)
227 {
228         struct gpib_softc *sc = &gpib_sc;
229         unsigned char unit;
230         unsigned char status;
231
232         unit=minor(dev);
233 if (unit!=0) { /*Here we need to send the last character with EOS*/
234                /*and unaddress the listening device*/
235
236
237   status=EWOULDBLOCK;
238
239   /*Wait for fifo to become empty*/
240   do {
241   status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
242    }
243   while ((inb(ISR3)&0x04)&&status==EWOULDBLOCK); /*Fifo is not empty*/
244
245  outb(CMDR,0x08); /*Issue STOP to TURBO488*/
246
247   /*Wait for DONE and STOP*/
248  if (status==EWOULDBLOCK) do {
249    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
250    }
251   while (!(inb(ISR3)&0x11)&&status==EWOULDBLOCK); /*not done and stop*/
252
253 /*Shut down TURBO488 */
254  outb(IMR2,0x00); /*DISABLE DMA to turbo488*/
255  outb(CMDR,0x20); /*soft reset turbo488*/
256  outb(CMDR,0x10); /*reset fifos*/
257
258
259 /*Send last byte with EOI set*/
260 /*Send second to last byte if there are 2 bytes left*/
261 if (status==EWOULDBLOCK)  {
262
263 do
264  if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
265 while (!(inb(ISR1)&2)&&(status==EWOULDBLOCK));
266 if (oldcount==2){
267  outb(CDOR,oldbytes[0]); /*Send second to last byte*/
268  while (!(inb(ISR1)&2)&&(status==EWOULDBLOCK));
269   status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
270  }
271
272    outb(AUXMR,seoi);  /*Set EOI for the last byte*/
273    outb(AUXMR,0x5E); /*Clear SYNC*/
274    if (oldcount==1)
275    outb(CDOR,oldbytes[0]);
276     else
277    if (oldcount==2)
278    outb(CDOR,oldbytes[1]);
279    else {
280    outb (CDOR,13); /*Send a CR.. we've got trouble*/
281    printf("gpib: Warning: gpclose called with nothing left in buffer\n");
282    }
283 }
284
285 do
286  if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
287 while (!(inb(ISR1)&2)&&(status==EWOULDBLOCK));
288
289
290  if (!(inb(ISR1)&2)&&status==EWOULDBLOCK) do
291    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
292  while (!(inb(ISR1)&2)&&status==EWOULDBLOCK);
293
294
295  outb(AUXMR,tca); /* Regain full control of the bus*/
296
297
298  do
299   status=inb(ISR2);
300  while (!(status&8)&&tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1)==EWOULDBLOCK);
301  outb(CDOR,63); /*unlisten*/
302  do
303   status=inb(ISR2);
304  while (!(status&8)&&tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1)==EWOULDBLOCK);
305  outb(AUXMR,0x5E); /*Clear SYNC*/
306  outb (CDOR,95);/*untalk*/
307  do
308   status=inb(ISR2);
309  while (!(status&8)&&tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1)==EWOULDBLOCK);
310 /*gotolocal(minor(dev));*/
311 }
312         closegpib();
313         sc->sc_flags = ATTACHED;
314         free(sc->sc_inbuf, M_DEVBUF);
315         sc->sc_inbuf = 0;       /* Sanity */
316         return(0);
317 }
318
319 /*
320  * gpwrite()
321  *      Copy from user's buffer, then write to GPIB device referenced
322  *    by minor(dev).
323  */
324 static  int
325 gpwrite(dev_t dev, struct uio *uio, int ioflag)
326 {
327         int err,count;
328
329         /* main loop */
330         while ((gpib_sc.sc_count = MIN(BUFSIZE-1, uio->uio_resid)) > 0) {
331                 /*  If there were >1 bytes left over, send them  */
332                 if (oldcount==2)
333                   sendrawgpibfifo(minor(dev),oldbytes,2);
334
335                 /*If there was 1 character left, put it at the beginning
336                    of the new buffer*/
337                 if (oldcount==1){
338                    (gpib_sc.sc_inbuf)[0]=oldbytes[0];
339                    gpib_sc.sc_cp = gpib_sc.sc_inbuf;
340                 /*  get from user-space  */
341                    uiomove(gpib_sc.sc_inbuf+1, gpib_sc.sc_count, uio);
342                    gpib_sc.sc_count++;
343                    }
344                  else {
345                 gpib_sc.sc_cp = gpib_sc.sc_inbuf;
346                 /*  get from user-space  */
347                 uiomove(gpib_sc.sc_inbuf, gpib_sc.sc_count, uio);
348                     }
349
350 /*NOTE we always leave one byte in case this is the last write
351   so close can send EOI with the last byte There may be 2 bytes
352   since we are doing 16 bit transfers.(note the -1 in the count below)*/
353       /*If count<=2 we'll either pick it up on the next write or on close*/
354             if (gpib_sc.sc_count>2) {
355                 count = sendrawgpibfifo(minor(dev),gpib_sc.sc_cp,gpib_sc.sc_count-1);
356                 err=!count;
357                 if (err)
358                         return(1);
359                 oldcount=gpib_sc.sc_count-count; /*Set # of remaining bytes*/
360                 gpib_sc.sc_count-=count;
361                 gpib_sc.sc_cp+=count; /*point char pointer to remaining bytes*/
362               }
363                 else oldcount=gpib_sc.sc_count;
364                   oldbytes[0]=gpib_sc.sc_cp[0];
365                 if (oldcount==2)
366                   oldbytes[1]=gpib_sc.sc_cp[1];
367         }
368         return(0);
369 }
370 /* Here is how you would usually access a GPIB device
371    An exception would be a plotter or printer that you can just
372    write to using a minor device = its GPIB address */
373
374 static  int
375 gpioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
376 {
377         struct gpibdata *gd = (struct gpibdata *)data;
378         int     error,result;
379         error = 0;
380
381         switch (cmd) {
382         case GPIBWRITE:
383                 sendgpibfifo(gd->address,gd->data,*(gd->count));
384                 error=0;
385                 break;
386         case GPIBREAD:
387                 result=readgpibfifo(gd->address,gd->data,*(gd->count));
388                 *(gd->count)=result;
389                 error=0;
390                 break;
391         case GPIBINIT:
392                 initgpib();
393                 error=0;
394                 break;
395         case GPIBTRIGGER:
396                 trigger(gd->address);
397                 error=0;
398                 break;
399         case GPIBREMOTE:
400                 enableremote(gd->address);
401                 error=0;
402                 break;
403         case GPIBLOCAL:
404                 gotolocal(gd->address);
405                 error=0;
406                 break;
407
408         case GPIBMTRIGGER:
409                 mtrigger(gd->data);
410                 error=0;
411                 break;
412         case GPIBMREMOTE:
413                 menableremote(gd->data);
414                 error=0;
415                 break;
416         case GPIBMLOCAL:
417                 mgotolocal(gd->data);
418                 error=0;
419                 break;
420         case GPIBSPOLL:
421                 *(gd->data)=spoll(gd->address);
422                 error=0;
423                 break;
424         default:
425                 error = ENODEV;
426         }
427
428         return(error);
429 }
430
431
432
433
434 #if 0
435 /*Just in case you want a dump of the registers...*/
436
437 static void showregs() {
438  printf ("NAT4882:\n");
439  printf ("ISR1=%X\t",inb(ISR1));
440  printf ("ISR2=%X\t",inb(ISR2));
441  printf ("SPSR=%X\t",inb(SPSR));
442  printf ("KSR =%X\t",inb(KSR));
443  printf ("ADSR=%X\t",inb(ADSR));
444  printf ("CPTR=%X\t",inb(CPTR));
445  printf ("SASR=%X\t",inb(SASR));
446  printf ("ADR0=%X\t",inb(ADR0));
447  printf ("ISR0=%X\t",inb(ISR0));
448  printf ("ADR1=%X\t",inb(ADR1));
449  printf ("BSR =%X\n",inb(BSR));
450
451  printf ("Turbo488\n");
452  printf ("STS1=%X ",inb(STS1));
453  printf ("STS2=%X ",inb(STS2));
454  printf ("ISR3=%X ",inb(ISR3));
455  printf ("CNT0=%X ",inb(CNT0));
456  printf ("CNT1=%X ",inb(CNT1));
457  printf ("CNT2=%X ",inb(CNT2));
458  printf ("CNT3=%X ",inb(CNT3));
459  printf ("IMR3=%X ",inb(IMR3));
460  printf ("TIMER=%X\n",inb(TIMER));
461
462
463  }
464 #endif
465 /*Set up the NAT4882 and TURBO488 registers */
466 /*This will be nonsense to you unless you have a data sheet from
467   National Instruments.  They should give you one if you call them*/
468
469 static int
470 initgpib(void) {
471   outb(CMDR,0x20);
472   outb(CFG,0x16);
473   outb(IMR3,0);
474   outb(CMDR,0x10);
475   outb(CNT0,0);
476   outb(CNT1,0);
477   outb(CNT2,0);
478   outb(CNT3,0);
479   outb(INTR,0); /* Put interrupt line in tri-state mode??*/
480   outb(AUXMR,chip_reset);
481
482   outb(IMR1,0x10); /* send interrupt to TURBO488 when END received*/
483   outb(IMR2,0);
484   outb(IMR0,0x90); /* Do we want nba here too??? */
485   outb(ADMR,1);
486   outb(ADR,0);
487   outb(ADR,128);
488   outb(AUXMR,0xE9);
489   outb(AUXMR,0x49);
490   outb(AUXMR,0x70);
491   outb(AUXMR,0xD0);
492   outb(AUXMR,0xA0);
493
494   outb(EOSR,10); /*set EOS message to newline*/
495                  /*should I make the default to interpret END as EOS?*/
496                  /*It isn't now.  The following changes this*/
497   outb(AUXMR,0x80);    /*No special EOS handling*/
498  /*outb(AUXMR,0x88) */ /* Transmit END with EOS*/
499  /*outb(AUXMR,0x84) */ /* Set END on EOS received*/
500  /*outb(AUXMR,0x8C) */ /* Do both of the above*/
501
502
503  /* outb(AUXMR,hldi); */ /*Perform RFD Holdoff for all data in*/
504                          /*Not currently supported*/
505
506   outb(AUXMR,pon);
507   outb(AUXMR,sic_rsc);
508  tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
509
510   outb(AUXMR,sic_rsc_off);
511
512 return(0);
513
514
515    }
516
517 /*This is kind of Brute force..  But it works*/
518
519 static void 
520 closegpib(void) 
521 {
522    outb(AUXMR,chip_reset);
523 }
524
525 /*GPIB ROUTINES:
526   These will also make little sense unless you have a data sheet.
527   Note that the routines with an "m" in the beginning are for
528   accessing multiple devices in one call*/
529
530
531 /*This is one thing I could not figure out how to do correctly.
532   I tried to use the auxilary  command to enable remote, but it
533   never worked.  Here, I bypass everything and write to the BSR
534   to enable the remote line.  NOTE that these lines are effectively
535   "OR'ed" with the actual lines, so writing a 1 to the bit in the BSR
536   forces the GPIB line true, no matter what the fancy circuitry of the
537   NAT4882 wants to do with it*/
538
539 static void
540 enableremote(unsigned char device)
541 {
542  int status;
543
544 status=EWOULDBLOCK;
545   if (status==EWOULDBLOCK) do {
546    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
547    }
548   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
549
550  outb(BSR,1);           /*Set REN bit on GPIB*/
551   if (status==EWOULDBLOCK) do {
552    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
553    }
554   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
555  outb(CDOR,(device&31)+32); /*address device to listen*/
556   if (status==EWOULDBLOCK) do {
557    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
558    }
559   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
560  outb (CDOR,63); /*Unaddress device*/
561   if (status==EWOULDBLOCK) do {
562    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
563    }
564   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
565
566  }
567 /*This does not release the REM line on the gpib port, because if it did,
568   all the remote devices would go to local mode.  This only sends the
569   gotolocal message to one device.  Currently, REM is always held true
570   after enableremote is called, and is reset only on a close of the
571   gpib device */
572
573 static void
574 gotolocal(unsigned char device)
575 { int status;
576   status=EWOULDBLOCK;
577
578   if (status==EWOULDBLOCK) do {
579    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
580    }
581   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
582
583 outb(CDOR,(device&31)+32);
584
585   if (status==EWOULDBLOCK) do {
586    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
587    }
588   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
589
590 outb(AUXMR,0x5E);  /*Clear SYNC*/
591  outb (CDOR,1);
592
593   if (status==EWOULDBLOCK) do {
594    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
595    }
596   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
597
598  outb(AUXMR,0x5E);
599  outb (CDOR,63);/*unaddress device*/
600
601   if (status==EWOULDBLOCK) do {
602    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
603    }
604   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
605
606  }
607
608
609 static void
610 menableremote(unsigned char *device)
611 {
612  int status, counter = 0;
613
614 status=EWOULDBLOCK;
615   if (status==EWOULDBLOCK) do {
616    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
617    }
618   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
619
620  outb(BSR,1);           /*Set REN bit on GPIB*/
621  do
622   {
623   if (status==EWOULDBLOCK) do {
624    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
625    }
626   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
627  outb(CDOR,(device[counter]&31)+32); /*address device to listen*/
628  counter++;
629  }
630  while (device[counter]<32);
631
632   if (status==EWOULDBLOCK) do {
633    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
634    }
635   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
636
637  outb (CDOR,63); /*Unaddress device*/
638   if (status==EWOULDBLOCK) do {
639    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
640    }
641   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
642
643  }
644
645 static void
646 mgotolocal(unsigned char *device)
647 { int status;
648   int counter=0;
649 status=EWOULDBLOCK;
650  if (device[counter]<32) do {
651   if (status==EWOULDBLOCK) do {
652    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
653    }
654   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
655  outb(CDOR,(device[counter]&31)+32);
656  counter++;
657  } while (device[counter]<32);
658   if (status==EWOULDBLOCK) do {
659    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
660    }
661   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
662
663  outb(AUXMR,0x5E);  /*Clear SYNC*/
664  outb (CDOR,1);
665
666
667   if (status==EWOULDBLOCK) do {
668    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
669    }
670   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
671  outb(AUXMR,0x5E);
672  outb (CDOR,63);/*unaddress device*/
673   if (status==EWOULDBLOCK) do {
674    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",2);
675    }
676   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
677
678
679  }
680 /*Trigger a device.  What happens depends on how the device is
681  configured.  */
682
683 static void 
684 trigger(unsigned char device)
685 { int status;
686
687 status=EWOULDBLOCK;
688  if (device<32)  {
689   if (!(inb(ISR2)&0x08)) do {
690    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
691    }
692   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
693  outb(CDOR,(device&31)+32); /*address device to listen*/
694   if (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK) do {
695    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
696    }
697   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
698
699  outb (CDOR,8);  /*send GET*/
700
701   if (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK) do {
702    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
703    }
704   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
705  outb (AUXMR,0x5E);
706  outb (CDOR,63);/*unaddress device*/
707   if (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK) do {
708    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
709    }
710   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
711
712
713  }
714 }
715
716 /*Trigger multiple devices by addressing them all to listen, and then
717   sending GET*/
718
719 static void
720 mtrigger(unsigned char *device)
721 { int status=EWOULDBLOCK;
722   int counter=0;
723  if(device[0]<32){
724  do {
725  if (device[counter]<32)
726   if (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK) do {
727    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
728    }
729   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
730  outb(CDOR,(device[counter]&31)+32); /*address device to listen*/
731  counter++;
732    }
733  while (device[counter]<32);
734   if (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK) do {
735    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
736    }
737   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
738  outb (CDOR,8);  /*send GET*/
739
740   if (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK) do {
741    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
742    }
743   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
744  outb (AUXMR,0x5E);
745  outb (CDOR,63);/*unaddress device*/
746   if (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK) do {
747    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
748    }
749   while (!(inb(ISR2)&0x08)&&status==EWOULDBLOCK); /*Wait to send next cmd*/
750
751
752  }
753 }
754
755 /*This is not used now, but it should work with NI's 8 bit gpib board
756   since it does not use the TURBO488 registers at all */
757
758
759 /*Send data through the TURBO488 FIFOS to a device that is already
760  addressed to listen.  This is used by the write call when someone is
761  writing to a printer or plotter, etc... */
762 /*The last byte of each write is held off until either the next
763  write or close, so it can be sent with EOI set*/
764
765 static int
766 sendrawgpibfifo(unsigned char device,char *data,int count)
767  {
768  int status;
769  int counter;
770  int fifopos;
771  int sleeptime;
772
773
774  sleeptime=SLEEP_MIN;
775  counter=0;
776
777
778  fifopos=0;
779
780 status=EWOULDBLOCK;
781  do {
782   /*Wait for fifo to become not full if it is full */
783   sleeptime=SLEEP_MIN;
784   if (!(inb(ISR3)&0x08)) do {
785    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",sleeptime);
786    if (sleeptime<SLEEP_MAX) sleeptime=sleeptime*2;
787    }
788   while (!(inb(ISR3)&0x08)&&(status==EWOULDBLOCK)); /*Fifo is full*/
789
790    if((count>1)&&(inb(ISR3)&0x08)){
791    outw(FIFOB,*(unsigned*)(data+counter));
792  /*  printf ("gpib: sent:%c,%c\n",data[counter],data[counter+1]);*/
793
794   counter+=2;
795   count-=2;
796    }
797   }
798  while ((count>1)&&(status==EWOULDBLOCK));
799 /*The write routine and close routine must check if there is 1
800   byte left and handle it accordingly*/
801
802
803 /*Return the number of bytes written to the device*/
804  return(counter);
805
806
807
808 }
809
810 static int
811 sendgpibfifo(unsigned char device,char *data,int count)
812  {
813  int status;
814  int counter;
815  int fifopos;
816  int sleeptime;
817
818 outb(IMR2,0x30); /*we have to enable DMA (0x30) for turbo488 to work*/
819  outb(CNT0,0);
820  outb(CNT1,0);
821  outb(CNT2,0);
822  outb(CNT3,0);
823 status=EWOULDBLOCK;
824  if (!(inb(ISR2)&8)) do
825    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
826  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
827
828  outb(CDOR,(device&31)+32);/*address device to listen*/
829
830  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
831    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
832  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
833  outb (CDOR,64); /*Address controller (me) to talk*/
834
835  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
836    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
837  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
838
839  outb(AUXMR,gts); /*Set to Standby (Controller)*/
840  fifopos=0;
841
842  sleeptime=SLEEP_MIN;
843  counter=0;
844
845
846  fifopos=0;
847
848  outb(CMDR,0x20);
849  outb(CFG,0x47); /* 16 bit, write, fifo B first, TMOE TIM */
850  outb(CMDR,0x10); /*RESET fifos*/
851  outb(CCRG,seoi); /*program to send EOI at end*/
852  outb(CMDR,0x04); /*Tell TURBO488 to GO*/
853 status=EWOULDBLOCK;
854  do {
855   /*Wait for fifo to become not full if it is full */
856   sleeptime=SLEEP_MIN;
857   if (!(inb(ISR3)&0x08)) do {
858    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",sleeptime);
859    if (sleeptime<SLEEP_MAX) sleeptime=sleeptime*2;
860    }
861   while (!(inb(ISR3)&0x08)&&(status==EWOULDBLOCK)); /*Fifo is full*/
862
863    if((count>1)&&(inb(ISR3)&0x08)){
864    /*if(count==2) outb(CFG,15+0x40); *//*send eoi when done*/
865    outw(FIFOB,*(unsigned*)(data+counter));
866
867   counter+=2;
868   count-=2;
869    }
870   }
871  while ((count>2)&&(status==EWOULDBLOCK));
872
873  if (count==2&&status==EWOULDBLOCK) {
874   /*Wait for fifo to become not full*/
875   if(status==EWOULDBLOCK&&!(inb(ISR3)&0x08)) do {
876    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",SLEEP_MIN);
877    }
878   while (!(inb(ISR3)&0x08)&&status==EWOULDBLOCK); /*Fifo is full*/
879   /*outb(CFG,0x40+15);*//*send eoi when done*/
880   outb(FIFOB,data[counter]);
881   counter++;
882   count--;
883   }
884
885
886  /*outb(CMDR,0x04);*/
887
888   /*Wait for fifo to become empty*/
889   if (status==EWOULDBLOCK) do {
890   status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
891    }
892   while ((inb(ISR3)&0x04)&&status==EWOULDBLOCK); /*Fifo is not empty*/
893
894  outb(CMDR,0x08); /*Issue STOP to TURBO488*/
895
896   /*Wait for DONE and STOP*/
897  if (status==EWOULDBLOCK) do {
898    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
899    }
900   while (!(inb(ISR3)&0x11)&&status==EWOULDBLOCK); /*not done and stop*/
901
902  outb(IMR2,0x00); /*we have to enable DMA (0x30) for turbo488 to work*/
903  outb(CMDR,0x20); /*soft reset turbo488*/
904  outb(CMDR,0x10); /*reset fifos*/
905
906
907 /*Send last byte with EOI set*/
908 /*Here EOI is handled correctly since the string to be sent */
909 /*is actually all sent during the ioctl.  (See above)*/
910
911 if (count==1&&status==EWOULDBLOCK)  {  /*Count should always=1 here*/
912
913 do
914  if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
915 while (!(inb(ISR1)&2)&&(status==EWOULDBLOCK));
916
917    outb(AUXMR,seoi);  /*Set EOI for the last byte*/
918    outb(AUXMR,0x5E); /*Clear SYNC*/
919    outb(CDOR,data[counter]);
920  counter++;
921  count--;
922 }
923
924 do
925  if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
926 while (!(inb(ISR1)&2)&&(status==EWOULDBLOCK));
927
928
929  if (!(inb(ISR1)&2)&&status==EWOULDBLOCK) do
930    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
931  while (!(inb(ISR1)&2)&&status==EWOULDBLOCK);
932  outb(AUXMR,tca); /* Regain full control of the bus*/
933
934
935  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
936    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
937    while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
938
939    outb(CDOR,63); /*unlisten*/
940
941
942  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
943    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
944  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
945
946
947 outb(AUXMR,0x5E); /*Clear SYNC*/
948  outb (CDOR,95);/*untalk*/
949  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
950    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
951  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
952
953
954  return(counter);
955
956
957
958 }
959
960 static int
961 readgpibfifo(unsigned char device,char *data,int count)
962 {
963  int status;
964  int status2 = 0;
965  int status1;
966  int counter;
967  int fifopos;
968  unsigned inword;
969
970  outb(IMR2,0x30); /*we have to enable DMA (0x30) for turbo488 to work*/
971  /*outb(IMR3,0x1F);
972  outb(INTR,1); */
973  outb(CMDR,0x20);
974
975  outb(CFG,14+0x60+1); /* Halt on int,read, fifo B first, CCEN TMOE TIM */
976  outb(CMDR,0x10); /*RESET fifos*/
977  outb(CCRG,tcs); /*program to tcs at end*/
978  outb(CMDR,0x08);/*STOP??*/
979
980
981
982 status=EWOULDBLOCK;
983 do
984    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
985  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
986
987  outb (CDOR,32); /*Address controller (me) to listen*/
988
989   do
990    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
991  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
992
993  outb(CDOR,(device&31)+64);/*address device to talk*/
994
995
996   do
997    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
998  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
999
1000  outb(AUXMR,gts); /*Set to Standby (Controller)*/
1001
1002  counter=0;
1003  fifopos=0;
1004
1005   outb(CMDR,0x04); /*Tell TURBO488 to GO*/
1006
1007
1008  do {
1009    status1=inb(ISR3);
1010    if (!(status1&0x01)&&(status1&0x04)){
1011    status2=inb(STS2);
1012    inword=inw(FIFOB);
1013    *(unsigned*)(data+counter)=inword;
1014   /* printf ("Read:%c,%c\n",data[counter],data[counter+1]);*/
1015   counter+=2;
1016   }
1017  else {
1018    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",4);
1019   }
1020  }
1021  while (!(status1&0x01)&&status==EWOULDBLOCK);
1022  if(!(status2 & 0x04)){ /*Only 1 byte came in on last 16 bit transfer*/
1023   data[counter-1]=0;
1024   counter--; }
1025   else
1026     data[counter]=0;
1027  outb(CMDR,0x08); /*send STOP*/
1028
1029  do{
1030    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1031    }
1032  while(!(inb(ISR3)&0x11)&&status==EWOULDBLOCK); /*wait for DONE and STOP*/
1033  outb(AUXMR,0x55);
1034
1035  outb(IMR2,0x00); /*we have to enable DMA (0x30) for turbo488 to work*/
1036  outb(CMDR,0x20); /*soft reset turbo488*/
1037  outb(CMDR,0x10); /*reset fifos*/
1038
1039 /* do
1040    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1041  while (!(inb(ISR1)&2));*/
1042  outb(AUXMR,tca); /* Regain full control of the bus*/
1043
1044
1045  do
1046    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1047  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1048  outb(CDOR,63); /*unlisten*/
1049
1050  do
1051    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1052  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1053
1054 outb(AUXMR,0x5E); /*Clear SYNC*/
1055  outb (CDOR,95);/*untalk*/
1056  do
1057    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1058  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1059
1060  return(counter);
1061
1062
1063 }
1064
1065
1066 /* Return the status byte from device */
1067 static char
1068 spoll(unsigned char device)
1069  {
1070  int status=EWOULDBLOCK;
1071  unsigned int statusbyte;
1072
1073  if (!(inb(ISR2)&8)) do
1074    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1075  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1076
1077  outb(CDOR,(device&31)+64);/*address device to talk*/
1078
1079  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
1080    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1081  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1082
1083  outb (CDOR,32); /*Address controller (me) to listen*/
1084
1085  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
1086    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1087  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1088  outb(AUXMR,0x5E);
1089  outb (CDOR,0x18); /*Send SPE (serial poll enable)*/
1090  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
1091    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1092  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1093
1094   /*wait for bus to be synced*/
1095  if (!(inb(ISR0)&1)&&status==EWOULDBLOCK) do
1096    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1097  while (!(inb(ISR0)&1)&&status==EWOULDBLOCK);
1098
1099  outb(AUXMR,gts); /*Set to Standby (Controller)*/
1100
1101  if (!(inb(ISR1)&1)&&status==EWOULDBLOCK) do
1102    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1103  while (!(inb(ISR1)&1)&&status==EWOULDBLOCK);
1104  outb(AUXMR,0x5E);
1105  outb(AUXMR,tcs); /* Take control after next read*/
1106  statusbyte=inb(DIR);
1107
1108  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
1109    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1110  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1111
1112  outb(CDOR,0x19); /*SPD (serial poll disable)*/
1113
1114   /*wait for bus to be synced*/
1115  if (!(inb(ISR0)&1)&&status==EWOULDBLOCK) do
1116    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1117  while (!(inb(ISR0)&1)&&status==EWOULDBLOCK);
1118
1119
1120  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
1121    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1122  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1123
1124 outb(CDOR,95); /*untalk*/
1125
1126  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
1127    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1128  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1129  outb(AUXMR,0x5E);
1130  outb (CDOR,63);/*unlisten*/
1131  if (!(inb(ISR2)&8)&&status==EWOULDBLOCK) do
1132    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1133  while (!(inb(ISR2)&8)&&status==EWOULDBLOCK);
1134
1135   /*wait for bus to be synced*/
1136  if (!(inb(ISR0)&1)&&status==EWOULDBLOCK) do
1137    status=tsleep((caddr_t)&gpib_sc,GPIBPRI,"gpibpoll",1);
1138  while (!(inb(ISR0)&1)&&status==EWOULDBLOCK);
1139
1140
1141  return(statusbyte);
1142
1143
1144 }