> 
> ----- Original Message ----
> From: Ricardo Lugo <[EMAIL PROTECTED]>
> To: Discussion list for development of the IVTV driver 
> <[email protected]>
> Sent: Sunday, January 21, 2007 7:13:42 PM
> Subject: Re: [ivtv-devel] trunk on PPC - "couldn't find start of buffer"
> 
> Well, after some more testing, it seems that DMA doesn't work on 0.9  
> for PPC, it just backs down and attempts to get the data via PIO when  
> DMA doesn't work.
> 
> Anything I can do to get the new DMA code to work on PPC?
> 

looks like this is the same issue I'm having on my ARM (big-endian) platform.  
The attached patch fixes endian issues for me regarding the DMA_MAGIC_COOKIE 
check as well as endian issues with DMA setup that I found, however I'm still 
working with Hans to find a dma memory/sync issue that appears on my platform - 
so I'm not sure this will fix the PPC DMA or not.  Please test this and if it 
doesn't work show us a log with ivtv_debug=79

If this does not solve your issue then perhaps its similar to my issue I'm 
still working on regarding dma memory sync.  There is definitely some issues in 
ivtv-svn (and most likely past versions) with regards to sync'ing memory 
between device/cpu.  I'm still working with Hans on the issue and don't have an 
elegant solution yet that works on my ARM big-endian platform, but I can work 
around the issue by changing the allocation of the SGarray in ivtv-queue.c as 
follows:

Index: driver/ivtv-queue.c
===================================================================
--- driver/ivtv-queue.c (revision 3739)
+++ driver/ivtv-queue.c (working copy)
@@ -225,13 +225,14 @@
         
        /* Allocate DMA SG Arrays */
        if (s->dma != PCI_DMA_NONE) {
-                s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, 
GFP_KERNEL);
+//                s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, 
GFP_KERNEL);
+                s->SGarray = (struct ivtv_SG_element 
*)pci_alloc_consistent(itv->dev, SGsize, &s->SG_handle);
                 if (s->SGarray == NULL) {
                         IVTV_ERR("Could not allocate SGarray for %s stream\n", 
s->name);
                         return -ENOMEM;
                 }
                 s->SG_length = 0;
-               s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, 
s->dma);
+//             s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, 
s->dma);
        }
 
        /* allocate stream buffers. Initially all buffers are in q_free. */

You might want to try this as well.  The above patch is only for the MPEG 
stream, so I believe there would be other changes for YUV etc but again this 
patch is not intended to be the permanent fix.

Tim

> - Rick
> 
> On Jan 21, 2007, at 6:36 PM, Ricardo Lugo wrote:
> 
> > Hi Hans, Chris, any other developers working on the new DMA code,
> >
> > I tried the trunk on my PPC ivtv machine and can't get it to capture
> > anything. MythTV complains that the driver has stopped recording, and
> > I get the following kernel message:
> >
> >     ivtv0 warning: encoder MPEG: Couldn't find start of buffer within
> > the first 256 bytes
> >
> > Fortunately, ivtv-0.9.x works just fine on my PPC machine, so it must
> > be a new change in the trunk. I think the cause is the buffer
> > (pointer?) being byteswapped and the DMA_MAGIC_COOKIE never gets
> > found.... This could be a result of using a char instead of a
> > v4l2_buffer in ivtv_buffer in ivtv-driver.h. Typecasting chars to
> > pointers always result in endian issues....
> >
> > trunk ivtv-irq.c 218: u32buf = (u32 *)buf->buf;
> > 0.9 ivtv-irq.c 296: (u32 *)(buf->buffer.m.userptr)
> >
> > trunk struct ivtv_buffer {
> >          struct list_head list;
> >          dma_addr_t dma_handle;
> >          unsigned long b_flags;
> >          char *buf;                          // leads to endian issues...
> >
> >          u32 bytesused;
> >          u32 readpos;
> > };
> >
> > 0.9 struct ivtv_buffer {
> >          size_t readpos;
> >          dma_addr_t dma_handle;
> >          struct v4l2_buffer buffer;            // conversion handled by
> > v4l2_buffer!
> >          struct list_head list;
> >          unsigned long ts;
> >          unsigned long b_flags;
> >          unsigned long *page;
> >          unsigned char **vpage;
> > };
> >
> > The "0.9" way of doing the buffer looks much safer to me... hope this
> > helps.
> >
> > - Rick
> >
> > _______________________________________________
> > ivtv-devel mailing list
> > [email protected]
> > http://ivtvdriver.org/mailman/listinfo/ivtv-devel
> 
> 
> _______________________________________________
> ivtv-devel mailing list
> [email protected]
> http://ivtvdriver.org/mailman/listinfo/ivtv-devel
> 
[EMAIL PROTECTED] ivtv-svn]$ 


Index: driver/ivtv-yuv.c
===================================================================
--- driver/ivtv-yuv.c	(revision 3739)
+++ driver/ivtv-yuv.c	(working copy)
@@ -91,15 +91,15 @@
 	/* If we've offset the y plane, ensure top area is blanked */
 	if (args->src_h + args->src_y < 512-16) {
 		if (itv->yuv_info.blanking_dmaptr) {
-			dma->SGarray[dma->SG_length].size = 720*16;
-			dma->SGarray[dma->SG_length].src = itv->yuv_info.blanking_dmaptr;
-			dma->SGarray[dma->SG_length].dst = IVTV_DEC_MEM_START + yuv_offset[frame];
+			dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
+			dma->SGarray[dma->SG_length].src = cpu_to_le32(itv->yuv_info.blanking_dmaptr);
+			dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DEC_MEM_START + yuv_offset[frame]);
 			dma->SG_length++;
 		}
 	}
 
 	/* Tag SG Array with Interrupt Bit */
