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