From: "Ronald S. Bultje" <rbultje@ronald.bitfreak.net>

Attached patch adds some host<->le conversion functions for 32-bit integers. 
The hardware expects 32-bit integers, which the host does not always provide. 
With the attached patch, the hardware runs fine on PPC hardware as well.

Original patch by Ben Capper <benandeve@optusnet.com.au>.

Signed-off-by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/media/video/zoran_device.c |   31 +++++++++-------
 25-akpm/drivers/media/video/zoran_driver.c |   56 +++++++++++++++++------------
 2 files changed, 51 insertions(+), 36 deletions(-)

diff -puN drivers/media/video/zoran_device.c~zr36067-driver-ppc-be-port drivers/media/video/zoran_device.c
--- 25/drivers/media/video/zoran_device.c~zr36067-driver-ppc-be-port	2004-12-31 01:33:04.129269512 -0800
+++ 25-akpm/drivers/media/video/zoran_device.c	2004-12-31 01:33:04.137268296 -0800
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/byteorder/generic.h>
 
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
@@ -758,7 +759,7 @@ init_jpeg_queue (struct zoran *zr)
 		zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER;	/* nothing going on */
 	}
 	for (i = 0; i < BUZ_NUM_STAT_COM; i++) {
-		zr->stat_com[i] = 1;	/* mark as unavailable to zr36057 */
+		zr->stat_com[i] = cpu_to_le32(1);	/* mark as unavailable to zr36057 */
 	}
 }
 
@@ -1163,20 +1164,20 @@ zoran_feed_stat_com (struct zoran *zr)
 			/* fill 1 stat_com entry */
 			i = (zr->jpg_dma_head -
 			     zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
-			if (!(zr->stat_com[i] & 1))
+			if (!(zr->stat_com[i] & cpu_to_le32(1)))
 				break;
 			zr->stat_com[i] =
-			    zr->jpg_buffers.buffer[frame].frag_tab_bus;
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
 		} else {
 			/* fill 2 stat_com entries */
 			i = ((zr->jpg_dma_head -
 			      zr->jpg_err_shift) & 1) * 2;
-			if (!(zr->stat_com[i] & 1))
+			if (!(zr->stat_com[i] & cpu_to_le32(1)))
 				break;
 			zr->stat_com[i] =
-			    zr->jpg_buffers.buffer[frame].frag_tab_bus;
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
 			zr->stat_com[i + 1] =
-			    zr->jpg_buffers.buffer[frame].frag_tab_bus;
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
 		}
 		zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
 		zr->jpg_dma_head++;
@@ -1213,7 +1214,7 @@ zoran_reap_stat_com (struct zoran *zr)
 			i = ((zr->jpg_dma_tail -
 			      zr->jpg_err_shift) & 1) * 2 + 1;
 
-		stat_com = zr->stat_com[i];
+		stat_com = le32_to_cpu(zr->stat_com[i]);
 
 		if ((stat_com & 1) == 0) {
 			return;
@@ -1309,7 +1310,7 @@ error_handler (struct zoran *zr,
 					for (i = 0;
 					     i < zr->jpg_buffers.num_buffers;
 					     i++) {
-						if (zr->stat_com[j] ==
+						if (le32_to_cpu(zr->stat_com[j]) ==
 						    zr->jpg_buffers.
 						    buffer[i].
 						    frag_tab_bus) {
@@ -1321,7 +1322,6 @@ error_handler (struct zoran *zr,
 				printk("\n");
 			}
 		}
-
 		/* Find an entry in stat_com and rotate contents */
 		{
 			int i;
@@ -1334,9 +1334,9 @@ error_handler (struct zoran *zr,
 				      zr->jpg_err_shift) & 1) * 2;
 			if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
 				/* Mimic zr36067 operation */
-				zr->stat_com[i] |= 1;
+				zr->stat_com[i] |= cpu_to_le32(1);
 				if (zr->jpg_settings.TmpDcm != 1)
-					zr->stat_com[i + 1] |= 1;
+					zr->stat_com[i + 1] |= cpu_to_le32(1);
 				/* Refill */
 				zoran_reap_stat_com(zr);
 				zoran_feed_stat_com(zr);
@@ -1355,12 +1355,17 @@ error_handler (struct zoran *zr,
 				int j;
 				u32 bus_addr[BUZ_NUM_STAT_COM];
 
+				/* Here we are copying the stat_com array, which
+				 * is already in little endian format, so
+				 * no endian conversions here
+				 */
 				memcpy(bus_addr, zr->stat_com,
 				       sizeof(bus_addr));
 				for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
 					zr->stat_com[j] =
 					    bus_addr[(i + j) &
 						     BUZ_MASK_STAT_COM];
+
 				}
 				zr->jpg_err_shift += i;
 				zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
@@ -1564,7 +1569,7 @@ zoran_irq (int             irq,
 						int i;
 						strcpy(sv, sc);
 						for (i = 0; i < 4; i++) {
-							if (zr->stat_com[i] & 1)
+							if (le32_to_cpu(zr->stat_com[i]) & 1)
 								sv[i] = '1';
 						}
 						sv[4] = 0;
@@ -1592,7 +1597,7 @@ zoran_irq (int             irq,
 					       ZR_DEVNAME(zr), zr->jpg_seq_num);
 					for (i = 0; i < 4; i++) {
 						printk(" %08x",
-						       zr->stat_com[i]);
+						       le32_to_cpu(zr->stat_com[i]));
 					}
 					printk("\n");
 				}
diff -puN drivers/media/video/zoran_driver.c~zr36067-driver-ppc-be-port drivers/media/video/zoran_driver.c
--- 25/drivers/media/video/zoran_driver.c~zr36067-driver-ppc-be-port	2004-12-31 01:33:04.131269208 -0800
+++ 25-akpm/drivers/media/video/zoran_driver.c	2004-12-31 01:33:04.141267688 -0800
@@ -52,6 +52,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
+#include <linux/byteorder/generic.h>
 
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
@@ -516,6 +517,16 @@ v4l_fbuffer_free (struct file *file)
  *       virtual addresses) and then again have to make a lot of efforts
  *       to get the physical address.
  *
+ *   Ben Capper:
+ *       On big-endian architectures (such as ppc) some extra steps
+ *       are needed. When reading and writing to the stat_com array
+ *       and fragment buffers, the device expects to see little-
+ *       endian values. The use of cpu_to_le32() and le32_to_cpu()
+ *       in this function (and one or two others in zoran_device.c)
+ *       ensure that these values are always stored in little-endian
+ *       form, regardless of architecture. The zr36057 does Very Bad
+ *       Things on big endian architectures if the stat_com array
+ *       and fragment buffers are not little-endian.
  */
 
 static int
@@ -569,9 +580,9 @@ jpg_fbuffer_alloc (struct file *file)
 				return -ENOBUFS;
 			}
 			fh->jpg_buffers.buffer[i].frag_tab[0] =
-			    virt_to_bus((void *) mem);
+			    cpu_to_le32(virt_to_bus((void *) mem));
 			fh->jpg_buffers.buffer[i].frag_tab[1] =
-			    ((fh->jpg_buffers.buffer_size / 4) << 1) | 1;
+			    cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
 			for (off = 0; off < fh->jpg_buffers.buffer_size;
 			     off += PAGE_SIZE)
 				SetPageReserved(MAP_NR(mem + off));
@@ -591,14 +602,14 @@ jpg_fbuffer_alloc (struct file *file)
 				}
 
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
-				    virt_to_bus((void *) mem);
+				    cpu_to_le32(virt_to_bus((void *) mem));
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j +
 								   1] =
