videobuf-dma-contig.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*
  2. * helper functions for physically contiguous capture buffers
  3. *
  4. * The functions support hardware lacking scatter gather support
  5. * (i.e. the buffers must be linear in physical memory)
  6. *
  7. * Copyright (c) 2008 Magnus Damm
  8. *
  9. * Based on videobuf-vmalloc.c,
  10. * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2
  15. */
  16. #include <linux/init.h>
  17. #include <linux/module.h>
  18. #include <linux/mm.h>
  19. #include <linux/pagemap.h>
  20. #include <linux/dma-mapping.h>
  21. #include <linux/sched.h>
  22. #include <linux/slab.h>
  23. #include <media/videobuf-dma-contig.h>
  24. struct videobuf_dma_contig_memory {
  25. u32 magic;
  26. void *vaddr;
  27. dma_addr_t dma_handle;
  28. bool cached;
  29. unsigned long size;
  30. };
  31. #define MAGIC_DC_MEM 0x0733ac61
  32. #define MAGIC_CHECK(is, should) \
  33. if (unlikely((is) != (should))) { \
  34. pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
  35. BUG(); \
  36. }
  37. static int __videobuf_dc_alloc(struct device *dev,
  38. struct videobuf_dma_contig_memory *mem,
  39. unsigned long size, gfp_t flags)
  40. {
  41. mem->size = size;
  42. if (mem->cached) {
  43. mem->vaddr = alloc_pages_exact(mem->size, flags | GFP_DMA);
  44. if (mem->vaddr) {
  45. int err;
  46. mem->dma_handle = dma_map_single(dev, mem->vaddr,
  47. mem->size,
  48. DMA_FROM_DEVICE);
  49. err = dma_mapping_error(dev, mem->dma_handle);
  50. if (err) {
  51. dev_err(dev, "dma_map_single failed\n");
  52. free_pages_exact(mem->vaddr, mem->size);
  53. mem->vaddr = NULL;
  54. return err;
  55. }
  56. }
  57. } else
  58. mem->vaddr = dma_alloc_coherent(dev, mem->size,
  59. &mem->dma_handle, flags);
  60. if (!mem->vaddr) {
  61. dev_err(dev, "memory alloc size %ld failed\n", mem->size);
  62. return -ENOMEM;
  63. }
  64. dev_dbg(dev, "dma mapped data is at %p (%ld)\n", mem->vaddr, mem->size);
  65. return 0;
  66. }
  67. static void __videobuf_dc_free(struct device *dev,
  68. struct videobuf_dma_contig_memory *mem)
  69. {
  70. if (mem->cached) {
  71. if (!mem->vaddr)
  72. return;
  73. dma_unmap_single(dev, mem->dma_handle, mem->size,
  74. DMA_FROM_DEVICE);
  75. free_pages_exact(mem->vaddr, mem->size);
  76. } else
  77. dma_free_coherent(dev, mem->size, mem->vaddr, mem->dma_handle);
  78. mem->vaddr = NULL;
  79. }
  80. static void videobuf_vm_open(struct vm_area_struct *vma)
  81. {
  82. struct videobuf_mapping *map = vma->vm_private_data;
  83. dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
  84. map, map->count, vma->vm_start, vma->vm_end);
  85. map->count++;
  86. }
  87. static void videobuf_vm_close(struct vm_area_struct *vma)
  88. {
  89. struct videobuf_mapping *map = vma->vm_private_data;
  90. struct videobuf_queue *q = map->q;
  91. int i;
  92. dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
  93. map, map->count, vma->vm_start, vma->vm_end);
  94. map->count--;
  95. if (0 == map->count) {
  96. struct videobuf_dma_contig_memory *mem;
  97. dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
  98. videobuf_queue_lock(q);
  99. /* We need first to cancel streams, before unmapping */
  100. if (q->streaming)
  101. videobuf_queue_cancel(q);
  102. for (i = 0; i < VIDEO_MAX_FRAME; i++) {
  103. if (NULL == q->bufs[i])
  104. continue;
  105. if (q->bufs[i]->map != map)
  106. continue;
  107. mem = q->bufs[i]->priv;
  108. if (mem) {
  109. /* This callback is called only if kernel has
  110. allocated memory and this memory is mmapped.
  111. In this case, memory should be freed,
  112. in order to do memory unmap.
  113. */
  114. MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
  115. /* vfree is not atomic - can't be
  116. called with IRQ's disabled
  117. */
  118. dev_dbg(q->dev, "buf[%d] freeing %p\n",
  119. i, mem->vaddr);
  120. __videobuf_dc_free(q->dev, mem);
  121. mem->vaddr = NULL;
  122. }
  123. q->bufs[i]->map = NULL;
  124. q->bufs[i]->baddr = 0;
  125. }
  126. kfree(map);
  127. videobuf_queue_unlock(q);
  128. }
  129. }
  130. static const struct vm_operations_struct videobuf_vm_ops = {
  131. .open = videobuf_vm_open,
  132. .close = videobuf_vm_close,
  133. };
  134. /**
  135. * videobuf_dma_contig_user_put() - reset pointer to user space buffer
  136. * @mem: per-buffer private videobuf-dma-contig data
  137. *
  138. * This function resets the user space pointer
  139. */
  140. static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
  141. {
  142. mem->dma_handle = 0;
  143. mem->size = 0;
  144. }
  145. /**
  146. * videobuf_dma_contig_user_get() - setup user space memory pointer
  147. * @mem: per-buffer private videobuf-dma-contig data
  148. * @vb: video buffer to map
  149. *
  150. * This function validates and sets up a pointer to user space memory.
  151. * Only physically contiguous pfn-mapped memory is accepted.
  152. *
  153. * Returns 0 if successful.
  154. */
  155. static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
  156. struct videobuf_buffer *vb)
  157. {
  158. struct mm_struct *mm = current->mm;
  159. struct vm_area_struct *vma;
  160. unsigned long prev_pfn, this_pfn;
  161. unsigned long pages_done, user_address;
  162. unsigned int offset;
  163. int ret;
  164. offset = vb->baddr & ~PAGE_MASK;
  165. mem->size = PAGE_ALIGN(vb->size + offset);
  166. ret = -EINVAL;
  167. down_read(&mm->mmap_sem);
  168. vma = find_vma(mm, vb->baddr);
  169. if (!vma)
  170. goto out_up;
  171. if ((vb->baddr + mem->size) > vma->vm_end)
  172. goto out_up;
  173. pages_done = 0;
  174. prev_pfn = 0; /* kill warning */
  175. user_address = vb->baddr;
  176. while (pages_done < (mem->size >> PAGE_SHIFT)) {
  177. ret = follow_pfn(vma, user_address, &this_pfn);
  178. if (ret)
  179. break;
  180. if (pages_done == 0)
  181. mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
  182. else if (this_pfn != (prev_pfn + 1))
  183. ret = -EFAULT;
  184. if (ret)
  185. break;
  186. prev_pfn = this_pfn;
  187. user_address += PAGE_SIZE;
  188. pages_done++;
  189. }
  190. out_up:
  191. up_read(&current->mm->mmap_sem);
  192. return ret;
  193. }
  194. static struct videobuf_buffer *__videobuf_alloc_vb(size_t size, bool cached)
  195. {
  196. struct videobuf_dma_contig_memory *mem;
  197. struct videobuf_buffer *vb;
  198. vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
  199. if (vb) {
  200. vb->priv = ((char *)vb) + size;
  201. mem = vb->priv;
  202. mem->magic = MAGIC_DC_MEM;
  203. mem->cached = cached;
  204. }
  205. return vb;
  206. }
  207. static struct videobuf_buffer *__videobuf_alloc_uncached(size_t size)
  208. {
  209. return __videobuf_alloc_vb(size, false);
  210. }
  211. static struct videobuf_buffer *__videobuf_alloc_cached(size_t size)
  212. {
  213. return __videobuf_alloc_vb(size, true);
  214. }
  215. static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
  216. {
  217. struct videobuf_dma_contig_memory *mem = buf->priv;
  218. BUG_ON(!mem);
  219. MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
  220. return mem->vaddr;
  221. }
  222. static int __videobuf_iolock(struct videobuf_queue *q,
  223. struct videobuf_buffer *vb,
  224. struct v4l2_framebuffer *fbuf)
  225. {
  226. struct videobuf_dma_contig_memory *mem = vb->priv;
  227. BUG_ON(!mem);
  228. MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
  229. switch (vb->memory) {
  230. case V4L2_MEMORY_MMAP:
  231. dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
  232. /* All handling should be done by __videobuf_mmap_mapper() */
  233. if (!mem->vaddr) {
  234. dev_err(q->dev, "memory is not alloced/mmapped.\n");
  235. return -EINVAL;
  236. }
  237. break;
  238. case V4L2_MEMORY_USERPTR:
  239. dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
  240. /* handle pointer from user space */
  241. if (vb->baddr)
  242. return videobuf_dma_contig_user_get(mem, vb);
  243. /* allocate memory for the read() method */
  244. if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
  245. GFP_KERNEL))
  246. return -ENOMEM;
  247. break;
  248. case V4L2_MEMORY_OVERLAY:
  249. default:
  250. dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", __func__);
  251. return -EINVAL;
  252. }
  253. return 0;
  254. }
  255. static int __videobuf_sync(struct videobuf_queue *q,
  256. struct videobuf_buffer *buf)
  257. {
  258. struct videobuf_dma_contig_memory *mem = buf->priv;
  259. BUG_ON(!mem);
  260. MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
  261. dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size,
  262. DMA_FROM_DEVICE);
  263. return 0;
  264. }
  265. static int __videobuf_mmap_mapper(struct videobuf_queue *q,
  266. struct videobuf_buffer *buf,
  267. struct vm_area_struct *vma)
  268. {
  269. struct videobuf_dma_contig_memory *mem;
  270. struct videobuf_mapping *map;
  271. int retval;
  272. unsigned long size;
  273. unsigned long pos, start = vma->vm_start;
  274. struct page *page;
  275. dev_dbg(q->dev, "%s\n", __func__);
  276. /* create mapping + update buffer list */
  277. map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
  278. if (!map)
  279. return -ENOMEM;
  280. buf->map = map;
  281. map->q = q;
  282. buf->baddr = vma->vm_start;
  283. mem = buf->priv;
  284. BUG_ON(!mem);
  285. MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
  286. if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
  287. GFP_KERNEL | __GFP_COMP))
  288. goto error;
  289. /* Try to remap memory */
  290. size = vma->vm_end - vma->vm_start;
  291. size = (size < mem->size) ? size : mem->size;
  292. if (!mem->cached) {
  293. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  294. retval = remap_pfn_range(vma, vma->vm_start,
  295. mem->dma_handle >> PAGE_SHIFT,
  296. size, vma->vm_page_prot);
  297. if (retval) {
  298. dev_err(q->dev, "mmap: remap failed with error %d. ",
  299. retval);
  300. dma_free_coherent(q->dev, mem->size,
  301. mem->vaddr, mem->dma_handle);
  302. goto error;
  303. }
  304. } else {
  305. pos = (unsigned long)mem->vaddr;
  306. while (size > 0) {
  307. page = virt_to_page((void *)pos);
  308. if (NULL == page) {
  309. dev_err(q->dev, "mmap: virt_to_page failed\n");
  310. __videobuf_dc_free(q->dev, mem);
  311. goto error;
  312. }
  313. retval = vm_insert_page(vma, start, page);
  314. if (retval) {
  315. dev_err(q->dev, "mmap: insert failed with error %d\n",
  316. retval);
  317. __videobuf_dc_free(q->dev, mem);
  318. goto error;
  319. }
  320. start += PAGE_SIZE;
  321. pos += PAGE_SIZE;
  322. if (size > PAGE_SIZE)
  323. size -= PAGE_SIZE;
  324. else
  325. size = 0;
  326. }
  327. }
  328. vma->vm_ops = &videobuf_vm_ops;
  329. vma->vm_flags |= VM_DONTEXPAND;
  330. vma->vm_private_data = map;
  331. dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
  332. map, q, vma->vm_start, vma->vm_end,
  333. (long int)buf->bsize, vma->vm_pgoff, buf->i);
  334. videobuf_vm_open(vma);
  335. return 0;
  336. error:
  337. kfree(map);
  338. return -ENOMEM;
  339. }
  340. static struct videobuf_qtype_ops qops = {
  341. .magic = MAGIC_QTYPE_OPS,
  342. .alloc_vb = __videobuf_alloc_uncached,
  343. .iolock = __videobuf_iolock,
  344. .mmap_mapper = __videobuf_mmap_mapper,
  345. .vaddr = __videobuf_to_vaddr,
  346. };
  347. static struct videobuf_qtype_ops qops_cached = {
  348. .magic = MAGIC_QTYPE_OPS,
  349. .alloc_vb = __videobuf_alloc_cached,
  350. .iolock = __videobuf_iolock,
  351. .sync = __videobuf_sync,
  352. .mmap_mapper = __videobuf_mmap_mapper,
  353. .vaddr = __videobuf_to_vaddr,
  354. };
  355. void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
  356. const struct videobuf_queue_ops *ops,
  357. struct device *dev,
  358. spinlock_t *irqlock,
  359. enum v4l2_buf_type type,
  360. enum v4l2_field field,
  361. unsigned int msize,
  362. void *priv,
  363. struct mutex *ext_lock)
  364. {
  365. videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
  366. priv, &qops, ext_lock);
  367. }
  368. EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
  369. void videobuf_queue_dma_contig_init_cached(struct videobuf_queue *q,
  370. const struct videobuf_queue_ops *ops,
  371. struct device *dev,
  372. spinlock_t *irqlock,
  373. enum v4l2_buf_type type,
  374. enum v4l2_field field,
  375. unsigned int msize,
  376. void *priv, struct mutex *ext_lock)
  377. {
  378. videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
  379. priv, &qops_cached, ext_lock);
  380. }
  381. EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init_cached);
  382. dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
  383. {
  384. struct videobuf_dma_contig_memory *mem = buf->priv;
  385. BUG_ON(!mem);
  386. MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
  387. return mem->dma_handle;
  388. }
  389. EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
  390. void videobuf_dma_contig_free(struct videobuf_queue *q,
  391. struct videobuf_buffer *buf)
  392. {
  393. struct videobuf_dma_contig_memory *mem = buf->priv;
  394. /* mmapped memory can't be freed here, otherwise mmapped region
  395. would be released, while still needed. In this case, the memory
  396. release should happen inside videobuf_vm_close().
  397. So, it should free memory only if the memory were allocated for
  398. read() operation.
  399. */
  400. if (buf->memory != V4L2_MEMORY_USERPTR)
  401. return;
  402. if (!mem)
  403. return;
  404. MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
  405. /* handle user space pointer case */
  406. if (buf->baddr) {
  407. videobuf_dma_contig_user_put(mem);
  408. return;
  409. }
  410. /* read() method */
  411. if (mem->vaddr) {
  412. __videobuf_dc_free(q->dev, mem);
  413. mem->vaddr = NULL;
  414. }
  415. }
  416. EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
  417. MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
  418. MODULE_AUTHOR("Magnus Damm");
  419. MODULE_LICENSE("GPL");