aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-05-01 09:31:12 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-05-14 01:54:09 -0400
commit3f98387efa9333c5765d36e144c47c107d6ba64a (patch)
treeb5c8f515aecf306b0e0b6087458d221d9411f6cb /drivers
parent6a4a79355bfa9ae6977556595a68f2e3a0e143f7 (diff)
V4L/DVB (7854): cx18/ivtv: improve and fix out-of-memory handling
- don't show kernel backtrace when the allocation of the buffers fails: the normal ivtv/cx18 messages are clear enough and the backtrace scares users. - fix cleanup after the buffer allocation fails (caused kernel panic). Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/cx18/cx18-driver.c4
-rw-r--r--drivers/media/video/cx18/cx18-queue.c6
-rw-r--r--drivers/media/video/cx18/cx18-streams.c13
-rw-r--r--drivers/media/video/cx18/cx18-streams.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c12
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c13
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c2
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c6
10 files changed, 37 insertions, 27 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 7813380dce3f..9453223a3dea 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -805,7 +805,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
805 return 0; 805 return 0;
806 806
807free_streams: 807free_streams:
808 cx18_streams_cleanup(cx); 808 cx18_streams_cleanup(cx, 1);
809free_irq: 809free_irq:
810 free_irq(cx->dev->irq, (void *)cx); 810 free_irq(cx->dev->irq, (void *)cx);
811free_i2c: 811free_i2c:
@@ -908,7 +908,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
908 908
909 cx18_halt_firmware(cx); 909 cx18_halt_firmware(cx);
910 910
911 cx18_streams_cleanup(cx); 911 cx18_streams_cleanup(cx, 1);
912 912
913 exit_cx18_i2c(cx); 913 exit_cx18_i2c(cx);
914 914
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 65af1bb507ca..4ef6996b2048 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -239,12 +239,12 @@ int cx18_stream_alloc(struct cx18_stream *s)
239 239
240 /* allocate stream buffers. Initially all buffers are in q_free. */ 240 /* allocate stream buffers. Initially all buffers are in q_free. */
241 for (i = 0; i < s->buffers; i++) { 241 for (i = 0; i < s->buffers; i++) {
242 struct cx18_buffer *buf = 242 struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
243 kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL); 243 GFP_KERNEL|__GFP_NOWARN);
244 244
245 if (buf == NULL) 245 if (buf == NULL)
246 break; 246 break;
247 buf->buf = kmalloc(s->buf_size, GFP_KERNEL); 247 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
248 if (buf->buf == NULL) { 248 if (buf->buf == NULL) {
249 kfree(buf); 249 kfree(buf);
250 break; 250 break;
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index afb141b2027a..4ca9d847f1b1 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -218,7 +218,7 @@ int cx18_streams_setup(struct cx18 *cx)
218 return 0; 218 return 0;
219 219
220 /* One or more streams could not be initialized. Clean 'em all up. */ 220 /* One or more streams could not be initialized. Clean 'em all up. */
221 cx18_streams_cleanup(cx); 221 cx18_streams_cleanup(cx, 0);
222 return -ENOMEM; 222 return -ENOMEM;
223} 223}
224 224
@@ -296,12 +296,12 @@ int cx18_streams_register(struct cx18 *cx)
296 return 0; 296 return 0;
297 297
298 /* One or more streams could not be initialized. Clean 'em all up. */ 298 /* One or more streams could not be initialized. Clean 'em all up. */
299 cx18_streams_cleanup(cx); 299 cx18_streams_cleanup(cx, 1);
300 return -ENOMEM; 300 return -ENOMEM;
301} 301}
302 302
303/* Unregister v4l2 devices */ 303/* Unregister v4l2 devices */
304void cx18_streams_cleanup(struct cx18 *cx) 304void cx18_streams_cleanup(struct cx18 *cx, int unregister)
305{ 305{
306 struct video_device *vdev; 306 struct video_device *vdev;
307 int type; 307 int type;
@@ -319,8 +319,11 @@ void cx18_streams_cleanup(struct cx18 *cx)
319 319
320 cx18_stream_free(&cx->streams[type]); 320 cx18_stream_free(&cx->streams[type]);
321 321
322 /* Unregister device */ 322 /* Unregister or release device */
323 video_unregister_device(vdev); 323 if (unregister)
324 video_unregister_device(vdev);
325 else
326 video_device_release(vdev);
324 } 327 }
325} 328}
326 329
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 8c7ba7d2fa79..f327e947b24f 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -24,7 +24,7 @@
24u32 cx18_find_handle(struct cx18 *cx); 24u32 cx18_find_handle(struct cx18 *cx);
25int cx18_streams_setup(struct cx18 *cx); 25int cx18_streams_setup(struct cx18 *cx);
26int cx18_streams_register(struct cx18 *cx); 26int cx18_streams_register(struct cx18 *cx);
27void cx18_streams_cleanup(struct cx18 *cx); 27void cx18_streams_cleanup(struct cx18 *cx, int unregister);
28 28
29/* Capture related */ 29/* Capture related */
30int cx18_start_v4l2_encode_stream(struct cx18_stream *s); 30int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index a0756a9235d8..797e636771da 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1232,7 +1232,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1232 return 0; 1232 return 0;
1233 1233
1234free_streams: 1234free_streams:
1235 ivtv_streams_cleanup(itv); 1235 ivtv_streams_cleanup(itv, 1);
1236free_irq: 1236free_irq:
1237 free_irq(itv->dev->irq, (void *)itv); 1237 free_irq(itv->dev->irq, (void *)itv);
1238free_i2c: 1238free_i2c:
@@ -1377,7 +1377,7 @@ static void ivtv_remove(struct pci_dev *pci_dev)
1377 flush_workqueue(itv->irq_work_queues); 1377 flush_workqueue(itv->irq_work_queues);
1378 destroy_workqueue(itv->irq_work_queues); 1378 destroy_workqueue(itv->irq_work_queues);
1379 1379
1380 ivtv_streams_cleanup(itv); 1380 ivtv_streams_cleanup(itv, 1);
1381 ivtv_udma_free(itv); 1381 ivtv_udma_free(itv);
1382 1382
1383 exit_ivtv_i2c(itv); 1383 exit_ivtv_i2c(itv);
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index 3e1deec67a5e..fc8b1eaa333b 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -203,14 +203,14 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
203 s->dma != PCI_DMA_NONE ? "DMA " : "", 203 s->dma != PCI_DMA_NONE ? "DMA " : "",
204 s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); 204 s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
205 205
206 s->sg_pending = kzalloc(SGsize, GFP_KERNEL); 206 s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
207 if (s->sg_pending == NULL) { 207 if (s->sg_pending == NULL) {
208 IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name); 208 IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
209 return -ENOMEM; 209 return -ENOMEM;
210 } 210 }
211 s->sg_pending_size = 0; 211 s->sg_pending_size = 0;
212 212
213 s->sg_processing = kzalloc(SGsize, GFP_KERNEL); 213 s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
214 if (s->sg_processing == NULL) { 214 if (s->sg_processing == NULL) {
215 IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name); 215 IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
216 kfree(s->sg_pending); 216 kfree(s->sg_pending);
@@ -219,7 +219,8 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
219 } 219 }
220 s->sg_processing_size = 0; 220 s->sg_processing_size = 0;
221 221
222 s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), GFP_KERNEL); 222 s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element),
223 GFP_KERNEL|__GFP_NOWARN);
223 if (s->sg_dma == NULL) { 224 if (s->sg_dma == NULL) {
224 IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name); 225 IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
225 kfree(s->sg_pending); 226 kfree(s->sg_pending);
@@ -235,11 +236,12 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
235 236
236 /* allocate stream buffers. Initially all buffers are in q_free. */ 237 /* allocate stream buffers. Initially all buffers are in q_free. */
237 for (i = 0; i < s->buffers; i++) { 238 for (i = 0; i < s->buffers; i++) {
238 struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), GFP_KERNEL); 239 struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer),
240 GFP_KERNEL|__GFP_NOWARN);
239 241
240 if (buf == NULL) 242 if (buf == NULL)
241 break; 243 break;
242 buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL); 244 buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN);
243 if (buf->buf == NULL) { 245 if (buf->buf == NULL) {
244 kfree(buf); 246 kfree(buf);
245 break; 247 break;
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 4ab8d36831ba..c47c2b945147 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -244,7 +244,7 @@ int ivtv_streams_setup(struct ivtv *itv)
244 return 0; 244 return 0;
245 245
246 /* One or more streams could not be initialized. Clean 'em all up. */ 246 /* One or more streams could not be initialized. Clean 'em all up. */
247 ivtv_streams_cleanup(itv); 247 ivtv_streams_cleanup(itv, 0);
248 return -ENOMEM; 248 return -ENOMEM;
249} 249}
250 250
@@ -304,12 +304,12 @@ int ivtv_streams_register(struct ivtv *itv)
304 return 0; 304 return 0;
305 305
306 /* One or more streams could not be initialized. Clean 'em all up. */ 306 /* One or more streams could not be initialized. Clean 'em all up. */
307 ivtv_streams_cleanup(itv); 307 ivtv_streams_cleanup(itv, 1);
308 return -ENOMEM; 308 return -ENOMEM;
309} 309}
310 310
311/* Unregister v4l2 devices */ 311/* Unregister v4l2 devices */
312void ivtv_streams_cleanup(struct ivtv *itv) 312void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
313{ 313{
314 int type; 314 int type;
315 315
@@ -322,8 +322,11 @@ void ivtv_streams_cleanup(struct ivtv *itv)
322 continue; 322 continue;
323 323
324 ivtv_stream_free(&itv->streams[type]); 324 ivtv_stream_free(&itv->streams[type]);
325 /* Unregister device */ 325 /* Unregister or release device */
326 video_unregister_device(vdev); 326 if (unregister)
327 video_unregister_device(vdev);
328 else
329 video_device_release(vdev);
327 } 330 }
328} 331}
329 332
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
index 3d76a415fbd8..a653a5136417 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -23,7 +23,7 @@
23 23
24int ivtv_streams_setup(struct ivtv *itv); 24int ivtv_streams_setup(struct ivtv *itv);
25int ivtv_streams_register(struct ivtv *itv); 25int ivtv_streams_register(struct ivtv *itv);
26void ivtv_streams_cleanup(struct ivtv *itv); 26void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
27 27
28/* Capture related */ 28/* Capture related */
29int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s); 29int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 62f70bd5e3cb..a9417f6e4087 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -908,7 +908,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
908 } 908 }
909 909
910 /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ 910 /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
911 yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL); 911 yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
912 if (yi->blanking_ptr) { 912 if (yi->blanking_ptr) {
913 yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); 913 yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
914 } else { 914 } else {
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index df789f683e63..73be154f7f05 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -948,7 +948,8 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
948 } 948 }
949 949
950 /* Allocate the pseudo palette */ 950 /* Allocate the pseudo palette */
951 oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); 951 oi->ivtvfb_info.pseudo_palette =
952 kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
952 953
953 if (!oi->ivtvfb_info.pseudo_palette) { 954 if (!oi->ivtvfb_info.pseudo_palette) {
954 IVTVFB_ERR("abort, unable to alloc pseudo pallete\n"); 955 IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
@@ -1056,7 +1057,8 @@ static int ivtvfb_init_card(struct ivtv *itv)
1056 return -EBUSY; 1057 return -EBUSY;
1057 } 1058 }
1058 1059
1059 itv->osd_info = kzalloc(sizeof(struct osd_info), GFP_ATOMIC); 1060 itv->osd_info = kzalloc(sizeof(struct osd_info),
1061 GFP_ATOMIC|__GFP_NOWARN);
1060 if (itv->osd_info == NULL) { 1062 if (itv->osd_info == NULL) {
1061 IVTVFB_ERR("Failed to allocate memory for osd_info\n"); 1063 IVTVFB_ERR("Failed to allocate memory for osd_info\n");
1062 return -ENOMEM; 1064 return -ENOMEM;