Lines Matching +full:udma +full:- +full:c

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
6 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
7 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
11 #include "ivtv-driver.h"
12 #include "ivtv-udma.h"
16 dma_page->uaddr = first & PAGE_MASK; in ivtv_udma_get_page_info()
17 dma_page->offset = first & ~PAGE_MASK; in ivtv_udma_get_page_info()
18 dma_page->tail = 1 + ((first+size-1) & ~PAGE_MASK); in ivtv_udma_get_page_info()
19 dma_page->first = (first & PAGE_MASK) >> PAGE_SHIFT; in ivtv_udma_get_page_info()
20 dma_page->last = ((first+size-1) & PAGE_MASK) >> PAGE_SHIFT; in ivtv_udma_get_page_info()
21 dma_page->page_count = dma_page->last - dma_page->first + 1; in ivtv_udma_get_page_info()
22 if (dma_page->page_count == 1) dma_page->tail -= dma_page->offset; in ivtv_udma_get_page_info()
33 offset = dma_page->offset; in ivtv_udma_fill_sg_list()
36 for (i = 0; i < dma_page->page_count; i++) { in ivtv_udma_fill_sg_list()
37 unsigned int len = (i == dma_page->page_count - 1) ? in ivtv_udma_fill_sg_list()
38 dma_page->tail : PAGE_SIZE - offset; in ivtv_udma_fill_sg_list()
40 if (PageHighMem(dma->map[map_offset])) { in ivtv_udma_fill_sg_list()
43 if (dma->bouncemap[map_offset] == NULL) in ivtv_udma_fill_sg_list()
44 dma->bouncemap[map_offset] = alloc_page(GFP_KERNEL); in ivtv_udma_fill_sg_list()
45 if (dma->bouncemap[map_offset] == NULL) in ivtv_udma_fill_sg_list()
46 return -1; in ivtv_udma_fill_sg_list()
48 src = kmap_atomic(dma->map[map_offset]) + offset; in ivtv_udma_fill_sg_list()
49 memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len); in ivtv_udma_fill_sg_list()
52 sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset); in ivtv_udma_fill_sg_list()
55 sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset); in ivtv_udma_fill_sg_list()
67 for_each_sg(dma->SGlist, sg, dma->SG_length, i) { in ivtv_udma_fill_sg_array()
68 dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg)); in ivtv_udma_fill_sg_array()
69 dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg)); in ivtv_udma_fill_sg_array()
70 dma->SGarray[i].dst = cpu_to_le32(buffer_offset); in ivtv_udma_fill_sg_array()
73 split -= sg_dma_len(sg); in ivtv_udma_fill_sg_array()
82 if (itv->udma.SG_handle == 0) { in ivtv_udma_alloc()
84 itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray, in ivtv_udma_alloc()
85 sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); in ivtv_udma_alloc()
94 struct ivtv_user_dma *dma = &itv->udma; in ivtv_udma_setup()
100 if (dma->SG_length || dma->page_count) { in ivtv_udma_setup()
102 dma->SG_length, dma->page_count); in ivtv_udma_setup()
103 return -EBUSY; in ivtv_udma_setup()
111 return -EINVAL; in ivtv_udma_setup()
116 dma->map, FOLL_FORCE); in ivtv_udma_setup()
122 unpin_user_pages(dma->map, err); in ivtv_udma_setup()
123 return -EINVAL; in ivtv_udma_setup()
128 dma->page_count = user_dma.page_count; in ivtv_udma_setup()
132 unpin_user_pages(dma->map, dma->page_count); in ivtv_udma_setup()
133 dma->page_count = 0; in ivtv_udma_setup()
134 return -ENOMEM; in ivtv_udma_setup()
138 dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); in ivtv_udma_setup()
141 ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1); in ivtv_udma_setup()
144 dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000); in ivtv_udma_setup()
147 return dma->page_count; in ivtv_udma_setup()
152 struct ivtv_user_dma *dma = &itv->udma; in ivtv_udma_unmap()
157 if (dma->page_count == 0) in ivtv_udma_unmap()
161 if (dma->SG_length) { in ivtv_udma_unmap()
162 pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); in ivtv_udma_unmap()
163 dma->SG_length = 0; in ivtv_udma_unmap()
168 unpin_user_pages(dma->map, dma->page_count); in ivtv_udma_unmap()
169 dma->page_count = 0; in ivtv_udma_unmap()
177 if (itv->udma.SG_handle) { in ivtv_udma_free()
178 pci_unmap_single(itv->pdev, itv->udma.SG_handle, in ivtv_udma_free()
179 sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); in ivtv_udma_free()
183 if (itv->udma.SG_length) { in ivtv_udma_free()
184 pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE); in ivtv_udma_free()
188 if (itv->udma.bouncemap[i]) in ivtv_udma_free()
189 __free_page(itv->udma.bouncemap[i]); in ivtv_udma_free()
195 IVTV_DEBUG_DMA("start UDMA\n"); in ivtv_udma_start()
196 write_reg(itv->udma.SG_handle, IVTV_REG_DECDMAADDR); in ivtv_udma_start()
198 set_bit(IVTV_F_I_DMA, &itv->i_flags); in ivtv_udma_start()
199 set_bit(IVTV_F_I_UDMA, &itv->i_flags); in ivtv_udma_start()
200 clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags); in ivtv_udma_start()
207 spin_lock_irqsave(&itv->dma_reg_lock, flags); in ivtv_udma_prepare()
208 if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) in ivtv_udma_prepare()
211 set_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags); in ivtv_udma_prepare()
212 spin_unlock_irqrestore(&itv->dma_reg_lock, flags); in ivtv_udma_prepare()