From fb485ddc9a55dcc4816843e789da0253e05ad0c0 Mon Sep 17 00:00:00 2001 From: Tim Ousley Date: Tue, 10 Apr 2001 16:45:58 +0000 Subject: [PATCH] Tim Ousley 4/10/01: MITE DMA now works correctly for finite acquisitions smaller than the prealloc bufsz. uncomment #define PCIDMA in ni_pcimio.c --- comedi/drivers/mite.c | 15 +++--- comedi/drivers/mite.h | 5 +- comedi/drivers/ni_mio_common.c | 83 ++++++++++++++++++++++++---------- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c index 00a1145e..7f17c122 100644 --- a/comedi/drivers/mite.c +++ b/comedi/drivers/mite.c @@ -296,7 +296,7 @@ unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,in { int i,size_so_far; unsigned long nup; - //unsigned long prealloc_buf,prealloc_bufsz; + unsigned long prealloc_buf,prealloc_bufsz; //comedi_subdevice *s; //struct mite_struct *mite=NULL; //comedi_async *async=NULL; @@ -305,8 +305,8 @@ unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,in MDPRINTK("mite_ll_from_kvmem\n"); //s=dev->subdevices+cmd->subdev; //mite=devpriv->mite; - //prealloc_buf=(unsigned long)s->async->prealloc_buf; - //prealloc_bufsz=s->async->prealloc_bufsz; + prealloc_buf=(unsigned long)async->prealloc_buf; + prealloc_bufsz=async->prealloc_bufsz; //len = min(cmd->scan_end_arg*cmd->stop_arg*sizeof(sampl_t), async->data_len); if(async->data_lendata; i=0; size_so_far=0; - MDPRINTK("buf=0x%08lx bufsz=0x%08x\n", + MDPRINTK("buf=0x%08lx bufsz=0x%08lx\n", (unsigned long)prealloc_buf,prealloc_bufsz); while(((void*)nup < (async->data+len))&&(i<(MITE_RING_SIZE-1))) { @@ -342,6 +342,8 @@ unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,in return virt_to_bus(&(mite->ring[0])); } +/* This function would be used to DMA directly into user memory. +Since Comedi won't support that for a while, this should probably be removed. --Tim Ousley unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd) { int i,size_so_far,len; @@ -384,6 +386,7 @@ unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd) MDPRINTK("exit mite_ll_from_user\n"); return virt_to_bus(&(mite->ring[0])); } +*/ void mite_dma_arm(struct mite_struct *mite) { @@ -480,7 +483,7 @@ void mite_dma_disarm(struct mite_struct *mite) void mite_dump_regs(struct mite_struct *mite) { - unsigned long mite_io_addr = mite->mite_io_addr; + unsigned long mite_io_addr = (unsigned long) mite->mite_io_addr; unsigned long addr=0; unsigned long temp=0; @@ -566,7 +569,7 @@ EXPORT_SYMBOL(mite_list_devices); //Tim's debugging function EXPORT_SYMBOL(mite_dump_regs); -EXPORT_SYMBOL(mite_ll_from_user); +//EXPORT_SYMBOL(mite_ll_from_user); //obsolete EXPORT_SYMBOL(mite_ll_from_kvmem); EXPORT_SYMBOL(mite_setregs); EXPORT_SYMBOL(mite_bytes_transferred); diff --git a/comedi/drivers/mite.h b/comedi/drivers/mite.h index 5383638a..61a06f8c 100644 --- a/comedi/drivers/mite.h +++ b/comedi/drivers/mite.h @@ -41,8 +41,7 @@ #define MDPRINTK(format,args...) #endif -#define MITE_RING_SIZE 3000 - +#define MITE_RING_SIZE 3000 struct mite_dma_chain{ u32 count; u32 addr; @@ -95,7 +94,7 @@ int mite_dma_tcr(struct mite_struct *mite); void mite_dma_arm(struct mite_struct *mite); void mite_dma_disarm(struct mite_struct *mite); -unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd); +//unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd);//obsolete unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,int len); void mite_dump_regs(struct mite_struct *mite); void mite_setregs(struct mite_struct *mite,unsigned long ll_start,int chan, int dir); diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index 6e54f4b0..37818e59 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -54,7 +54,7 @@ //#define DEBUG_INTERRUPT //#define TRY_BLOCK -//#define DEBUG_STATUS_A +#define DEBUG_STATUS_A //#define DEBUG_STATUS_B #include <8255.h> @@ -219,7 +219,9 @@ static void pfi_setup(comedi_device *dev); static void handle_a_interrupt(comedi_device *dev,unsigned short status); static void handle_b_interrupt(comedi_device *dev,unsigned short status); #ifdef PCIDMA -static void mite_handle_interrupt(comedi_device *dev,unsigned short status); +/*status must be long because the CHSR is 32 bits and the high bits +are important to us */ +static void mite_handle_interrupt(comedi_device *dev,unsigned long status); #endif static @@ -230,7 +232,9 @@ void ni_E_interrupt(int irq,void *d,struct pt_regs * regs) unsigned short b_status; int wsave; #ifdef PCIDMA - unsigned short m_status; + /* m_status must be long because the CHSR is a 32 bit register and we are + interested in several high bits */ + unsigned long m_status; #endif MDPRINTK("ni_E_Interrupt\n"); @@ -254,21 +258,18 @@ void ni_E_interrupt(int irq,void *d,struct pt_regs * regs) ni_mio_print_status_b(b_status); #endif #ifdef PCIDMA - rt_printk("mite status=0x%08x\n",readw(devpriv->mite->mite_io_addr+0x14)); -#endif - -#ifdef PCIDMA + //rt_printk("mite status=0x%08lx\n",m_status); if(m_status&CHSR_INT)mite_handle_interrupt(dev,m_status); #endif if(a_status&Interrupt_A_St)handle_a_interrupt(dev,a_status); if(b_status&Interrupt_B_St)handle_b_interrupt(dev,b_status); - + win_restore(wsave); MDPRINTK("exit ni_E_Interrupt\n"); } #ifdef PCIDMA -static void mite_handle_interrupt(comedi_device *dev,unsigned short m_status) +static void mite_handle_interrupt(comedi_device *dev,unsigned long m_status) { comedi_subdevice *s=dev->subdevices+0; @@ -277,19 +278,15 @@ static void mite_handle_interrupt(comedi_device *dev,unsigned short m_status) MDPRINTK("MITE generated an int!!\n"); writel(CHOR_CLRLC, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0)); s->async->buf_int_count=mite_bytes_transferred(devpriv->mite, 0); - if (s->async->cmd.data ==NULL) { - s->async->buf_int_ptr= s->async->buf_int_count % s->async->prealloc_bufsz; - } else { - s->async->buf_int_ptr= s->async->buf_int_count % s->async->cmd.data_len; - } - MDPRINTK("CHSR is 0x%08X, count is %d\n",m_status,s->async->buf_int_count); + s->async->buf_int_ptr= s->async->buf_int_count % s->async->prealloc_bufsz; + MDPRINTK("CHSR is 0x%08lx, count is %d\n",m_status,s->async->buf_int_count); if(m_status&CHSR_DONE){ #ifdef DEBUG_MITE - /*mite_printk(devpriv->mite->mite_io_addr);*/ + mite_dump_regs(devpriv->mite); #endif writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0)); - printk("buf_int_count is %d, buf_int_ptr is %d\n", - s->async->buf_int_count,s->async->buf_int_ptr); + //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"); @@ -319,6 +316,7 @@ static void handle_a_interrupt(comedi_device *dev,unsigned short status) ni_mio_print_status_a(status); ni_handle_fifo_dregs(dev); win_out(0x0000,Interrupt_A_Enable_Register); + ni_ai_reset(dev,dev->subdevices);//added by tim comedi_done(dev,s); return; } @@ -328,7 +326,9 @@ static void handle_a_interrupt(comedi_device *dev,unsigned short status) #endif #ifdef TRY_BLOCK #ifdef PCIDMA - ni_handle_block_dma(dev); + //just ignore the terminal count from the STC + //instead finish up when the MITE asserts DONE + //ni_handle_block_dma(dev); #else ni_handle_block(dev); #endif @@ -465,13 +465,13 @@ static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s, #ifdef PCIDMA static void ni_handle_block_dma(comedi_device *dev) { - MDPRINTK("ni_handle_block\n"); - mite_dump_regs(devpriv->mite); + MDPRINTK("ni_handle_block_dma\n"); + //mite_dump_regs(devpriv->mite); mite_dma_disarm(devpriv->mite); win_out(0x0000,Interrupt_A_Enable_Register); ni_ai_reset(dev,dev->subdevices); comedi_done(dev,dev->subdevices); - MDPRINTK("exit ni_handle_block\n"); + MDPRINTK("exit ni_handle_block_dma\n"); } #endif @@ -700,6 +700,40 @@ printk("n_left = %d\n",devpriv->n_left); } #endif +#ifdef PCIDMA +int ni_ai_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd,int mode1) +{ + int n; + unsigned long ll_start; + comedi_async *async_mite; + + async_mite=dev->subdevices[cmd->subdev].async; + ll_start = mite_ll_from_kvmem(devpriv->mite, async_mite,cmd->stop_arg); + mite_setregs(devpriv->mite, ll_start,0,COMEDI_INPUT); + + /*tell the STC to use DMA0 for AI. + Select the MITE DMA channel to use, 0x01=A*/ + ni_writeb(0x01,AI_AO_Select); + + /* stage number of scans */ + n = cmd->stop_arg; + win_out((n-1)>>16,AI_SC_Load_A_Registers); + win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1); + win_out((n-1)>>16,AI_SC_Load_B_Registers); + win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1); + + /* load SC (Scan Count) */ + win_out(AI_SC_Load,AI_Command_1_Register); + + mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous; + win_out(mode1,AI_Mode_1_Register); + + /*start the MITE*/ + mite_dma_arm(devpriv->mite); + return mode1; +} +#endif + /* used for both cancel ioctl and board initialization @@ -1024,6 +1058,9 @@ static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s) win_out(AI_Configuration_Start,Joint_Reset_Register); #ifndef TRY_BLOCK + #ifdef PCIDMA + ni_ai_setup_MITE_dma(dev,cmd,mode1); + #else switch(cmd->stop_src){ case TRIG_COUNT: /* stage number of scans */ @@ -1054,8 +1091,8 @@ static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s) break; } + #endif #else - devpriv->blocksize = 0x4000; switch(cmd->stop_src){ case TRIG_COUNT: -- 2.26.2