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: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
88cccef019
Коммит
3781bc5425
|
@ -80,127 +80,53 @@ int comedi_close(void *d)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(comedi_close);
|
EXPORT_SYMBOL(comedi_close);
|
||||||
|
|
||||||
/*
|
static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn)
|
||||||
* COMEDI_INSN
|
|
||||||
* perform an instruction
|
|
||||||
*/
|
|
||||||
static int comedi_do_insn(void *d, struct comedi_insn *insn)
|
|
||||||
{
|
{
|
||||||
struct comedi_device *dev = (struct comedi_device *)d;
|
|
||||||
struct comedi_subdevice *s;
|
struct comedi_subdevice *s;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (insn->insn & INSN_MASK_SPECIAL) {
|
/* a subdevice instruction */
|
||||||
switch (insn->insn) {
|
if (insn->subdev >= dev->n_subdevices) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (ret < 0)
|
|
||||||
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");
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#endif
|
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 = 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:
|
error:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче