From b249bb68039708908f2443a4b9a09c16e33996bc Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 5 Dec 2007 14:45:49 +0000 Subject: [PATCH] Check for various errors such as subdevice in range and support for commands. Use comedi_set_subdevice_runflags and comedi_get_subdevice_runflags when checking/modifying SRF_RT runflag. --- comedi/kcomedilib/kcomedilib_main.c | 72 +++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/comedi/kcomedilib/kcomedilib_main.c b/comedi/kcomedilib/kcomedilib_main.c index c68e64cf..f2b0330b 100644 --- a/comedi/kcomedilib/kcomedilib_main.c +++ b/comedi/kcomedilib/kcomedilib_main.c @@ -118,6 +118,7 @@ int comedi_command(comedi_t * d, comedi_cmd * cmd) comedi_device *dev = (comedi_device *) d; comedi_subdevice *s; comedi_async *async; + unsigned runflags; if (cmd->subdev >= dev->n_subdevices) return -ENODEV; @@ -139,9 +140,13 @@ int comedi_command(comedi_t * d, comedi_cmd * cmd) async->cmd = *cmd; - s->runflags |= SRF_RT; - comedi_switch_to_rt(dev); - comedi_set_subdevice_runflags(s, SRF_RUNNING, SRF_RUNNING); + runflags = SRF_RUNNING; + +#ifdef CONFIG_COMEDI_RT + if (comedi_switch_to_rt(dev) == 0) + runflags |= SRF_RT; +#endif + comedi_set_subdevice_runflags(s, ~0, runflags); comedi_reset_async_buf(async); @@ -308,10 +313,15 @@ int comedi_do_insn(comedi_t * d, comedi_insn * insn) int comedi_lock(comedi_t * d, unsigned int subdevice) { comedi_device *dev = (comedi_device *) d; - comedi_subdevice *s = dev->subdevices + subdevice; + comedi_subdevice *s; unsigned long flags; int ret = 0; + if (subdevice >= dev->n_subdevices) { + return -EINVAL; + } + s = dev->subdevices + subdevice; + comedi_spin_lock_irqsave(&s->spin_lock, flags); if (s->busy) { @@ -346,11 +356,16 @@ int comedi_lock(comedi_t * d, unsigned int subdevice) int comedi_unlock(comedi_t * d, unsigned int subdevice) { comedi_device *dev = (comedi_device *) d; - comedi_subdevice *s = dev->subdevices + subdevice; + comedi_subdevice *s; unsigned long flags; comedi_async *async; int ret; + if (subdevice >= dev->n_subdevices) { + return -EINVAL; + } + s = dev->subdevices + subdevice; + async = s->async; comedi_spin_lock_irqsave(&s->spin_lock, flags); @@ -393,9 +408,14 @@ int comedi_unlock(comedi_t * d, unsigned int subdevice) int comedi_cancel(comedi_t * d, unsigned int subdevice) { comedi_device *dev = (comedi_device *) d; - comedi_subdevice *s = dev->subdevices + subdevice; + comedi_subdevice *s; int ret = 0; + if (subdevice >= dev->n_subdevices) { + return -EINVAL; + } + s = dev->subdevices + subdevice; + if (s->lock && s->lock != d) return -EACCES; @@ -407,17 +427,19 @@ int comedi_cancel(comedi_t * d, unsigned int subdevice) return -EBUSY; #endif - if (!s->cancel) + if (!s->cancel || !s->async) return -EINVAL; if ((ret = s->cancel(dev, s))) return ret; - if (s->runflags & SRF_RT) { - // XXX race - s->runflags &= ~SRF_RT; +#ifdef CONFIG_COMEDI_RT + if (comedi_get_subdevice_runflags(s) & SRF_RT) { comedi_switch_to_non_rt(dev); } +#endif + comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0); + s->async->inttrig = NULL; s->busy = NULL; return 0; @@ -430,11 +452,16 @@ int comedi_register_callback(comedi_t * d, unsigned int subdevice, unsigned int mask, int (*cb) (unsigned int, void *), void *arg) { comedi_device *dev = (comedi_device *) d; - comedi_subdevice *s = dev->subdevices + subdevice; + comedi_subdevice *s; comedi_async *async; + if (subdevice >= dev->n_subdevices) { + return -EINVAL; + } + s = dev->subdevices + subdevice; + async = s->async; - if (s->type == COMEDI_SUBD_UNUSED) + if (s->type == COMEDI_SUBD_UNUSED || !async) return -EIO; /* are we locked? (ioctl lock) */ @@ -461,9 +488,14 @@ int comedi_register_callback(comedi_t * d, unsigned int subdevice, int comedi_poll(comedi_t * d, unsigned int subdevice) { comedi_device *dev = (comedi_device *) d; - comedi_subdevice *s = dev->subdevices + subdevice; + comedi_subdevice *s = dev->subdevices; comedi_async *async; + if (subdevice >= dev->n_subdevices) { + return -EINVAL; + } + s = dev->subdevices + subdevice; + async = s->async; if (s->type == COMEDI_SUBD_UNUSED || !async) return -EIO; @@ -483,7 +515,12 @@ int comedi_poll(comedi_t * d, unsigned int subdevice) int comedi_map(comedi_t * d, unsigned int subdevice, void *ptr) { comedi_device *dev = (comedi_device *) d; - comedi_subdevice *s = dev->subdevices + subdevice; + comedi_subdevice *s; + + if (subdevice >= dev->n_subdevices) { + return -EINVAL; + } + s = dev->subdevices + subdevice; if (!s->async) return -EINVAL; @@ -501,7 +538,12 @@ int comedi_map(comedi_t * d, unsigned int subdevice, void *ptr) int comedi_unmap(comedi_t * d, unsigned int subdevice) { comedi_device *dev = (comedi_device *) d; - comedi_subdevice *s = dev->subdevices + subdevice; + comedi_subdevice *s; + + if (subdevice >= dev->n_subdevices) { + return -EINVAL; + } + s = dev->subdevices + subdevice; if (!s->async) return -EINVAL; -- 2.26.2