Commit b80696b7 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (10704): zoran: remove broken BIGPHYS_AREA and BUZ_HIMEM code, and...


V4L/DVB (10704): zoran: remove broken BIGPHYS_AREA and BUZ_HIMEM code, and allow for kmallocs > 128 kB

Remove memory allocation madness.

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 96b8e145
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -170,8 +170,6 @@ Private IOCTL to set up for displaying MJPEG
#endif
#define   V4L_MASK_FRAME   (V4L_MAX_FRAME - 1)

#define MAX_KMALLOC_MEM (128*1024)

#include "zr36057.h"

enum card_type {
+31 −158
Original line number Diff line number Diff line
@@ -191,9 +191,6 @@ const struct zoran_format zoran_formats[] = {
};
#define NUM_FORMATS ARRAY_SIZE(zoran_formats)

// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined


static int lock_norm;	/* 0 = default 1 = Don't change TV standard (norm) */
module_param(lock_norm, int, 0644);
MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)");
@@ -229,77 +226,8 @@ static void jpg_fbuffer_free(struct file *file);
 *   Allocate the V4L grab buffers
 *
 *   These have to be pysically contiguous.
 *   If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
 *   else we try to allocate them with bigphysarea_alloc_pages
 *   if the bigphysarea patch is present in the kernel,
 *   else we try to use high memory (if the user has bootet
 *   Linux with the necessary memory left over).
 */

static unsigned long
get_high_mem (unsigned long size)
{
/*
 * Check if there is usable memory at the end of Linux memory
 * of at least size. Return the physical address of this memory,
 * return 0 on failure.
 *
 * The idea is from Alexandro Rubini's book "Linux device drivers".
 * The driver from him which is downloadable from O'Reilly's
 * web site misses the "virt_to_phys(high_memory)" part
 * (and therefore doesn't work at all - at least with 2.2.x kernels).
 *
 * It should be unnecessary to mention that THIS IS DANGEROUS,
 * if more than one driver at a time has the idea to use this memory!!!!
 */

	volatile unsigned char __iomem *mem;
	unsigned char c;
	unsigned long hi_mem_ph;
	unsigned long i;

	/* Map the high memory to user space */

	hi_mem_ph = virt_to_phys(high_memory);

	mem = ioremap(hi_mem_ph, size);
	if (!mem) {
		dprintk(1,
			KERN_ERR "%s: get_high_mem() - ioremap failed\n",
			ZORAN_NAME);
		return 0;
	}

	for (i = 0; i < size; i++) {
		/* Check if it is memory */
		c = i & 0xff;
		writeb(c, mem + i);
		if (readb(mem + i) != c)
			break;
		c = 255 - c;
		writeb(c, mem + i);
		if (readb(mem + i) != c)
			break;
		writeb(0, mem + i);	/* zero out memory */

		/* give the kernel air to breath */
		if ((i & 0x3ffff) == 0x3ffff)
			schedule();
	}

	iounmap(mem);

	if (i != size) {
		dprintk(1,
			KERN_ERR
			"%s: get_high_mem() - requested %lu, avail %lu\n",
			ZORAN_NAME, size, i);
		return 0;
	}

	return hi_mem_ph;
}

