Commit 3781bc54 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Staging: comedi: kcomedilib: simplify comedi_do_insn()

Now that we know we are only making 2 different types of instructions,
only handle those two types.

Also make the call a bit more typesafe by passing the correct pointer
type.

Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Frank Mori Hess <fmhess@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 88cccef0
......@@ -80,127 +80,53 @@ int comedi_close(void *d)
}
EXPORT_SYMBOL(comedi_close);
/*
* COMEDI_INSN
* perform an instruction
*/
static int comedi_do_insn(void *d, struct comedi_insn *insn)
static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn)
{
struct comedi_device *dev = (struct comedi_device *)d;
struct comedi_subdevice *s;
int ret = 0;
if (insn->insn & INSN_MASK_SPECIAL) {
switch (insn->insn) {
case INSN_GTOD:
{
struct timeval tv;
do_gettimeofday(&tv);
insn->data[0] = tv.tv_sec;
insn->data[1] = tv.tv_usec;
ret = 2;
break;
}
case INSN_WAIT:
/* XXX isn't the value supposed to be nanosecs? */
if (insn->n != 1 || insn->data[0] >= 100) {
ret = -EINVAL;
break;
}
udelay(insn->data[0]);
ret = 1;
break;
case INSN_INTTRIG:
if (insn->n != 1) {
ret = -EINVAL;
break;
}
if (insn->subdev >= dev->n_subdevices) {
printk("%d not usable subdevice\n",
insn->subdev);
ret = -EINVAL;
break;
}
s = dev->subdevices + insn->subdev;
if (!s->async) {
printk("no async\n");
ret = -EINVAL;
break;
}
if (!s->async->inttrig) {
printk("no inttrig\n");
ret = -EAGAIN;
break;
}
ret = s->async->inttrig(dev, s, insn->data[0]);
if (ret >= 0)
ret = 1;
break;
default:
ret = -EINVAL;
}
} else {
/* a subdevice instruction */
if (insn->subdev >= dev->n_subdevices) {
ret = -EINVAL;
goto error;
}
s = dev->subdevices + insn->subdev;
if (s->type == COMEDI_SUBD_UNUSED) {
printk("%d not useable subdevice\n", insn->subdev);
ret = -EIO;
goto error;
}
/* XXX check lock */
ret = comedi_check_chanlist(s, 1, &insn->chanspec);
if (ret < 0) {
printk("bad chanspec\n");
ret = -EINVAL;
goto error;
}
if (s->busy) {
ret = -EBUSY;
goto error;
}
s->busy = d;
switch (insn->insn) {
case INSN_READ:
ret = s->insn_read(dev, s, insn, insn->data);
break;
case INSN_WRITE:
ret = s->insn_write(dev, s, insn, insn->data);
break;
case INSN_BITS:
ret = s->insn_bits(dev, s, insn, insn->data);
break;
case INSN_CONFIG:
/* XXX should check instruction length */
ret = s->insn_config(dev, s, insn, insn->data);
break;
default:
ret = -EINVAL;
break;
}
s->busy = NULL;
/* a subdevice instruction */
if (insn->subdev >= dev->n_subdevices) {
ret = -EINVAL;
goto error;
}
if (ret < 0)
s = dev->subdevices + insn->subdev;
if (s->type == COMEDI_SUBD_UNUSED) {
printk("%d not useable subdevice\n", insn->subdev);
ret = -EIO;
goto error;
#if 0
/* XXX do we want this? -- abbotti #if'ed it out for now. */
if (ret != insn->n) {
printk("BUG: result of insn != insn.n\n");
}
/* XXX check lock */
ret = comedi_check_chanlist(s, 1, &insn->chanspec);
if (ret < 0) {
printk("bad chanspec\n");
ret = -EINVAL;
goto error;
}
#endif
if (s->busy) {
ret = -EBUSY;
goto error;
}
s->busy = dev;
switch (insn->insn) {
case INSN_BITS:
ret = s->insn_bits(dev, s, insn, insn->data);
break;
case INSN_CONFIG:
/* XXX should check instruction length */
ret = s->insn_config(dev, s, insn, insn->data);
break;
default:
ret = -EINVAL;
break;
}
s->busy = NULL;
error:
return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment