Signed-off-by: Hartmut Birr diff -r 1760a612cc98 linux/drivers/media/dvb/ttpci/av7110.c --- a/linux/drivers/media/dvb/ttpci/av7110.c Sun Aug 03 05:02:35 2008 +0200 +++ b/linux/drivers/media/dvb/ttpci/av7110.c Sun Aug 31 14:45:44 2008 +0200 @@ -372,10 +372,14 @@ static void processDmaRx(unsigned long d struct av7110 *av7110 = (struct av7110 *) data; int idx; + /* Ensure streamed PCI data is synced to CPU */ + pci_dma_sync_single_for_cpu(av7110->dev->pci, av7110->debi_rx_bus, + DMA_RX_BUF_LEN, PCI_DMA_FROMDEVICE); + 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]; + u8 *debibuf = av7110->debi_rx_virt + av7110->rx.offset[idx]; unsigned debilen = av7110->rx.debilen[idx]; switch (debitype & 0xff) { @@ -466,7 +470,7 @@ static void fillDmaTx(unsigned long data int len; while (! av7110->tx_av.debilen[idx = av7110->tx_av.writeIdx]) { - debibuf = av7110->debi_virt + av7110->tx_av.offset[idx]; + debibuf = av7110->debi_tx_virt + av7110->tx_av.offset[idx]; len = av7110_pes_play(debibuf, &av7110->avout, DMA_TX_BUF_SIZE); if (len <= 0) break; @@ -477,7 +481,7 @@ static void fillDmaTx(unsigned long data } while (! av7110->tx_a.debilen[idx = av7110->tx_a.writeIdx]) { - debibuf = av7110->debi_virt + av7110->tx_a.offset[idx]; + debibuf = av7110->debi_tx_virt + av7110->tx_a.offset[idx]; len = av7110_pes_play(debibuf, &av7110->aout, DMA_TX_BUF_SIZE); if (len <= 0) break; @@ -492,7 +496,7 @@ static void fillDmaTx(unsigned long data len = min(av7110->bmplen, DMA_TX_BUF_SIZE); if (len <= 0) break; - debibuf = av7110->debi_virt + av7110->tx_bmp.offset[idx]; + debibuf = av7110->debi_tx_virt + av7110->tx_bmp.offset[idx]; memcpy(debibuf, av7110->bmpbuf + av7110->bmpp, len); av7110->bmpp += len; av7110->bmplen -= len; @@ -501,6 +505,9 @@ static void fillDmaTx(unsigned long data idx = 0; av7110->tx_bmp.writeIdx = idx; } + /* Ensure CPU data is synced to the device */ + pci_dma_sync_single_for_device(av7110->dev->pci, av7110->debi_tx_bus, + DMA_TX_BUF_LEN, PCI_DMA_TODEVICE); } @@ -801,7 +808,13 @@ static void gpioirq(struct av7110 *av711 } DVB_RINGBUFFER_SKIP(cibuf, 2); - dvb_ringbuffer_read(cibuf, av7110->debi_virt, len); + dvb_ringbuffer_read(cibuf, av7110->debi_tx_virt, len); + + /* Ensure CPU data is synced to the device */ + pci_dma_sync_single_for_device(av7110->dev->pci, + av7110->debi_tx_bus, + DMA_TX_BUF_LEN, + PCI_DMA_TODEVICE); iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); dprintk(8, "DMA: CI\n"); @@ -2837,19 +2850,26 @@ static int __devinit av7110_attach(struc av7110->arm_thread = NULL; /* allocate and init buffers */ - av7110->debi_virt = pci_alloc_consistent(pdev, DMA_BUF_LEN, &av7110->debi_bus); - if (!av7110->debi_virt) - goto err_saa71466_vfree_4; + av7110->debi_rx_virt = pci_alloc_consistent(pdev, DMA_RX_BUF_LEN, + &av7110->debi_rx_bus); + if (!av7110->debi_rx_virt) + goto err_saa7146_vfree_4; + av7110->debi_tx_virt = pci_alloc_consistent(pdev, DMA_TX_BUF_LEN, + &av7110->debi_tx_bus); + if (!av7110->debi_tx_virt) + goto err_saa7146_vfree_4a; 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; + + offset = 0; + for (i = 0; i < DMA_RX_BUFS; i++, offset += DMA_RX_BUF_SIZE) + av7110->rx.offset[i] = offset; av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS); if (!av7110->iobuf) @@ -2932,8 +2952,12 @@ err_iobuf_vfree_6: err_iobuf_vfree_6: vfree(av7110->iobuf); err_pci_free_5: - pci_free_consistent(pdev, DMA_BUF_LEN, av7110->debi_virt, av7110->debi_bus); -err_saa71466_vfree_4: + pci_free_consistent(pdev, DMA_TX_BUF_LEN, + av7110->debi_tx_virt, av7110->debi_tx_bus); +err_saa7146_vfree_4a: + pci_free_consistent(pdev, DMA_RX_BUF_LEN, + av7110->debi_rx_virt, av7110->debi_rx_bus); +err_saa7146_vfree_4: if (av7110->grabbing) saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt); err_i2c_del_3: @@ -2985,8 +3009,10 @@ static int __devexit av7110_detach(struc av7110_av_exit(av7110); vfree(av7110->iobuf); - pci_free_consistent(saa->pci, DMA_BUF_LEN, av7110->debi_virt, - av7110->debi_bus); + pci_free_consistent(saa->pci, DMA_RX_BUF_LEN, av7110->debi_rx_virt, + av7110->debi_rx_bus); + pci_free_consistent(saa->pci, DMA_TX_BUF_LEN, av7110->debi_tx_virt, + av7110->debi_tx_bus); i2c_del_adapter(&av7110->i2c_adap); diff -r 1760a612cc98 linux/drivers/media/dvb/ttpci/av7110.h --- a/linux/drivers/media/dvb/ttpci/av7110.h Sun Aug 03 05:02:35 2008 +0200 +++ b/linux/drivers/media/dvb/ttpci/av7110.h Sun Aug 31 14:45:44 2008 +0200 @@ -104,11 +104,11 @@ struct infrared { #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 \ +#define DMA_RX_BUF_LEN (DMA_RX_BUFS * DMA_RX_BUF_SIZE) +#define DMA_TX_BUF_LEN (DMA_TX_MISC_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 ) + + DMA_TX_BMP_BUFS * DMA_TX_BUF_SIZE) struct dma_rx { unsigned readIdx; @@ -266,8 +266,10 @@ struct av7110 { u16 arm_loops; /* DMA buffers */ - void *debi_virt; - dma_addr_t debi_bus; + void *debi_rx_virt; + void *debi_tx_virt; + dma_addr_t debi_rx_bus; + dma_addr_t debi_tx_bus; struct dma_rx rx; struct tasklet_struct rx_tasklet; struct dma_tx tx_a; diff -r 1760a612cc98 linux/drivers/media/dvb/ttpci/av7110_hw.c --- a/linux/drivers/media/dvb/ttpci/av7110_hw.c Sun Aug 03 05:02:35 2008 +0200 +++ b/linux/drivers/media/dvb/ttpci/av7110_hw.c Sun Aug 31 14:45:44 2008 +0200 @@ -64,7 +64,7 @@ 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 + offset); + saa7146_write(dev, DEBI_AD, av7110->debi_tx_bus + offset); saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff)); saa7146_write(dev, MC2, (2 << 16) | 2); return 0; @@ -84,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 + offset); + saa7146_write(dev, DEBI_AD, av7110->debi_rx_bus + offset); saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); saa7146_write(dev, DEBI_CONFIG, config); diff -r 1760a612cc98 linux/drivers/media/dvb/ttpci/av7110_hw.h --- a/linux/drivers/media/dvb/ttpci/av7110_hw.h Sun Aug 03 05:02:35 2008 +0200 +++ b/linux/drivers/media/dvb/ttpci/av7110_hw.h Sun Aug 31 14:45:44 2008 +0200 @@ -392,7 +392,9 @@ static inline void iwdebi(struct av7110 /* buffer writes */ static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count) { - memcpy(av7110->debi_virt, val, count); + memcpy(av7110->debi_tx_virt, val, count); + pci_dma_sync_single_for_device(av7110->dev->pci, av7110->debi_tx_bus, + DMA_TX_BUF_LEN, PCI_DMA_TODEVICE); av7110_debiwrite(av7110, config, 0, addr, 0, count); }