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