Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e21de1a8 authored by Ian Abbott's avatar Ian Abbott Committed by Greg Kroah-Hartman
Browse files

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: default avatarFrank Mori Hess <fmhess@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent a71f18d2
Loading
Loading
Loading
Loading
+28 −23
Original line number Diff line number Diff line
@@ -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;
		}
	}