From 394e4859cc89df1670f843e2997443da6103d4f9 Mon Sep 17 00:00:00 2001
From: David Schleef <ds@schleef.org>
Date: Sat, 17 Mar 2001 03:38:12 +0000
Subject: [PATCH] Removed dependency on s->async->cur_trig in all the drivers.
 Only dependency is in comedi_fops.c, where it could be replaced by a local
 variable.  Also cleaned up the buffer code in many of the drivers.

Probably broke a lot of code that was techinically already broken.
---
 comedi/comedi_fops.c            |  46 +++++-------
 comedi/drivers/adl_pci9118.c    |   8 +--
 comedi/drivers/comedi_parport.c |   4 +-
 comedi/drivers/das16-new.c      |   4 +-
 comedi/drivers/das6402.c        |   5 +-
 comedi/drivers/dt282x.c         |  32 +++++----
 comedi/drivers/mite.c           |   2 +-
 comedi/drivers/ni_atmio16d.c    |   5 +-
 comedi/drivers/ni_mio_common.c  |  24 +++----
 comedi/drivers/pcl812.c         |  43 ++++++-----
 comedi/drivers/pcl818.c         | 124 +++++++++++++++++++-------------
 include/linux/comedidev.h       |   4 ++
 12 files changed, 166 insertions(+), 135 deletions(-)

diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c
index a782ff07..d843508e 100644
--- a/comedi/comedi_fops.c
+++ b/comedi/comedi_fops.c
@@ -628,7 +628,8 @@ static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_tri
 	}
 cleanup:
 
-	do_become_nonbusy(dev,s);
+	s->busy=NULL;
+	//do_become_nonbusy(dev,s);
 
 	return ret;
 }
@@ -992,13 +993,13 @@ static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file)
 		DPRINTK("no buffer (?)\n");
 		goto cleanup;
 	}
+
+	/* XXX this needs to be removed when the drivers are ready */
 	async->cmd.data = async->prealloc_buf;
 	async->cmd.data_len=async->prealloc_bufsz;
 
-#ifdef CONFIG_COMEDI_MODE_CORE
-	s->cur_trig.data=async->prealloc_buf;	/* XXX */
-	s->cur_trig.data_len=async->prealloc_bufsz;
-#endif
+	async->data = async->prealloc_buf;
+	async->data_len=async->prealloc_bufsz;
 
 	async->buf_int_ptr=0;
 	async->buf_int_count=0;
@@ -1450,16 +1451,16 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes,
 		return -EIO;
 
 	if(!s->busy){
+		/* XXX this is going to change soon -- write cmds
+		 * will require start_src=TRIG_READY */
 		buf_ptr=async->prealloc_buf;
 		buf_len=async->prealloc_bufsz;
 	}else{
 		if(s->busy != file)
 			return -EACCES;
 
-#ifdef CONFIG_COMEDI_MODE_CORE
-		buf_ptr=s->cur_trig.data; /* XXX */
-		buf_len=s->cur_trig.data_len;
-#endif
+		buf_ptr=async->data;
+		buf_len=async->data_len;
 	}
 
 	if(!buf_ptr)
@@ -1550,11 +1551,6 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t
 	if(!s->busy)
 		return 0;
 
-#ifdef CONFIG_COMEDI_MODE_CORE
-	if(!s->cur_trig.data || !(s->subdev_flags&SDF_READABLE))	/* XXX */
-		return -EIO;
-#endif
-
 	if(s->busy != file)
 		return -EACCES;
 
@@ -1566,8 +1562,8 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t
 
 		m=async->buf_int_count-async->buf_user_count;
 
