diff -pur v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110_av.c v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110_av.c
--- v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110_av.c	2008-09-03 23:24:46.000000000 +0200
+++ v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110_av.c	2008-09-06 00:49:56.000000000 +0200
@@ -830,7 +830,7 @@ void dvb_video_add_event(struct av7110 *
 	struct dvb_video_events *events = &av7110->video_events;
 	int wp;
 
-	spin_lock_bh(&events->lock);
+	spin_lock(&events->lock);
 
 	wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
 	if (wp == events->eventr) {
@@ -842,7 +842,7 @@ void dvb_video_add_event(struct av7110 *
 	memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
 	events->eventw = wp;
 
-	spin_unlock_bh(&events->lock);
+	spin_unlock(&events->lock);
 
 	wake_up_interruptible(&events->wait_queue);
 }
@@ -868,13 +868,13 @@ static int dvb_video_get_event (struct a
 			return ret;
 	}
 
-	spin_lock_bh(&events->lock);
+	spin_lock_irq(&events->lock);
 
 	memcpy(event, &events->events[events->eventr],
 	       sizeof(struct video_event));
 	events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
 
-	spin_unlock_bh(&events->lock);
+	spin_unlock_irq(&events->lock);
 
 	return 0;
 }
@@ -1207,7 +1207,7 @@ static int dvb_video_ioctl(struct inode 
 	case VIDEO_CLEAR_BUFFER:
 		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
 		av7110_ipack_reset(&av7110->ipack[1]);
-
+		av7110->tx_av.clear = 1;
 		if (av7110->playing == RP_AV) {
 			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
 					    __Play, 2, AV_PES, 0);
@@ -1362,6 +1362,7 @@ static int dvb_audio_ioctl(struct inode 
 	case AUDIO_CLEAR_BUFFER:
 		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
 		av7110_ipack_reset(&av7110->ipack[0]);
+		av7110->tx_a.clear = 1;
 		if (av7110->playing == RP_AV)
 			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
 					    __Play, 2, AV_PES, 0);
Nur in v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/: av7110_av.c.orig.
diff -pur v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110.c v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110.c
--- v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110.c	2008-11-07 13:29:57.000000000 +0100
+++ v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110.c	2008-09-06 00:49:49.000000000 +0200
@@ -276,6 +273,12 @@ static int arm_thread(void *data)
 		av7110_check_ir_config(av7110, false);
 #endif
 
+		if (av7110->rx_overflow_cnt) {
+			printk("dvb-ttpci card %u: DMA RX overflow %u times\n",
+				av7110->dvb_adapter.num, av7110->rx_overflow_cnt);
+			av7110->rx_overflow_cnt = 0;
+		}
+
 		if (mutex_lock_interruptible(&av7110->dcomlock))
 			break;
 		newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
@@ -354,18 +357,156 @@ static int DvbDmxFilterCallback(u8 *buff
 
 
 //#define DEBUG_TIMING
+#ifdef DEBUG_TIMING
 static inline void print_time(char *s)
 {
-#ifdef DEBUG_TIMING
 	struct timeval tv;
 	do_gettimeofday(&tv);
 	printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
+}
 #endif
+
+
+static void processDmaRx(unsigned long data)
+{
+	struct av7110 *av7110 = (struct av7110 *) data;
+	int idx;
+
+	while (av7110->rx.debilen[idx = av7110->rx.readIdx]) {
+		int debitype = av7110->rx.debitype[idx];
+		int handle = (debitype >> 8) & 0x1f;
+		u8 *debibuf = av7110->debi_virt + av7110->rx.offset[idx];
+		unsigned debilen = av7110->rx.debilen[idx];
+
+		switch (debitype & 0xff) {
+		case DATA_TS_RECORD:
+#if 1
+			if (*debibuf != 0x47)
+				printk("%s no SYNC byte, got %02x %02x %02x %02x %02x\n",
+					__func__,  debibuf[0], debibuf[1], debibuf[2],
+					debibuf[3], debibuf[4]);
+			if (debilen % 188)
+				printk("%s invalid length %d\n",
+					__func__, debilen);
+#endif
+			dvb_dmx_swfilter_packets(&av7110->demux, (const u8 *) debibuf,
+						 debilen / 188);
+			break;
+
+		case DATA_PES_RECORD:
+			if (av7110->demux.recording)
+				av7110_record_cb(&av7110->p2t[handle], debibuf, debilen);
+			break;
+
+		case DATA_IPMPE:
+		case DATA_FSECTION:
+		case DATA_PIPING:
+			if (av7110->handle2filter[handle])
+				DvbDmxFilterCallback(debibuf, debilen, NULL, 0,
+						     av7110->handle2filter[handle],
+						     DMX_OK, av7110);
+			break;
+
+		case DATA_CI_GET:
+		{
+			if ((debibuf[0] < 2) && debibuf[2] == 0xff) {
+				int flags = 0;
+				if (debibuf[5] > 0)
+					flags |= CA_CI_MODULE_PRESENT;
+				if (debibuf[5] > 5)
+					flags |= CA_CI_MODULE_READY;
+				av7110->ci_slot[debibuf[0]].flags = flags;
+			} else
+				ci_get_data(&av7110->ci_rbuffer, debibuf, debilen);
+			break;
+		}
+
+		case DATA_COMMON_INTERFACE:
+			CI_handle(av7110, debibuf, debilen);
+#if 0 /* keep */
+		{
+			int i;
+
+			printk("av7110(%d): ", av7110->dvb_adapter.num);
+			printk("%02x ", debibuf[0]);
+			printk("%02x ", debibuf[1]);
+			for (i = 2; i < debilen; i++)
+				printk("%02x ", debibuf[i]);
+			for (i = 2; i < debilen; i++)
+				printk("%c", chtrans(debibuf[i]));
+			printk("\n");
+		}
+#endif
+			break;
+
+		case DATA_DEBUG_MESSAGE:
+			debibuf[Reserved_SIZE - 1] = 0;
+			printk("%s\n", (s8 *) debibuf);
+			break;
+
+		default:
+			printk("dvb-ttpci: %s unsupported debitype %d\n",
+				__func__, debitype);
+			break;
+		}
+
+		av7110->rx.debilen[idx] = 0;
+		if (++idx >= DMA_RX_BUFS)
+			idx = 0;
+		av7110->rx.readIdx = idx;
+	}
 }
 
+
+static void fillDmaTx(unsigned long data)
+{
+	struct av7110 *av7110 = (struct av7110 *) data;
+	int idx;
+	u8 *debibuf;
+	int len;
+
+	while (! av7110->tx_av.debilen[idx = av7110->tx_av.writeIdx]) {
+		debibuf = av7110->debi_virt + av7110->tx_av.offset[idx];
+		len = av7110_pes_play(debibuf, &av7110->avout, DMA_TX_BUF_SIZE);
+		if (len <= 0)
+			break;
+		av7110->tx_av.debilen[idx] = len;
+		if (++idx >= DMA_TX_AV_BUFS)
+			idx = 0;
+		av7110->tx_av.writeIdx = idx;
+	}
+
+	while (! av7110->tx_a.debilen[idx = av7110->tx_a.writeIdx]) {
+		debibuf = av7110->debi_virt + av7110->tx_a.offset[idx];
+		len = av7110_pes_play(debibuf, &av7110->aout, DMA_TX_BUF_SIZE);
+		if (len <= 0)
+			break;
+		av7110->tx_a.debilen[idx] = len;
+		if (++idx >= DMA_TX_A_BUFS)
+			idx = 0;
+		av7110->tx_a.writeIdx = idx;
+	}
+
+	while (av7110->bmp_state == BMP_LOADING &&
+	       ! av7110->tx_bmp.debilen[idx = av7110->tx_bmp.writeIdx]) {
+		len = min(av7110->bmplen, DMA_TX_BUF_SIZE);
+		if (len <= 0)
+			break;
+		debibuf = av7110->debi_virt + av7110->tx_bmp.offset[idx];
+		memcpy(debibuf, av7110->bmpbuf + av7110->bmpp, len);
+		av7110->bmpp += len;
+		av7110->bmplen -= len;
+		av7110->tx_bmp.debilen[idx] = len;
+		if (++idx >= DMA_TX_BMP_BUFS)
+			idx = 0;
+		av7110->tx_bmp.writeIdx = idx;
+	}
+}
+
+
 #define DEBI_READ 0
 #define DEBI_WRITE 1
-static inline void start_debi_dma(struct av7110 *av7110, int dir,
+static inline void start_debi_dma(struct av7110 *av7110, int dir, u32 offset,
 				  unsigned long addr, unsigned int len)
 {
 	dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
@@ -379,127 +520,130 @@ static inline void start_debi_dma(struct
 	if (len < 5)
 		len = 5; /* we want a real DEBI DMA */
 	if (dir == DEBI_WRITE)
-		iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
+		av7110_debiwrite(av7110, DEBISWAB, offset, addr, 0, (len + 3) & ~3);
 	else
-		irdebi(av7110, DEBISWAB, addr, 0, len);
+		av7110_debiread(av7110, DEBISWAB, offset, addr, len);
 }
 
-static void debiirq(unsigned long cookie)
+static inline u16 debiack(struct av7110 *av7110, u16 xfer)
+{
+	u16 nextBuf = 0;
+
+	spin_lock(&av7110->debilock);
+	if (xfer) {
+		iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
+#if 0
+		if (xfer == RX_BUFF) {
+			if (irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2))
+				nextBuf = TX_BUFF;
+		} else {
+			if (irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2))
+				nextBuf = RX_BUFF;
+		}
+#endif
+	}
+	if (nextBuf == 0)
+		ARM_ClearMailBox(av7110);
+	spin_unlock(&av7110->debilock);
+	return nextBuf;
+}
+
+static void gpioirq(struct av7110 *av7110, u16 nextBuf);
+
+static void debiirq(struct av7110 *av7110)
 {
-	struct av7110 *av7110 = (struct av7110 *)cookie;
 	int type = av7110->debitype;
-	int handle = (type >> 8) & 0x1f;
-	unsigned int xfer = 0;
+	int idx;
+	u16 nextBuf;
 
+#ifdef DEBUG_TIMING
 	print_time("debi");
+#endif
 	dprintk(4, "type 0x%04x\n", type);
 
 	if (type == -1) {
-		printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
+		printk("DEBI irq oops @ %ld, psr 0x%08x, ssr 0x%08x\n",
 		       jiffies, saa7146_read(av7110->dev, PSR),
 		       saa7146_read(av7110->dev, SSR));
-		goto debi_done;
+		debiack(av7110, 0);
+		return;
 	}
+
 	av7110->debitype = -1;
 
 	switch (type & 0xff) {
 
 	case DATA_TS_RECORD:
-		dvb_dmx_swfilter_packets(&av7110->demux,
-					 (const u8 *) av7110->debi_virt,
-					 av7110->debilen / 188);
-		xfer = RX_BUFF;
-		break;
-
 	case DATA_PES_RECORD:
-		if (av7110->demux.recording)
-			av7110_record_cb(&av7110->p2t[handle],
-					 (u8 *) av7110->debi_virt,
-					 av7110->debilen);
-		xfer = RX_BUFF;
-		break;
-
 	case DATA_IPMPE:
 	case DATA_FSECTION:
 	case DATA_PIPING:
-		if (av7110->handle2filter[handle])
-			DvbDmxFilterCallback((u8 *)av7110->debi_virt,
-					     av7110->debilen, NULL, 0,
-					     av7110->handle2filter[handle],
-					     DMX_OK, av7110);
-		xfer = RX_BUFF;
-		break;
-
 	case DATA_CI_GET:
-	{
-		u8 *data = av7110->debi_virt;
-
-		if ((data[0] < 2) && data[2] == 0xff) {
-			int flags = 0;
-			if (data[5] > 0)
-				flags |= CA_CI_MODULE_PRESENT;
-			if (data[5] > 5)
-				flags |= CA_CI_MODULE_READY;
-			av7110->ci_slot[data[0]].flags = flags;
-		} else
-			ci_get_data(&av7110->ci_rbuffer,
-				    av7110->debi_virt,
-				    av7110->debilen);
-		xfer = RX_BUFF;
-		break;
-	}
-
 	case DATA_COMMON_INTERFACE:
-		CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
-#if 0 /* keep */
-	{
-		int i;
-
-		printk("av7110%d: ", av7110->num);
-		printk("%02x ", *(u8 *)av7110->debi_virt);
-		printk("%02x ", *(1+(u8 *)av7110->debi_virt));
-		for (i = 2; i < av7110->debilen; i++)
-			printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
-		for (i = 2; i < av7110->debilen; i++)
-			printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
-
-		printk("\n");
-	}
-#endif
-		xfer = RX_BUFF;
-		break;
-
 	case DATA_DEBUG_MESSAGE:
-		((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
-		printk("%s\n", (s8 *) av7110->debi_virt);
-		xfer = RX_BUFF;
+		nextBuf = debiack(av7110, RX_BUFF);
+		idx = av7110->rx.writeIdx;
+		av7110->rx.debitype[idx] = type;
+		av7110->rx.debilen[idx] = av7110->debilen;
+		if (++idx >= DMA_RX_BUFS)
+			idx = 0;
+		av7110->rx.writeIdx = idx;
+		tasklet_schedule(&av7110->rx_tasklet);
 		break;
 
-	case DATA_CI_PUT:
-		dprintk(4, "debi DATA_CI_PUT\n");
 	case DATA_MPEG_PLAY:
+		nextBuf = debiack(av7110, TX_BUFF);
 		dprintk(4, "debi DATA_MPEG_PLAY\n");
+		if (type & 0x100) {
+			idx = av7110->tx_a.readIdx;
+			av7110->tx_a.debilen[idx] = 0;
+			if (++idx >= DMA_TX_A_BUFS)
+				idx = 0;
+			av7110->tx_a.readIdx = idx;
+		} else {
+			idx = av7110->tx_av.readIdx;
+			av7110->tx_av.debilen[idx] = 0;
+			if (++idx >= DMA_TX_AV_BUFS)
+				idx = 0;
+			av7110->tx_av.readIdx = idx;
+		}
+		tasklet_schedule(&av7110->tx_tasklet);
+		break;
+
 	case DATA_BMP_LOAD:
+		nextBuf = debiack(av7110, TX_BUFF);
 		dprintk(4, "debi DATA_BMP_LOAD\n");
-		xfer = TX_BUFF;
+		idx = av7110->tx_bmp.readIdx;
+		av7110->tx_bmp.debilen[idx] = 0;
+		if (++idx >= DMA_TX_BMP_BUFS)
+			idx = 0;
+		av7110->tx_bmp.readIdx = idx;
+		tasklet_schedule(&av7110->tx_tasklet);
 		break;
+
+	case DATA_CI_PUT:
+		nextBuf = debiack(av7110, TX_BUFF);
+		dprintk(4, "debi DATA_CI_PUT\n");
+		break;
+
 	default:
+		printk("dvb-ttpci: %s unknown debitype %d\n", __func__, type);
+		nextBuf = debiack(av7110, 0);
 		break;
 	}
-debi_done:
-	spin_lock(&av7110->debilock);
-	if (xfer)
-		iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
-	ARM_ClearMailBox(av7110);
-	spin_unlock(&av7110->debilock);
+
+	if (nextBuf)
+		gpioirq(av7110, nextBuf);
 }
 
+
 /* irq from av7110 firmware writing the mailbox register in the DPRAM */
-static void gpioirq(unsigned long cookie)
+static void gpioirq(struct av7110 *av7110, u16 nextBuf)
 {
-	struct av7110 *av7110 = (struct av7110 *)cookie;
-	u32 rxbuf, txbuf;
+	u32 tmp;
+	u32 buf;
 	int len;
+	int idx;
 
 	if (av7110->debitype != -1)
 		/* we shouldn't get any irq while a debi xfer is running */
@@ -513,129 +657,102 @@ static void gpioirq(unsigned long cookie
 	}
 
 	spin_lock(&av7110->debilock);
-	ARM_ClearIrq(av7110);
 
 	/* see what the av7110 wants */
-	av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
-	av7110->debilen  = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-	rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-	txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+	switch (nextBuf) {
+	case TX_BUFF:
+		tmp = irdebi(av7110, DEBINOSWAP, TX_TYPE, 0, 4);
+		break;
+
+	case RX_BUFF:
+		tmp = irdebi(av7110, DEBINOSWAP, RX_TYPE, 0, 4);
+		break;
+
+	default:
+		ARM_ClearIrq(av7110);
+		tmp = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 4);
+		break;
+	}
+	av7110->debitype = tmp & 0xffff;
+	av7110->debilen  = (tmp >> 16) & 0xffff;
 	len = (av7110->debilen + 3) & ~3;
 
+#ifdef DEBUG_TIMING
 	print_time("gpio");
+#endif
 	dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
 
 	switch (av7110->debitype & 0xff) {
 
-	case DATA_TS_PLAY:
-	case DATA_PES_PLAY:
-		break;
-
-	case DATA_MPEG_VIDEO_EVENT:
-	{
-		u32 h_ar;
-		struct video_event event;
-
-		av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
-		h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
-
-		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-		iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-
-		av7110->video_size.h = h_ar & 0xfff;
-
-		event.type = VIDEO_EVENT_SIZE_CHANGED;
-		event.u.size.w = av7110->video_size.w;
-		event.u.size.h = av7110->video_size.h;
-		switch ((h_ar >> 12) & 0xf)
-		{
-		case 3:
-			av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
-			event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
-			av7110->videostate.video_format = VIDEO_FORMAT_16_9;
-			break;
-		case 4:
-			av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
-			event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
-			av7110->videostate.video_format = VIDEO_FORMAT_221_1;
+	case DATA_CI_GET:
+	case DATA_COMMON_INTERFACE:
+	case DATA_FSECTION:
+	case DATA_IPMPE:
+	case DATA_PIPING:
+		if (!len || len > 4 * 1024) {
+			iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
 			break;
-		default:
-			av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
-			event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
-			av7110->videostate.video_format = VIDEO_FORMAT_4_3;
 		}
+		/* fall through */
 
-		dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
-			av7110->video_size.w, av7110->video_size.h,
-			av7110->video_size.aspect_ratio);
-
-		dvb_video_add_event(av7110, &event);
-		break;
-	}
-
-	case DATA_CI_PUT:
-	{
-		int avail;
-		struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
-
-		avail = dvb_ringbuffer_avail(cibuf);
-		if (avail <= 2) {
-			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
-			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-			break;
-		}
-		len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
-		len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
-		if (avail < len + 2) {
-			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
-			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+	case DATA_TS_RECORD:
+	case DATA_PES_RECORD:
+		dprintk(8, "DMA: TS_REC etc.\n");
+		idx = av7110->rx.writeIdx;
+		if (av7110->rx.debilen[idx]) {
+			av7110->rx_overflow_cnt++;
+			iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
 			break;
 		}
-		DVB_RINGBUFFER_SKIP(cibuf, 2);
-
-		dvb_ringbuffer_read(cibuf, av7110->debi_virt, len);
-
-		iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
-		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-		dprintk(8, "DMA: CI\n");
-		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
+		buf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+		start_debi_dma(av7110, DEBI_READ, av7110->rx.offset[idx], DPRAM_BASE + buf, len);
 		spin_unlock(&av7110->debilock);
-		wake_up(&cibuf->queue);
 		return;
-	}
 
 	case DATA_MPEG_PLAY:
 		if (!av7110->playing) {
-			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
 			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
 			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
 			break;
 		}
 		len = 0;
 		if (av7110->debitype & 0x100) {
-			spin_lock(&av7110->aout.lock);
-			len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
-			spin_unlock(&av7110->aout.lock);
+			if (av7110->tx_a.clear) {
+				while (av7110->tx_a.readIdx != av7110->tx_a.writeIdx) {
+					av7110->tx_a.debilen[av7110->tx_a.readIdx] = 0;
+					av7110->tx_a.readIdx = (av7110->tx_a.readIdx + 1) % DMA_TX_A_BUFS;
+				}
+				av7110->tx_a.clear = 0;
+			}
+			len = av7110->tx_a.debilen[av7110->tx_a.readIdx];
 		}
 		if (len <= 0 && (av7110->debitype & 0x200)
-		    &&av7110->videostate.play_state != VIDEO_FREEZED) {
-			spin_lock(&av7110->avout.lock);
-			len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
-			spin_unlock(&av7110->avout.lock);
+		    && av7110->videostate.play_state != VIDEO_FREEZED) {
+			av7110->debitype &= ~0x100;
+			if (av7110->tx_av.clear) {
+				while (av7110->tx_av.readIdx != av7110->tx_av.writeIdx) {
+					av7110->tx_av.debilen[av7110->tx_av.readIdx] = 0;
+					av7110->tx_av.readIdx = (av7110->tx_av.readIdx + 1) % DMA_TX_AV_BUFS;
+				}
+				av7110->tx_av.clear = 0;
+			}
+			len = av7110->tx_av.debilen[av7110->tx_av.readIdx];
 		}
 		if (len <= 0) {
-			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
 			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
 			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+			tasklet_schedule(&av7110->tx_tasklet);
 			break;
 		}
 		dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
 		iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
-		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
 		dprintk(8, "DMA: MPEG_PLAY\n");
-		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
+		buf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+		start_debi_dma(av7110, DEBI_WRITE,
+				(av7110->debitype & 0x100)
+					? av7110->tx_a.offset[av7110->tx_a.readIdx]
+					: av7110->tx_av.offset[av7110->tx_av.readIdx],
+				DPRAM_BASE + buf, len);
 		spin_unlock(&av7110->debilock);
 		return;
 
@@ -644,53 +761,97 @@ static void gpioirq(unsigned long cookie
 		dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
 		if (!len) {
 			av7110->bmp_state = BMP_LOADED;
-			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
 			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
 			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
 			wake_up(&av7110->bmpq);
 			dprintk(8, "gpio DATA_BMP_LOAD done\n");
 			break;
 		}
-		if (len > av7110->bmplen)
-			len = av7110->bmplen;
-		if (len > 2 * 1024)
-			len = 2 * 1024;
+		if (av7110->bmp_loadpal) {
+			/* palette transfer (dummy, not used) */
+			av7110->bmp_loadpal = 0;
+			iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
+			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+			break;
+		}
+		len = av7110->tx_bmp.debilen[av7110->tx_bmp.readIdx];
 		iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
-		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-		memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
-		av7110->bmpp += len;
-		av7110->bmplen -= len;
-		dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
-		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
+		buf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+		start_debi_dma(av7110, DEBI_WRITE, av7110->tx_bmp.offset[av7110->tx_bmp.readIdx], DPRAM_BASE + buf, len);
 		spin_unlock(&av7110->debilock);
 		return;
 
-	case DATA_CI_GET:
-	case DATA_COMMON_INTERFACE:
-	case DATA_FSECTION:
-	case DATA_IPMPE:
-	case DATA_PIPING:
-		if (!len || len > 4 * 1024) {
-			iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+	case DATA_CI_PUT:
+	{
+		int avail;
+		struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
+
+		avail = dvb_ringbuffer_avail(cibuf);
+		if (avail <= 2) {
+			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
+			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
 			break;
 		}
-		/* fall through */
+		len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
+		len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
+		if (avail < len + 2) {
+			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
+			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+			break;
+		}
+		DVB_RINGBUFFER_SKIP(cibuf, 2);
 
-	case DATA_TS_RECORD:
-	case DATA_PES_RECORD:
-		dprintk(8, "DMA: TS_REC etc.\n");
-		start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
+		dvb_ringbuffer_read(cibuf, av7110->debi_virt, len);
+
+		iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
+		dprintk(8, "DMA: CI\n");
+		buf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+		start_debi_dma(av7110, DEBI_WRITE, 0, DPRAM_BASE + buf, len);
 		spin_unlock(&av7110->debilock);
+		wake_up(&cibuf->queue);
 		return;
+	}
 
-	case DATA_DEBUG_MESSAGE:
-		if (!len || len > 0xff) {
-			iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+	case DATA_MPEG_VIDEO_EVENT:
+	{
+		u32 h_ar;
+		struct video_event event;
+
+		av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
+		h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
+
+		iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+
+		av7110->video_size.h = h_ar & 0xfff;
+
+		event.type = VIDEO_EVENT_SIZE_CHANGED;
+		event.u.size.w = av7110->video_size.w;
+		event.u.size.h = av7110->video_size.h;
+		switch ((h_ar >> 12) & 0xf)
+		{
+		case 3:
+			av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
+			event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
+			av7110->videostate.video_format = VIDEO_FORMAT_16_9;
 			break;
+		case 4:
+			av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
+			event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
+			av7110->videostate.video_format = VIDEO_FORMAT_221_1;
+			break;
+		default:
+			av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
+			event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
+			av7110->videostate.video_format = VIDEO_FORMAT_4_3;
 		}
-		start_debi_dma(av7110, DEBI_READ, Reserved, len);
-		spin_unlock(&av7110->debilock);
-		return;
+
+		dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
+			av7110->video_size.w, av7110->video_size.h,
+			av7110->video_size.aspect_ratio);
+
+		dvb_video_add_event(av7110, &event);
+		break;
+	}
 
 	case DATA_IRCOMMAND:
 		if (av7110->ir.ir_handler)
@@ -699,9 +860,19 @@ static void gpioirq(unsigned long cookie
 		iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
 		break;
 
+	case DATA_DEBUG_MESSAGE:
+		if (!len || len > 0xff) {
+			iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+			break;
+		}
+		idx = av7110->rx.writeIdx;
+		start_debi_dma(av7110, DEBI_READ, av7110->rx.offset[idx], Reserved, len);
+		spin_unlock(&av7110->debilock);
+		return;
+
 	default:
-		printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
-		       av7110->debitype, av7110->debilen);
+		printk("dvb-ttpci: %s unknown debitype %d len %d\n",
+		       __func__, av7110->debitype, av7110->debilen);
 		break;
 	}
 	av7110->debitype = -1;
@@ -1263,9 +1434,9 @@ static int budget_stop_feed(struct dvb_d
 	return status;
 }
 
-static void vpeirq(unsigned long cookie)
+static void vpeirq(unsigned long data)
 {
-	struct av7110 *budget = (struct av7110 *)cookie;
+	struct av7110 *budget = (struct av7110 *) data;
 	u8 *mem = (u8 *) (budget->grabbing);
 	u32 olddma = budget->ttbp;
 	u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
@@ -2379,6 +2550,8 @@ static int __devinit av7110_attach(struc
 	struct av7110 *av7110;
 	struct task_struct *thread;
 	int ret, count = 0;
+	int i;
+	unsigned offset;
 
 	dprintk(4, "dev: %p\n", dev);
 
@@ -2642,8 +2815,8 @@ static int __devinit av7110_attach(struc
 		saa7146_write(dev, GPIO_CTRL, 0x000000);
 	}
 
-	tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
-	tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
+	tasklet_init(&av7110->rx_tasklet, processDmaRx, (unsigned long) av7110);
+	tasklet_init(&av7110->tx_tasklet, fillDmaTx, (unsigned long) av7110);
 
 	mutex_init(&av7110->pid_mutex);
 
@@ -2665,10 +2838,19 @@ static int __devinit av7110_attach(struc
 	av7110->arm_thread = NULL;
 
 	/* allocate and init buffers */
-	av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
+	av7110->debi_virt = pci_alloc_consistent(pdev, DMA_BUF_LEN, &av7110->debi_bus);
 	if (!av7110->debi_virt)
 		goto err_saa71466_vfree_4;
 
+	offset = DMA_TX_MISC_BUF_SIZE;
+	for (i = 0; i < DMA_RX_BUFS; i++, offset += DMA_RX_BUF_SIZE)
+		av7110->rx.offset[i] = offset;
+	for (i = 0; i < DMA_TX_AV_BUFS; i++, offset += DMA_TX_BUF_SIZE)
+		av7110->tx_av.offset[i] = offset;
+	for (i = 0; i < DMA_TX_A_BUFS; i++, offset += DMA_TX_BUF_SIZE)
+		av7110->tx_a.offset[i] = offset;
+	for (i = 0; i < DMA_TX_BMP_BUFS; i++, offset += DMA_TX_BUF_SIZE)
+		av7110->tx_bmp.offset[i] = offset;
 
 	av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
 	if (!av7110->iobuf)
@@ -2751,7 +2933,7 @@ err_av7110_av_exit_7:
 err_iobuf_vfree_6:
 	vfree(av7110->iobuf);
 err_pci_free_5:
-	pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
+	pci_free_consistent(pdev, DMA_BUF_LEN, av7110->debi_virt, av7110->debi_bus);
 err_saa71466_vfree_4:
 	if (av7110->grabbing)
 		saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
@@ -2771,6 +2953,9 @@ static int __devexit av7110_detach(struc
 	struct av7110 *av7110 = saa->ext_priv;
 	dprintk(4, "%p\n", av7110);
 
+	SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
+	SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
+
 #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
 	av7110_ir_exit(av7110);
 #endif
@@ -2792,19 +2977,16 @@ static int __devexit av7110_detach(struc
 
 	av7110_arm_sync(av7110);
 
-	tasklet_kill(&av7110->debi_tasklet);
-	tasklet_kill(&av7110->gpio_tasklet);
+	tasklet_kill(&av7110->rx_tasklet);
+	tasklet_kill(&av7110->tx_tasklet);
 
 	dvb_unregister(av7110);
 
-	SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
-	SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
-
 	av7110_ca_exit(av7110);
 	av7110_av_exit(av7110);
 
 	vfree(av7110->iobuf);
-	pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
+	pci_free_consistent(saa->pci, DMA_BUF_LEN, av7110->debi_virt,
 			    av7110->debi_bus);
 
 	i2c_del_adapter(&av7110->i2c_adap);
@@ -2852,12 +3034,12 @@ static void av7110_irq(struct saa7146_de
 		 */
 		SAA7146_IER_DISABLE(av7110->dev, MASK_19);
 		SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
-		tasklet_schedule(&av7110->debi_tasklet);
+		debiirq(av7110);
 	}
 
 	if (*isr & MASK_03) {
 		//printk("av7110_irq: GPIO\n");
-		tasklet_schedule(&av7110->gpio_tasklet);
+		gpioirq(av7110, 0);
 	}
 
 	if (*isr & MASK_10)
Nur in v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/: av7110.c.orig.
diff -pur v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110.h v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110.h
--- v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110.h	2008-09-03 23:24:46.000000000 +0200
+++ v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110.h	2008-09-06 00:49:55.000000000 +0200
@@ -95,6 +95,38 @@ struct infrared {
 };
 
 
+/* DMA buffer control */
+#define DMA_RX_BUF_SIZE		0x1000
+#define DMA_RX_BUFS		8	/* RX transfers */
+#define DMA_TX_BUF_SIZE		0x0800
+#define DMA_TX_A_BUFS		3	/* TX audio */
+#define DMA_TX_AV_BUFS		5	/* TX audio/video */
+#define DMA_TX_BMP_BUFS		3	/* TX bitmap */
+#define DMA_MAX_TX_BUFS		5	/* maximum of the above */
+#define DMA_TX_MISC_BUF_SIZE	0x800	/* TX everything else */
+#define DMA_BUF_LEN		( DMA_TX_MISC_BUF_SIZE			\
+				+ DMA_RX_BUFS * DMA_RX_BUF_SIZE		\
+				+ DMA_TX_A_BUFS * DMA_TX_BUF_SIZE	\
+				+ DMA_TX_AV_BUFS * DMA_TX_BUF_SIZE	\
+				+ DMA_TX_BMP_BUFS * DMA_TX_BUF_SIZE )
+
+struct dma_rx {
+	unsigned	readIdx;
+	unsigned	writeIdx;
+	unsigned	offset[DMA_RX_BUFS];
+	int		debitype[DMA_RX_BUFS];
+	unsigned	debilen[DMA_RX_BUFS];
+};
+
+struct dma_tx {
+	int		clear;
+	unsigned	readIdx;
+	unsigned	writeIdx;
+	unsigned	offset[DMA_MAX_TX_BUFS];
+	unsigned	debilen[DMA_MAX_TX_BUFS];
+};
+
+
 /* place to store all the necessary device information */
 struct av7110 {
 
@@ -117,9 +149,6 @@ struct av7110 {
 	int			current_input;
 	u32			current_freq;
 
-	struct tasklet_struct	debi_tasklet;
-	struct tasklet_struct	gpio_tasklet;
-
 	int adac_type;	       /* audio DAC type */
 #define DVB_ADAC_TI	  0
 #define DVB_ADAC_CRYSTAL  1
@@ -136,12 +165,13 @@ struct av7110 {
 	struct dvb_ringbuffer	aout;    /* buffer for audio */
 #define AOUTLEN (64*1024)
 	void		       *bmpbuf;
-#define BMPLEN (8*32768+1024)
+#define BMPLEN (8*32768)
 
 	/* bitmap buffers and states */
 
 	int			bmpp;
 	int			bmplen;
+	int			bmp_loadpal;
 	volatile int		bmp_state;
 #define BMP_NONE     0
 #define BMP_LOADING  1
@@ -235,8 +265,16 @@ struct av7110 {
 	wait_queue_head_t   arm_wait;
 	u16		    arm_loops;
 
-	void		   *debi_virt;
-	dma_addr_t	    debi_bus;
+	/* DMA buffers */
+	void			*debi_virt;
+	dma_addr_t		debi_bus;
+	struct dma_rx		rx;
+	struct tasklet_struct	rx_tasklet;
+	struct dma_tx		tx_a;
+	struct dma_tx		tx_av;
+	struct dma_tx		tx_bmp;
+	struct tasklet_struct	tx_tasklet;
+	u32			rx_overflow_cnt;
 
 	u16		    pids[DMX_PES_OTHER];
 
Nur in v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/: av7110.h.orig.
diff -pur v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110_hw.c v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110_hw.c
--- v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110_hw.c	2008-06-20 01:08:40.000000000 +0200
+++ v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110_hw.c	2008-08-03 03:48:03.000000000 +0200
@@ -47,7 +47,7 @@
 /* This DEBI code is based on the Stradis driver
    by Nathan Laredo <laredo@gnu.org> */
 
-int av7110_debiwrite(struct av7110 *av7110, u32 config,
+int av7110_debiwrite(struct av7110 *av7110, u32 config, u32 offset,
 		     int addr, u32 val, int count)
 {
 	struct saa7146_dev *dev = av7110->dev;
@@ -64,13 +64,14 @@ int av7110_debiwrite(struct av7110 *av71
 	if (count <= 4)		/* immediate transfer */
 		saa7146_write(dev, DEBI_AD, val);
 	else			/* block transfer */
-		saa7146_write(dev, DEBI_AD, av7110->debi_bus);
+		saa7146_write(dev, DEBI_AD, av7110->debi_bus + offset);
 	saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
 	saa7146_write(dev, MC2, (2 << 16) | 2);
 	return 0;
 }
 
-u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
+u32 av7110_debiread(struct av7110 *av7110, u32 config, u32 offset,
+		    int addr, int count)
 {
 	struct saa7146_dev *dev = av7110->dev;
 	u32 result = 0;
@@ -83,7 +84,7 @@ u32 av7110_debiread(struct av7110 *av711
 		printk("%s: wait_for_debi_done #1 failed\n", __func__);
 		return 0;
 	}
-	saa7146_write(dev, DEBI_AD, av7110->debi_bus);
+	saa7146_write(dev, DEBI_AD, av7110->debi_bus + offset);
 	saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
 
 	saa7146_write(dev, DEBI_CONFIG, config);
@@ -879,7 +880,6 @@ static inline int LoadBitmap(struct av71
 
 	format = bpp2bit[av7110->osdbpp[av7110->osdwin]];
 
-	av7110->bmp_state = BMP_LOADING;
 	if	(format == OSD_BITMAP8) {
 		bpp=8; delta = 1;
 	} else if (format == OSD_BITMAP4) {
@@ -899,22 +899,27 @@ static inline int LoadBitmap(struct av71
 		return -EINVAL;
 	}
 	for (i = 0; i < dy; i++) {
-		if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
+		if (copy_from_user(av7110->bmpbuf + i * dx, data + i * inc, dx)) {
 			av7110->bmp_state = BMP_NONE;
 			return -EINVAL;
 		}
 	}
 	if (format != OSD_BITMAP8) {
 		for (i = 0; i < dx * dy / delta; i++) {
-			c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
+			c = ((u8 *)av7110->bmpbuf)[i * delta + delta - 1];
 			for (d = delta - 2; d >= 0; d--) {
-				c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d]
+				c |= (((u8 *)av7110->bmpbuf)[i * delta + d]
 				      << ((delta - d - 1) * bpp));
-				((u8 *)av7110->bmpbuf)[1024 + i] = c;
+				((u8 *)av7110->bmpbuf)[i] = c;
 			}
 		}
 	}
-	av7110->bmplen += 1024;
+	for (i = 0; i < DMA_TX_BMP_BUFS; i++)
+		av7110->tx_bmp.debilen[i] = 0;
+	av7110->tx_bmp.readIdx = av7110->tx_bmp.writeIdx = 0;
+	av7110->bmp_loadpal = 1;
+	av7110->bmp_state = BMP_LOADING;
+	tasklet_schedule(&av7110->tx_tasklet);
 	dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
 	ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
 	if (!ret)
diff -pur v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110_hw.h v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110_hw.h
--- v4l-dvb.reference/linux/drivers/media/dvb/ttpci/av7110_hw.h	2008-06-20 00:46:42.000000000 +0200
+++ v4l-dvb-av7110-full-ts-mod/linux/drivers/media/dvb/ttpci/av7110_hw.h	2008-08-03 03:48:03.000000000 +0200
@@ -376,9 +376,9 @@ extern int av7110_fw_request(struct av71
 
 
 /* DEBI (saa7146 data extension bus interface) access */
-extern int av7110_debiwrite(struct av7110 *av7110, u32 config,
+extern int av7110_debiwrite(struct av7110 *av7110, u32 config, u32 offset,
 			    int addr, u32 val, int count);
-extern u32 av7110_debiread(struct av7110 *av7110, u32 config,
+extern u32 av7110_debiread(struct av7110 *av7110, u32 config, u32 offset,
 			   int addr, int count);
 
 
@@ -386,24 +386,19 @@ extern u32 av7110_debiread(struct av7110
 /* single word writes */
 static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
 {
-	av7110_debiwrite(av7110, config, addr, val, count);
+	av7110_debiwrite(av7110, config, 0, addr, val, count);
 }
 
 /* buffer writes */
 static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count)
 {
 	memcpy(av7110->debi_virt, val, count);
-	av7110_debiwrite(av7110, config, addr, 0, count);
+	av7110_debiwrite(av7110, config, 0, addr, 0, count);
 }
 
 static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
 {
-	u32 res;
-
-	res=av7110_debiread(av7110, config, addr, count);
-	if (count<=4)
-		memcpy(av7110->debi_virt, (char *) &res, count);
-	return res;
+	return av7110_debiread(av7110, config, 0, addr, count);
 }
 
 /* DEBI outside interrupts, only for count <= 4! */
@@ -412,7 +407,7 @@ static inline void wdebi(struct av7110 *
 	unsigned long flags;
 
 	spin_lock_irqsave(&av7110->debilock, flags);
-	av7110_debiwrite(av7110, config, addr, val, count);
+	av7110_debiwrite(av7110, config, 0, addr, val, count);
 	spin_unlock_irqrestore(&av7110->debilock, flags);
 }
 
@@ -422,7 +417,7 @@ static inline u32 rdebi(struct av7110 *a
 	u32 res;
 
 	spin_lock_irqsave(&av7110->debilock, flags);
-	res=av7110_debiread(av7110, config, addr, count);
+	res=av7110_debiread(av7110, config, 0, addr, count);
 	spin_unlock_irqrestore(&av7110->debilock, flags);
 	return res;
 }
@@ -433,8 +428,8 @@ static inline void ARM_ResetMailBox(stru
 	unsigned long flags;
 
 	spin_lock_irqsave(&av7110->debilock, flags);
-	av7110_debiread(av7110, DEBINOSWAP, IRQ_RX, 2);
-	av7110_debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
+	av7110_debiread(av7110, DEBINOSWAP, 0, IRQ_RX, 2);
+	av7110_debiwrite(av7110, DEBINOSWAP, 0, IRQ_RX, 0, 2);
 	spin_unlock_irqrestore(&av7110->debilock, flags);
 }
 