static int
v4l_fbuffer_alloc (struct file *file)
{
@@ -307,19 +235,15 @@ v4l_fbuffer_alloc (struct file *file)
	struct zoran *zr = fh->zr;
	int i, off;
	unsigned char *mem;
	unsigned long pmem = 0;

	for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
		if (fh->v4l_buffers.buffer[i].fbuffer)
			dprintk(2,
				KERN_WARNING
				"%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n",
				"%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n",
				ZR_DEVNAME(zr), i);

		//udelay(20);
		if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
			/* Use kmalloc */

		mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
		if (!mem) {
			dprintk(1,
@@ -339,50 +263,9 @@ v4l_fbuffer_alloc (struct file *file)
			SetPageReserved(MAP_NR(mem + off));
		dprintk(4,
			KERN_INFO
				"%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\n",
			"%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
			ZR_DEVNAME(zr), i, (unsigned long) mem,
				(unsigned long long)virt_to_bus(mem));
		} else {

			/* Use high memory which has been left at boot time */

			/* Ok., Ok. this is an evil hack - we make
			 * the assumption that physical addresses are
			 * the same as bus addresses (true at least
			 * for Intel processors). The whole method of
			 * obtaining and using this memory is not very
			 * nice - but I hope it saves some poor users
			 * from kernel hacking, which might have even
			 * more evil results */

			if (i == 0) {
				int size =
				    fh->v4l_buffers.num_buffers *
				    fh->v4l_buffers.buffer_size;

				pmem = get_high_mem(size);
				if (pmem == 0) {
					dprintk(1,
						KERN_ERR
						"%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n",
						ZR_DEVNAME(zr), size >> 10);
					return -ENOBUFS;
				}
				fh->v4l_buffers.buffer[0].fbuffer = NULL;
				fh->v4l_buffers.buffer[0].fbuffer_phys = pmem;
				fh->v4l_buffers.buffer[0].fbuffer_bus = pmem;
				dprintk(4,
					KERN_INFO
					"%s: v4l_fbuffer_alloc() - using %d KB high memory\n",
					ZR_DEVNAME(zr), size >> 10);
			} else {
				fh->v4l_buffers.buffer[i].fbuffer = NULL;
				fh->v4l_buffers.buffer[i].fbuffer_phys =
				    pmem + i * fh->v4l_buffers.buffer_size;
				fh->v4l_buffers.buffer[i].fbuffer_bus =
				    pmem + i * fh->v4l_buffers.buffer_size;
			}
		}
			virt_to_bus(mem));
	}

	fh->v4l_buffers.allocated = 1;
@@ -405,13 +288,11 @@ v4l_fbuffer_free (struct file *file)
		if (!fh->v4l_buffers.buffer[i].fbuffer)
			continue;

		if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
		mem = fh->v4l_buffers.buffer[i].fbuffer;
		for (off = 0; off < fh->v4l_buffers.buffer_size;
		     off += PAGE_SIZE)
			ClearPageReserved(MAP_NR(mem + off));
		kfree((void *) fh->v4l_buffers.buffer[i].fbuffer);
		}
		fh->v4l_buffers.buffer[i].fbuffer = NULL;
	}

@@ -421,16 +302,10 @@ v4l_fbuffer_free (struct file *file)
/*
 *   Allocate the MJPEG grab buffers.
 *
 *   If the requested buffer size is smaller than MAX_KMALLOC_MEM,
 *   kmalloc is used to request a physically contiguous area,
 *   else we allocate the memory in framgents with get_zeroed_page.
 *
 *   If a Natoma chipset is present and this is a revision 1 zr36057,
 *   each MJPEG buffer needs to be physically contiguous.
 *   (RJ: This statement is from Dave Perks' original driver,
 *   I could never check it because I have a zr36067)
 *   The driver cares about this because it reduces the buffer
 *   size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
 *
 *   RJ: The contents grab buffers needs never be accessed in the driver.
 *       Therefore there is no need to allocate them with vmalloc in order
@@ -464,7 +339,7 @@ jpg_fbuffer_alloc (struct file *file)
		if (fh->jpg_buffers.buffer[i].frag_tab)
			dprintk(2,
				KERN_WARNING
				"%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n",
				"%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n",
				ZR_DEVNAME(zr), i);

		/* Allocate fragment table for this buffer */
@@ -504,7 +379,7 @@ jpg_fbuffer_alloc (struct file *file)
			     off += PAGE_SIZE)
				SetPageReserved(MAP_NR(mem + off));
		} else {
			/* jpg_bufsize is allreay page aligned */
			/* jpg_bufsize is already page aligned */
			for (j = 0;
			     j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
			     j++) {
@@ -2173,6 +2048,7 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
		return res;
	}


	case VIDIOCGMBUF:
	{
		struct video_mbuf *vmbuf = arg;
@@ -2369,16 +2245,13 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
		 * tables to a Maximum of 2 MB */
		if (breq->size > jpg_bufsize)
			breq->size = jpg_bufsize;
		if (fh->jpg_buffers.need_contiguous &&
		    breq->size > MAX_KMALLOC_MEM)
			breq->size = MAX_KMALLOC_MEM;

		mutex_lock(&zr->resource_lock);

		if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
			dprintk(1,
				KERN_ERR
				"%s: BUZIOC_REQBUFS - buffers allready allocated\n",
				"%s: BUZIOC_REQBUFS - buffers already allocated\n",
				ZR_DEVNAME(zr));
			res = -EBUSY;
			goto jpgreqbuf_unlock_and_return;