The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/gpib.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.