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