diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-02-18 11:20:05 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:55 -0400 |
commit | b80696b700b25b7aa054610af84a1f05e4f4ea58 (patch) | |
tree | 375e1654ca11cabf4a263d8486e8fc3450b9d162 | |
parent | 96b8e145f0a6f3c0470b5cdbe7ba9be314bb556f (diff) |
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: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/zoran/zoran.h | 2 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_driver.c | 189 |
2 files changed, 31 insertions, 160 deletions
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 1bf540cb546c..76668bda0494 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h | |||
@@ -170,8 +170,6 @@ Private IOCTL to set up for displaying MJPEG | |||
170 | #endif | 170 | #endif |
171 | #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) | 171 | #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) |
172 | 172 | ||
173 | #define MAX_KMALLOC_MEM (128*1024) | ||
174 | |||
175 | #include "zr36057.h" | 173 | #include "zr36057.h" |
176 | 174 | ||
177 | enum card_type { | 175 | enum card_type { |
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index dc6ba554597f..1f8d3a8b0cba 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -191,9 +191,6 @@ const struct zoran_format zoran_formats[] = { | |||
191 | }; | 191 | }; |
192 | #define NUM_FORMATS ARRAY_SIZE(zoran_formats) | 192 | #define NUM_FORMATS ARRAY_SIZE(zoran_formats) |
193 | 193 | ||
194 | // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined | ||
195 | |||
196 | |||
197 | static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ | 194 | static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ |
198 | module_param(lock_norm, int, 0644); | 195 | module_param(lock_norm, int, 0644); |
199 | MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); | 196 | MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); |
@@ -229,77 +226,8 @@ static void jpg_fbuffer_free(struct file *file); | |||
229 | * Allocate the V4L grab buffers | 226 | * Allocate the V4L grab buffers |
230 | * | 227 | * |
231 | * These have to be pysically contiguous. | 228 | * These have to be pysically contiguous. |
232 | * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc | ||
233 | * else we try to allocate them with bigphysarea_alloc_pages | ||
234 | * if the bigphysarea patch is present in the kernel, | ||
235 | * else we try to use high memory (if the user has bootet | ||
236 | * Linux with the necessary memory left over). | ||
237 | */ | ||
238 | |||
239 | static unsigned long | ||
240 | get_high_mem (unsigned long size) | ||
241 | { | ||
242 | /* | ||
243 | * Check if there is usable memory at the end of Linux memory | ||
244 | * of at least size. Return the physical address of this memory, | ||
245 | * return 0 on failure. | ||
246 | * | ||
247 | * The idea is from Alexandro Rubini's book "Linux device drivers". | ||
248 | * The driver from him which is downloadable from O'Reilly's | ||
249 | * web site misses the "virt_to_phys(high_memory)" part | ||
250 | * (and therefore doesn't work at all - at least with 2.2.x kernels). | ||
251 | * | ||
252 | * It should be unnecessary to mention that THIS IS DANGEROUS, | ||
253 | * if more than one driver at a time has the idea to use this memory!!!! | ||
254 | */ | 229 | */ |
255 | 230 | ||
256 | volatile unsigned char __iomem *mem; | ||
257 | unsigned char c; | ||
258 | unsigned long hi_mem_ph; | ||
259 | unsigned long i; | ||
260 | |||
261 | /* Map the high memory to user space */ | ||
262 | |||
263 | hi_mem_ph = virt_to_phys(high_memory); | ||
264 | |||
265 | mem = ioremap(hi_mem_ph, size); | ||
266 | if (!mem) { | ||
267 | dprintk(1, | ||
268 | KERN_ERR "%s: get_high_mem() - ioremap failed\n", | ||
269 | ZORAN_NAME); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | for (i = 0; i < size; i++) { | ||
274 | /* Check if it is memory */ | ||
275 | c = i & 0xff; | ||
276 | writeb(c, mem + i); | ||
277 | if (readb(mem + i) != c) | ||
278 | break; | ||
279 | c = 255 - c; | ||
280 | writeb(c, mem + i); | ||
281 | if (readb(mem + i) != c) | ||
282 | break; | ||
283 | writeb(0, mem + i); /* zero out memory */ | ||
284 | |||
285 | /* give the kernel air to breath */ | ||
286 | if ((i & 0x3ffff) == 0x3ffff) | ||
287 | schedule(); | ||
288 | } | ||
289 | |||
290 | iounmap(mem); | ||
291 | |||
292 | if (i != size) { | ||
293 | dprintk(1, | ||
294 | KERN_ERR | ||
295 | "%s: get_high_mem() - requested %lu, avail %lu\n", | ||
296 | ZORAN_NAME, size, i); | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | return hi_mem_ph; | ||
301 | } | ||
302 | |||
303 | static int | 231 | static int |
304 | v4l_fbuffer_alloc (struct file *file) | 232 | v4l_fbuffer_alloc (struct file *file) |
305 | { | 233 | { |
@@ -307,82 +235,37 @@ v4l_fbuffer_alloc (struct file *file) | |||
307 | struct zoran *zr = fh->zr; | 235 | struct zoran *zr = fh->zr; |
308 | int i, off; | 236 | int i, off; |
309 | unsigned char *mem; | 237 | unsigned char *mem; |
310 | unsigned long pmem = 0; | ||
311 | 238 | ||
312 | for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { | 239 | for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { |
313 | if (fh->v4l_buffers.buffer[i].fbuffer) | 240 | if (fh->v4l_buffers.buffer[i].fbuffer) |
314 | dprintk(2, | 241 | dprintk(2, |
315 | KERN_WARNING | 242 | KERN_WARNING |
316 | "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n", | 243 | "%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n", |
317 | ZR_DEVNAME(zr), i); | 244 | ZR_DEVNAME(zr), i); |
318 | 245 | ||
319 | //udelay(20); | 246 | //udelay(20); |
320 | if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { | 247 | mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); |
321 | /* Use kmalloc */ | 248 | if (!mem) { |
322 | 249 | dprintk(1, | |
323 | mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); | 250 | KERN_ERR |
324 | if (!mem) { | 251 | "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", |
325 | dprintk(1, | 252 | ZR_DEVNAME(zr), i); |
326 | KERN_ERR | 253 | v4l_fbuffer_free(file); |
327 | "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", | 254 | return -ENOBUFS; |
328 | ZR_DEVNAME(zr), i); | ||
329 | v4l_fbuffer_free(file); | ||
330 | return -ENOBUFS; | ||
331 | } | ||
332 | fh->v4l_buffers.buffer[i].fbuffer = mem; | ||
333 | fh->v4l_buffers.buffer[i].fbuffer_phys = | ||
334 | virt_to_phys(mem); | ||
335 | fh->v4l_buffers.buffer[i].fbuffer_bus = | ||
336 | virt_to_bus(mem); | ||
337 | for (off = 0; off < fh->v4l_buffers.buffer_size; | ||
338 | off += PAGE_SIZE) | ||
339 | SetPageReserved(MAP_NR(mem + off)); | ||
340 | dprintk(4, | ||
341 | KERN_INFO | ||
342 | "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", | ||
343 | ZR_DEVNAME(zr), i, (unsigned long) mem, | ||
344 | (unsigned long long)virt_to_bus(mem)); | ||
345 | } else { | ||
346 | |||
347 | /* Use high memory which has been left at boot time */ | ||
348 | |||
349 | /* Ok., Ok. this is an evil hack - we make | ||
350 | * the assumption that physical addresses are | ||
351 | * the same as bus addresses (true at least | ||
352 | * for Intel processors). The whole method of | ||
353 | * obtaining and using this memory is not very | ||
354 | * nice - but I hope it saves some poor users | ||
355 | * from kernel hacking, which might have even | ||
356 | * more evil results */ | ||
357 | |||
358 | if (i == 0) { | ||
359 | int size = | ||
360 | fh->v4l_buffers.num_buffers * | ||
361 | fh->v4l_buffers.buffer_size; | ||
362 | |||
363 | pmem = get_high_mem(size); | ||
364 | if (pmem == 0) { | ||
365 | dprintk(1, | ||
366 | KERN_ERR | ||
367 | "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n", | ||
368 | ZR_DEVNAME(zr), size >> 10); | ||
369 | return -ENOBUFS; | ||
370 | } | ||
371 | fh->v4l_buffers.buffer[0].fbuffer = NULL; | ||
372 | fh->v4l_buffers.buffer[0].fbuffer_phys = pmem; | ||
373 | fh->v4l_buffers.buffer[0].fbuffer_bus = pmem; | ||
374 | dprintk(4, | ||
375 | KERN_INFO | ||
376 | "%s: v4l_fbuffer_alloc() - using %d KB high memory\n", | ||
377 | ZR_DEVNAME(zr), size >> 10); | ||
378 | } else { | ||
379 | fh->v4l_buffers.buffer[i].fbuffer = NULL; | ||
380 | fh->v4l_buffers.buffer[i].fbuffer_phys = | ||
381 | pmem + i * fh->v4l_buffers.buffer_size; | ||
382 | fh->v4l_buffers.buffer[i].fbuffer_bus = | ||
383 | pmem + i * fh->v4l_buffers.buffer_size; | ||
384 | } | ||
385 | } | 255 | } |
256 | fh->v4l_buffers.buffer[i].fbuffer = mem; | ||
257 | fh->v4l_buffers.buffer[i].fbuffer_phys = | ||
258 | virt_to_phys(mem); | ||
259 | fh->v4l_buffers.buffer[i].fbuffer_bus = | ||
260 | virt_to_bus(mem); | ||
261 | for (off = 0; off < fh->v4l_buffers.buffer_size; | ||
262 | off += PAGE_SIZE) | ||
263 | SetPageReserved(MAP_NR(mem + off)); | ||
264 | dprintk(4, | ||
265 | KERN_INFO | ||
266 | "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", | ||
267 | ZR_DEVNAME(zr), i, (unsigned long) mem, | ||
268 | virt_to_bus(mem)); | ||
386 | } | 269 | } |
387 | 270 | ||
388 | fh->v4l_buffers.allocated = 1; | 271 | fh->v4l_buffers.allocated = 1; |
@@ -405,13 +288,11 @@ v4l_fbuffer_free (struct file *file) | |||
405 | if (!fh->v4l_buffers.buffer[i].fbuffer) | 288 | if (!fh->v4l_buffers.buffer[i].fbuffer) |
406 | continue; | 289 | continue; |
407 | 290 | ||
408 | if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { | 291 | mem = fh->v4l_buffers.buffer[i].fbuffer; |
409 | mem = fh->v4l_buffers.buffer[i].fbuffer; | 292 | for (off = 0; off < fh->v4l_buffers.buffer_size; |
410 | for (off = 0; off < fh->v4l_buffers.buffer_size; | 293 | off += PAGE_SIZE) |
411 | off += PAGE_SIZE) | 294 | ClearPageReserved(MAP_NR(mem + off)); |
412 | ClearPageReserved(MAP_NR(mem + off)); | 295 | kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); |
413 | kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); | ||
414 | } | ||
415 | fh->v4l_buffers.buffer[i].fbuffer = NULL; | 296 | fh->v4l_buffers.buffer[i].fbuffer = NULL; |
416 | } | 297 | } |
417 | 298 | ||
@@ -421,16 +302,10 @@ v4l_fbuffer_free (struct file *file) | |||
421 | /* | 302 | /* |
422 | * Allocate the MJPEG grab buffers. | 303 | * Allocate the MJPEG grab buffers. |
423 | * | 304 | * |
424 | * If the requested buffer size is smaller than MAX_KMALLOC_MEM, | ||
425 | * kmalloc is used to request a physically contiguous area, | ||
426 | * else we allocate the memory in framgents with get_zeroed_page. | ||
427 | * | ||
428 | * If a Natoma chipset is present and this is a revision 1 zr36057, | 305 | * If a Natoma chipset is present and this is a revision 1 zr36057, |
429 | * each MJPEG buffer needs to be physically contiguous. | 306 | * each MJPEG buffer needs to be physically contiguous. |
430 | * (RJ: This statement is from Dave Perks' original driver, | 307 | * (RJ: This statement is from Dave Perks' original driver, |
431 | * I could never check it because I have a zr36067) | 308 | * I could never check it because I have a zr36067) |
432 | * The driver cares about this because it reduces the buffer | ||
433 | * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation). | ||
434 | * | 309 | * |
435 | * RJ: The contents grab buffers needs never be accessed in the driver. | 310 | * RJ: The contents grab buffers needs never be accessed in the driver. |
436 | * Therefore there is no need to allocate them with vmalloc in order | 311 | * Therefore there is no need to allocate them with vmalloc in order |
@@ -464,7 +339,7 @@ jpg_fbuffer_alloc (struct file *file) | |||
464 | if (fh->jpg_buffers.buffer[i].frag_tab) | 339 | if (fh->jpg_buffers.buffer[i].frag_tab) |
465 | dprintk(2, | 340 | dprintk(2, |
466 | KERN_WARNING | 341 | KERN_WARNING |
467 | "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n", | 342 | "%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n", |
468 | ZR_DEVNAME(zr), i); | 343 | ZR_DEVNAME(zr), i); |
469 | 344 | ||
470 | /* Allocate fragment table for this buffer */ | 345 | /* Allocate fragment table for this buffer */ |
@@ -504,7 +379,7 @@ jpg_fbuffer_alloc (struct file *file) | |||
504 | off += PAGE_SIZE) | 379 | off += PAGE_SIZE) |
505 | SetPageReserved(MAP_NR(mem + off)); | 380 | SetPageReserved(MAP_NR(mem + off)); |
506 | } else { | 381 | } else { |
507 | /* jpg_bufsize is allreay page aligned */ | 382 | /* jpg_bufsize is already page aligned */ |
508 | for (j = 0; | 383 | for (j = 0; |
509 | j < fh->jpg_buffers.buffer_size / PAGE_SIZE; | 384 | j < fh->jpg_buffers.buffer_size / PAGE_SIZE; |
510 | j++) { | 385 | j++) { |
@@ -2173,6 +2048,7 @@ schan_unlock_and_return: | |||
2173 | return res; | 2048 | return res; |
2174 | } | 2049 | } |
2175 | 2050 | ||
2051 | |||
2176 | case VIDIOCGMBUF: | 2052 | case VIDIOCGMBUF: |
2177 | { | 2053 | { |
2178 | struct video_mbuf *vmbuf = arg; | 2054 | struct video_mbuf *vmbuf = arg; |
@@ -2369,16 +2245,13 @@ sparams_unlock_and_return: | |||
2369 | * tables to a Maximum of 2 MB */ | 2245 | * tables to a Maximum of 2 MB */ |
2370 | if (breq->size > jpg_bufsize) | 2246 | if (breq->size > jpg_bufsize) |
2371 | breq->size = jpg_bufsize; | 2247 | breq->size = jpg_bufsize; |
2372 | if (fh->jpg_buffers.need_contiguous && | ||
2373 | breq->size > MAX_KMALLOC_MEM) | ||
2374 | breq->size = MAX_KMALLOC_MEM; | ||
2375 | 2248 | ||
2376 | mutex_lock(&zr->resource_lock); | 2249 | mutex_lock(&zr->resource_lock); |
2377 | 2250 | ||
2378 | if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { | 2251 | if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { |
2379 | dprintk(1, | 2252 | dprintk(1, |
2380 | KERN_ERR | 2253 | KERN_ERR |
2381 | "%s: BUZIOC_REQBUFS - buffers allready allocated\n", | 2254 | "%s: BUZIOC_REQBUFS - buffers already allocated\n", |
2382 | ZR_DEVNAME(zr)); | 2255 | ZR_DEVNAME(zr)); |
2383 | res = -EBUSY; | 2256 | res = -EBUSY; |
2384 | goto jpgreqbuf_unlock_and_return; | 2257 | goto jpgreqbuf_unlock_and_return; |