PCI DMA support
authorDavid Schleef <ds@schleef.org>
Wed, 14 Jun 2000 07:45:16 +0000 (07:45 +0000)
committerDavid Schleef <ds@schleef.org>
Wed, 14 Jun 2000 07:45:16 +0000 (07:45 +0000)
comedi/drivers/mite.c
comedi/drivers/mite.h
comedi/drivers/ni_mio_common.c
comedi/drivers/ni_pcimio.c

index 5ff8a444e8b5f92ac1fb8b4ecee5326e284f20b9..1f384156261c0a3dc4355dcfa46734db95be00e3 100644 (file)
@@ -202,10 +202,12 @@ int mite_setup(struct mite_struct *mite)
 #endif
 
        /* DMA setup */
-       for(i=0;i<MITE_RING_SIZE;i++){
+       for(i=0;i<MITE_RING_SIZE-1;i++){
                mite->ring[i].next=virt_to_bus(mite->ring+i+1);
                mite->ring[i].unused=0x1c; /* eh? */
        }
+       mite->ring[i].next=0;
+       mite->ring[i].unused=0x1c; /* eh? */
 
        return (int) mite->daq_io_addr;
 }
@@ -260,17 +262,15 @@ void mite_dma_prep(struct mite_struct *mite,comedi_subdevice *s)
                n=s->prealloc_bufsz-s->buf_int_ptr;
                n=mite_kvmem_segment_load(mite,i,((void *)s->cur_trig.data)+s->buf_int_ptr,n);
                s->buf_int_ptr+=n;
-               if(s->buf_int_ptr>=s->cur_trig.data_len)
+               if(s->buf_int_ptr>=s->prealloc_bufsz)
                        s->buf_int_ptr=0;
        }
 
-       writel(virt_to_bus(mite->ring),mite->mite_io_addr+MITE_LKAR+CHAN_OFFSET(0));
-
        chor = CHOR_DMARESET | CHOR_FRESET;
        writel(chor,mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0));
 
        chcr = CHCR_LINKLONG | CHCR_DEV_TO_MEM;
-       chcr = CHCR_LINKLONG | CHCR_MEM_TO_DEV;
+       //chcr = CHCR_LINKLONG | CHCR_MEM_TO_DEV;
        writel(chcr,mite->mite_io_addr+MITE_CHCR+CHAN_OFFSET(0));
 
        mcr = CR_RL64 | CR_ASEQxP1 | CR_PSIZEHALF;
@@ -283,7 +283,7 @@ void mite_dma_prep(struct mite_struct *mite,comedi_subdevice *s)
        lkcr = CR_RL64 | CR_ASEQUP | CR_PSIZEWORD;
        writel(lkcr,mite->mite_io_addr+MITE_LKCR+CHAN_OFFSET(0));
 
-       //lkar = 0;
+       writel(virt_to_bus(mite->ring),mite->mite_io_addr+MITE_LKAR+CHAN_OFFSET(0));
 
 }
 
@@ -294,6 +294,20 @@ void mite_dma_arm(struct mite_struct *mite)
        /* arm */
        chor = CHOR_START;
        writel(chor,mite->mite_io_addr+CHAN_OFFSET(0)+MITE_CHOR);
+
+       mite_dma_tcr(mite);
+}
+
+int mite_dma_tcr(struct mite_struct *mite)
+{
+       int tcr;
+       int lkar;
+
+       lkar=readl(mite->mite_io_addr+CHAN_OFFSET(0)+MITE_LKAR);
+       tcr=readl(mite->mite_io_addr+CHAN_OFFSET(0)+MITE_TCR);
+       printk("lkar=0x%08x tcr=%d\n",lkar,tcr);
+
+       return tcr;
 }
 
 void mite_dma_disarm(struct mite_struct *mite)
