diff options
Diffstat (limited to 'drivers/media/video/videobuf-dma-sg.c')
-rw-r--r-- | drivers/media/video/videobuf-dma-sg.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 06f9a9c2a39..2ad0bc252b0 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -94,7 +94,7 @@ err: | |||
94 | * must free the memory. | 94 | * must free the memory. |
95 | */ | 95 | */ |
96 | static struct scatterlist *videobuf_pages_to_sg(struct page **pages, | 96 | static struct scatterlist *videobuf_pages_to_sg(struct page **pages, |
97 | int nr_pages, int offset) | 97 | int nr_pages, int offset, size_t size) |
98 | { | 98 | { |
99 | struct scatterlist *sglist; | 99 | struct scatterlist *sglist; |
100 | int i; | 100 | int i; |
@@ -110,12 +110,14 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, | |||
110 | /* DMA to highmem pages might not work */ | 110 | /* DMA to highmem pages might not work */ |
111 | goto highmem; | 111 | goto highmem; |
112 | sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); | 112 | sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); |
113 | size -= PAGE_SIZE - offset; | ||
113 | for (i = 1; i < nr_pages; i++) { | 114 | for (i = 1; i < nr_pages; i++) { |
114 | if (NULL == pages[i]) | 115 | if (NULL == pages[i]) |
115 | goto nopage; | 116 | goto nopage; |
116 | if (PageHighMem(pages[i])) | 117 | if (PageHighMem(pages[i])) |
117 | goto highmem; | 118 | goto highmem; |
118 | sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0); | 119 | sg_set_page(&sglist[i], pages[i], min(PAGE_SIZE, size), 0); |
120 | size -= min(PAGE_SIZE, size); | ||
119 | } | 121 | } |
120 | return sglist; | 122 | return sglist; |
121 | 123 | ||
@@ -170,7 +172,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, | |||
170 | 172 | ||
171 | first = (data & PAGE_MASK) >> PAGE_SHIFT; | 173 | first = (data & PAGE_MASK) >> PAGE_SHIFT; |
172 | last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; | 174 | last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; |
173 | dma->offset = data & ~PAGE_MASK; | 175 | dma->offset = data & ~PAGE_MASK; |
176 | dma->size = size; | ||
174 | dma->nr_pages = last-first+1; | 177 | dma->nr_pages = last-first+1; |
175 | dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); | 178 | dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); |
176 | if (NULL == dma->pages) | 179 | if (NULL == dma->pages) |
@@ -252,7 +255,7 @@ int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma) | |||
252 | 255 | ||
253 | if (dma->pages) { | 256 | if (dma->pages) { |
254 | dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, | 257 | dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, |
255 | dma->offset); | 258 | dma->offset, dma->size); |
256 | } | 259 | } |
257 | if (dma->vaddr) { | 260 | if (dma->vaddr) { |
258 | dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr, | 261 | dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr, |