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