summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2005-02-12 21:07:09 +0000
committerphk <phk@FreeBSD.org>2005-02-12 21:07:09 +0000
commit2bebe00e4309269f720ee56533cd77256cb7673d (patch)
tree47713eba086151828434a42e5e99ca85ad1ff2ae
parent26eab3d80642690062d224dd48aa6b92e41f59f2 (diff)
downloadFreeBSD-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
-rw-r--r--lib/libgpib/gpib.h2
-rw-r--r--lib/libgpib/ibfoo.c101
-rw-r--r--sys/dev/ieee488/ibfoo.c509
-rw-r--r--sys/dev/ieee488/ibfoo_int.h6
-rw-r--r--sys/dev/ieee488/ugpib.h2
5 files changed, 327 insertions, 293 deletions
diff --git a/lib/libgpib/gpib.h b/lib/libgpib/gpib.h
index db6e0de..d3144b5 100644
--- a/lib/libgpib/gpib.h
+++ b/lib/libgpib/gpib.h
@@ -29,3 +29,5 @@
*/
#include <dev/ieee488/ugpib.h>
+
+#define ibcntl ibcnt
diff --git a/lib/libgpib/ibfoo.c b/lib/libgpib/ibfoo.c
index 4fda2d8..0ac2a0d 100644
--- a/lib/libgpib/ibfoo.c
+++ b/lib/libgpib/ibfoo.c
@@ -37,12 +37,12 @@
#include <dev/ieee488/ugpib.h>
#include <dev/ieee488/ibfoo_int.h>
-int ibcnt, iberr;
+int ibcnt, iberr, ibsta;
static int fd = -1;
static int
-__ibsubmit(struct ibfoo_iocarg *ap)
+__ibsubmit(struct ibarg *ap)
{
int i;
@@ -55,13 +55,14 @@ __ibsubmit(struct ibfoo_iocarg *ap)
err(1, "GPIB_IBFOO(%d, 0x%x) failed", ap->__ident, ap->__field);
ibcnt = ap->__ibcnt;
iberr = ap->__iberr;
+ ibsta = ap->__ibsta;
return (ap->__retval);
}
int
ibask (int handle, int option, int * retval)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBASK;
io.handle = handle;
@@ -74,7 +75,7 @@ ibask (int handle, int option, int * retval)
int
ibbna (int handle, char * bdname)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBBNA;
io.handle = handle;
@@ -86,7 +87,7 @@ ibbna (int handle, char * bdname)
int
ibcac (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBCAC;
io.handle = handle;
@@ -98,7 +99,7 @@ ibcac (int handle, int v)
int
ibclr (int handle)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBCLR;
io.handle = handle;
@@ -109,7 +110,7 @@ ibclr (int handle)
int
ibcmd (int handle, void * buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBCMD;
io.handle = handle;
@@ -122,7 +123,7 @@ ibcmd (int handle, void * buffer, long cnt)
int
ibcmda (int handle, void * buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBCMDA;
io.handle = handle;
@@ -135,7 +136,7 @@ ibcmda (int handle, void * buffer, long cnt)
int
ibconfig (int handle, int option, int value)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBCONFIG;
io.handle = handle;
@@ -148,7 +149,7 @@ ibconfig (int handle, int option, int value)
int
ibdev (int boardID, int pad, int sad, int tmo, int eot, int eos)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBDEV;
io.boardID = boardID;
@@ -164,7 +165,7 @@ ibdev (int boardID, int pad, int sad, int tmo, int eot, int eos)
int
ibdiag (int handle, void * buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBDIAG;
io.handle = handle;
@@ -177,7 +178,7 @@ ibdiag (int handle, void * buffer, long cnt)
int
ibdma (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBDMA;
io.handle = handle;
@@ -189,7 +190,7 @@ ibdma (int handle, int v)
int
ibeos (int handle, int eos)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBEOS;
io.handle = handle;
@@ -201,7 +202,7 @@ ibeos (int handle, int eos)
int
ibeot (int handle, int eot)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBEOT;
io.handle = handle;
@@ -213,7 +214,7 @@ ibeot (int handle, int eot)
int
ibevent (int handle, short * event)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBEVENT;
io.handle = handle;
@@ -225,7 +226,7 @@ ibevent (int handle, short * event)
int
ibfind (char * bdname)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBFIND;
io.bdname = bdname;
@@ -236,7 +237,7 @@ ibfind (char * bdname)
int
ibgts (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBGTS;
io.handle = handle;
@@ -248,7 +249,7 @@ ibgts (int handle, int v)
int
ibist (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBIST;
io.handle = handle;
@@ -260,7 +261,7 @@ ibist (int handle, int v)
int
iblines (int handle, short * lines)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBLINES;
io.handle = handle;
@@ -272,7 +273,7 @@ iblines (int handle, short * lines)
int
ibllo (int handle)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBLLO;
io.handle = handle;
@@ -283,7 +284,7 @@ ibllo (int handle)
int
ibln (int handle, int padval, int sadval, short * listenflag)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBLN;
io.handle = handle;
@@ -297,7 +298,7 @@ ibln (int handle, int padval, int sadval, short * listenflag)
int
ibloc (int handle)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBLOC;
io.handle = handle;
@@ -308,7 +309,7 @@ ibloc (int handle)
int
ibonl (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBONL;
io.handle = handle;
@@ -320,7 +321,7 @@ ibonl (int handle, int v)
int
ibpad (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBPAD;
io.handle = handle;
@@ -332,7 +333,7 @@ ibpad (int handle, int v)
int
ibpct (int handle)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBPCT;
io.handle = handle;
@@ -343,7 +344,7 @@ ibpct (int handle)
int
ibpoke (int handle, int option, int value)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBPOKE;
io.handle = handle;
@@ -356,7 +357,7 @@ ibpoke (int handle, int option, int value)
int
ibppc (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBPPC;
io.handle = handle;
@@ -368,7 +369,7 @@ ibppc (int handle, int v)
int
ibrd (int handle, void * buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRD;
io.handle = handle;
@@ -381,7 +382,7 @@ ibrd (int handle, void * buffer, long cnt)
int
ibrda (int handle, void * buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRDA;
io.handle = handle;
@@ -394,7 +395,7 @@ ibrda (int handle, void * buffer, long cnt)
int
ibrdf (int handle, char * flname)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRDF;
io.handle = handle;
@@ -406,7 +407,7 @@ ibrdf (int handle, char * flname)
int
ibrdkey (int handle, void * buffer, int cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRDKEY;
io.handle = handle;
@@ -419,7 +420,7 @@ ibrdkey (int handle, void * buffer, int cnt)
int
ibrpp (int handle, char * ppr)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRPP;
io.handle = handle;
@@ -431,7 +432,7 @@ ibrpp (int handle, char * ppr)
int
ibrsc (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRSC;
io.handle = handle;
@@ -443,7 +444,7 @@ ibrsc (int handle, int v)
int
ibrsp (int handle, char * spr)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRSP;
io.handle = handle;
@@ -455,7 +456,7 @@ ibrsp (int handle, char * spr)
int
ibrsv (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBRSV;
io.handle = handle;
@@ -467,7 +468,7 @@ ibrsv (int handle, int v)
int
ibsad (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBSAD;
io.handle = handle;
@@ -479,7 +480,7 @@ ibsad (int handle, int v)
int
ibsgnl (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBSGNL;
io.handle = handle;
@@ -491,7 +492,7 @@ ibsgnl (int handle, int v)
int
ibsic (int handle)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBSIC;
io.handle = handle;
@@ -502,7 +503,7 @@ ibsic (int handle)
int
ibsre (int handle, int v)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBSRE;
io.handle = handle;
@@ -514,7 +515,7 @@ ibsre (int handle, int v)
int
ibsrq (ibsrq_t * func)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBSRQ;
io.func = func;
@@ -525,7 +526,7 @@ ibsrq (ibsrq_t * func)
int
ibstop (int handle)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBSTOP;
io.handle = handle;
@@ -536,7 +537,7 @@ ibstop (int handle)
int
ibtmo (int handle, int tmo)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBTMO;
io.handle = handle;
@@ -548,7 +549,7 @@ ibtmo (int handle, int tmo)
int
ibtrap (int mask, int mode)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBTRAP;
io.mask = mask;
@@ -560,7 +561,7 @@ ibtrap (int mask, int mode)
int
ibtrg (int handle)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBTRG;
io.handle = handle;
@@ -571,7 +572,7 @@ ibtrg (int handle)
int
ibwait (int handle, int mask)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBWAIT;
io.handle = handle;
@@ -583,7 +584,7 @@ ibwait (int handle, int mask)
int
ibwrt (int handle, const void *buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBWRT;
io.handle = handle;
@@ -596,7 +597,7 @@ ibwrt (int handle, const void *buffer, long cnt)
int
ibwrta (int handle, const void * buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBWRTA;
io.handle = handle;
@@ -609,7 +610,7 @@ ibwrta (int handle, const void * buffer, long cnt)
int
ibwrtf (int handle, const char *flname)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBWRTF;
io.handle = handle;
@@ -621,7 +622,7 @@ ibwrtf (int handle, const char *flname)
int
ibwrtkey (int handle, const void *buffer, int cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBWRTKEY;
io.handle = handle;
@@ -634,7 +635,7 @@ ibwrtkey (int handle, const void *buffer, int cnt)
int
ibxtrc (int handle, void * buffer, long cnt)
{
- struct ibfoo_iocarg io;
+ struct ibarg io;
io.__ident = __ID_IBXTRC;
io.handle = handle;
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);
OpenPOWER on IntegriCloud