-		if(async->buf_user_ptr+m > s->cur_trig.data_len){ /* XXX MODE */
-			m=s->cur_trig.data_len - async->buf_user_ptr;
+		if(async->buf_user_ptr+m > async->data_len){
+			m=async->data_len - async->buf_user_ptr;
 #if 0
 printk("m is %d\n",m);
 #endif
@@ -1591,12 +1587,12 @@ printk("m is %d\n",m);
 			schedule();
 			continue;
 		}
-		m=copy_to_user(buf,((void *)(s->cur_trig.data))+async->buf_user_ptr,n);
+		m=copy_to_user(buf,async->data+async->buf_user_ptr,n);
 		if(m) retval=-EFAULT;
 		n-=m;
 
 		// check for buffer overrun
-		if(async->buf_int_count - async->buf_user_count > s->cur_trig.data_len){	/* XXX MODE */
+		if(async->buf_int_count - async->buf_user_count > async->data_len){	/* XXX MODE */
 			async->buf_user_count = async->buf_int_count;
 			async->buf_user_ptr = async->buf_int_ptr;
 			retval=-EINVAL;
@@ -1610,7 +1606,7 @@ printk("m is %d\n",m);
 		async->buf_user_ptr+=n;
 		async->buf_user_count+=n;
 
-		if(async->buf_user_ptr>=s->cur_trig.data_len ){
+		if(async->buf_user_ptr>=async->data_len ){
 			async->buf_user_ptr=0;
 		}
 
@@ -1650,19 +1646,13 @@ static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s)
 		s->cur_trig.chanlist=NULL;
 	}
 
-	if(s->cur_trig.data){
-		if(async == NULL || s->cur_trig.data != async->prealloc_buf)
-			kfree(s->cur_trig.data);
-
-		s->cur_trig.data=NULL;
-	}
-
-	if(async)
-	{
+	if(async){
 		async->buf_user_ptr=0;
 		async->buf_int_ptr=0;
 		async->buf_user_count=0;
 		async->buf_int_count=0;
+	}else{
+		printk("BUG: (?) do_become_nonbusy called with async=0\n");
 	}
 
 	s->busy=NULL;
diff --git a/comedi/drivers/adl_pci9118.c b/comedi/drivers/adl_pci9118.c
index b3431abc..b0aa82a3 100644
--- a/comedi/drivers/adl_pci9118.c
+++ b/comedi/drivers/adl_pci9118.c
@@ -364,8 +364,8 @@ static void interrupt_pci9118_ai_dma(int irq, void *d, struct pt_regs *regs)
 
 	if(s->async->buf_int_ptr+samplesinbuf*sizeof(sampl_t)>=devpriv->ai1234_data_len){
 		m=(devpriv->ai1234_data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
-		if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m); }
-					    else   { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m); }
+		if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->async->data))+s->async->buf_int_ptr,m); }
+					    else   { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->async->data))+s->async->buf_int_ptr,m); }
 		s->async->buf_int_count+=m*sizeof(sampl_t);
 		ptr+=m*sizeof(sampl_t);
 		samplesinbuf-=m;
@@ -373,8 +373,8 @@ static void interrupt_pci9118_ai_dma(int irq, void *d, struct pt_regs *regs)
 
 		comedi_eobuf(dev,s);
 	}
-	if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,samplesinbuf); }
-				    else   { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,samplesinbuf); }
+	if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->async->data))+s->async->buf_int_ptr,samplesinbuf); }
+				    else   { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->async->data))+s->async->buf_int_ptr,samplesinbuf); }
 	s->async->buf_int_count+=samplesinbuf*sizeof(sampl_t);
 	s->async->buf_int_ptr+=samplesinbuf*sizeof(sampl_t);
 
diff --git a/comedi/drivers/comedi_parport.c b/comedi/drivers/comedi_parport.c
index e60a6d8a..e5c43053 100644
--- a/comedi/drivers/comedi_parport.c
+++ b/comedi/drivers/comedi_parport.c
@@ -215,10 +215,10 @@ static void parport_interrupt(int irq,void *d,struct pt_regs *regs)
 		return;
 	}
 
-	*(sampl_t *)(((void *)s->cur_trig.data)+s->async->buf_int_ptr)=0;
+	*(sampl_t *)(s->async->data+s->async->buf_int_ptr)=0;
 	s->async->buf_int_ptr+=sizeof(sampl_t);
 	s->async->buf_int_count+=sizeof(sampl_t);
