Staging: comedi: pcl818: Tidy up AI command after channel dropout or similar error.
It was causing subsequent commands to fail with -EBUSY. From: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Frank Mori Hess <fmhess@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
a71f18d2a1
commit
e21de1a8e5
@ -820,6 +820,27 @@ static irqreturn_t interrupt_pcl818(int irq, void *d)
|
||||
}
|
||||
/* rt_printk("I\n"); */
|
||||
|
||||
if (devpriv->irq_blocked && devpriv->irq_was_now_closed) {
|
||||
if ((devpriv->neverending_ai || (!devpriv->neverending_ai &&
|
||||
devpriv->ai_act_scan > 0)) &&
|
||||
(devpriv->ai_mode == INT_TYPE_AI1_DMA ||
|
||||
devpriv->ai_mode == INT_TYPE_AI3_DMA)) {
|
||||
/* The cleanup from ai_cancel() has been delayed
|
||||
until now because the card doesn't seem to like
|
||||
being reprogrammed while a DMA transfer is in
|
||||
progress.
|
||||
*/
|
||||
struct comedi_subdevice *s = dev->subdevices + 0;
|
||||
devpriv->ai_act_scan = 0;
|
||||
devpriv->neverending_ai = 0;
|
||||
pcl818_ai_cancel(dev, s);
|
||||
}
|
||||
|
||||
outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
switch (devpriv->ai_mode) {
|
||||
case INT_TYPE_AI1_DMA:
|
||||
case INT_TYPE_AI3_DMA:
|
||||
@ -843,25 +864,6 @@ static irqreturn_t interrupt_pcl818(int irq, void *d)
|
||||
|
||||
if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked)
|
||||
|| (!devpriv->ai_mode)) {
|
||||
if (devpriv->irq_was_now_closed) {
|
||||
if (devpriv->neverending_ai &&
|
||||
(devpriv->ai_mode == INT_TYPE_AI1_DMA
|
||||
|| devpriv->ai_mode ==
|
||||
INT_TYPE_AI3_DMA)) {
|
||||
/* we had neverending ai but ai_cancel() has been called
|
||||
the cleanup from ai_cancel() has been delayed until know
|
||||
because the card doesn't seem to like being reprogrammed
|
||||
while a DMA transfer is in progress
|
||||
*/
|
||||
struct comedi_subdevice *s = dev->subdevices + 0;
|
||||
devpriv->ai_mode = devpriv->irq_was_now_closed;
|
||||
devpriv->irq_was_now_closed = 0;
|
||||
devpriv->neverending_ai = 0;
|
||||
pcl818_ai_cancel(dev, s);
|
||||
}
|
||||
devpriv->irq_was_now_closed = 0;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
comedi_error(dev, "bad IRQ!");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
@ -1453,10 +1455,9 @@ static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice
|
||||
{
|
||||
if (devpriv->irq_blocked > 0) {
|
||||
rt_printk("pcl818_ai_cancel()\n");
|
||||
devpriv->irq_was_now_closed = devpriv->ai_mode;
|
||||
devpriv->ai_mode = 0;
|
||||
devpriv->irq_was_now_closed = 1;
|
||||
|
||||
switch (devpriv->irq_was_now_closed) {
|
||||
switch (devpriv->ai_mode) {
|
||||
#ifdef unused
|
||||
case INT_TYPE_AI1_DMA_RTC:
|
||||
case INT_TYPE_AI3_DMA_RTC:
|
||||
@ -1465,7 +1466,9 @@ static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice
|
||||
#endif
|
||||
case INT_TYPE_AI1_DMA:
|
||||
case INT_TYPE_AI3_DMA:
|
||||
if (devpriv->neverending_ai) {
|
||||
if (devpriv->neverending_ai ||
|
||||
(!devpriv->neverending_ai &&
|
||||
devpriv->ai_act_scan > 0)) {
|
||||
/* wait for running dma transfer to end, do cleanup in interrupt */
|
||||
goto end;
|
||||
}
|
||||
@ -1494,6 +1497,8 @@ static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice
|
||||
devpriv->irq_blocked = 0;
|
||||
devpriv->last_int_sub = s;
|
||||
devpriv->neverending_ai = 0;
|
||||
devpriv->ai_mode = 0;
|
||||
devpriv->irq_was_now_closed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user