提交 b80696b7 编写于 作者: H Hans Verkuil 提交者: Mauro Carvalho Chehab

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: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 96b8e145
......@@ -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 {
......
......@@ -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,82 +235,37 @@ 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,
KERN_ERR
"%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
ZR_DEVNAME(zr), i);
v4l_fbuffer_free(file);
return -ENOBUFS;
}
fh->v4l_buffers.buffer[i].fbuffer = mem;
fh->v4l_buffers.buffer[i].fbuffer_phys =
virt_to_phys(mem);
fh->v4l_buffers.buffer[i].fbuffer_bus =
virt_to_bus(mem);
for (off = 0; off < fh->v4l_buffers.buffer_size;
off += PAGE_SIZE)
SetPageReserved(MAP_NR(mem + off));
dprintk(4,
KERN_INFO
"%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\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;
}
mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
if (!mem) {
dprintk(1,
KERN_ERR
"%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
ZR_DEVNAME(zr), i);
v4l_fbuffer_free(file);
return -ENOBUFS;
}
fh->v4l_buffers.buffer[i].fbuffer = mem;
fh->v4l_buffers.buffer[i].fbuffer_phys =
virt_to_phys(mem);
fh->v4l_buffers.buffer[i].fbuffer_bus =
virt_to_bus(mem);
for (off = 0; off < fh->v4l_buffers.buffer_size;
off += PAGE_SIZE)
SetPageReserved(MAP_NR(mem + off));
dprintk(4,
KERN_INFO
"%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
ZR_DEVNAME(zr), i, (unsigned long) mem,
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);
}
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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册