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:
committed by
Greg Kroah-Hartman
parent
a71f18d2a1
commit
e21de1a8e5
@@ -820,6 +820,27 @@ static irqreturn_t interrupt_pcl818(int irq, void *d)
|
|||||||
}
|
}
|
||||||
/* rt_printk("I\n"); */
|
/* 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) {
|
switch (devpriv->ai_mode) {
|
||||||
case INT_TYPE_AI1_DMA:
|
case INT_TYPE_AI1_DMA:
|
||||||
case INT_TYPE_AI3_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)
|
if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked)
|
||||||
|| (!devpriv->ai_mode)) {
|
|| (!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!");
|
comedi_error(dev, "bad IRQ!");
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
@@ -1453,10 +1455,9 @@ static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice
|
|||||||
{
|
{
|
||||||
if (devpriv->irq_blocked > 0) {
|
if (devpriv->irq_blocked > 0) {
|
||||||
rt_printk("pcl818_ai_cancel()\n");
|
rt_printk("pcl818_ai_cancel()\n");
|
||||||
devpriv->irq_was_now_closed = devpriv->ai_mode;
|
devpriv->irq_was_now_closed = 1;
|
||||||
devpriv->ai_mode = 0;
|
|
||||||
|
|
||||||
switch (devpriv->irq_was_now_closed) {
|
switch (devpriv->ai_mode) {
|
||||||
#ifdef unused
|
#ifdef unused
|
||||||
case INT_TYPE_AI1_DMA_RTC:
|
case INT_TYPE_AI1_DMA_RTC:
|
||||||
case INT_TYPE_AI3_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
|
#endif
|
||||||
case INT_TYPE_AI1_DMA:
|
case INT_TYPE_AI1_DMA:
|
||||||
case INT_TYPE_AI3_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 */
|
/* wait for running dma transfer to end, do cleanup in interrupt */
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -1494,6 +1497,8 @@ static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice
|
|||||||
devpriv->irq_blocked = 0;
|
devpriv->irq_blocked = 0;
|
||||||
devpriv->last_int_sub = s;
|
devpriv->last_int_sub = s;
|
||||||
devpriv->neverending_ai = 0;
|
devpriv->neverending_ai = 0;
|
||||||
|
devpriv->ai_mode = 0;
|
||||||
|
devpriv->irq_was_now_closed = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user