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