aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index c0875378acc2..dcbab6ad4c26 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -77,23 +77,51 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
77 /* Get user pages for DMA Xfer */ 77 /* Get user pages for DMA Xfer */
78 down_read(&current->mm->mmap_sem); 78 down_read(&current->mm->mmap_sem);
79 y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL); 79 y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
80 uv_pages = get_user_pages(current, current->mm, uv_dma.uaddr, uv_dma.page_count, 0, 1, &dma->map[y_pages], NULL); 80 uv_pages = 0; /* silence gcc. value is set and consumed only if: */
81 if (y_pages == y_dma.page_count) {
82 uv_pages = get_user_pages(current, current->mm,
83 uv_dma.uaddr, uv_dma.page_count, 0, 1,
84 &dma->map[y_pages], NULL);
85 }
81 up_read(&current->mm->mmap_sem); 86 up_read(&current->mm->mmap_sem);
82 87
83 dma->page_count = y_dma.page_count + uv_dma.page_count; 88 if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
84 89 int rc = -EFAULT;
85 if (y_pages + uv_pages != dma->page_count) { 90
86 IVTV_DEBUG_WARN 91 if (y_pages == y_dma.page_count) {
87 ("failed to map user pages, returned %d instead of %d\n", 92 IVTV_DEBUG_WARN
88 y_pages + uv_pages, dma->page_count); 93 ("failed to map uv user pages, returned %d "
89 94 "expecting %d\n", uv_pages, uv_dma.page_count);
90 for (i = 0; i < dma->page_count; i++) { 95
91 put_page(dma->map[i]); 96 if (uv_pages >= 0) {
97 for (i = 0; i < uv_pages; i++)
98 put_page(dma->map[y_pages + i]);
99 rc = -EFAULT;
100 } else {
101 rc = uv_pages;
102 }
103 } else {
104 IVTV_DEBUG_WARN
105 ("failed to map y user pages, returned %d "
106 "expecting %d\n", y_pages, y_dma.page_count);
92 } 107 }
93 dma->page_count = 0; 108 if (y_pages >= 0) {
94 return -EINVAL; 109 for (i = 0; i < y_pages; i++)
110 put_page(dma->map[i]);
111 /*
112 * Inherit the -EFAULT from rc's
113 * initialization, but allow it to be
114 * overriden by uv_pages above if it was an
115 * actual errno.
116 */
117 } else {
118 rc = y_pages;
119 }
120 return rc;
95 } 121 }
96 122
123 dma->page_count = y_pages + uv_pages;
124
97 /* Fill & map SG List */ 125 /* Fill & map SG List */
98 if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) { 126 if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
99 IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n"); 127 IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");