comedi_device *dev = (comedi_device *) d;
comedi_subdevice *s;
comedi_async *async;
+ unsigned runflags;
if (cmd->subdev >= dev->n_subdevices)
return -ENODEV;
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);
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) {
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);
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;
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;
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) */
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;
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;
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;