summaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/drivers
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2016-04-21 12:04:37 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-28 22:19:49 -0700
commitcc38da7287ed4f0f08956351167c31e4e6abc427 (patch)
treeca22e748ce4e931c1693b6c421f4b917ac96d364 /drivers/staging/comedi/drivers
parent21e871fef7a681826c661332c285be95f0204aca (diff)
staging: comedi: mite: check for transfer errors in mite_ack_linkc()
Currently only some of the users of mite dma check for transfer errors. The ni_mio_common code does the check for the analog input and analog output subdevices. The m-series digital I/O subdevice and the counter subdevices (handled by ni_tiocmd) do not check. The ni_pcidio driver checks for the digital input subdevice. The ni_660x driver counter subdevices (handled by ni_tiocmd) also do not check. Move the transfer error checking into mite_ack_linkc() so that the drivers that use mite don't have to deal with it. This also makes sure that all the subdevices that use mite for dma will cancel the async command if a transfer error is detected. Simplfy the transfer error check by just checking the CHSR_XFERR bit. This bit will be set if one or more transfer processes terminated with an error. The actual error is determined by the LERR, MERR, and DERR bits. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/drivers')
-rw-r--r--drivers/staging/comedi/drivers/mite.c8
-rw-r--r--drivers/staging/comedi/drivers/mite.h3
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c27
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c10
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c2
5 files changed, 17 insertions, 33 deletions
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index 2233a412cf26..d97059217825 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -778,7 +778,8 @@ static unsigned int mite_get_status(struct mite_channel *mite_chan)
return status;
}
-unsigned int mite_ack_linkc(struct mite_channel *mite_chan)
+unsigned int mite_ack_linkc(struct mite_channel *mite_chan,
+ struct comedi_subdevice *s)
{
struct mite_struct *mite = mite_chan->mite;
unsigned int status;
@@ -787,6 +788,11 @@ unsigned int mite_ack_linkc(struct mite_channel *mite_chan)
if (status & CHSR_LINKC)
writel(CHOR_CLRLC,
mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
+ if (status & CHSR_XFERR) {
+ dev_err(s->device->class_dev,
+ "mite: transfer error %08x\n", status);
+ s->async->events |= COMEDI_CB_ERROR;
+ }
return status;
}
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index 4942853fb41f..f8364edf8ce8 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -93,7 +93,8 @@ void mite_dma_arm(struct mite_channel *mite_chan);
void mite_dma_disarm(struct mite_channel *mite_chan);
void mite_sync_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s);
u32 mite_bytes_in_transit(struct mite_channel *mite_chan);
-unsigned int mite_ack_linkc(struct mite_channel *mite_chan);
+unsigned int mite_ack_linkc(struct mite_channel *mite_chan,
+ struct comedi_subdevice *s);
int mite_done(struct mite_channel *mite_chan);
void mite_prep_dma(struct mite_channel *mite_chan,
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 3312f978754b..2e27815bd632 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -1317,16 +1317,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
#ifdef PCIDMA
if (ai_mite_status & CHSR_LINKC)
ni_sync_ai_dma(dev);
-
- if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
- CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
- CHSR_SABORT | CHSR_XFERR | CHSR_LERR_MASK)) {
- dev_err(dev->class_dev,
- "unknown mite interrupt (ai_mite_status=%08x)\n",
- ai_mite_status);
- s->async->events |= COMEDI_CB_ERROR;
- /* disable_irq(dev->irq); */
- }
#endif
/* test for all uncommon interrupt events at the same time */
@@ -1422,15 +1412,6 @@ static void handle_b_interrupt(struct comedi_device *dev,
mite_handle_b_linkc(devpriv->mite, dev);
}
-
- if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
- CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
- CHSR_SABORT | CHSR_XFERR | CHSR_LERR_MASK)) {
- dev_err(dev->class_dev,
- "unknown mite interrupt (ao_mite_status=%08x)\n",
- ao_mite_status);
- s->async->events |= COMEDI_CB_ERROR;
- }
#endif
if (b_status == 0xffff)
@@ -3697,7 +3678,7 @@ static void handle_cdio_interrupt(struct comedi_device *dev)
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
if (devpriv->cdo_mite_chan) {
- mite_ack_linkc(devpriv->cdo_mite_chan);
+ mite_ack_linkc(devpriv->cdo_mite_chan, s);
mite_sync_dma(devpriv->cdo_mite_chan, s);
}
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -5217,9 +5198,11 @@ static irqreturn_t ni_E_interrupt(int irq, void *d)
spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
if (devpriv->ai_mite_chan)
- ai_mite_status = mite_ack_linkc(devpriv->ai_mite_chan);
+ ai_mite_status = mite_ack_linkc(devpriv->ai_mite_chan,
+ dev->read_subdev);
if (devpriv->ao_mite_chan)
- ao_mite_status = mite_ack_linkc(devpriv->ao_mite_chan);
+ ao_mite_status = mite_ack_linkc(devpriv->ao_mite_chan,
+ dev->write_subdev);
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
}
#endif
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index d2276de7ad6a..b4c6bab57a26 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -400,19 +400,13 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
spin_lock(&devpriv->mite_channel_lock);
if (devpriv->di_mite_chan) {
- unsigned int m_status = mite_ack_linkc(devpriv->di_mite_chan);
+ unsigned int m_status = mite_ack_linkc(devpriv->di_mite_chan,
+ s);
if (m_status & CHSR_LINKC) {
mite_sync_dma(devpriv->di_mite_chan, s);
/* XXX need to byteswap */
}
- if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
- CHSR_DRQ1 | CHSR_MRDY)) {
- dev_dbg(dev->class_dev,
- "unknown mite interrupt, disabling IRQ\n");
- async->events |= COMEDI_CB_ERROR;
- disable_irq(dev->irq);
- }
}
spin_unlock(&devpriv->mite_channel_lock);
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
index 4c76cb80f34c..5228b9fc2a72 100644
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -429,7 +429,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter,
}
spin_lock_irqsave(&counter->lock, flags);
if (counter->mite_chan) {
- mite_ack_linkc(counter->mite_chan);
+ mite_ack_linkc(counter->mite_chan, s);
mite_sync_dma(counter->mite_chan, s);
}
spin_unlock_irqrestore(&counter->lock, flags);