DEV messaging stage 1/4: Rearrange struct cdevsw and add a message port
[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.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
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 /* 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
94static 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? */
102static int oldcount;
103static char oldbytes[2];
104/*Probe routine*/
105/*This needs to be changed to be a bit more robust*/
106static int
107gpprobe(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;
119if ((inb(KSR)&0xF7)==0x34) sc->sc_type=3;
120else if ((inb(KSR)&0xF7)==0x24) sc->sc_type=2;
121else 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 */
131static int
132gpattach(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 */
157static int
158gpopen(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;
193if (unit!=0) { /*Someone is trying to access an actual device*/
194 /*So.. we'll address it to listen*/
195enableremote(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 */
235static int
236gpclose(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);
247if (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*/
275if (status==EWOULDBLOCK) {
276
277do
278 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
279while (!(inb(ISR1)&2)&&(status==EWOULDBLOCK));
280if (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
299do
300 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
301while (!(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 */
338static int
339gpwrite(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
391static int
392gpioctl(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
454static 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
486static int
487initgpib() {
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
529return(0);
530
531
532 }
533
534/*This is kind of Brute force.. But it works*/
535
536static void
537closegpib()
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
556static void
557enableremote(unsigned char device)
558{
559 int status;
560
561status=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
590static void
591gotolocal(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
600outb(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
607outb(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
626static void
627menableremote(unsigned char *device)
628{
629 int status, counter = 0;
630
631status=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
662static void
663mgotolocal(unsigned char *device)
664{ int status;
665 int counter=0;
666status=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
700static void
701trigger(unsigned char device)
702{ int status;
703
704status=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
736static void
737mtrigger(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
782static int
783sendrawgpibfifo(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
797status=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
827static int
828sendgpibfifo(unsigned char device,char *data,int count)
829 {
830 int status;
831 int counter;
832 int fifopos;
833 int sleeptime;
834
835outb(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);
840status=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*/
870status=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
928if (count==1&&status==EWOULDBLOCK) { /*Count should always=1 here*/
929
930do
931 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
932while (!(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
941do
942 if (!(inb(ISR1)&2)) status=tsleep((caddr_t)&gpib_sc, GPIBPRI,"gpibpoll",1);
943while (!(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
964outb(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
977static int
978readgpibfifo(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
999status=EWOULDBLOCK;
1000do
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
1071outb(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 */
1084static char
1085spoll(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
1141outb(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}