dma sync fix for FF-cards
PATCH 1/1 dma sync fix for FF-cards
Hi,
according to DMA-API.txt, dma synchronisation must be done before a transfer to the device starts and after a transfer from the device ends. This is missing for the DEBI dma transfer of a FF-card.
-Hartmut
Signed-off-by Hartmut Birr <[email protected]>
linux/drivers/media/dvb/ttpci/av7110.c +28 -2
@@ -397,6 +397,9 @@ static void debiirq(unsigned long data)switch (type &0xff ) {case DATA_TS_RECORD : +pci_dma_sync_single_for_cpu (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_FROMDEVICE ); +dvb_dmx_swfilter_packets (&av7110->demux, (const u8 *) av7110->debi_virt, av7110->debilen /188 );
@@ -404,6 +407,9 @@ static void debiirq(unsigned long data)break ;case DATA_PES_RECORD : +pci_dma_sync_single_for_cpu (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_FROMDEVICE ); +if (av7110->demux.recording) av7110_record_cb(&av7110->p2t[handle], (u8 *) av7110->debi_virt,
@@ -414,6 +420,9 @@ static void debiirq(unsigned long data)case DATA_IPMPE :case DATA_FSECTION :case DATA_PIPING : +pci_dma_sync_single_for_cpu (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_FROMDEVICE ); +if (av7110->handle2filter[handle]) DvbDmxFilterCallback((u8 *)av7110->debi_virt, av7110->debilen, NULL, 0,
@@ -425,6 +434,9 @@ static void debiirq(unsigned long data)case DATA_CI_GET : {u8 *data = av7110->debi_virt; + +pci_dma_sync_single_for_cpu (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_FROMDEVICE );if ((data[0 ] <2 ) && data[2 ] ==0xff ) {int flags =0 ;
@@ -442,6 +454,9 @@ static void debiirq(unsigned long data) }case DATA_COMMON_INTERFACE : +pci_dma_sync_single_for_cpu (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_FROMDEVICE ); +CI_handle (av7110, (u8 *)av7110->debi_virt, av7110->debilen);#if 0 /* keep */ {
@@ -462,6 +477,9 @@ static void debiirq(unsigned long data)break ;case DATA_DEBUG_MESSAGE : +pci_dma_sync_single_for_cpu (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_FROMDEVICE ); + ((s8 *)av7110->debi_virt)[Reserved_SIZE -1 ] =0 ;printk ("%s\n" , (s8 *) av7110->debi_virt); xfer =RX_BUFF ;
@@ -588,6 +606,9 @@ static void gpioirq(unsigned long data)DVB_RINGBUFFER_SKIP (cibuf,2 );dvb_ringbuffer_read (cibuf, av7110->debi_virt, len); + +pci_dma_sync_single_for_device (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_TODEVICE );iwdebi (av7110,DEBINOSWAP ,TX_LEN , len,2 );iwdebi (av7110,DEBINOSWAP ,IRQ_STATE_EXT , len,2 );
@@ -623,6 +644,9 @@ static void gpioirq(unsigned long data)iwdebi (av7110,DEBINOSWAP ,TX_BUFF ,0 ,2 );break ; } +pci_dma_sync_single_for_device (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_TODEVICE ); +dprintk (8 ,"GPIO0 PES_PLAY len=%04x\n" , len);iwdebi (av7110,DEBINOSWAP ,TX_LEN , len,2 );iwdebi (av7110,DEBINOSWAP ,IRQ_STATE_EXT , len,2 );
@@ -650,6 +674,8 @@ static void gpioirq(unsigned long data)iwdebi (av7110,DEBINOSWAP ,TX_LEN , len,2 );iwdebi (av7110,DEBINOSWAP ,IRQ_STATE_EXT , len,2 );memcpy (av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len); +pci_dma_sync_single_for_device (av7110->dev->pci, + av7110->debi_bus,8192 ,PCI_DMA_TODEVICE ); av7110->bmpp += len; av7110->bmplen -= len;dprintk (8 ,"gpio DATA_BMP_LOAD DMA len %d\n" , len);
@@ -2603,7 +2629,7 @@ static int __devinit av7110_attach(struc/* allocate and init buffers */ av7110->debi_virt =pci_alloc_consistent (pdev,8192 , &av7110->debi_bus);if (!av7110->debi_virt) - goto err_saa71466_vfree_4; + goto err_saa7146_vfree_4; av7110->iobuf =vmalloc (AVOUTLEN +AOUTLEN +BMPLEN +4 *IPACKS );
@@ -2688,7 +2714,7 @@ err_iobuf_vfree_6:vfree (av7110->iobuf); err_pci_free_5:pci_free_consistent (pdev,8192 , av7110->debi_virt, av7110->debi_bus); -err_saa71466_vfree_4: +err_saa7146_vfree_4:if (av7110->grabbing)saa7146_vfree_destroy_pgtable (pdev, av7110->grabbing, &av7110->pt); err_i2c_del_3:
Signed-off-by Hartmut Birr <[email protected]>
linux/drivers/media/dvb/ttpci/av7110.c +40 -14
119 lines not on this page · raw message
linux/drivers/media/dvb/ttpci/av7110.h +7 -5
@@ -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;
linux/drivers/media/dvb/ttpci/av7110_hw.c +2 -2
@@ -64,7 +64,7 @@ int av7110_debiwrite(struct av7110 *av71if (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 *av711printk ("%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);
linux/drivers/media/dvb/ttpci/av7110_hw.h +3 -1
@@ -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); }
_______________________________________________
linux-dvb mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb