From f9d9ab9533c94e193fe3e5c399bd559033791606 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Mon, 5 Apr 2004 22:47:59 +0000 Subject: [PATCH] take into account possibility of comedi_poll getting called from interrupt context (kcomedilib). Removed some dead code. Fix tiny possibility of undetected buffer overrun. Added a memory barrier to ni_sync_ai_dma(). --- comedi/drivers/ni_mio_common.c | 71 ++++++---------------------------- 1 file changed, 12 insertions(+), 59 deletions(-) diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index bf415a01..acca2498 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -409,10 +409,12 @@ static void ni_sync_ai_dma(struct mite_struct *mite, comedi_device *dev) comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz); nbytes = mite_bytes_transferred(mite, AI_DMA_CHAN); - /* XXX should use mite_bytes_read() for the overrun check - * since mite_bytes_transferred returns a conservative - * lower bound */ - if( (int)(nbytes - old_alloc_count) > 0 ){ + rmb(); + /* We use mite_bytes_read() for the overrun check + * because it returns an upper board, and mite_bytes_transferred + * returns a lower bound on the number of bytes actually + * transferred */ + if( (int)(mite_bytes_read(mite, AI_DMA_CHAN) - old_alloc_count) > 0 ){ printk("ni_mio_common: DMA overwrite of free area\n"); ni_ai_reset(dev,s); async->events |= COMEDI_CB_OVERFLOW; @@ -420,12 +422,12 @@ static void ni_sync_ai_dma(struct mite_struct *mite, comedi_device *dev) } count = nbytes - async->buf_write_count; - if( count < 0 ){ + if( count <= 0 ){ /* it's possible count will be negative due to * conservative value returned by mite_bytes_transferred */ return; } - + mb(); comedi_buf_write_free(async, count); async->scan_progress += count; @@ -471,57 +473,6 @@ static void mite_handle_b_linkc(struct mite_struct *mite, comedi_device *dev) async->events |= COMEDI_CB_BLOCK; } -#if 0 -static void mite_handle_interrupt(comedi_device *dev,unsigned int m_status) -{ - int len; - comedi_subdevice *s = dev->subdevices+0; - comedi_async *async = s->async; - struct mite_struct *mite = devpriv->mite; - - async->events |= COMEDI_CB_BLOCK; - - MDPRINTK("mite_handle_interrupt: m_status=%08x\n",m_status); - if(m_status & CHSR_DONE){ - writel(CHOR_CLRDONE, mite->mite_io_addr + MITE_CHOR(0)); - } - -#if 0 - len = sizeof(sampl_t)*async->cmd.stop_arg*async->cmd.scan_end_arg; - if((devpriv->mite->DMA_CheckNearEnd) && - (s->async->buf_int_count > (len - s->async->prealloc_bufsz))) { - long offset; - int i; - - offset = len % async->prealloc_bufsz; - if(offset < mite->ring[0].count) { - mite->ring[0].count = offset; - mite->ring[1].count = 0; - }else{ - offset -= mite->ring[0].count; - i = offset >> PAGE_SHIFT; - mite->ring[i].count = offset & ~PAGE_MASK; - mite->ring[(i+1)%mite->n_links].count = 0; - } - mite->DMA_CheckNearEnd = 0; - } -#endif - -#if 0 - MDPRINTK("CHSR is 0x%08x, count is %d\n",m_status,async->buf_int_count); - if(m_status&CHSR_DONE){ - writel(CHOR_CLRDONE, mite->mite_io_addr + MITE_CHOR(mite->chan)); - //printk("buf_int_count is %d, buf_int_ptr is %d\n", - // s->async->buf_int_count,s->async->buf_int_ptr); - ni_handle_block_dma(dev); - } - MDPRINTK("exit mite_handle_interrupt\n"); -#endif - - //comedi_event(dev,s,async->events); -} -#endif - static int ni_ao_wait_for_dma_load( comedi_device *dev ) { static const int timeout = 10000; @@ -1180,14 +1131,16 @@ static int ni_ai_poll(comedi_device *dev,comedi_subdevice *s) int count; // lock to avoid race with interrupt handler - comedi_spin_lock_irqsave(&dev->spinlock, flags); + if(in_interrupt() == 0) + comedi_spin_lock_irqsave(&dev->spinlock, flags); #ifndef PCIDMA ni_handle_fifo_dregs(dev); #else ni_sync_ai_dma(devpriv->mite, dev); #endif count = s->async->buf_write_count - s->async->buf_read_count; - comedi_spin_unlock_irqrestore(&dev->spinlock, flags); + if(in_interrupt() == 0) + comedi_spin_unlock_irqrestore(&dev->spinlock, flags); return count; } -- 2.26.2