-	dma->SGarray[dma->SG_length - 1].size |= 0x80000000;
+	dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
 
 	pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, dma->SG_handle,
 					sizeof(dma->SGarray), PCI_DMA_TODEVICE);
Index: driver/ivtv-irq.c
===================================================================
--- driver/ivtv-irq.c	(revision 3739)
+++ driver/ivtv-irq.c	(working copy)
@@ -122,11 +122,11 @@
 		if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
                     s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
 	                s->dma_backup = read_dec(offset - IVTV_DECODER_OFFSET);
-                	write_dec(DMA_MAGIC_COOKIE, offset - IVTV_DECODER_OFFSET);
+                	write_dec(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET);
 		}
 		else {
 	                s->dma_backup = read_enc(offset);
-                	write_enc(DMA_MAGIC_COOKIE, offset);
+                	write_enc(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
 		}
                 s->dma_offset = offset;
 	}
@@ -165,9 +165,9 @@
 		if (skip_bufs-- > 0)
 			continue;
 		if (!ivtv_use_pio(s)) {
-			s->SGarray[idx].dst = buf->dma_handle;
-			s->SGarray[idx].src = offset;
-			s->SGarray[idx].size = s->buf_size;
+			s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
+			s->SGarray[idx].src = cpu_to_le32(offset);
+			s->SGarray[idx].size = cpu_to_le32(s->buf_size);
 		}
 		buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
 
@@ -222,7 +222,8 @@
 
 		if (x == 0) {
 			offset = s->dma_last_offset;
-			if (u32buf[offset / 4] != DMA_MAGIC_COOKIE) {
+			if (u32buf[offset / 4] != DMA_MAGIC_COOKIE) 
+			{
 				for (offset = 0; offset < 64; offset++) {
 					if (u32buf[offset] == DMA_MAGIC_COOKIE) {
 						break;
@@ -312,9 +313,9 @@
                         offset = uv_offset;
                         y_done = 1;	
                 }
-		s->SGarray[idx].src = buf->dma_handle;
-		s->SGarray[idx].dst = offset;
-		s->SGarray[idx].size = buf->bytesused;
+		s->SGarray[idx].src = cpu_to_le32(buf->dma_handle);
+		s->SGarray[idx].dst = cpu_to_le32(offset);
+		s->SGarray[idx].size = cpu_to_le32(buf->bytesused);
 
 		offset += buf->bytesused;
 		bytes_written += buf->bytesused;
@@ -326,7 +327,7 @@
 	s->SG_length = idx;
 
 	/* Mark last buffer size for Interrupt flag */
-	s->SGarray[s->SG_length - 1].size |= 0x80000000;
+	s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
 
 	/* Sync Hardware SG List of buffers */
 	pci_dma_sync_single_for_device((struct pci_dev *)itv->dev,
@@ -353,7 +354,7 @@
 	if (s->q_predma.bytesused)
 		ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
 	IVTV_DEBUG_DMA("start DMA for %s\n", s->name);
-	s->SGarray[s->SG_length - 1].size += 256;
+	s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
 
         /* If this is an MPEG stream, and VBI data is also pending, then append the
            VBI DMA to the MPEG DMA and transfer both sets of data at once.
@@ -367,7 +368,7 @@
 	if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
 			s->SG_length + s_vbi->SG_length <= s->buffers) {
 		ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
-		s_vbi->SGarray[s_vbi->SG_length - 1].size += 256;
+		s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
 		for (i = 0; i < s_vbi->SG_length; i++) {
 			s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
 		}
@@ -377,7 +378,7 @@
 	}
 
 	/* Mark last buffer size for Interrupt flag */
-	s->SGarray[s->SG_length - 1].size |= 0x80000000;
+	s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
 
 	/* Sync Hardware SG List of buffers */
 	pci_dma_sync_single_for_device((struct pci_dev *)itv->dev,
Index: driver/ivtv-udma.c
===================================================================
--- driver/ivtv-udma.c	(revision 3739)
+++ driver/ivtv-udma.c	(working copy)
@@ -61,12 +61,12 @@
 	struct scatterlist *sg;
 
 	for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg++) {
-		dma->SGarray[i].size = sg_dma_len(sg);
-		dma->SGarray[i].src = sg_dma_address(sg);
-		dma->SGarray[i].dst = buffer_offset;
-		buffer_offset += dma->SGarray[i].size;
+		dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg));
+		dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg));
+		dma->SGarray[i].dst = cpu_to_le32(buffer_offset);
+		buffer_offset += sg_dma_len(sg);
 
-		split -= dma->SGarray[i].size;
+		split -= sg_dma_len(sg);
 		if (split == 0)
 			buffer_offset = buffer_offset_2;
 	}
@@ -130,7 +130,7 @@
 	ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
 
 	/* Tag SG Array with Interrupt Bit */
-	dma->SGarray[dma->SG_length - 1].size |= 0x80000000;
+	dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
 
 	pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, dma->SG_handle,
 		sizeof(dma->SGarray), PCI_DMA_TODEVICE);
_______________________________________________
ivtv-devel mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-devel

Reply via email to