From 04e3a8898c9873a9e263cf2dbf8300c29f25ac40 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 10 Feb 2002 04:13:57 +0000 Subject: [PATCH] More DMA hacking. Works nicely now. Allocator moved to mite.c. Converted to new MITE DMA functions and dynamic ring buffer. Added more mite interrupt handling. --- comedi/drivers/ni_pcidio.c | 99 ++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/comedi/drivers/ni_pcidio.c b/comedi/drivers/ni_pcidio.c index 48e48e6f..f1afde6e 100644 --- a/comedi/drivers/ni_pcidio.c +++ b/comedi/drivers/ni_pcidio.c @@ -382,7 +382,8 @@ static void nidio_interrupt(int irq, void *d, struct pt_regs *regs) comedi_device *dev=d; comedi_subdevice *s = dev->subdevices; comedi_async *async = s->async; - int i, j; + struct mite_struct *mite = devpriv->mite; + //int i, j; long int AuxData = 0; sampl_t data1 = 0; sampl_t data2 = 0; @@ -393,7 +394,7 @@ static void nidio_interrupt(int irq, void *d, struct pt_regs *regs) status = readb(dev->iobase+Interrupt_And_Window_Status); flags = readb(dev->iobase+Group_1_Flags); - m_status = readl(devpriv->mite->mite_io_addr + MITE_CHSR + CHAN_OFFSET(1)); + m_status = readl(mite->mite_io_addr + MITE_CHSR + CHAN_OFFSET(1)); //interrupcions parasites if(dev->attached == 0){ @@ -401,24 +402,47 @@ static void nidio_interrupt(int irq, void *d, struct pt_regs *regs) async->events |= COMEDI_CB_ERROR|COMEDI_CB_EOA; } - DPRINTK("ni_pcidio_interrupt: IntEn=0x%02x,flags=0x%02x,status=0x%02x,m_status=0x%08x\n", - IntEn,flags,status,m_status); + DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x,m_status=0x%08x\n", + status,flags,m_status); ni_pcidio_print_flags(flags); ni_pcidio_print_status(status); - printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(devpriv->mite,1)); - mite_dump_regs(devpriv->mite); + mite_print_chsr(m_status); + //printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,1)); + //mite_dump_regs(mite); - printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); + //printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); + //printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096)); if(m_status & CHSR_INT){ if(m_status & CHSR_LINKC){ - writel(CHOR_CLRLC, devpriv->mite->mite_io_addr + - MITE_CHOR + CHAN_OFFSET(1)); + unsigned int count; + + writel(CHOR_CLRLC, mite->mite_io_addr + MITE_CHOR + CHAN_OFFSET(1)); + count = le32_to_cpu(mite->ring[mite->current_link].count); + + /* XXX need to byteswap */ + + async->buf_int_count += count; + async->buf_int_ptr += count; + if(async->buf_int_ptr >= async->data_len){ + async->buf_int_ptr -= async->data_len; + } + mite->current_link++; + if(mite->current_link >= mite->n_links){ + mite->current_link=0; + } } if(m_status & CHSR_DONE){ - writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr + - MITE_CHOR + CHAN_OFFSET(1)); + writel(CHOR_CLRDONE, mite->mite_io_addr + MITE_CHOR + + CHAN_OFFSET(1)); } + if(m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY)){ + DPRINTK("unknown mite interrupt, disabling IRQ\n"); + writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR + + CHAN_OFFSET(1)); + disable_irq(dev->irq); + } + async->events |= COMEDI_CB_BLOCK; } while(status&DataLeft){ @@ -463,9 +487,9 @@ static void nidio_interrupt(int irq, void *d, struct pt_regs *regs) writeb(0x00,dev->iobase+OpMode); writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control); #ifdef USE_DMA - mite_dma_disarm(devpriv->mite); - writel(CHOR_DMARESET, devpriv->mite->mite_io_addr + - MITE_CHOR + CHAN_OFFSET(1)); + mite_dma_disarm(mite); + writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR + + CHAN_OFFSET(1)); #endif break; }else if(flags & Waited){ @@ -474,9 +498,9 @@ static void nidio_interrupt(int irq, void *d, struct pt_regs *regs) writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; #ifdef USE_DMA - mite_dma_disarm(devpriv->mite); - writel(CHOR_DMARESET, devpriv->mite->mite_io_addr + - MITE_CHOR + CHAN_OFFSET(1)); + mite_dma_disarm(mite); + writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR + + CHAN_OFFSET(1)); #endif break; }else if(flags & PrimaryTC){ @@ -810,7 +834,6 @@ static int ni_pcidio_cmd(comedi_device *dev,comedi_subdevice *s) writeb(0x30,dev->iobase+Group_1_First_Clear); setup_mite_dma(dev,s); - //mite_dma_prep(devpriv->mite,s); #else writeb(0x00,dev->iobase+DMA_Line_Control); #endif @@ -838,16 +861,16 @@ static int ni_pcidio_cmd(comedi_device *dev,comedi_subdevice *s) static void setup_mite_dma(comedi_device *dev,comedi_subdevice *s) { - int n,len; - unsigned long ll_start; - comedi_async *async = s->async; - comedi_cmd *cmd = &async->cmd; + struct mite_struct *mite = devpriv->mite; + + mite->current_link = 0; - len = sizeof(lsampl_t)*cmd->stop_arg; - ll_start = mite_ll_from_kvmem(devpriv->mite, async, len); - mite_setregs(devpriv->mite, ll_start, 1, COMEDI_INPUT); + mite->dir = COMEDI_INPUT; + mite->chan = 1; - mite_dma_arm(devpriv->mite); + mite_prep_dma(mite); + + mite_dma_arm(mite); } @@ -874,28 +897,12 @@ static int ni_pcidio_cancel(comedi_device *dev, comedi_subdevice *s) static int ni_pcidio_alloc(comedi_device *dev, comedi_subdevice *s, unsigned long new_size) { - comedi_async *async = s->async; - - if(async->prealloc_buf && async->prealloc_bufsz == new_size){ - return 0; - } - - if(async->prealloc_bufsz){ - kfree(async->prealloc_buf); - async->prealloc_buf = NULL; - async->prealloc_bufsz = 0; - } + int ret; - if(new_size){ - async->prealloc_buf = kmalloc(new_size, GFP_KERNEL); - if(async->prealloc_buf == NULL){ - async->prealloc_bufsz = 0; - return -ENOMEM; - } - } - async->prealloc_bufsz = new_size; + ret = mite_buf_alloc(devpriv->mite, s->async, new_size); + if(ret<0)return ret; - memset(async->prealloc_buf, 0xaa, async->prealloc_bufsz); + memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz); return 0; } -- 2.26.2