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/dev/ieee488/ibfoo.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
    3  * Copyright (c) 2010 Joerg Wunsch <joerg@FreeBSD.org>
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * High-level driver for µPD7210 based GPIB cards.
   28  *
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD: releng/8.4/sys/dev/ieee488/ibfoo.c 216573 2010-12-19 21:33:28Z joerg $");
   33 
   34 #  define       IBDEBUG
   35 #  undef        IBDEBUG
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/conf.h>
   40 #include <sys/malloc.h>
   41 #include <sys/kernel.h>
   42 #include <sys/limits.h>
   43 #include <sys/module.h>
   44 #include <sys/rman.h>
   45 #include <sys/bus.h>
   46 #include <sys/lock.h>
   47 #include <sys/mutex.h>
   48 #include <sys/uio.h>
   49 #include <sys/time.h>
   50 #include <machine/bus.h>
   51 #include <machine/resource.h>
   52 #include <isa/isavar.h>
   53 
   54 #include <dev/ieee488/ugpib.h>
   55 
   56 #define UPD7210_SW_DRIVER
   57 #include <dev/ieee488/upd7210.h>
   58 #include <dev/ieee488/tnt4882.h>
   59 
   60 static MALLOC_DEFINE(M_IBFOO, "IBFOO", "IBFOO");
   61 
   62 
   63 /* ibfoo API */
   64 
   65 #include <dev/ieee488/ibfoo_int.h>
   66 
   67 /* XXX: This is really a bitmap */
   68 enum h_kind {
   69         H_DEV = 1,
   70         H_BOARD = 2,
   71         H_EITHER = 3
   72 };
   73 
   74 struct handle {
   75         LIST_ENTRY(handle)      list;
   76         int                     handle;
   77         enum h_kind             kind;
   78         int                     pad;
   79         int                     sad;
   80         struct timeval          timeout;
   81         int                     eot;
   82         int                     eos;
   83         int                     dma;
   84 };
   85 
   86 struct ibfoo {
   87         struct upd7210          *u;
   88         LIST_HEAD(,handle)      handles;
   89         struct unrhdr           *unrhdr;
   90         struct callout          callout;
   91         struct handle           *h;
   92         struct ibarg            *ap;
   93 
   94         enum {
   95                 IDLE,
   96                 BUSY,
   97                 PIO_IDATA,
   98                 PIO_ODATA,
   99                 PIO_CMD,
  100                 DMA_IDATA,
  101                 FIFO_IDATA,
  102                 FIFO_ODATA,
  103                 FIFO_CMD
  104         }                       mode;
  105 
  106         struct timeval          deadline;
  107 
  108         struct handle           *rdh;           /* addressed for read */
  109         struct handle           *wrh;           /* addressed for write */
  110 
  111         int                     doeoi;
  112 
  113         u_char                  *buf;
  114         u_int                   buflen;
  115 };
  116 
  117 typedef int ibhandler_t(struct ibfoo *ib);
  118 
  119 static struct timeval timeouts[] = {
  120         [TNONE] =       {    0,      0},
  121         [T10us] =       {    0,     10},
  122         [T30us] =       {    0,     30},
  123         [T100us] =      {    0,    100},
  124         [T300us] =      {    0,    300},
  125         [T1ms] =        {    0,   1000},
  126         [T3ms] =        {    0,   3000},
  127         [T10ms] =       {    0,  10000},
  128         [T30ms] =       {    0,  30000},
  129         [T100ms] =      {    0, 100000},
  130         [T300ms] =      {    0, 300000},
  131         [T1s] =         {    1,      0},
  132         [T3s] =         {    3,      0},
  133         [T10s] =        {   10,      0},
  134         [T30s] =        {   30,      0},
  135         [T100s] =       {  100,      0},
  136         [T300s] =       {  300,      0},
  137         [T1000s] =      { 1000,      0}
  138 };
  139 
  140 static const u_int max_timeouts = sizeof timeouts / sizeof timeouts[0];
  141 
  142 static int ibdebug;
  143 
  144 static int
  145 ib_set_error(struct ibarg *ap, int error)
  146 {
  147 
  148         if (ap->__iberr == 0)
  149                 ap->__iberr = error;
  150         ap->__ibsta |= ERR;
  151         ap->__retval = ap->__ibsta;
  152         return (0);
  153 }
  154 
  155 static int
  156 ib_had_timeout(struct ibarg *ap)
  157 {
  158 
  159         ib_set_error(ap, EABO);
  160         ap->__ibsta |= TIMO;
  161         ap->__retval = ap->__ibsta;
  162         return (0);
  163 }
  164 
  165 static int
  166 ib_set_errno(struct ibarg *ap, int errno)
  167 {
  168 
  169         if (ap->__iberr == 0) {
  170                 ap->__iberr = EDVR;
  171                 ap->__ibcnt = errno;
  172         }
  173         ap->__ibsta |= ERR;
  174         ap->__retval = ap->__ibsta;
  175         return (0);
  176 }
  177 
  178 static int
  179 gpib_ib_irq(struct upd7210 *u, int isr_3)
  180 {
  181         struct ibfoo *ib;
  182 
  183         ib = u->ibfoo;
  184 
  185         mtx_assert(&u->mutex, MA_OWNED);
  186         switch (ib->mode) {
  187         case PIO_CMD:
  188                 if (!(u->rreg[ISR2] & IXR2_CO))
  189                         return (0);
  190                 if (ib->buflen == 0)
  191                         break;
  192                 upd7210_wr(u, CDOR, *ib->buf);
  193                 ib->buf++;
  194                 ib->buflen--;
  195                 return (1);
  196         case PIO_IDATA:
  197                 if (!(u->rreg[ISR1] & IXR1_DI))
  198                         return (0);
  199                 *ib->buf = upd7210_rd(u, DIR);
  200                 ib->buf++;
  201                 ib->buflen--;
  202                 if (ib->buflen == 0 || (u->rreg[ISR1] & IXR1_ENDRX))
  203                         break;
  204                 return (1);
  205         case PIO_ODATA:
  206                 if (!(u->rreg[ISR1] & IXR1_DO))
  207                         return (0);
  208                 if (ib->buflen == 0)
  209                         break;
  210                 if (ib->buflen == 1 && ib->doeoi)
  211                         upd7210_wr(u, AUXMR, AUXMR_SEOI);
  212                 upd7210_wr(u, CDOR, *ib->buf);
  213                 ib->buf++;
  214                 ib->buflen--;
  215                 return (1);
  216         case DMA_IDATA:
  217                 if (!(u->rreg[ISR1] & IXR1_ENDRX))
  218                         return (0);
  219                 break;
  220         case FIFO_IDATA:
  221                 if (!(isr_3 & 0x15))
  222                         return (0);
  223                 while (ib->buflen != 0 && (isr_3 & 0x04 /* NEF */) != 0) {
  224                         *ib->buf = bus_read_1(u->reg_res[0], fifob);
  225                         ib->buf++;
  226                         ib->buflen--;
  227                         isr_3 = bus_read_1(u->reg_res[0], isr3);
  228                 }
  229                 if ((isr_3 & 0x01) != 0 /* xfr done */ ||
  230                     (u->rreg[ISR1] & IXR1_ENDRX) != 0 ||
  231                     ib->buflen == 0)
  232                         break;
  233                 if (isr_3 & 0x10)
  234                         /* xfr stopped */
  235                         bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
  236                 upd7210_wr(u, AUXMR, AUXMR_RFD);
  237                 return (1);
  238         case FIFO_CMD:
  239         case FIFO_ODATA:
  240                 if (!(isr_3 & 0x19))
  241                         return (0);
  242                 if (ib->buflen == 0)
  243                         /* xfr DONE */
  244                         break;
  245                 while (ib->buflen != 0 && (isr_3 & 0x08 /* NFF */) != 0) {
  246                         bus_write_1(u->reg_res[0], fifob, *ib->buf);
  247                         ib->buf++;
  248                         ib->buflen--;
  249                         isr_3 = bus_read_1(u->reg_res[0], isr3);
  250                 }
  251                 if (isr_3 & 0x10)
  252                         /* xfr stopped */
  253                         bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
  254                 if (ib->buflen == 0)
  255                         /* no more NFF interrupts wanted */
  256                         bus_write_1(u->reg_res[0], imr3, 0x11); /* STOP IE, DONE IE */
  257                 return (1);
  258         default:
  259                 return (0);
  260         }
  261         upd7210_wr(u, IMR1, 0);
  262         upd7210_wr(u, IMR2, 0);
  263         if (u->use_fifo) {
  264                 bus_write_1(u->reg_res[0], imr3, 0x00);
  265                 bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */
  266         }
  267         ib->mode = BUSY;
  268         wakeup(&ib->buflen);
  269         return (1);
  270 }
  271 
  272 static void
  273 gpib_ib_timeout(void *arg)
  274 {
  275         struct upd7210 *u;
  276         struct ibfoo *ib;
  277         struct timeval tv;
  278         u_int isr_3;
  279 
  280         u = arg;
  281         ib = u->ibfoo;
  282         mtx_lock(&u->mutex);
  283         if (ib->mode == DMA_IDATA && isa_dmatc(u->dmachan)) {
  284                 KASSERT(u->dmachan >= 0, ("Bogus dmachan = %d", u->dmachan));
  285                 upd7210_wr(u, IMR1, 0);
  286                 upd7210_wr(u, IMR2, 0);
  287                 ib->mode = BUSY;
  288                 wakeup(&ib->buflen);
  289         }
  290         if (ib->mode > BUSY) {
  291                 upd7210_rd(u, ISR1);
  292                 upd7210_rd(u, ISR2);
  293                 if (u->use_fifo)
  294                         isr_3 = bus_read_1(u->reg_res[0], isr3);
  295                 else
  296                         isr_3 = 0;
  297                 gpib_ib_irq(u, isr_3);
  298         }
  299         if (ib->mode != IDLE && timevalisset(&ib->deadline)) {
  300                 getmicrouptime(&tv);
  301                 if (timevalcmp(&ib->deadline, &tv, <)) {
  302                         ib_had_timeout(ib->ap);
  303                         upd7210_wr(u, IMR1, 0);
  304                         upd7210_wr(u, IMR2, 0);
  305                         if (u->use_fifo) {
  306                                 bus_write_1(u->reg_res[0], imr3, 0x00);
  307                                 bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */
  308                         }
  309                         ib->mode = BUSY;
  310                         wakeup(&ib->buflen);
  311                 }
  312         }
  313         if (ib->mode != IDLE)
  314                 callout_reset(&ib->callout, hz / 5, gpib_ib_timeout, arg);
  315         mtx_unlock(&u->mutex);
  316 }
  317 
  318 static void
  319 gpib_ib_wait_xfer(struct upd7210 *u, struct ibfoo *ib)
  320 {
  321         int i;
  322 
  323         mtx_assert(&u->mutex, MA_OWNED);
  324         while (ib->mode > BUSY) {
  325                 i = msleep(&ib->buflen, &u->mutex,
  326                     PZERO | PCATCH, "ibwxfr", 0);
  327                 if (i == EINTR) {
  328                         ib_set_errno(ib->ap, i);
  329                         break;
  330                 }
  331                 if (u->rreg[ISR1] & IXR1_ERR) {
  332                         ib_set_error(ib->ap, EABO);     /* XXX ? */
  333                         break;
  334                 }
  335         }
  336         if ((u->rreg[ISR1] & IXR1_ENDRX) != 0) {
  337                 ib->ap->__retval |= END;
  338                 ib->ap->__ibsta |= END;
  339         }
  340         if ((u->rreg[ISR2] & IXR2_SRQI) != 0) {
  341                 ib->ap->__retval |= SRQI;
  342                 ib->ap->__ibsta |= SRQI;
  343         }
  344         ib->mode = BUSY;
  345         ib->buf = NULL;
  346         upd7210_wr(u, IMR1, 0);
  347         upd7210_wr(u, IMR2, 0);
  348         if (u->use_fifo)
  349                 bus_write_1(u->reg_res[0], imr3, 0x00);
  350 }
  351 
  352 static void
  353 config_eos(struct upd7210 *u, struct handle *h)
  354 {
  355         int i;
  356 
  357         i = 0;
  358         if (h->eos & REOS) {
  359                 upd7210_wr(u, EOSR, h->eos & 0xff);
  360                 i |= AUXA_REOS;
  361         }
  362         if (h->eos & XEOS) {
  363                 upd7210_wr(u, EOSR, h->eos & 0xff);
  364                 i |= AUXA_XEOS;
  365         }
  366         if (h->eos & BIN)
  367                 i |= AUXA_BIN;
  368         upd7210_wr(u, AUXRA, C_AUXA | i);
  369 }
  370 
  371 /*
  372  * Look up the handle, and set the deadline if the handle has a timeout.
  373  */
  374 static int
  375 gethandle(struct upd7210 *u, struct ibarg *ap, struct handle **hp)
  376 {
  377         struct ibfoo *ib;
  378         struct handle *h;
  379 
  380         KASSERT(ap->__field & __F_HANDLE, ("gethandle without __F_HANDLE"));
  381         ib = u->ibfoo;
  382         LIST_FOREACH(h, &ib->handles, list) {
  383                 if (h->handle == ap->handle) {
  384                         *hp = h;
  385                         return (0);
  386                 }
  387         }
  388         ib_set_error(ap, EARG);
  389         return (1);
  390 }
  391 
  392 static int
  393 pio_cmd(struct upd7210 *u, u_char *cmd, int len)
  394 {
  395         struct ibfoo *ib;
  396 
  397         ib = u->ibfoo;
  398 
  399         if (ib->rdh != NULL || ib->wrh != NULL) {
  400                 upd7210_take_ctrl_async(u);
  401                 ib->rdh = NULL;
  402                 ib->wrh = NULL;
  403         }
  404         mtx_lock(&u->mutex);
  405         ib->buf = cmd;
  406         ib->buflen = len;
  407         if (u->use_fifo) {
  408                 /* TNT5004 or TNT4882 in FIFO mode */
  409                 ib->mode = FIFO_CMD;
  410                 upd7210_wr(u, AUXMR, 0x51);             /* holdoff immediately */
  411                 bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */
  412                 bus_write_1(u->reg_res[0], cfg, 0x80); /* CMD, xfer OUT, 8-bit FIFO */
  413                 bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */
  414                 bus_write_1(u->reg_res[0], cnt0, -len);
  415                 bus_write_1(u->reg_res[0], cnt1, (-len) >> 8);
  416                 bus_write_1(u->reg_res[0], cnt2, (-len) >> 16);
  417                 bus_write_1(u->reg_res[0], cnt3, (-len) >> 24);
  418                 bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
  419         } else {
  420                 ib->mode = PIO_CMD;
  421                 upd7210_wr(u, IMR2, IXR2_CO);
  422                 gpib_ib_irq(u, 0);
  423         }
  424 
  425         gpib_ib_wait_xfer(u, ib);
  426 
  427         if (u->use_fifo)
  428                 bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */
  429 
  430         mtx_unlock(&u->mutex);
  431         return (len - ib->buflen);
  432 }
  433 
  434 static int
  435 pio_odata(struct upd7210 *u, u_char *data, int len)
  436 {
  437         struct ibfoo *ib;
  438 
  439         ib = u->ibfoo;
  440 
  441         if (len == 0)
  442                 return (0);
  443         mtx_lock(&u->mutex);
  444         ib->buf = data;
  445         ib->buflen = len;
  446         if (u->use_fifo) {
  447                 /* TNT5004 or TNT4882 in FIFO mode */
  448                 ib->mode = FIFO_ODATA;
  449                 bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */
  450                 if (ib->doeoi)
  451                         bus_write_1(u->reg_res[0], cfg, 0x08); /* CCEN */
  452                 else
  453                         bus_write_1(u->reg_res[0], cfg, 0x00); /* xfer OUT, 8-bit FIFO */
  454                 bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */
  455                 bus_write_1(u->reg_res[0], cnt0, -len);
  456                 bus_write_1(u->reg_res[0], cnt1, (-len) >> 8);
  457                 bus_write_1(u->reg_res[0], cnt2, (-len) >> 16);
  458                 bus_write_1(u->reg_res[0], cnt3, (-len) >> 24);
  459                 bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
  460         } else {
  461                 ib->mode = PIO_ODATA;
  462                 upd7210_wr(u, IMR1, IXR1_DO);
  463         }
  464 
  465         gpib_ib_wait_xfer(u, ib);
  466 
  467         if (u->use_fifo)
  468                 bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */
  469 
  470         mtx_unlock(&u->mutex);
  471         return (len - ib->buflen);
  472 }
  473 
  474 static int
  475 pio_idata(struct upd7210 *u, u_char *data, int len)
  476 {
  477         struct ibfoo *ib;
  478 
  479         ib = u->ibfoo;
  480 
  481         mtx_lock(&u->mutex);
  482         ib->buf = data;
  483         ib->buflen = len;
  484         if (u->use_fifo) {
  485                 /* TNT5004 or TNT4882 in FIFO mode */
  486                 ib->mode = FIFO_IDATA;
  487                 bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */
  488                 bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */
  489                 bus_write_1(u->reg_res[0], cnt0, -len);
  490                 bus_write_1(u->reg_res[0], cnt1, (-len) >> 8);
  491                 bus_write_1(u->reg_res[0], cnt2, (-len) >> 16);
  492                 bus_write_1(u->reg_res[0], cnt3, (-len) >> 24);
  493                 bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
  494                 upd7210_wr(u, AUXMR, AUXMR_RFD);
  495                 bus_write_1(u->reg_res[0], imr3, 0x15); /* STOP IE, NEF IE, DONE IE */
  496         } else {
  497                 ib->mode = PIO_IDATA;
  498                 upd7210_wr(u, IMR1, IXR1_DI);
  499         }
  500 
  501         gpib_ib_wait_xfer(u, ib);
  502 
  503         if (u->use_fifo)
  504                 bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */
  505 
  506         mtx_unlock(&u->mutex);
  507         return (len - ib->buflen);
  508 }
  509 
  510 static int
  511 dma_idata(struct upd7210 *u, u_char *data, int len)
  512 {
  513         int j;
  514         struct ibfoo *ib;
  515 
  516         KASSERT(u->dmachan >= 0, ("Bogus dmachan %d", u->dmachan));
  517         ib = u->ibfoo;
  518         ib->mode = DMA_IDATA;
  519         mtx_lock(&Giant);
  520         isa_dmastart(ISADMA_READ, data, len, u->dmachan);
  521         mtx_unlock(&Giant);
  522         mtx_lock(&u->mutex);
  523         upd7210_wr(u, IMR1, IXR1_ENDRX);
  524         upd7210_wr(u, IMR2, IMR2_DMAI);
  525         gpib_ib_wait_xfer(u, ib);
  526         mtx_unlock(&u->mutex);
  527         mtx_lock(&Giant);
  528         j = isa_dmastatus(u->dmachan);
  529         isa_dmadone(ISADMA_READ, data, len, u->dmachan);
  530         mtx_unlock(&Giant);
  531         return (len - j);
  532 }
  533 
  534 static int
  535 ib_send_msg(struct ibfoo *ib, int msg)
  536 {
  537         u_char buf[10];
  538         int i, j;
  539 
  540         i = 0;
  541         buf[i++] = UNT;
  542         buf[i++] = UNL;
  543         buf[i++] = LAD | ib->h->pad;
  544         if (ib->h->sad)
  545                 buf[i++] = LAD | TAD | ib->h->sad;
  546         buf[i++] = TAD | 0;
  547         buf[i++] = msg;
  548         j = pio_cmd(ib->u, buf, i);
  549         if (i != j)
  550                 ib_set_error(ib->ap, EABO); /* XXX ? */
  551         return (0);
  552 }
  553 
  554 static int
  555 ibask(struct ibfoo *ib)
  556 {       /* XXX */
  557 
  558         ibdebug = ib->ap->option;
  559         return (0);
  560 }
  561 
  562 #define ibbna NULL
  563 #define ibcac NULL
  564 
  565 static int
  566 ibclr(struct ibfoo *ib)
  567 {
  568 
  569         return (ib_send_msg(ib, SDC));
  570 }
  571 
  572 #define ibcmd NULL
  573 #define ibcmda NULL
  574 #define ibconfig NULL
  575 
  576 static int
  577 ibdev(struct ibfoo *ib)
  578 {       /* TBD */
  579         struct handle *h;
  580 
  581         h = malloc(sizeof *h, M_IBFOO, M_ZERO | M_WAITOK);
  582         h->handle = alloc_unr(ib->unrhdr);
  583         h->kind = H_DEV;
  584         h->pad = ib->ap->pad;
  585         h->sad = ib->ap->sad;
  586         h->timeout = timeouts[ib->ap->tmo];
  587         h->eot = ib->ap->eot;
  588         h->eos = ib->ap->eos;
  589         mtx_lock(&ib->u->mutex);
  590         LIST_INSERT_HEAD(&ib->handles, h, list);
  591         mtx_unlock(&ib->u->mutex);
  592         ib->ap->__retval = h->handle;
  593         return (0);
  594 }
  595 
  596 #define ibdiag NULL
  597 
  598 static int
  599 ibdma(struct ibfoo *ib)
  600 {
  601 
  602         if (ib->u->dmachan < 0 && ib->ap->v)
  603                 return (ib_set_error(ib->ap, EARG));
  604         ib->h->dma = ib->ap->v;
  605         return (0);
  606 }
  607 
  608 static int
  609 ibeos(struct ibfoo *ib)
  610 {
  611 
  612         ib->ap->__iberr = ib->h->eos;
  613         ib->h->eos = ib->ap->eos;
  614         if (ib->rdh == ib->h)
  615                 config_eos(ib->u, ib->h);
  616         return (0);
  617 }
  618 
  619 static int
  620 ibeot(struct ibfoo *ib)
  621 {
  622 
  623         ib->h->eot = ib->ap->eot;
  624         return (0);
  625 }
  626 
  627 #define ibevent NULL
  628 #define ibfind NULL
  629 #define ibgts NULL
  630 #define ibist NULL
  631 #define iblines NULL
  632 #define ibllo NULL
  633 #define ibln NULL
  634 
  635 static int
  636 ibloc(struct ibfoo *ib)
  637 {       /* XXX */
  638 
  639         if (ib->h->kind == H_BOARD)
  640                 return (EOPNOTSUPP); /* XXX */
  641         return (ib_send_msg(ib, GTL));
  642 }
  643 
  644 static int
  645 ibonl(struct ibfoo *ib)
  646 {       /* XXX */
  647 
  648         if (ib->ap->v)
  649                 return (EOPNOTSUPP);    /* XXX */
  650         mtx_lock(&ib->u->mutex);
  651         LIST_REMOVE(ib->h, list);
  652         mtx_unlock(&ib->u->mutex);
  653         free(ib->h, M_IBFOO);
  654         ib->h = NULL;
  655         return (0);
  656 }
  657 
  658 static int
  659 ibpad(struct ibfoo *ib)
  660 {
  661 
  662         ib->h->pad = ib->ap->pad;
  663         return (0);
  664 }
  665 
  666 #define ibpct NULL
  667 #define ibpoke NULL
  668 #define ibppc NULL
  669 
  670 static int
  671 ibrd(struct ibfoo *ib)
  672 {       /* TBD */
  673         u_char buf[10], *bp;
  674         int i, j, error, bl, bc;
  675         u_char *dp;
  676 
  677         if (ib->h->kind == H_BOARD)
  678                 return (EOPNOTSUPP); /* XXX */
  679         bl = ib->ap->cnt;
  680         if (bl > PAGE_SIZE)
  681                 bl = PAGE_SIZE;
  682         bp = malloc(bl, M_IBFOO, M_WAITOK);
  683 
  684         if (ib->rdh != ib->h) {
  685                 i = 0;
  686                 buf[i++] = UNT;
  687                 buf[i++] = UNL;
  688                 buf[i++] = LAD | 0;
  689                 buf[i++] = TAD | ib->h->pad;
  690                 if (ib->h->sad)
  691                         buf[i++] = ib->h->sad;
  692                 i = pio_cmd(ib->u, buf, i);
  693                 config_eos(ib->u, ib->h);
  694                 ib->rdh = ib->h;
  695                 ib->wrh = NULL;
  696         }
  697         upd7210_goto_standby(ib->u);
  698         dp = ib->ap->buffer;
  699         bc = ib->ap->cnt;
  700         error = 0;
  701         while (bc > 0 && ib->ap->__iberr == 0) {
  702                 j = imin(bc, PAGE_SIZE);
  703                 if (ib->h->dma)
  704                         i = dma_idata(ib->u, bp, j);
  705                 else
  706                         i = pio_idata(ib->u, bp, j);
  707                 error = copyout(bp, dp , i);
  708                 if (error)
  709                         break;
  710                 ib->ap->__ibcnt += i;
  711                 if (i != j)
  712                         break;
  713                 bc -= i;
  714                 dp += i;
  715         }
  716         upd7210_take_ctrl_async(ib->u);
  717         free(bp, M_IBFOO);
  718         return (error);
  719 }
  720 
  721 #define ibrda NULL
  722 #define ibrdf NULL
  723 #define ibrdkey NULL
  724 #define ibrpp NULL
  725 #define ibrsc NULL
  726 #define ibrsp NULL
  727 #define ibrsv NULL
  728 
  729 static int
  730 ibsad(struct ibfoo *ib)
  731 {
  732 
  733         ib->h->sad = ib->ap->sad;
  734         return (0);
  735 }
  736 
  737 #define ibsgnl NULL
  738 
  739 static int
  740 ibsic(struct ibfoo *ib)
  741 {       /* TBD */
  742 
  743         upd7210_wr(ib->u, AUXMR, AUXMR_SIFC);
  744         DELAY(100);
  745         upd7210_wr(ib->u, AUXMR, AUXMR_CIFC);
  746         return (0);
  747 }
  748 
  749 #define ibsre NULL
  750 #define ibsrq NULL
  751 #define ibstop NULL
  752 
  753 static int
  754 ibtmo(struct ibfoo *ib)
  755 {
  756 
  757         ib->h->timeout = timeouts[ib->ap->tmo];
  758         return (0);
  759 }
  760 
  761 #define ibtrap NULL
  762 
  763 static int
  764 ibtrg(struct ibfoo *ib)
  765 {
  766 
  767         return (ib_send_msg(ib, GET));
  768 }
  769 
  770 #define ibwait NULL
  771 
  772 static int
  773 ibwrt(struct ibfoo *ib)
  774 {       /* XXX */
  775         u_char buf[10], *bp;
  776         int i;
  777 
  778         if (ib->h->kind == H_BOARD)
  779                 return (EOPNOTSUPP);
  780         bp = malloc(ib->ap->cnt, M_IBFOO, M_WAITOK);
  781         /* XXX: bigger than PAGE_SIZE handling */
  782         i = copyin(ib->ap->buffer, bp, ib->ap->cnt);
  783         if (i) {
  784                 free(bp, M_IBFOO);
  785                 return (i);
  786         }
  787         if (ib->wrh != ib->h) {
  788                 i = 0;
  789                 buf[i++] = UNT;
  790                 buf[i++] = UNL;
  791                 buf[i++] = LAD | ib->h->pad;
  792                 if (ib->h->sad)
  793                         buf[i++] = LAD | TAD | ib->h->sad;
  794                 buf[i++] = TAD | 0;
  795                 i = pio_cmd(ib->u, buf, i);
  796                 ib->rdh = NULL;
  797                 ib->wrh = ib->h;
  798                 config_eos(ib->u, ib->h);
  799         }
  800         upd7210_goto_standby(ib->u);
  801         ib->doeoi = ib->h->eot;
  802         i = pio_odata(ib->u, bp, ib->ap->cnt);
  803         upd7210_take_ctrl_async(ib->u);
  804         ib->ap->__ibcnt = i;
  805         free(bp, M_IBFOO);
  806         return (0);
  807 }
  808 
  809 #define ibwrta NULL
  810 #define ibwrtf NULL
  811 #define ibwrtkey NULL
  812 #define ibxtrc NULL
  813 
  814 static struct ibhandler {
  815         const char      *name;
  816         enum h_kind     kind;
  817         ibhandler_t     *func;
  818         u_int           args;
  819 } ibhandlers[] = {
  820         [__ID_IBASK] =          { "ibask",      H_EITHER,       ibask,          __F_HANDLE | __F_OPTION | __F_RETVAL },
  821         [__ID_IBBNA] =          { "ibbna",      H_DEV,          ibbna,          __F_HANDLE | __F_BDNAME },
  822         [__ID_IBCAC] =          { "ibcac",      H_BOARD,        ibcac,          __F_HANDLE | __F_V },
  823         [__ID_IBCLR] =          { "ibclr",      H_DEV,          ibclr,          __F_HANDLE },
  824         [__ID_IBCMD] =          { "ibcmd",      H_BOARD,        ibcmd,          __F_HANDLE | __F_BUFFER | __F_CNT },
  825         [__ID_IBCMDA] =         { "ibcmda",     H_BOARD,        ibcmda,         __F_HANDLE | __F_BUFFER | __F_CNT },
  826         [__ID_IBCONFIG] =       { "ibconfig",   H_EITHER,       ibconfig,       __F_HANDLE | __F_OPTION | __F_VALUE },
  827         [__ID_IBDEV] =          { "ibdev",      0,              ibdev,          __F_BOARDID | __F_PAD | __F_SAD | __F_TMO | __F_EOT | __F_EOS },
  828         [__ID_IBDIAG] =         { "ibdiag",     H_EITHER,       ibdiag,         __F_HANDLE | __F_BUFFER | __F_CNT },
  829         [__ID_IBDMA] =          { "ibdma",      H_EITHER,       ibdma,          __F_HANDLE | __F_V },
  830         [__ID_IBEOS] =          { "ibeos",      H_EITHER,       ibeos,          __F_HANDLE | __F_EOS },
  831         [__ID_IBEOT] =          { "ibeot",      H_EITHER,       ibeot,          __F_HANDLE | __F_EOT },
  832         [__ID_IBEVENT] =        { "ibevent",    H_BOARD,        ibevent,        __F_HANDLE | __F_EVENT },
  833         [__ID_IBFIND] =         { "ibfind",     0,              ibfind,         __F_BDNAME },
  834         [__ID_IBGTS] =          { "ibgts",      H_BOARD,        ibgts,          __F_HANDLE | __F_V },
  835         [__ID_IBIST] =          { "ibist",      H_BOARD,        ibist,          __F_HANDLE | __F_V },
  836         [__ID_IBLINES] =        { "iblines",    H_BOARD,        iblines,        __F_HANDLE | __F_LINES },
  837         [__ID_IBLLO] =          { "ibllo",      H_EITHER,       ibllo,          __F_HANDLE },
  838         [__ID_IBLN] =           { "ibln",       H_BOARD,        ibln,           __F_HANDLE | __F_PADVAL | __F_SADVAL | __F_LISTENFLAG },
  839         [__ID_IBLOC] =          { "ibloc",      H_EITHER,       ibloc,          __F_HANDLE },
  840         [__ID_IBONL] =          { "ibonl",      H_EITHER,       ibonl,          __F_HANDLE | __F_V },
  841         [__ID_IBPAD] =          { "ibpad",      H_EITHER,       ibpad,          __F_HANDLE | __F_PAD },
  842         [__ID_IBPCT] =          { "ibpct",      H_DEV,          ibpct,          __F_HANDLE },
  843         [__ID_IBPOKE] =         { "ibpoke",     H_EITHER,       ibpoke,         __F_HANDLE | __F_OPTION | __F_VALUE },
  844         [__ID_IBPPC] =          { "ibppc",      H_EITHER,       ibppc,          __F_HANDLE | __F_V },
  845         [__ID_IBRD] =           { "ibrd",       H_EITHER,       ibrd,           __F_HANDLE | __F_BUFFER | __F_CNT },
  846         [__ID_IBRDA] =          { "ibrda",      H_EITHER,       ibrda,          __F_HANDLE | __F_BUFFER | __F_CNT },
  847         [__ID_IBRDF] =          { "ibrdf",      H_EITHER,       ibrdf,          __F_HANDLE | __F_FLNAME },
  848         [__ID_IBRDKEY] =        { "ibrdkey",    H_EITHER,       ibrdkey,        __F_HANDLE | __F_BUFFER | __F_CNT },
  849         [__ID_IBRPP] =          { "ibrpp",      H_EITHER,       ibrpp,          __F_HANDLE | __F_PPR },
  850         [__ID_IBRSC] =          { "ibrsc",      H_BOARD,        ibrsc,          __F_HANDLE | __F_V },
  851         [__ID_IBRSP] =          { "ibrsp",      H_DEV,          ibrsp,          __F_HANDLE | __F_SPR },
  852         [__ID_IBRSV] =          { "ibrsv",      H_EITHER,       ibrsv,          __F_HANDLE | __F_V },
  853         [__ID_IBSAD] =          { "ibsad",      H_EITHER,       ibsad,          __F_HANDLE | __F_SAD },
  854         [__ID_IBSGNL] =         { "ibsgnl",     H_EITHER,       ibsgnl,         __F_HANDLE | __F_V },
  855         [__ID_IBSIC] =          { "ibsic",      H_BOARD,        ibsic,          __F_HANDLE },
  856         [__ID_IBSRE] =          { "ibsre",      H_BOARD,        ibsre,          __F_HANDLE | __F_V },
  857         [__ID_IBSRQ] =          { "ibsrq",      H_EITHER,       ibsrq,          __F_FUNC },
  858         [__ID_IBSTOP] =         { "ibstop",     H_EITHER,       ibstop,         __F_HANDLE },
  859         [__ID_IBTMO] =          { "ibtmo",      H_EITHER,       ibtmo,          __F_HANDLE | __F_TMO },
  860         [__ID_IBTRAP] =         { "ibtrap",     H_EITHER,       ibtrap,         __F_MASK | __F_MODE },
  861         [__ID_IBTRG] =          { "ibtrg",      H_DEV,          ibtrg,          __F_HANDLE },
  862         [__ID_IBWAIT] =         { "ibwait",     H_EITHER,       ibwait,         __F_HANDLE | __F_MASK },
  863         [__ID_IBWRT] =          { "ibwrt",      H_EITHER,       ibwrt,          __F_HANDLE | __F_BUFFER | __F_CNT },
  864         [__ID_IBWRTA] =         { "ibwrta",     H_EITHER,       ibwrta,         __F_HANDLE | __F_BUFFER | __F_CNT },
  865         [__ID_IBWRTF] =         { "ibwrtf",     H_EITHER,       ibwrtf,         __F_HANDLE | __F_FLNAME },
  866         [__ID_IBWRTKEY] =       { "ibwrtkey",   H_EITHER,       ibwrtkey,       __F_HANDLE | __F_BUFFER | __F_CNT },
  867         [__ID_IBXTRC] =         { "ibxtrc",     H_EITHER,       ibxtrc,         __F_HANDLE | __F_BUFFER | __F_CNT },
  868 };
  869 
  870 static const u_int max_ibhandler = sizeof ibhandlers / sizeof ibhandlers[0];
  871 
  872 static void
  873 ib_dump_args(struct ibhandler *ih, struct ibarg *ap)
  874 {
  875 
  876         if (ih->name != NULL)
  877                 printf("%s(", ih->name);
  878         else
  879                 printf("ibinvalid(");
  880         printf("[0x%x]", ap->__field);
  881         if (ap->__field & __F_HANDLE)   printf(" handle=%d", ap->handle);
  882         if (ap->__field & __F_EOS)      printf(" eos=0x%x", ap->eos);
  883         if (ap->__field & __F_EOT)      printf(" eot=%d", ap->eot);
  884         if (ap->__field & __F_TMO)      printf(" tmo=%d", ap->tmo);
  885         if (ap->__field & __F_PAD)      printf(" pad=0x%x", ap->pad);
  886         if (ap->__field & __F_SAD)      printf(" sad=0x%x", ap->sad);
  887         if (ap->__field & __F_BUFFER)   printf(" buffer=%p", ap->buffer);
  888         if (ap->__field & __F_CNT)      printf(" cnt=%ld", ap->cnt);
  889         if (ap->__field & __F_V)        printf(" v=%d/0x%x", ap->v, ap->v);
  890         /* XXX more ... */
  891         printf(")\n");
  892 }
  893 
  894 static int
  895 gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
  896 {
  897         struct upd7210 *u;
  898         struct ibfoo *ib;
  899         int error = 0;
  900 
  901         u = dev->si_drv1;
  902 
  903         mtx_lock(&u->mutex);
  904         if (u->busy) {
  905                 mtx_unlock(&u->mutex);
  906                 return (EBUSY);
  907         }
  908         u->busy = 1;
  909         mtx_unlock(&u->mutex);
  910 
  911         if (u->dmachan >= 0) {
  912                 mtx_lock(&Giant);
  913                 error = isa_dma_acquire(u->dmachan);
  914                 if (!error) {
  915                         error = isa_dma_init(u->dmachan, PAGE_SIZE, M_WAITOK);
  916                         if (error)
  917                                 isa_dma_release(u->dmachan);
  918                 }
  919                 mtx_unlock(&Giant);
  920         }
  921 
  922         if (error) {
  923                 mtx_lock(&u->mutex);
  924                 u->busy = 0;
  925                 mtx_unlock(&u->mutex);
  926                 return (error);
  927         }
  928 
  929         ib = malloc(sizeof *ib, M_IBFOO, M_WAITOK | M_ZERO);
  930         LIST_INIT(&ib->handles);
  931         callout_init(&ib->callout, CALLOUT_MPSAFE);
  932         ib->unrhdr = new_unrhdr(0, INT_MAX, NULL);
  933         dev->si_drv2 = ib;
  934         ib->u = u;
  935         u->ibfoo = ib;
  936         u->irq = gpib_ib_irq;
  937 
  938         upd7210_wr(u, AUXMR, AUXMR_CRST);
  939         DELAY(10000);
  940         DELAY(1000);
  941         upd7210_wr(u, IMR1, 0x00);
  942         upd7210_wr(u, IMR2, 0x00);
  943         upd7210_wr(u, SPMR, 0x00);
  944         upd7210_wr(u, ADR, 0x00);
  945         upd7210_wr(u, ADR, ADR_ARS | ADR_DL | ADR_DT);
  946         upd7210_wr(u, ADMR, ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1);
  947         upd7210_wr(u, EOSR, 0x00);
  948         upd7210_wr(u, AUXMR, C_ICR | 8);
  949         upd7210_wr(u, AUXMR, C_PPR | PPR_U);
  950         upd7210_wr(u, AUXMR, C_AUXA);
  951         upd7210_wr(u, AUXMR, C_AUXB + 3);
  952         upd7210_wr(u, AUXMR, C_AUXE + 0);
  953         upd7210_wr(u, AUXMR, AUXMR_PON);
  954         if (u->use_fifo) {
  955                 bus_write_1(u->reg_res[0], imr3, 0x00);
  956                 bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft reset */
  957                 bus_write_1(u->reg_res[0], cmdr, 0x03); /* set system
  958                                                          * controller bit */
  959         }
  960         upd7210_wr(u, AUXMR, AUXMR_CIFC);
  961         DELAY(100);
  962         upd7210_wr(u, AUXMR, AUXMR_SIFC);
  963         upd7210_wr(u, AUXMR, AUXMR_SREN);
  964         return (0);
  965 }
  966 
  967 static int
  968 gpib_ib_close(struct cdev *dev, int oflags, int devtype, struct thread *td)
  969 {
  970         struct upd7210 *u;
  971         struct ibfoo *ib;
  972 
  973         u = dev->si_drv1;
  974         ib = dev->si_drv2;
  975         /* XXX: assert pointer consistency */
  976 
  977         u->ibfoo = NULL;
  978         /* XXX: free handles */
  979         dev->si_drv2 = NULL;
  980         free(ib, M_IBFOO);
  981 
  982         if (u->dmachan >= 0) {
  983                 mtx_lock(&Giant);
  984                 isa_dma_release(u->dmachan);
  985                 mtx_unlock(&Giant);
  986         }
  987         mtx_lock(&u->mutex);
  988         u->busy = 0;
  989         ibdebug = 0;
  990         upd7210_wr(u, IMR1, 0x00);
  991         upd7210_wr(u, IMR2, 0x00);
  992         if (u->use_fifo) {
  993                 bus_write_1(u->reg_res[0], imr3, 0x00);
  994                 bus_write_1(u->reg_res[0], cmdr, 0x02); /* clear system
  995                                                          * controller bit */
  996         }
  997         upd7210_wr(u, AUXMR, AUXMR_CRST);
  998         DELAY(10000);
  999         mtx_unlock(&u->mutex);
 1000         return (0);
 1001 }
 1002 
 1003 static int
 1004 gpib_ib_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
 1005 {
 1006         struct ibarg *ap;
 1007         struct ibhandler *ih;
 1008         struct handle *h;
 1009         struct upd7210 *u;
 1010         struct ibfoo *ib;
 1011         int error;
 1012         struct timeval deadline, tv;
 1013 
 1014         u = dev->si_drv1;
 1015         ib = u->ibfoo;
 1016 
 1017         /* We only support a single ioctl, everything else is a mistake */
 1018         if (cmd != GPIB_IBFOO)
 1019                 return (ENOIOCTL);
 1020 
 1021         /* Check the identifier and field-bitmap in the arguments.  */
 1022         ap = (void *)data;
 1023         if (ap->__ident < 0 || ap->__ident >= max_ibhandler)
 1024                 return (EINVAL);
 1025         ih = &ibhandlers[ap->__ident];
 1026         if (ap->__field != ih->args)
 1027                 return (EINVAL);
 1028 
 1029         if (ibdebug)
 1030                 ib_dump_args(ih, ap);
 1031 
 1032         if (ih->func == NULL)
 1033                 return (EOPNOTSUPP);
 1034 
 1035         ap->__iberr = 0;
 1036         ap->__ibsta = 0;
 1037         ap->__ibcnt = 0;
 1038         ap->__retval = 0;
 1039 
 1040         if (ap->__field & __F_TMO) {
 1041                 if (ap->tmo < 0 || ap->tmo >= max_timeouts)
 1042                         return (ib_set_error(ap, EARG));
 1043         }
 1044 
 1045         if (ap->__field & __F_EOS) {
 1046                 if ((ap->eos & ~(REOS | XEOS | BIN | 0xff)) ||
 1047                     ((ap->eos & (BIN | 0x80)) == 0x80))
 1048                         return (ib_set_error(ap, EARG));
 1049         }
 1050         if (ap->__field & __F_PAD) {
 1051                 if (ap->pad < 0 || ap->pad > 30)
 1052                         return (ib_set_error(ap, EARG));
 1053         }
 1054         if (ap->__field & __F_SAD) {
 1055                 if (ap->sad != 0 && (ap->sad < 0x60 || ap->sad > 126))
 1056                         return (ib_set_error(ap, EARG));
 1057         }
 1058         
 1059 
 1060         mtx_lock(&u->mutex);
 1061 
 1062         
 1063         /* Find the handle, if any */
 1064         h = NULL;
 1065         if ((ap->__field & __F_HANDLE) && gethandle(u, ap, &h)) {
 1066                 mtx_unlock(&u->mutex);
 1067                 return (0);
 1068         }
 1069 
 1070         /* Check that the handle is the right kind */
 1071         if (h != NULL && !(h->kind & ih->kind)) {
 1072                 mtx_unlock(&u->mutex);
 1073                 return (ib_set_error(ap, EARG));
 1074         }
 1075 
 1076         /* Set up handle and deadline */
 1077         if (h != NULL && timevalisset(&h->timeout)) {
 1078                 getmicrouptime(&deadline);
 1079                 timevaladd(&deadline, &h->timeout);
 1080         } else {
 1081                 timevalclear(&deadline);
 1082         }
 1083 
 1084         /* Wait for the card to be(come) available, respect deadline */
 1085         while(u->busy != 1) {
 1086                 error = msleep(ib, &u->mutex,
 1087                     PZERO | PCATCH, "gpib_ibioctl", hz / 10);
 1088                 if (error == 0)
 1089                         continue;
 1090                 mtx_unlock(&u->mutex);
 1091                 if (error == EINTR)
 1092                         return(ib_set_error(ap, EABO));
 1093                 if (error == EWOULDBLOCK && timevalisset(&deadline)) {
 1094                         getmicrouptime(&tv);
 1095                         if (timevalcmp(&deadline, &tv, <))
 1096                                 return(ib_had_timeout(ap));
 1097                 }
 1098                 mtx_lock(&u->mutex);
 1099         }
 1100         u->busy = 2;
 1101         mtx_unlock(&u->mutex);
 1102 
 1103         /* Hand over deadline handling to the callout routine */
 1104         ib->ap = ap;
 1105         ib->h = h;
 1106         ib->mode = BUSY;
 1107         ib->deadline = deadline;
 1108         callout_reset(&ib->callout, hz / 5, gpib_ib_timeout, u);
 1109 
 1110         error = ih->func(ib);
 1111 
 1112         /* Release card */
 1113         ib->mode = IDLE;
 1114         ib->ap = NULL;
 1115         ib->h = NULL;
 1116         timevalclear(&deadline);
 1117         callout_stop(&ib->callout);
 1118 
 1119         mtx_lock(&u->mutex);
 1120         u->busy = 1;
 1121         wakeup(ib);
 1122         mtx_unlock(&u->mutex);
 1123 
 1124         if (error) 
 1125                 return(ib_set_errno(ap, error));
 1126         return (0);
 1127 }
 1128 
 1129 struct cdevsw gpib_ib_cdevsw = {
 1130         .d_version =    D_VERSION,
 1131         .d_name =       "gpib_ib",
 1132         .d_open =       gpib_ib_open,
 1133         .d_ioctl =      gpib_ib_ioctl,
 1134         .d_close =      gpib_ib_close,
 1135 };

Cache object: 9228da17b2a4e2ff3d4487727f93afae


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