diff options
author | phk <phk@FreeBSD.org> | 2005-02-12 21:07:09 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2005-02-12 21:07:09 +0000 |
commit | 2bebe00e4309269f720ee56533cd77256cb7673d (patch) | |
tree | 47713eba086151828434a42e5e99ca85ad1ff2ae /sys/dev/ieee488 | |
parent | 26eab3d80642690062d224dd48aa6b92e41f59f2 (diff) | |
download | FreeBSD-src-2bebe00e4309269f720ee56533cd77256cb7673d.zip FreeBSD-src-2bebe00e4309269f720ee56533cd77256cb7673d.tar.gz |
Add ibcntl as alias for ibcnt
Add ibsta and start to use it.
Rename the argument structure more sensibly.
Improve timeout and error handling
Diffstat (limited to 'sys/dev/ieee488')
-rw-r--r-- | sys/dev/ieee488/ibfoo.c | 509 | ||||
-rw-r--r-- | sys/dev/ieee488/ibfoo_int.h | 6 | ||||
-rw-r--r-- | sys/dev/ieee488/ugpib.h | 2 |
3 files changed, 274 insertions, 243 deletions
diff --git a/sys/dev/ieee488/ibfoo.c b/sys/dev/ieee488/ibfoo.c index a2bd1c5..958b117 100644 --- a/sys/dev/ieee488/ibfoo.c +++ b/sys/dev/ieee488/ibfoo.c @@ -73,16 +73,20 @@ struct handle { }; struct ibfoo { - struct upd7210 *upd7210; + struct upd7210 *u; LIST_HEAD(,handle) handles; struct unrhdr *unrhdr; + struct callout callout; + struct handle *h; + struct ibarg *ap; enum { IDLE, + BUSY, PIO_IDATA, - DMA_IDATA, PIO_ODATA, - PIO_CMD + PIO_CMD, + DMA_IDATA } mode; struct timeval deadline; @@ -96,6 +100,8 @@ struct ibfoo { u_int buflen; }; +typedef int ibhandler_t(struct ibfoo *ib); + static struct timeval timeouts[] = { [TNONE] = { 0, 0}, [T10us] = { 0, 10}, @@ -119,24 +125,41 @@ static struct timeval timeouts[] = { static const u_int max_timeouts = sizeof timeouts / sizeof timeouts[0]; +static int ibdebug; + static int -deadyet(struct ibfoo *ib) +ib_set_error(struct ibarg *ap, int error) { - struct timeval tv; - if (!timevalisset(&ib->deadline)) - return (0); + if (ap->__iberr == 0) + ap->__iberr = error; + ap->__ibsta |= ERR; + ap->__retval = ap->__ibsta; + return (0); +} - getmicrouptime(&tv); - if (timevalcmp(&ib->deadline, &tv, <)) { -printf("DEADNOW\n"); - return (1); - } +static int +ib_had_timeout(struct ibarg *ap) +{ + ib_set_error(ap, EABO); + ap->__ibsta |= TIMO; + ap->__retval = ap->__ibsta; return (0); } -typedef int ibhandler_t(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap); +static int +ib_set_errno(struct ibarg *ap, int errno) +{ + + if (ap->__iberr == 0) { + ap->__iberr = EDVR; + ap->__ibcnt = errno; + } + ap->__ibsta |= ERR; + ap->__retval = ap->__ibsta; + return (0); +} static int gpib_ib_irq(struct upd7210 *u, int intr __unused) @@ -145,6 +168,7 @@ gpib_ib_irq(struct upd7210 *u, int intr __unused) ib = u->ibfoo; + mtx_assert(&u->mutex, MA_OWNED); switch (ib->mode) { case PIO_CMD: if (!(u->rreg[ISR2] & IXR2_CO)) @@ -184,12 +208,72 @@ gpib_ib_irq(struct upd7210 *u, int intr __unused) } upd7210_wr(u, IMR1, 0); upd7210_wr(u, IMR2, 0); - ib->mode = IDLE; - wakeup(ib); + ib->mode = BUSY; + wakeup(&ib->buflen); return (1); } static void +gpib_ib_timeout(void *arg) +{ + struct upd7210 *u; + struct ibfoo *ib; + struct timeval tv; + + u = arg; + ib = u->ibfoo; + mtx_lock(&u->mutex); + if (ib->mode == DMA_IDATA && isa_dmatc(u->dmachan)) { + upd7210_wr(u, IMR1, 0); + upd7210_wr(u, IMR2, 0); + ib->mode = IDLE; + wakeup(&ib->buflen); + } + if (ib->mode > BUSY) { + upd7210_rd(u, ISR1); + upd7210_rd(u, ISR2); + gpib_ib_irq(u, 2); + } + if (ib->mode != IDLE && timevalisset(&ib->deadline)) { + getmicrouptime(&tv); + if (timevalcmp(&ib->deadline, &tv, <)) { + ib_had_timeout(ib->ap); + upd7210_wr(u, IMR1, 0); + upd7210_wr(u, IMR2, 0); + ib->mode = BUSY; + wakeup(&ib->buflen); + } + } + if (ib->mode != IDLE) + callout_reset(&ib->callout, hz / 100, gpib_ib_timeout, arg); + mtx_unlock(&u->mutex); +} + +static void +gpib_ib_wait_xfer(struct upd7210 *u, struct ibfoo *ib) +{ + int i; + + mtx_assert(&u->mutex, MA_OWNED); + while (ib->mode > BUSY) { + i = msleep(&ib->buflen, &u->mutex, + PZERO | PCATCH, "ibwxfr", 0); + if (i == EINTR) { + ib_set_errno(ib->ap, i); + break; + } + if (u->rreg[ISR1] & IXR1_ERR) { + ib_set_error(ib->ap, EABO); /* XXX ? */ + break; + } + } + ib->mode = BUSY; + ib->buf = NULL; + upd7210_wr(u, IMR1, 0); + upd7210_wr(u, IMR2, 0); +} + +static void config_eos(struct upd7210 *u, struct handle *h) { int i; @@ -212,7 +296,7 @@ config_eos(struct upd7210 *u, struct handle *h) * Look up the handle, and set the deadline if the handle has a timeout. */ static int -gethandle(struct upd7210 *u, struct ibfoo_iocarg *ap, struct handle **hp) +gethandle(struct upd7210 *u, struct ibarg *ap, struct handle **hp) { struct ibfoo *ib; struct handle *h; @@ -222,23 +306,16 @@ gethandle(struct upd7210 *u, struct ibfoo_iocarg *ap, struct handle **hp) LIST_FOREACH(h, &ib->handles, list) { if (h->handle == ap->handle) { *hp = h; - if (timevalisset(&h->timeout)) { - getmicrouptime(&ib->deadline); - timevaladd(&ib->deadline, &h->timeout); - } else { - timevalclear(&ib->deadline); - } return (0); } } - ap->__iberr = EARG; + ib_set_error(ap, EARG); return (1); } static int pio_cmd(struct upd7210 *u, u_char *cmd, int len) { - int i; struct ibfoo *ib; ib = u->ibfoo; @@ -256,26 +333,15 @@ pio_cmd(struct upd7210 *u, u_char *cmd, int len) gpib_ib_irq(u, 1); - while (1) { - i = msleep(ib, &u->mutex, PZERO | PCATCH, "gpib_cmd", hz/10); - if (i == EINTR) - break; - if (u->rreg[ISR1] & IXR1_ERR) - break; - if (!ib->buflen) - break; - if (deadyet(ib)) - break; - } - upd7210_wr(u, IMR2, 0); + gpib_ib_wait_xfer(u, ib); + mtx_unlock(&u->mutex); - return (0); + return (len - ib->buflen); } static int pio_odata(struct upd7210 *u, u_char *data, int len) { - int i; struct ibfoo *ib; ib = u->ibfoo; @@ -290,20 +356,8 @@ pio_odata(struct upd7210 *u, u_char *data, int len) gpib_ib_irq(u, 1); - while (1) { - i = msleep(ib, &u->mutex, PZERO | PCATCH, "gpib_out", hz/100); - if (i == EINTR || i == 0) - break; -#if 0 - if (u->rreg[ISR1] & IXR1_ERR) - break; -#endif - if (deadyet(ib)) - break; - } - ib->mode = IDLE; - upd7210_wr(u, IMR1, 0); - upd7210_wr(u, IMR2, 0); + gpib_ib_wait_xfer(u, ib); + mtx_unlock(&u->mutex); return (len - ib->buflen); } @@ -311,7 +365,6 @@ pio_odata(struct upd7210 *u, u_char *data, int len) static int pio_idata(struct upd7210 *u, u_char *data, int len) { - int i; struct ibfoo *ib; ib = u->ibfoo; @@ -321,70 +374,34 @@ pio_idata(struct upd7210 *u, u_char *data, int len) ib->buf = data; ib->buflen = len; upd7210_wr(u, IMR1, IXR1_DI); - while (1) { - i = msleep(ib, &u->mutex, PZERO | PCATCH, - "ib_pioidata", hz/100); - if (i == EINTR || i == 0) - break; - if (deadyet(u->ibfoo)) - break; - } - ib->mode = IDLE; - upd7210_wr(u, IMR1, 0); - upd7210_wr(u, IMR2, 0); + + gpib_ib_wait_xfer(u, ib); + mtx_unlock(&u->mutex); - if (deadyet(u->ibfoo)) { - return (-1); - } else { - return (len - ib->buflen); - } + return (len - ib->buflen); } static int dma_idata(struct upd7210 *u, u_char *data, int len) { - int i1, i2, i, j; + int j; struct ibfoo *ib; ib = u->ibfoo; ib->mode = DMA_IDATA; - upd7210_wr(u, IMR1, IXR1_ENDRX); mtx_lock(&Giant); isa_dmastart(ISADMA_READ, data, len, u->dmachan); mtx_unlock(&Giant); mtx_lock(&u->mutex); + upd7210_wr(u, IMR1, IXR1_ENDRX); upd7210_wr(u, IMR2, IMR2_DMAI); - while (1) { - i = msleep(ib, &u->mutex, PZERO | PCATCH, - "gpib_idata", hz/100); - if (i == EINTR) - break; - if (isa_dmatc(u->dmachan)) - break; - if (i == EWOULDBLOCK) { - i1 = upd7210_rd(u, ISR1); - i2 = upd7210_rd(u, ISR2); - } else { - i1 = u->rreg[ISR1]; - i2 = u->rreg[ISR2]; - } - if (i1 & IXR1_ENDRX) - break; - if (deadyet(ib)) - break; - } - upd7210_wr(u, IMR1, 0); - upd7210_wr(u, IMR2, 0); + gpib_ib_wait_xfer(u, ib); mtx_unlock(&u->mutex); mtx_lock(&Giant); j = isa_dmastatus(u->dmachan); isa_dmadone(ISADMA_READ, data, len, u->dmachan); mtx_unlock(&Giant); - if (deadyet(ib)) { - return (-1); - } else { - return (len - j); - } + return (len - j); } #define ibask NULL @@ -396,63 +413,49 @@ dma_idata(struct upd7210 *u, u_char *data, int len) #define ibconfig NULL static int -ibdev(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) +ibdev(struct ibfoo *ib) { - struct ibfoo *ib; + struct handle *h; - if (ap->pad < 0 || - ap->pad > 30 || - (ap->sad != 0 && ap->sad < 0x60) || - ap->sad > 126) { - ap->__retval = -1; - ap->__iberr = EARG; - return (0); - } - - ib = u->ibfoo; h = malloc(sizeof *h, M_IBFOO, M_ZERO | M_WAITOK); h->handle = alloc_unr(ib->unrhdr); + h->pad = ib->ap->pad; + h->sad = ib->ap->sad; + h->timeout = timeouts[ib->ap->tmo]; + h->eot = ib->ap->eot; + h->eos = ib->ap->eos; + mtx_lock(&ib->u->mutex); LIST_INSERT_HEAD(&ib->handles, h, list); - h->pad = ap->pad; - h->sad = ap->sad; - h->timeout = timeouts[ap->tmo]; - h->eot = ap->eot; - h->eos = ap->eos; - ap->__retval = h->handle; + mtx_unlock(&ib->u->mutex); + ib->ap->__retval = h->handle; return (0); } #define ibdiag NULL static int -ibdma(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) +ibdma(struct ibfoo *ib) { - h->dma = ap->v; + ib->h->dma = ib->ap->v; return (0); } static int -ibeos(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) +ibeos(struct ibfoo *ib) { - struct ibfoo *ib; - ib = u->ibfoo; - h->eos = ap->eos; - if (ib->rdh == h) - config_eos(u, h); - ap->__retval = 0; + ib->h->eos = ib->ap->eos; + if (ib->rdh == ib->h) + config_eos(ib->u, ib->h); return (0); } static int -ibeot(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) +ibeot(struct ibfoo *ib) { - struct ibfoo *ib; - ib = u->ibfoo; - - h->eot = ap->eot; + ib->h->eot = ib->ap->eot; return (0); } @@ -471,56 +474,52 @@ ibeot(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) #define ibppc NULL static int -ibrd(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) +ibrd(struct ibfoo *ib) { - struct ibfoo *ib; u_char buf[10], *bp; int i, j, error, bl, bc; u_char *dp; - ib = u->ibfoo; - bl = ap->cnt; + bl = ib->ap->cnt; if (bl > PAGE_SIZE) bl = PAGE_SIZE; bp = malloc(bl, M_IBFOO, M_WAITOK); - if (ib->rdh != h) { + if (ib->rdh != ib->h) { i = 0; buf[i++] = UNT; buf[i++] = UNL; buf[i++] = LAD | 0; - buf[i++] = TAD | h->pad; - if (h->sad) - buf[i++] = h->sad; - i = pio_cmd(u, buf, i); - config_eos(u, h); - ib->rdh = h; + buf[i++] = TAD | ib->h->pad; + if (ib->h->sad) + buf[i++] = ib->h->sad; + i = pio_cmd(ib->u, buf, i); + config_eos(ib->u, ib->h); + ib->rdh = ib->h; ib->wrh = NULL; - upd7210_goto_standby(u); + upd7210_goto_standby(ib->u); } - ap->__ibcnt = 0; - dp = ap->buffer; - bc = ap->cnt; + dp = ib->ap->buffer; + bc = ib->ap->cnt; error = 0; - while (bc > 0) { + while (bc > 0 && ib->ap->__iberr == 0) { j = imin(bc, PAGE_SIZE); - if (h->dma) - i = dma_idata(u, bp, j); + if (ib->h->dma) + i = dma_idata(ib->u, bp, j); else - i = pio_idata(u, bp, j); + i = pio_idata(ib->u, bp, j); if (i <= 0) break; error = copyout(bp, dp , i); if (error) break; - ap->__ibcnt += i; + ib->ap->__ibcnt += i; if (i != j) break; bc -= i; dp += i; } free(bp, M_IBFOO); - ap->__retval = 0; return (error); } @@ -539,10 +538,10 @@ ibrd(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) #define ibstop NULL static int -ibtmo(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) +ibtmo(struct ibfoo *ib) { - h->timeout = timeouts[ap->tmo]; + ib->h->timeout = timeouts[ib->ap->tmo]; return (0); } @@ -551,37 +550,35 @@ ibtmo(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) #define ibwait NULL static int -ibwrt(struct handle *h, struct upd7210 *u, struct ibfoo_iocarg *ap) +ibwrt(struct ibfoo *ib) { - struct ibfoo *ib; u_char buf[10], *bp; int i; - ib = u->ibfoo; - bp = malloc(ap->cnt, M_IBFOO, M_WAITOK); - i = copyin(ap->buffer, bp, ap->cnt); + bp = malloc(ib->ap->cnt, M_IBFOO, M_WAITOK); + /* XXX: bigger than PAGE_SIZE handling */ + i = copyin(ib->ap->buffer, bp, ib->ap->cnt); if (i) { free(bp, M_IBFOO); return (i); } - if (ib->wrh != h) { + if (ib->wrh != ib->h) { i = 0; buf[i++] = UNT; buf[i++] = UNL; - buf[i++] = LAD | h->pad; - if (h->sad) - buf[i++] = LAD | TAD | h->sad; + buf[i++] = LAD | ib->h->pad; + if (ib->h->sad) + buf[i++] = LAD | TAD | ib->h->sad; buf[i++] = TAD | 0; - i = pio_cmd(u, buf, i); + i = pio_cmd(ib->u, buf, i); ib->rdh = NULL; - ib->wrh = h; - upd7210_goto_standby(u); - config_eos(u, h); + ib->wrh = ib->h; + upd7210_goto_standby(ib->u); + config_eos(ib->u, ib->h); } - ib->doeoi = h->eot; - i = pio_odata(u, bp, ap->cnt); - ap->__ibcnt = i; - ap->__retval = 0; + ib->doeoi = ib->h->eot; + i = pio_odata(ib->u, bp, ib->ap->cnt); + ib->ap->__ibcnt = i; free(bp, M_IBFOO); return (0); } @@ -646,7 +643,28 @@ static struct ibhandler { [__ID_IBXTRC] = { "ibxtrc", ibxtrc, __F_HANDLE | __F_BUFFER | __F_CNT }, }; -static u_int max_ibhandler = sizeof ibhandlers / sizeof ibhandlers[0]; +static const u_int max_ibhandler = sizeof ibhandlers / sizeof ibhandlers[0]; + +static void +ib_dump_args(struct ibhandler *ih, struct ibarg *ap) +{ + + if (ih->name != NULL) + printf("%s(", ih->name); + else + printf("ibinvalid("); + printf("[0x%x]", ap->__field); + if (ap->__field & __F_HANDLE) printf(" handle=%d", ap->handle); + if (ap->__field & __F_EOS) printf(" eos=%d", ap->eos); + if (ap->__field & __F_EOT) printf(" eot=%d", ap->eot); + if (ap->__field & __F_TMO) printf(" tmo=%d", ap->tmo); + if (ap->__field & __F_PAD) printf(" pad=%d", ap->pad); + if (ap->__field & __F_SAD) printf(" sad=%d", ap->sad); + if (ap->__field & __F_BUFFER) printf(" buffer=%p", ap->buffer); + if (ap->__field & __F_CNT) printf(" cnt=%ld", ap->cnt); + /* XXX more ... */ + printf(")\n"); +} static int gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td) @@ -682,9 +700,10 @@ gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td) ib = malloc(sizeof *ib, M_IBFOO, M_WAITOK | M_ZERO); LIST_INIT(&ib->handles); + callout_init(&ib->callout, 1); ib->unrhdr = new_unrhdr(0, INT_MAX); dev->si_drv2 = ib; - ib->upd7210 = u; + ib->u = u; u->ibfoo = ib; u->irq = gpib_ib_irq; @@ -742,17 +761,22 @@ gpib_ib_close(struct cdev *dev, int oflags, int devtype, struct thread *td) static int gpib_ib_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { - struct ibfoo_iocarg *ap; + struct ibarg *ap; struct ibhandler *ih; struct handle *h; struct upd7210 *u; + struct ibfoo *ib; int error; + struct timeval deadline, tv; u = dev->si_drv1; + ib = u->ibfoo; + /* We only support a single ioctl, everything else is a mistake */ if (cmd != GPIB_IBFOO) return (ENOIOCTL); + /* Check the identifier and field-bitmap in the arguments. */ ap = (void *)data; if (ap->__ident < 0 || ap->__ident >= max_ibhandler) return (EINVAL); @@ -760,91 +784,98 @@ gpib_ib_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thre if (ap->__field != ih->args) return (EINVAL); + if (ibdebug) + ib_dump_args(ih, ap); + + if (ih->func == NULL) + return (EOPNOTSUPP); + + ap->__iberr = 0; + ap->__ibsta = 0; + ap->__ibcnt = 0; + ap->retval = 0; + if (ap->__field & __F_TMO) { - if (ap->tmo < 0 || ap->tmo >= max_timeouts) { - ap->__retval = -1; - ap->__iberr = EARG; - return (0); - } + if (ap->tmo < 0 || ap->tmo >= max_timeouts) + return (ib_set_error(ap, EARG)); } if (ap->__field & __F_EOS) { - if (ap->eos & ~(REOS | XEOS | BIN | 0xff)) { - ap->__retval = -1; - ap->__iberr = EARG; - return (0); - } - if (ap->eos & (REOS | XEOS)) { - if ((ap->eos & (BIN | 0x80)) == 0x80) { - ap->__retval = -1; - ap->__iberr = EARG; - return (0); - } - } else if (ap->eos != 0) { - ap->__retval = -1; - ap->__iberr = EARG; - return (0); - } + if ((ap->eos & ~(REOS | XEOS | BIN | 0xff)) || + ((ap->eos & (BIN | 0x80)) == 0x80)) + return (ib_set_error(ap, EARG)); + } + if (ap->__field & __F_PAD) { + if (ap->pad < 0 || ap->pad > 30) + return (ib_set_error(ap, EARG)); + } + if (ap->__field & __F_SAD) { + if (ap->sad != 0 && (ap->sad < 0x60 || ap->sad > 126)) + return (ib_set_error(ap, EARG)); } + mtx_lock(&u->mutex); + + + /* Find the handle, if any */ + h = NULL; + if ((ap->__field & __F_HANDLE) && gethandle(u, ap, &h)) { + mtx_unlock(&u->mutex); + return (0); + } + + /* Set up handle and deadline */ + if (h != NULL && timevalisset(&h->timeout)) { + getmicrouptime(&deadline); + timevaladd(&deadline, &h->timeout); + } else { + timevalclear(&deadline); + } + + /* Wait for the card to be(come) available, respect deadline */ while(u->busy != 1) { - error = msleep(u->ibfoo, &u->mutex, PZERO | PCATCH, - "gpib_ibioctl", 0); - if (error) { - mtx_unlock(&u->mutex); - return (EINTR); + error = msleep(ib, &u->mutex, + PZERO | PCATCH, "gpib_ibioctl", hz / 10); + if (error == 0) + continue; + mtx_unlock(&u->mutex); + if (error == EINTR) + return(ib_set_error(ap, EABO)); + if (error == EWOULDBLOCK && timevalisset(&deadline)) { + getmicrouptime(&tv); + if (timevalcmp(&deadline, &tv, <)) + return(ib_had_timeout(ap)); } + mtx_lock(&u->mutex); } u->busy = 2; mtx_unlock(&u->mutex); -#ifdef IBDEBUG - if (ih->name != NULL) - printf("%s(", ih->name); - else - printf("ibinvalid("); - printf("[0x%x]", ap->__field); - if (ap->__field & __F_HANDLE) printf(" handle=%d", ap->handle); - if (ap->__field & __F_EOS) printf(" eos=%d", ap->eos); - if (ap->__field & __F_EOT) printf(" eot=%d", ap->eot); - if (ap->__field & __F_TMO) printf(" tmo=%d", ap->tmo); - if (ap->__field & __F_PAD) printf(" pad=%d", ap->pad); - if (ap->__field & __F_SAD) printf(" sad=%d", ap->sad); - if (ap->__field & __F_BUFFER) printf(" buffer=%p", ap->buffer); - if (ap->__field & __F_CNT) printf(" cnt=%ld", ap->cnt); - /* XXX more ... */ - printf(")\n"); -#endif + /* Hand over deadline handling to the callout routine */ + ib->ap = ap; + ib->h = h; + ib->mode = BUSY; + ib->deadline = deadline; + callout_reset(&ib->callout, hz / 100, gpib_ib_timeout, u); - if (ap->__field & __F_HANDLE) { - if (gethandle(u, ap, &h)) { - error = 0; /* XXX iberr */ - goto bail; - } - } else - h = NULL; - ap->__iberr = 0; - error = EOPNOTSUPP; - if (ih->func != NULL) - error = ih->func(h, u, ap); - if (error) { - ap->__retval = EDVR; - ap->__iberr = EDVR; - ap->__ibcnt = error; - } else if (ap->__iberr) { - ap->__retval = -1; - } -#ifdef IBDEBUG - printf("%s(...) = %d (error=%d)\n", ih->name, ap->__retval, error); -#endif + error = ih->func(ib); + + /* Release card */ + ib->mode = IDLE; + ib->ap = NULL; + ib->h = NULL; + timevalclear(&deadline); + callout_stop(&ib->callout); -bail: mtx_lock(&u->mutex); u->busy = 1; - wakeup(u->ibfoo); + wakeup(ib); mtx_unlock(&u->mutex); - return (error); + + if (error) + return(ib_set_errno(ap, error)); + return (0); } struct cdevsw gpib_ib_cdevsw = { diff --git a/sys/dev/ieee488/ibfoo_int.h b/sys/dev/ieee488/ibfoo_int.h index 845bb7f..28f7289 100644 --- a/sys/dev/ieee488/ibfoo_int.h +++ b/sys/dev/ieee488/ibfoo_int.h @@ -110,11 +110,11 @@ enum ibfoo_id { #define __F_LISTENFLAG (1 << 23) #define __F_EVENT (1 << 24) -struct ibfoo_iocarg { +struct ibarg { enum ibfoo_id __ident; unsigned int __field; int __retval; - int __ibsts; + int __ibsta; int __iberr; int __ibcnt; int handle; @@ -144,4 +144,4 @@ struct ibfoo_iocarg { short * event; }; -#define GPIB_IBFOO _IOWR(4, 0, struct ibfoo_iocarg) +#define GPIB_IBFOO _IOWR(4, 0, struct ibarg) diff --git a/sys/dev/ieee488/ugpib.h b/sys/dev/ieee488/ugpib.h index 2452207..1604041 100644 --- a/sys/dev/ieee488/ugpib.h +++ b/sys/dev/ieee488/ugpib.h @@ -98,7 +98,7 @@ #ifndef _KERNEL -extern int ibcnt, iberr; +extern int ibcnt, iberr, ibsta; int ibask(int handle, int option, int *retval); int ibbna(int handle, char *bdname); |