// SPDX-License-Identifier: GPL-2.0-or-later /* User DMA
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> Copyright (C) 2004 Chris Kennedy <c@groovy.org> Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset)
{ int i, offset; unsignedlong flags;
if (map_offset < 0) return map_offset;
offset = dma_page->offset;
/* Fill SG Array with new values */ for (i = 0; i < dma_page->page_count; i++) { unsignedint len = (i == dma_page->page_count - 1) ?
dma_page->tail : PAGE_SIZE - offset;
if (PageHighMem(dma->map[map_offset])) { void *src;
/* Still in USE */ if (dma->SG_length || dma->page_count) {
IVTV_DEBUG_WARN("ivtv_udma_setup: SG_length %d page_count %d still full?\n",
dma->SG_length, dma->page_count); return -EBUSY;
}
if (user_dma.page_count <= 0) {
IVTV_DEBUG_WARN("ivtv_udma_setup: Error %d page_count from %d bytes %d offset\n",
user_dma.page_count, size_in_bytes, user_dma.offset); return -EINVAL;
}
/* Pin user pages for DMA Xfer */
err = pin_user_pages_unlocked(user_dma.uaddr, user_dma.page_count,
dma->map, 0);
if (user_dma.page_count != err) {
IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
err, user_dma.page_count); if (err >= 0) {
unpin_user_pages(dma->map, err); return -EINVAL;
} return err;
}
dma->page_count = user_dma.page_count;
/* Fill SG List with new values */ if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
IVTV_DEBUG_WARN("%s: could not allocate bounce buffers for highmem userspace buffers\n",
__func__);
unpin_user_pages(dma->map, dma->page_count);
dma->page_count = 0; return -ENOMEM;
}
/* Map SG List */
dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
dma->page_count, DMA_TO_DEVICE); if (!dma->SG_length) {
IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
unpin_user_pages(dma->map, dma->page_count);
dma->page_count = 0; return -EINVAL;
}
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
/* Tag SG Array with Interrupt Bit */
dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.