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