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