-	if(s->async->buf_int_ptr>=s->cur_trig.data_len){
+	if(s->async->buf_int_ptr>=s->async->data_len){
 		s->async->buf_int_ptr=0;
 		comedi_eobuf(dev,s);
 	}
diff --git a/comedi/drivers/das16-new.c b/comedi/drivers/das16-new.c
index 190bfbe2..f6aee000 100644
--- a/comedi/drivers/das16-new.c
+++ b/comedi/drivers/das16-new.c
@@ -715,13 +715,13 @@ static void das16_interrupt(int irq, void *d, struct pt_regs *regs)
 			msb = inb(dev->iobase+DAS16_AI_MSB);
 			
 			/* all this just to put data into a buffer! */
-			*(sampl_t *)(((void *)s->cur_trig.data)+s->async->buf_int_ptr) =
+			*(sampl_t *)(s->async->data+s->async->buf_int_ptr) =
 				(lsb>>4) + (msb<<4);
 
 			s->async->buf_int_ptr += sizeof(sampl_t);
 			s->async->buf_int_count += sizeof(sampl_t);
 
-			if(s->async->buf_int_ptr >= s->cur_trig.data_len) {	/* buffer rollover */
+			if(s->async->buf_int_ptr >= s->async->data_len) {	/* buffer rollover */
 				s->async->buf_int_ptr = 0;
 				comedi_eobuf(dev, s);
 			}
diff --git a/comedi/drivers/das6402.c b/comedi/drivers/das6402.c
index f7815cab..8402318e 100644
--- a/comedi/drivers/das6402.c
+++ b/comedi/drivers/das6402.c
@@ -197,9 +197,9 @@ static void das6402_ai_fifo_dregs(comedi_device *dev,comedi_subdevice *s)
 	int n,i;
 	sampl_t *data;
 
-	data=((void *)s->cur_trig.data);
 	while(1){
-		n=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
+		data=s->async->data+s->async->buf_int_ptr;
+		n=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
 		for(i=0;i<n;i++){
 			if(!(inb(dev->iobase+8)&0x01))
 				return;
@@ -209,7 +209,6 @@ static void das6402_ai_fifo_dregs(comedi_device *dev,comedi_subdevice *s)
 			s->async->buf_int_count+=sizeof(sampl_t);
 		}
 		s->async->buf_int_ptr=0;
-		data=s->cur_trig.data;
 		comedi_eobuf(dev,s);
 	}
 #if 0
diff --git a/comedi/drivers/dt282x.c b/comedi/drivers/dt282x.c
index c3f384b0..7b8845d9 100644
--- a/comedi/drivers/dt282x.c
+++ b/comedi/drivers/dt282x.c
@@ -383,16 +383,16 @@ static void copy_to_buf(comedi_device *dev,comedi_subdevice *s,void *buf,unsigne
 	unsigned int n;
 
 	n=n_bytes;
-	if(s->async->buf_int_ptr+n >= s->cur_trig.data_len){
-		n=s->cur_trig.data_len-s->async->buf_int_ptr;
-		memcpy(((void *)(s->cur_trig.data))+s->async->buf_int_ptr,buf,n);
+	if(s->async->buf_int_ptr+n >= s->async->data_len){
+		n=s->async->data_len-s->async->buf_int_ptr;
+		memcpy(s->async->data+s->async->buf_int_ptr,buf,n);
 		buf+=n;
 		s->async->buf_int_count+=n;
 		s->async->buf_int_ptr=0;
 
 		n=n_bytes-n;
 	}
-	memcpy(((void *)(s->cur_trig.data))+s->async->buf_int_ptr,buf,n);
+	memcpy(s->async->data+s->async->buf_int_ptr,buf,n);
 	buf+=n;
 	s->async->buf_int_count+=n;
 	s->async->buf_int_ptr+=n;
@@ -408,16 +408,16 @@ static int copy_from_buf(comedi_device *dev,comedi_subdevice *s,void *buf,unsign
 		n=n_bytes;
 
 	n_bytes=n;
-	if(s->async->buf_int_ptr+n >= s->cur_trig.data_len){
-		m=s->cur_trig.data_len-s->async->buf_int_ptr;
-		memcpy(buf,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m);
+	if(s->async->buf_int_ptr+n >= s->async->data_len){
+		m=s->async->data_len-s->async->buf_int_ptr;
+		memcpy(buf,s->async->data+s->async->buf_int_ptr,m);
 		buf+=m;
 		s->async->buf_int_count+=m;
 		s->async->buf_int_ptr=0;
 
 		n-=m;
 	}
-	memcpy(buf,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+	memcpy(buf,s->async->data+s->async->buf_int_ptr,n);
 	s->async->buf_int_count+=n;
 	s->async->buf_int_ptr+=n;
 
@@ -434,8 +434,8 @@ static void dt282x_ao_dma_interrupt(comedi_device * dev)
 
 	update_supcsr(DT2821_CLRDMADNE);
 
-	if(!s->cur_trig.data){
-		printk("cur_trig.data disappeared.  dang!\n");
+	if(!s->async->data){
+		printk("async->data disappeared.  dang!\n");
 		return;
 	}
 
@@ -470,8 +470,8 @@ static void dt282x_ai_dma_interrupt(comedi_device * dev)
 
 	update_supcsr(DT2821_CLRDMADNE);
 
-	if(!s->cur_trig.data){
-		printk("cur_trig.data disappeared.  dang!\n");
+	if(!s->async->data){
+		printk("async->data disappeared.  dang!\n");
 		return;
 	}
 
@@ -610,7 +610,13 @@ static void dt282x_interrupt(int irq, void *d, struct pt_regs *regs)
 		if(devpriv->ad_2scomp){
 			data^=1<<(boardtype.adbits-1);
 		}
-		s->cur_trig.data[s->async->buf_int_ptr++]=data;
+		*(sampl_t *)(s->async->data+s->async->buf_int_ptr)=data;
+		s->async->buf_int_ptr+=sizeof(sampl_t);
+		s->async->buf_int_count+=sizeof(sampl_t);
+		if(s->async->buf_int_ptr>=s->async->data_len){
+			s->async->buf_int_ptr = 0;
+			//s->events |= COMEDI_EOBUF;
+		}
 
 		devpriv->nread--;
 		if(!devpriv->nread){
diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c
index 3c8d15ff..76fd59b4 100644
--- a/comedi/drivers/mite.c
+++ b/comedi/drivers/mite.c
@@ -252,7 +252,7 @@ void mite_dma_prep(struct mite_struct *mite,comedi_subdevice *s)
 
 	for(i=0;i<MITE_RING_SIZE;i++){
 		n=s->async->prealloc_bufsz-s->async->buf_int_ptr;
-		n=mite_kvmem_segment_load(mite,i,((void *)s->cur_trig.data)+s->async->buf_int_ptr,n);
+		n=mite_kvmem_segment_load(mite,i,s->async->data+s->async->buf_int_ptr,n);
 		s->async->buf_int_ptr+=n;
 		if(s->async->buf_int_ptr>=s->async->prealloc_bufsz)
 			s->async->buf_int_ptr=0;
diff --git a/comedi/drivers/ni_atmio16d.c b/comedi/drivers/ni_atmio16d.c
index 88523646..b8ac09d7 100644
--- a/comedi/drivers/ni_atmio16d.c
+++ b/comedi/drivers/ni_atmio16d.c
@@ -262,7 +262,8 @@ static void atmio16d_interrupt(int irq, void *d, struct pt_regs *regs)
 	
 //	printk("atmio16d_interrupt!\n");
 
-	*(sampl_t *)(((void *)s->cur_trig.data)+s->async->buf_int_ptr) = inw(dev->iobase+AD_FIFO_REG);
+	*(sampl_t *)(s->async->data+s->async->buf_int_ptr) =
+		inw(dev->iobase+AD_FIFO_REG);
 	s->async->buf_int_ptr += sizeof(sampl_t);
 	s->async->buf_int_count += sizeof(sampl_t);
 
@@ -271,7 +272,7 @@ static void atmio16d_interrupt(int irq, void *d, struct pt_regs *regs)
 		comedi_eos(dev, s);
 	}
 
-	if (s->async->buf_int_ptr >= s->cur_trig.data_len) {	/* buffer rollover */
+	if (s->async->buf_int_ptr >= s->async->data_len) {	/* buffer rollover */
 		s->async->buf_int_ptr = 0;
 		comedi_eobuf(dev, s);
 	}
diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c
index 18777da0..de66a6f5 100644
--- a/comedi/drivers/ni_mio_common.c
+++ b/comedi/drivers/ni_mio_common.c
@@ -452,16 +452,16 @@ static void ni_handle_fifo_half_full(comedi_device *dev)
 	/* this makes the assumption that the buffer length is
 	   greater than the half-fifo depth. */
 
-	if(s->async->buf_int_ptr+n*sizeof(sampl_t)>=s->cur_trig.data_len){
-		m=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
-		ni_ai_fifo_read(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m);
+	if(s->async->buf_int_ptr+n*sizeof(sampl_t)>=s->async->data_len){
+		m=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
+		ni_ai_fifo_read(dev,s,s->async->data+s->async->buf_int_ptr,m);
 		s->async->buf_int_count+=m*sizeof(sampl_t);
 		n-=m;
 		s->async->buf_int_ptr=0;
 
 		comedi_eobuf(dev,s);
 	}
-	ni_ai_fifo_read(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+	ni_ai_fifo_read(dev,s,s->async->data+s->async->buf_int_ptr,n);
 	s->async->buf_int_count+=n*sizeof(sampl_t);
 	s->async->buf_int_ptr+=n*sizeof(sampl_t);
 
@@ -486,9 +486,9 @@ static void ni_handle_fifo_dregs(comedi_device *dev)
 
 	mask=(1<<boardtype.adbits)-1;
 	j=s->async->cur_chan;
-	data=((void *)s->cur_trig.data)+s->async->buf_int_ptr;
+	data=s->async->data+s->async->buf_int_ptr;
 	while(1){
-		n=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
+		n=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
 		for(i=0;i<n;i++){
 			if(ni_readw(AI_Status_1)&AI_FIFO_Empty_St){
 				s->async->cur_chan=j;
@@ -508,7 +508,7 @@ static void ni_handle_fifo_dregs(comedi_device *dev)
 			s->async->buf_int_count+=sizeof(sampl_t);
 		}
 		s->async->buf_int_ptr=0;
-		data=s->cur_trig.data;
+		data=s->async->data;
 		comedi_eobuf(dev,s);
 	}
 }
@@ -1122,14 +1122,14 @@ static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s)
 	if(n>boardtype.ao_fifo_depth/2)
 		n=boardtype.ao_fifo_depth/2;
 
-	if(s->async->buf_int_ptr+n*sizeof(sampl_t)>s->cur_trig.data_len){
-		m=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
-		ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m);
+	if(s->async->buf_int_ptr+n*sizeof(sampl_t)>s->async->data_len){
+		m=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
+		ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,m);
 		s->async->buf_int_count+=m*sizeof(sampl_t);
 		s->async->buf_int_ptr=0;
 		n-=m;
 	}
-	ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+	ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,n);
 	s->async->buf_int_count+=n*sizeof(sampl_t);
 	s->async->buf_int_ptr+=n*sizeof(sampl_t);
 
@@ -1151,7 +1151,7 @@ static int ni_ao_prep_fifo(comedi_device *dev,comedi_subdevice *s)
 	if(n>boardtype.ao_fifo_depth)
 		n=boardtype.ao_fifo_depth;
 
-	ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+	ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,n);
 	s->async->buf_int_count+=n*sizeof(sampl_t);
 	s->async->buf_int_ptr+=n*sizeof(sampl_t);
 
diff --git a/comedi/drivers/pcl812.c b/comedi/drivers/pcl812.c
index 006b1122..47a95d1a 100644
--- a/comedi/drivers/pcl812.c
+++ b/comedi/drivers/pcl812.c
@@ -75,6 +75,8 @@
 
 #define PCL812_DRDY 0x10
 
+#define AI_LEN_CHANLIST 16
+
 /*
   For PCL-813B: 
   I don't know if timeouts which are specified at a documentation 
@@ -214,7 +216,7 @@ typedef struct {
 	int int812_mode; /*1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */
 	//int int13_act_ptr;
 	int int13_act_scan;
-	int int13_act_chan;
+	unsigned int chanlist[AI_LEN_CHANLIST];
 } pcl812_private;
 
 #define devpriv ((pcl812_private *)dev->private)
@@ -351,34 +353,39 @@ static void interrupt_pcl812_ai_mode13_int(int irq, void *d, struct pt_regs *reg
 
       conv_finish:
 
-	s->cur_trig.data[s->async->buf_int_ptr++] = ((hi << 8) | inb(dev->iobase + PCL812_AD_LO)) & 0xfff;
+	*(sampl_t *)(s->async->data+s->async->buf_int_ptr) =
+		((hi << 8) | inb(dev->iobase + PCL812_AD_LO)) & 0xfff;
+	s->async->buf_int_ptr+=sizeof(sampl_t);
 
 	outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
 
 	s->async->buf_int_count += sizeof(sampl_t);
 
-	if ((++devpriv->int13_act_chan) >= s->cur_trig.n_chan) {	/* one scan done */
-		devpriv->int13_act_chan = 0;
-		outb(CR_RANGE(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_GAIN);	/* select next gain */
-		outb(CR_CHAN(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_MUX);	/* select next channel */
-		if (s->cur_trig.flags & TRIG_WAKE_EOS) {
+	s->async->cur_chan++;
+	if (s->async->cur_chan >= s->async->cur_chanlist_len) {	/* one scan done */
+		s->async->cur_chan=0;
+#if 0
+		/* this uses comedi_eos and comedi_bufcheck incorrectly */
+		if (devpriv->cur_flags & TRIG_WAKE_EOS) {
 			comedi_eos(dev, s);
 		} else {
 			comedi_bufcheck(dev, s);
 		}
-		devpriv->int13_act_scan++;
-	} else {
-		outb(CR_RANGE(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_GAIN);	/* select next gain */
-		outb(CR_CHAN(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_MUX);	/* select next channel */
+#else
+		comedi_bufcheck(dev, s);
+#endif
+		devpriv->int13_act_scan--;
 	}
+	outb(CR_RANGE(devpriv->chanlist[s->async->cur_chan]), dev->iobase + PCL812_GAIN);	/* select next gain */
+	outb(CR_CHAN(devpriv->chanlist[s->async->cur_chan]), dev->iobase + PCL812_MUX);	/* select next channel */
 
-	if (s->async->buf_int_ptr >= s->cur_trig.data_len) {	/* buffer rollover */
+	if (s->async->buf_int_ptr >= s->async->data_len) {	/* buffer rollover */
 		s->async->buf_int_ptr = 0;
 		//devpriv->int13_act_ptr=0;
 		comedi_eobuf(dev, s);
 	}
 
-	if (devpriv->int13_act_scan >= s->cur_trig.n) {	/* all data sampled */
+	if (devpriv->int13_act_scan == 0) {	/* all data sampled */
 		outb(0, dev->iobase + PCL812_MODE);	/* Stop A/D */
 		outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
 		if (devpriv->int812_mode == 1) {
@@ -467,11 +474,12 @@ static int pcl812_ai_mode1_int(comedi_device * dev, comedi_subdevice * s, comedi
 
 	//devpriv->int13_act_ptr=0;
 	devpriv->int13_act_scan = 0;
-	devpriv->int13_act_chan = 0;
 	devpriv->int812_mode = INT_TYPE_AI1_INT;	/* analog in, mode 0, int driven */
 	devpriv->irq_blocked = 1;
 	devpriv->irq_was_now_closed = 0;
 
+	memcpy(devpriv->chanlist,it->chanlist,sizeof(int)*it->n_chan);
+
 	outb(6, dev->iobase + PCL812_MODE);	/* Pacer+IRQ */
 
 	return 0;
@@ -530,11 +538,12 @@ static int pcl812_ai_mode3_int(comedi_device * dev, comedi_subdevice * s, comedi
 	outb(0, dev->iobase + PCL812_CLRINT);
 
 	//devpriv->int13_act_ptr=0;
-	devpriv->int13_act_scan = 0;
-	devpriv->int13_act_chan = 0;
+	devpriv->int13_act_scan = it->n;
 	devpriv->int812_mode = 3;	/* analog in, mode 3, int driven */
 	devpriv->irq_blocked = 1;
 
+	memcpy(devpriv->chanlist,it->chanlist,sizeof(int)*it->n_chan);
+
 	outb(6, dev->iobase + PCL812_MODE);	/* external trigger+IRQ */
 
 	return 0;
@@ -726,7 +735,7 @@ static int pcl812_attach(comedi_device * dev, comedi_devconfig * it)
 		s->subdev_flags = SDF_READABLE;
 		s->n_chan = this_board->n_aichan;
 		s->maxdata = 0xfff;
-		s->len_chanlist = 1024;
+		s->len_chanlist = AI_LEN_CHANLIST;
 		s->range_table = this_board->ai_range_type;
 		s->subdev_flags |= SDF_GROUND;
 		s->trig[0] = pcl812_ai_mode0;
diff --git a/comedi/drivers/pcl818.c b/comedi/drivers/pcl818.c
index c12add38..500e9805 100644
--- a/comedi/drivers/pcl818.c
+++ b/comedi/drivers/pcl818.c
@@ -446,7 +446,8 @@ static void interrupt_pcl818_ai_mode13_int(int irq, void *d, struct pt_regs *reg
 
 conv_finish:
         low=inb(dev->iobase + PCL818_AD_LO);
-	s->cur_trig.data[devpriv->buf_ptr++]=((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4)); // get one sample
+	*(sampl_t *)(s->async->data+devpriv->buf_ptr)=((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4)); // get one sample
+	devpriv->buf_ptr+=sizeof(sampl_t);
         outb(0,dev->iobase+PCL818_CLRINT); /* clear INT request */
 
         if ((low & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
@@ -458,18 +459,23 @@ conv_finish:
         s->async->buf_int_ptr+=sizeof(sampl_t);
         s->async->buf_int_count+=sizeof(sampl_t);
 
-
-        if (++devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
-
-        if ((++devpriv->int13_act_chan)>=s->cur_trig.n_chan) { /* one scan done */
-		devpriv->int13_act_chan=0;
-		if (s->cur_trig.flags & TRIG_WAKE_EOS) { comedi_eos(dev,s); }
-						    else { comedi_bufcheck(dev,s); }
+	s->async->cur_chan++;
+        if (s->async->cur_chan>=s->async->cur_chanlist_len){
+		s->async->cur_chan=0;
+#if 0
+		if (devpriv->cur_flags & TRIG_WAKE_EOS){
+			comedi_eos(dev,s);
+		} else {
+			comedi_bufcheck(dev,s);
+		}
+#else
+		comedi_bufcheck(dev,s);
+#endif
 		// rt_printk("E");
-		devpriv->int13_act_scan++;
+		devpriv->int13_act_scan--;
         }
 
-	if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+	if (s->async->buf_int_ptr>=s->async->data_len) { /* buffer rollover */
 		s->async->buf_int_ptr=0;
 		devpriv->buf_ptr=0;
 		//printk("B ");
@@ -477,7 +483,7 @@ conv_finish:
         }
 
 	if (!devpriv->neverending_ai)
-		if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
+		if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */
 			pcl818_ai_cancel(dev,s);
 	        	comedi_done(dev,s);
 			return;
@@ -523,27 +529,27 @@ static void interrupt_pcl818_ai_mode13_dma(int irq, void *d, struct pt_regs *reg
 			return;
 		}
 
-		s->cur_trig.data[devpriv->buf_ptr++]=ptr[bufptr++] >> 4; // get one sample
+		*(sampl_t *)(s->async->data+s->async->buf_int_ptr)=
+			ptr[bufptr++] >> 4; // get one sample
+		devpriv->buf_ptr++;
 
 		s->async->buf_int_ptr+=sizeof(sampl_t);
 		s->async->buf_int_count+=sizeof(sampl_t);
 		devpriv->act_chanlist_pos++;
 
-		if (devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
-
-		if ((++devpriv->int13_act_chan)>=s->cur_trig.n_chan) { /* one scan done */
-			devpriv->int13_act_chan=0;
-		        devpriv->int13_act_scan++;
+		s->async->cur_chan++;
+		if(s->async->cur_chan>=s->async->cur_chanlist_len){
+			s->async->cur_chan=0;
 		}
 
-		if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+		if (s->async->buf_int_ptr>=s->async->data_len) { /* buffer rollover */
 	    		s->async->buf_int_ptr=0;
 			devpriv->buf_ptr=0;
 			comedi_eobuf(dev,s);
 		}
 
 		if (!devpriv->neverending_ai)
-	    		if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
+	    		if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */
 				pcl818_ai_cancel(dev,s);
 				comedi_done(dev,s);
 				// printk("done int ai13 dma\n");
@@ -609,28 +615,28 @@ static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs
 				return;
 			}
 
-			s->cur_trig.data[devpriv->buf_ptr++]=dmabuf[bufptr++] >> 4; // get one sample
+			*(sampl_t *)(s->async->data+s->async->buf_int_ptr)=
+				dmabuf[bufptr++] >> 4; // get one sample
+			devpriv->buf_ptr++;
 			bufptr&=(devpriv->dmasamplsize-1);
 
 			s->async->buf_int_ptr+=sizeof(sampl_t);
 			s->async->buf_int_count+=sizeof(sampl_t);
-			devpriv->act_chanlist_pos++;
-
-			if (devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
 
-			if ((++devpriv->int13_act_chan)>=s->cur_trig.n_chan) { /* one scan done */
-				devpriv->int13_act_chan=0;
-				devpriv->int13_act_scan++;
+			s->async->cur_chan++;
+			if(s->async->cur_chan>=s->async->cur_chanlist_len){
+				s->async->cur_chan++;
+				devpriv->int13_act_scan--;
 			}
 
-			if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+			if (s->async->buf_int_ptr>=s->async->data_len) { /* buffer rollover */
 				s->async->buf_int_ptr=0;
 				devpriv->buf_ptr=0;
 				comedi_eobuf(dev,s);
 			}
 
 			if (!devpriv->neverending_ai)
-				if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
+				if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */
 					pcl818_ai_cancel(dev,s);
 					comedi_done(dev,s);
 					//printk("done int ai13 dma\n");
@@ -691,26 +697,26 @@ static void interrupt_pcl818_ai_mode13_fifo(int irq, void *d, struct pt_regs *re
 			return;
 		}
 
-		s->cur_trig.data[devpriv->buf_ptr++]=(lo >> 4)|(inb(dev->iobase + PCL818_FI_DATAHI) << 4); // get one sample
+		*(sampl_t *)(s->async->data+s->async->buf_int_ptr)=
+			(lo >> 4)|(inb(dev->iobase + PCL818_FI_DATAHI) << 4); // get one sample
+		devpriv->buf_ptr++;
 		s->async->buf_int_ptr+=sizeof(sampl_t);
 		s->async->buf_int_count+=sizeof(sampl_t);
-		devpriv->act_chanlist_pos++;
 
-		if (devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
-
-		if ((++devpriv->int13_act_chan)>=s->cur_trig.n_chan) { /* one scan done */
-			devpriv->int13_act_chan=0;
-			devpriv->int13_act_scan++;
+		s->async->cur_chan++;
+		if(s->async->cur_chan>=s->async->cur_chanlist_len){
+			s->async->cur_chan = 0;
+			devpriv->int13_act_scan--;
 		}
 
-		if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+		if (s->async->buf_int_ptr>=s->async->data_len) { /* buffer rollover */
 			s->async->buf_int_ptr=0;
 			devpriv->buf_ptr=0;
     			comedi_eobuf(dev,s);    
 		}
      
 		if (!devpriv->neverending_ai)
-			if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
+			if ( devpriv->int13_act_scan == 0 ) { /* all data sampled */
 				comedi_bufcheck(dev,s);
 				pcl818_ai_cancel(dev,s);
 				comedi_done(dev,s); 
@@ -778,7 +784,7 @@ void pcl818_ai_mode13dma_int(int mode, comedi_device * dev, comedi_subdevice * s
 
         bytes=devpriv->hwdmasize[0];
         if (!devpriv->neverending_ai) {
-		bytes=s->cur_trig.n_chan*s->cur_trig.n*sizeof(sampl_t); // how many 
+		bytes=it->n_chan*it->n*sizeof(sampl_t); // how many 
 		devpriv->dma_runs_to_end=bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fiil
 		devpriv->last_dma_run=bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved
 		devpriv->dma_runs_to_end--;
@@ -861,7 +867,7 @@ static int pcl818_ai_mode13(int mode, comedi_device * dev, comedi_subdevice * s,
         if (!check_and_setup_channel_list(dev, s, it)) return -EINVAL;
 	udelay(1);
 
-        devpriv->int13_act_scan=0;
+        devpriv->int13_act_scan=it->n;
         devpriv->int13_act_chan=0;
 	devpriv->irq_blocked=1;
         devpriv->irq_was_now_closed=0;
@@ -869,7 +875,7 @@ static int pcl818_ai_mode13(int mode, comedi_device * dev, comedi_subdevice * s,
         devpriv->act_chanlist_pos=0;
         devpriv->buf_ptr=0;
   
-	if ((s->cur_trig.n==0)||(s->cur_trig.n==-1)) devpriv->neverending_ai=1; //well, user want neverending
+	if ((it->n==0)||(it->n==-1)) devpriv->neverending_ai=1; //well, user want neverending
   
         if (mode==1) {
 		if (it->trigvar<devpriv->ns_min) it->trigvar=devpriv->ns_min;
@@ -964,7 +970,7 @@ static int pcl818_ao_mode13(int mode, comedi_device * dev, comedi_subdevice * s,
 
         start_pacer(dev, -1, 0, 0); // stop pacer
 
-	devpriv->int13_act_scan=0;
+	devpriv->int13_act_scan=it->n;
         devpriv->int13_act_chan=0;
         devpriv->irq_blocked=1;
         devpriv->irq_was_now_closed=0;
@@ -1053,24 +1059,36 @@ int check_and_setup_channel_list(comedi_device * dev, comedi_subdevice * s, come
         }
 
         if (it->n_chan > 1) {
-		chansegment[0]=it->chanlist[0]; // first channel is everytime ok
-		for (i=1, seglen=1; i<it->n_chan; i++, seglen++) { // build part of chanlist
+		// first channel is everytime ok
+		chansegment[0]=it->chanlist[0];
+		// build part of chanlist
+		for (i=1, seglen=1; i<it->n_chan; i++, seglen++) {
 			// rt_printk("%d. %d %d\n",i,CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
-			if (it->chanlist[0]==it->chanlist[i]) break; // we detect loop, this must by finish
+			// we detect loop, this must by finish
+			if (it->chanlist[0]==it->chanlist[i]) break;
 			nowmustbechan=(CR_CHAN(chansegment[i-1])+1) % s->n_chan;
-			if (nowmustbechan!=CR_CHAN(it->chanlist[i])) { // channel list isn't continous :-(
+			// channel list isn't continous :-(
+			if (nowmustbechan!=CR_CHAN(it->chanlist[i])) {
 				rt_printk("comedi%d: pcl818: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
-					    dev->minor,i,CR_CHAN(it->chanlist[i]),nowmustbechan,CR_CHAN(it->chanlist[0]) );
+					    dev->minor,i,CR_CHAN(it->chanlist[i]),
+					    nowmustbechan,CR_CHAN(it->chanlist[0]) );
 				return 0;             
 			}
-			chansegment[i]=it->chanlist[i]; // well, this is next correct channel in list
+			// well, this is next correct channel in list
+			chansegment[i]=it->chanlist[i];
 		}
 
-		for (i=0, segpos=0; i<it->n_chan; i++) {  // check whole chanlist
+		// check whole chanlist
+		for (i=0, segpos=0; i<it->n_chan; i++) {
 			//rt_printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
 			if (it->chanlist[i]!=chansegment[i%seglen]) {
 				rt_printk("comedi%d: pcl818: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
-					    dev->minor,i,CR_CHAN(chansegment[i]),CR_RANGE(chansegment[i]),CR_AREF(chansegment[i]),CR_CHAN(it->chanlist[i%seglen]),CR_RANGE(it->chanlist[i%seglen]),CR_AREF(chansegment[i%seglen]));
+				  dev->minor,i,CR_CHAN(chansegment[i]),
+				  CR_RANGE(chansegment[i]),
+				  CR_AREF(chansegment[i]),
+				  CR_CHAN(it->chanlist[i%seglen]),
+				  CR_RANGE(it->chanlist[i%seglen]),
+				  CR_AREF(chansegment[i%seglen]));
 				return 0; // chan/gain list is strange
 			}
 		}
@@ -1089,9 +1107,13 @@ int check_and_setup_channel_list(comedi_device * dev, comedi_subdevice * s, come
 
 	udelay(1);
 
-	outb(devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen-1] << 4) , dev->iobase+PCL818_MUX); /* select channel interval to sca n*/
+	/* select channel interval to sca n*/
+	outb(devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen-1] << 4),
+		dev->iobase+PCL818_MUX);
 	// printk(" MUX %x\n",devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen-1] << 4));
-	return 1; // we can serve this with MUX logic
+	
+	// we can serve this with MUX logic
+	return 1;
 }
 
 /* 
diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h
index 3eafac70..f23db122 100644
--- a/include/linux/comedidev.h
+++ b/include/linux/comedidev.h
@@ -113,6 +113,7 @@ struct comedi_async_struct{
 	unsigned int	prealloc_bufsz;		/* buffer size, in bytes */
 	unsigned int	max_bufsize;		/* maximum buffer size, bytes */
 	unsigned int	mmap_count;	/* current number of mmaps of prealloc_buf */
+
 	volatile unsigned int buf_int_ptr;	/* buffer marker for interrupt */
 	unsigned int buf_user_ptr;		/* buffer marker for read() and write() */
 	volatile unsigned int buf_int_count;	/* byte count for interrupt */
@@ -120,6 +121,9 @@ struct comedi_async_struct{
 	unsigned int cur_chan;		/* useless channel marker for interrupt */
 	unsigned int cur_chanlist_len;
 
+	void		*data;
+	unsigned int	data_len;
+
 	comedi_cmd cmd;
 
 	// callback stuff
-- 
2.26.2