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

Cache object: f08b3800e61ee73b16d028648410549e


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