More DMA hacking. Works nicely now. Allocator moved to mite.c.
authorDavid Schleef <ds@schleef.org>
Sun, 10 Feb 2002 04:13:57 +0000 (04:13 +0000)
committerDavid Schleef <ds@schleef.org>
Sun, 10 Feb 2002 04:13:57 +0000 (04:13 +0000)
Converted to new MITE DMA functions and dynamic ring buffer.  Added
more mite interrupt handling.

comedi/drivers/ni_pcidio.c

index 48e48e6f71ce47210596ecf1f249df9d365e2d91..f1afde6eeb7764c1467b0a0a1990dfd4b74b5c58 100644 (file)
@@ -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;
 }