From 394dc27e9c35e50d1731c847797a6033d9bf48d4 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 14 Jun 2000 07:45:16 +0000 Subject: [PATCH] PCI DMA support --- comedi/drivers/mite.c | 27 +++++++++++++++++++++------ comedi/drivers/mite.h | 5 +++++ comedi/drivers/ni_mio_common.c | 34 +++++++++++++++++++++++++++++----- comedi/drivers/ni_pcimio.c | 9 +++++++++ 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c index 5ff8a444..1f384156 100644 --- a/comedi/drivers/mite.c +++ b/comedi/drivers/mite.c @@ -202,10 +202,12 @@ int mite_setup(struct mite_struct *mite) #endif /* DMA setup */ - for(i=0;iring[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); diff --git a/comedi/drivers/mite.h b/comedi/drivers/mite.h index e038a2d9..0a97ea19 100644 --- a/comedi/drivers/mite.h +++ b/comedi/drivers/mite.h @@ -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)) diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index d55f0fa6..0ce2e2c6 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -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 diff --git a/comedi/drivers/ni_pcimio.c b/comedi/drivers/ni_pcimio.c index 15f56b9b..c02037ff 100644 --- a/comedi/drivers/ni_pcimio.c +++ b/comedi/drivers/ni_pcimio.c @@ -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 -- 2.26.2