-				    (PAGE_SIZE / 4) << 1;
+				    cpu_to_le32((PAGE_SIZE / 4) << 1);
 				SetPageReserved(MAP_NR(mem));
 			}
 
-			fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= 1;
+			fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
 		}
 	}
 
@@ -631,13 +642,8 @@ jpg_fbuffer_free (struct file *file)
 		//if (alloc_contig) {
 		if (fh->jpg_buffers.need_contiguous) {
 			if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
-				mem =
-				    (unsigned char *) bus_to_virt(fh->
-								  jpg_buffers.
-								  buffer
-								  [i].
-								  frag_tab
-								  [0]);
+				mem = (unsigned char *) bus_to_virt(le32_to_cpu(
+					fh->jpg_buffers.buffer[i].frag_tab[0]));
 				for (off = 0;
 				     off < fh->jpg_buffers.buffer_size;
 				     off += PAGE_SIZE)
@@ -656,13 +662,16 @@ jpg_fbuffer_free (struct file *file)
 					break;
 				ClearPageReserved(MAP_NR
 						  (bus_to_virt
-						   (fh->jpg_buffers.
-						    buffer[i].frag_tab[2 *
-								       j])));
+						   (le32_to_cpu
+						    (fh->jpg_buffers.
+						     buffer[i].frag_tab[2 *
+								       j]))));
 				free_page((unsigned long)
-					  bus_to_virt(fh->jpg_buffers.
+					  bus_to_virt
+					          (le32_to_cpu
+						   (fh->jpg_buffers.
 						      buffer[i].
-						      frag_tab[2 * j]));
+						      frag_tab[2 * j])));
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
 				    0;
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j +
@@ -4539,14 +4548,14 @@ zoran_mmap (struct file           *file,
 			     j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
 			     j++) {
 				fraglen =
-				    (fh->jpg_buffers.buffer[i].
-				     frag_tab[2 * j + 1] & ~1) << 1;
+				    (le32_to_cpu(fh->jpg_buffers.buffer[i].
+				     frag_tab[2 * j + 1]) & ~1) << 1;
 				todo = size;
 				if (todo > fraglen)
 					todo = fraglen;
 				pos =
-				    (unsigned long) fh->jpg_buffers.
-				    buffer[i].frag_tab[2 * j];
+				    le32_to_cpu((unsigned long) fh->jpg_buffers.
+				    buffer[i].frag_tab[2 * j]);
 				/* should just be pos on i386 */
 				page = virt_to_phys(bus_to_virt(pos))
 								>> PAGE_SHIFT;
@@ -4563,8 +4572,8 @@ zoran_mmap (struct file           *file,
 				start += todo;
 				if (size == 0)
 					break;
-				if (fh->jpg_buffers.buffer[i].
-				    frag_tab[2 * j + 1] & 1)
+				if (le32_to_cpu(fh->jpg_buffers.buffer[i].
+				    frag_tab[2 * j + 1]) & 1)
 					break;	/* was last fragment */
 			}
 			fh->jpg_buffers.buffer[i].map = map;
@@ -4689,3 +4698,4 @@ struct video_device zoran_template __dev
 	.release = &zoran_vdev_release,
 	.minor = -1
 };
+
_