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

Cache object: 55e486e3312e81e1b1d9e73d51fe2df3


[ 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.