Fix a minor compile-time errors when INVARIANTS is not defined.
[dragonfly.git] / sys / dev / misc / gpib / gpib.c
CommitLineData
984263bc
MD
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 $
377d4740 20 * $DragonFly: src/sys/dev/misc/gpib/gpib.c,v 1.3 2003/07/19 21:14:34 dillon Exp $
984263bc
MD
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
377d4740 36#define GPIBPRI PCATCH
984263bc
MD
37#define SLEEP_MAX 1000
38#define SLEEP_MIN 4
39
40
41
42static int initgpib(void);
43static void closegpib(void);
44static int sendgpibfifo(unsigned char device,char *data,int count);
45static int sendrawgpibfifo(unsigned char device,char *data,int count);
46static int readgpibfifo(unsigned char device,char *data,int count);
47#if 0
48static void showregs(void);
49#endif
50static void enableremote(unsigned char device);
51static void gotolocal(unsigned char device);
52static void menableremote(unsigned char *device);
53static void mgotolocal(unsigned char *device);
54static void mtrigger(unsigned char *device);
55static void trigger(unsigned char device);
56static char spoll(unsigned char device);
57
58static int gpprobe(struct isa_device *dvp);
59static int gpattach(struct isa_device *dvp);
60
61struct isa_driver gpdriver = {gpprobe, gpattach, "gp"};
62
63static d_open_t gpopen;
64static d_close_t gpclose;
65static d_write_t gpwrite;
66static d_ioctl_t gpioctl;
67
68#define CDEV_MAJOR 44
69static struct cdevsw gp_cdevsw = {
70 /* open */ gpopen,
71 /* close */ gpclose,
72 /* read */ noread,
73 /* write */ gpwrite,
74 /* ioctl */ gpioctl,
75 /* poll */ nopoll,
76 /* mmap */ nommap,
77 /* strategy */ nostrategy,
78 /* name */ "gp",
79 /* maj */ CDEV_MAJOR,
80 /* dump */ nodump,
81 /* psize */ nopsize,
82 /* flags */ 0,
83 /* bmaj */ -1
84};
85
86#define BUFSIZE 1024
87#define ATTACHED 0x08
88#define OPEN 0x04
89#define INIT 0x02
90
91
92static 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? */
100static int oldcount;
101static char oldbytes[2];
102/*Probe routine*/
103/*This needs to be changed to be a bit more robust*/
104static int
105gpprobe(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;
117if ((inb(KSR)&0xF7)==0x34) sc->sc_type=3;
118else if ((inb(KSR)&0xF7)==0x24) sc->sc_type=2;
119else 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 */
129static int
130gpattach(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 */
155static int
156gpopen(dev, flags, fmt, p)
157 dev_t dev;
158 int flags;
159 int fmt;
160 struct proc *p;
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;
191if (unit!=0) { /*Someone is trying to access an actual device*/
192 /*So.. we'll address it to listen*/
193enableremote(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 */
233static int
234gpclose(dev, flags, fmt, p)
235 dev_t dev;
236 int flags;
237 int fmt;
238 struct proc *p;
239{
240 struct gpib_softc *sc = &gpib_sc;
241 unsigned char unit;
242 unsigned char status;
243
244 unit=minor(dev);
245if (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*/
273if (status==EWOULDBLOCK) {
274
275do
276 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
277while (!(inb(ISR1)&2)&&(status==EWOULDBLOCK));
278if (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
297do
298 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
299while (!(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 */
336static int
337gpwrite(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
389static int
390gpioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
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
452static 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
484static int
485initgpib() {
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
527return(0);
528
529
530 }
531
532/*This is kind of Brute force.. But it works*/
533
534static void
535closegpib()
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
554static void
555enableremote(unsigned char device)
556{
557 int status;
558
559status=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
588static void
589gotolocal(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
598outb(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
605outb(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
624static void
625menableremote(unsigned char *device)
626{
627 int status, counter = 0;
628
629status=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
660static void
661mgotolocal(unsigned char *device)
662{ int status;
663 int counter=0;
664status=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
698static void
699trigger(unsigned char device)
700{ int status;
701
702status=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
734static void
735mtrigger(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
780static int
781sendrawgpibfifo(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
795status=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
825static int
826sendgpibfifo(unsigned char device,char *data,int count)
827 {
828 int status;
829 int counter;
830 int fifopos;
831 int sleeptime;
832
833outb(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);
838status=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*/
868status=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
926if (count==1&&status==EWOULDBLOCK) { /*Count should always=1 here*/
927
928do
929 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
930while (!(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
939do
940 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
941while (!(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
962outb(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
975static int
976readgpibfifo(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
997status=EWOULDBLOCK;
998do
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
1069outb(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 */
1082static char
1083spoll(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
1139outb(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}