@@ -336,6 +350,7 @@ struct symbol_table mite_syms = {
 
 #ifdef LINUX_V22
 
+EXPORT_SYMBOL(mite_dma_tcr);
 EXPORT_SYMBOL(mite_dma_arm);
 EXPORT_SYMBOL(mite_dma_disarm);
 EXPORT_SYMBOL(mite_dma_prep);
index e038a2d92ab84c27b86eae28dfa52ae0b1f14b52..0a97ea19b717b8603ee542f559371958e7136e11 100644 (file)
@@ -83,6 +83,11 @@ void mite_unsetup(struct mite_struct *mite);
 
 void mite_dma_prep(struct mite_struct *mite,comedi_subdevice *s);
 
+int mite_dma_tcr(struct mite_struct *mite);
+
+void mite_dma_arm(struct mite_struct *mite);
+void mite_dma_disarm(struct mite_struct *mite);
+
 
 #define CHAN_OFFSET(x)                 (0x100*(x))
 
index d55f0fa68aa2628082b70d96a8a0d7e61d8f45b4..0ce2e2c68d1a30ebeca302df51ffed5c2d623765 100644 (file)
@@ -212,12 +212,16 @@ static void ni_E_interrupt(int irq,void *d,struct pt_regs * regs)
        wsave=win_save();
        
        b_status=ni_readw(AO_Status_1);
-#if 0
-printk("B status=0x%04x\n",b_status);
-#endif
        status=ni_readw(AI_Status_1);
-#if 0
-printk("A status=0x%04x\n",status);
+#if 1
+printk("status=0x%04x,0x%04x\n",status,b_status);
+#ifdef PCIMIO
+printk("mite status=0x%08x\n",readw(devpriv->mite->mite_io_addr+0x14));
+#endif
+#endif
+
+#ifdef PCIMIO
+mite_dma_tcr(devpriv->mite);
 #endif
        if(status&(AI_Overrun_St|AI_Overflow_St)){
                rt_printk("ni_E: overrun/overflow status=0x%04x\n",status);
@@ -432,6 +436,9 @@ static void ni_handle_fifo_dregs(comedi_device *dev)
  */
 static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s)
 {
+#ifdef PCIMIO
+       mite_dma_disarm(devpriv->mite);
+#endif
        win_out(0x0000,Interrupt_A_Enable_Register);
 
        win_out(AI_Reset,Joint_Reset_Register);
@@ -964,6 +971,7 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
                }else{
                        devpriv->aimode=AIMODE_HALF_FULL;
                }
+devpriv->aimode=AIMODE_SAMPLE;
                switch(devpriv->aimode){
                case AIMODE_HALF_FULL:
                        /*generate FIFO interrupts on half-full */
@@ -982,6 +990,9 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
                        break;
                }
 
+bits=AI_SC_TC_Interrupt_Enable;
+bits|=AI_Error_Interrupt_Enable;
+//bits|=Pass_Thru_0_Interrupt_Enable;
                win_out(0x3f80,Interrupt_A_Ack_Register); /* clear interrupts */
 
                win_out(bits,Interrupt_A_Enable_Register) ;
@@ -992,6 +1003,19 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
                /* XXX start polling if necessary */
        }
 
+#ifdef PCIMIO
+#if 0 
+       Strobes_Register
+       AI_AO_Select_Register
+       Interrupt_B_Enable_Register MSC_Pass_thru
+#endif
+
+       ni_writeb(0x01,AI_AO_Select);
+       mite_dma_prep(devpriv->mite, s);
+
+       mite_dma_arm(devpriv->mite);
+#endif
+
 #ifdef DEBUG
 rt_printk("end config\n");
 #endif
index 15f56b9b8da6c8e060be63c18b571dc6645aa8fc..c02037ff83825aa58e6850696e3972b4af533b61 100644 (file)
@@ -360,12 +360,21 @@ comedi_driver driver_pcimio={
  * on the PCI-MIO is really dumb.  I'd bet that the
  * registers can actually be acessed without windowing...
  * must try this sometime...
+ *
+ * but it doesn't work...
  */
 
+#if 0
+#define win_out(a,b) (ni_writew((a),(b)*2))
+#define win_in(b) (ni_readw((b)*2))
+#define win_save() 0
+#define win_restore(a)
+#else
 #define win_out(a,b) (ni_writew((b),Window_Address),ni_writew((a),Window_Data))
 #define win_in(b) (ni_writew((b),Window_Address),ni_readw(Window_Data))
 #define win_save() (ni_readw(Window_Address))
 #define win_restore(a) (ni_writew((a),Window_Address))
+#endif
 
 /*
    If interrupts _still_ don't work, play with the