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