1 /* 2 * helper functions for vmalloc video4linux capture buffers 3 * 4 * The functions expect the hardware being able to scatter gather 5 * (i.e. the buffers are not linear in physical memory, but fragmented 6 * into PAGE_SIZE chunks). They also assume the driver does not need 7 * to touch the video data. 8 * 9 * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 14 */ 15 16 #include <linux/init.h> 17 #include <linux/module.h> 18 #include <linux/moduleparam.h> 19 #include <linux/slab.h> 20 #include <linux/interrupt.h> 21 22 #include <linux/pci.h> 23 #include <linux/vmalloc.h> 24 #include <linux/pagemap.h> 25 #include <asm/page.h> 26 #include <asm/pgtable.h> 27 28 #include <media/videobuf-vmalloc.h> 29 30 #define MAGIC_DMABUF 0x17760309 31 #define MAGIC_VMAL_MEM 0x18221223 32 33 #define MAGIC_CHECK(is, should) \ 34 if (unlikely((is) != (should))) { \ 35 printk(KERN_ERR "magic mismatch: %x (expected %x)\n", \ 36 is, should); \ 37 BUG(); \ 38 } 39 40 static int debug; 41 module_param(debug, int, 0644); 42 43 MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers"); 44 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 45 MODULE_LICENSE("GPL"); 46 47 #define dprintk(level, fmt, arg...) \ 48 if (debug >= level) \ 49 printk(KERN_DEBUG "vbuf-vmalloc: " fmt , ## arg) 50 51 52 /***************************************************************************/ 53 54 static void videobuf_vm_open(struct vm_area_struct *vma) 55 { 56 struct videobuf_mapping *map = vma->vm_private_data; 57 struct videobuf_queue *q = map->q; 58 59 dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map, 60 map->count, vma->vm_start, vma->vm_end); 61 62 videobuf_queue_lock(q); 63 map->count++; 64 videobuf_queue_unlock(q); 65 } 66 67 static void videobuf_vm_close(struct vm_area_struct *vma) 68 { 69 struct videobuf_mapping *map = vma->vm_private_data; 70 struct videobuf_queue *q = map->q; 71 int i; 72 73 dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, 74 map->count, vma->vm_start, vma->vm_end); 75 76 videobuf_queue_lock(q); 77 if (!--map->count) { 78 struct videobuf_vmalloc_memory *mem; 79 80 dprintk(1, "munmap %p q=%p\n", map, q); 81 82 /* We need first to cancel streams, before unmapping */ 83 if (q->streaming) 84 videobuf_queue_cancel(q); 85 86 for (i = 0; i < VIDEO_MAX_FRAME; i++) { 87 if (NULL == q->bufs[i]) 88 continue; 89 90 if (q->bufs[i]->map != map) 91 continue; 92 93 mem = q->bufs[i]->priv; 94 if (mem) { 95 /* This callback is called only if kernel has 96 allocated memory and this memory is mmapped. 97 In this case, memory should be freed, 98 in order to do memory unmap. 99 */ 100 101 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 102 103 /* vfree is not atomic - can't be 104 called with IRQ's disabled 105 */ 106 dprintk(1, "%s: buf[%d] freeing (%p)\n", 107 __func__, i, mem->vaddr); 108 109 vfree(mem->vaddr); 110 mem->vaddr = NULL; 111 } 112 113 q->bufs[i]->map = NULL; 114 q->bufs[i]->baddr = 0; 115 } 116 117 kfree(map); 118 119 } 120 videobuf_queue_unlock(q); 121 122 return; 123 } 124 125 static const struct vm_operations_struct videobuf_vm_ops = { 126 .open = videobuf_vm_open, 127 .close = videobuf_vm_close, 128 }; 129 130 /* --------------------------------------------------------------------- 131 * vmalloc handlers for the generic methods 132 */ 133 134 /* Allocated area consists on 3 parts: 135 struct video_buffer 136 struct <driver>_buffer (cx88_buffer, saa7134_buf, ...) 137 struct videobuf_dma_sg_memory 138 */ 139 140 static struct videobuf_buffer *__videobuf_alloc_vb(size_t size) 141 { 142 struct videobuf_vmalloc_memory *mem; 143 struct videobuf_buffer *vb; 144 145 vb = kzalloc(size + sizeof(*mem), GFP_KERNEL); 146 if (!vb) 147 return vb; 148 149 mem = vb->priv = ((char *)vb) + size; 150 mem->magic = MAGIC_VMAL_MEM; 151 152 dprintk(1, "%s: allocated at %p(%ld+%ld) & %p(%ld)\n", 153 __func__, vb, (long)sizeof(*vb), (long)size - sizeof(*vb), 154 mem, (long)sizeof(*mem)); 155 156 return vb; 157 } 158 159 static int __videobuf_iolock(struct videobuf_queue *q, 160 struct videobuf_buffer *vb, 161 struct v4l2_framebuffer *fbuf) 162 { 163 struct videobuf_vmalloc_memory *mem = vb->priv; 164 int pages; 165 166 BUG_ON(!mem); 167 168 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 169 170 switch (vb->memory) { 171 case V4L2_MEMORY_MMAP: 172 dprintk(1, "%s memory method MMAP\n", __func__); 173 174 /* All handling should be done by __videobuf_mmap_mapper() */ 175 if (!mem->vaddr) { 176 printk(KERN_ERR "memory is not alloced/mmapped.\n"); 177 return -EINVAL; 178 } 179 break; 180 case V4L2_MEMORY_USERPTR: 181 pages = PAGE_ALIGN(vb->size); 182 183 dprintk(1, "%s memory method USERPTR\n", __func__); 184 185 if (vb->baddr) { 186 printk(KERN_ERR "USERPTR is currently not supported\n"); 187 return -EINVAL; 188 } 189 190 /* The only USERPTR currently supported is the one needed for 191 * read() method. 192 */ 193 194 mem->vaddr = vmalloc_user(pages); 195 if (!mem->vaddr) { 196 printk(KERN_ERR "vmalloc (%d pages) failed\n", pages); 197 return -ENOMEM; 198 } 199 dprintk(1, "vmalloc is at addr %p (%d pages)\n", 200 mem->vaddr, pages); 201 202 #if 0 203 int rc; 204 /* Kernel userptr is used also by read() method. In this case, 205 there's no need to remap, since data will be copied to user 206 */ 207 if (!vb->baddr) 208 return 0; 209 210 /* FIXME: to properly support USERPTR, remap should occur. 211 The code below won't work, since mem->vma = NULL 212 */ 213 /* Try to remap memory */ 214 rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0); 215 if (rc < 0) { 216 printk(KERN_ERR "mmap: remap failed with error %d", rc); 217 return -ENOMEM; 218 } 219 #endif 220 221 break; 222 case V4L2_MEMORY_OVERLAY: 223 default: 224 dprintk(1, "%s memory method OVERLAY/unknown\n", __func__); 225 226 /* Currently, doesn't support V4L2_MEMORY_OVERLAY */ 227 printk(KERN_ERR "Memory method currently unsupported.\n"); 228 return -EINVAL; 229 } 230 231 return 0; 232 } 233 234 static int __videobuf_mmap_mapper(struct videobuf_queue *q, 235 struct videobuf_buffer *buf, 236 struct vm_area_struct *vma) 237 { 238 struct videobuf_vmalloc_memory *mem; 239 struct videobuf_mapping *map; 240 int retval, pages; 241 242 dprintk(1, "%s\n", __func__); 243 244 /* create mapping + update buffer list */ 245 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); 246 if (NULL == map) 247 return -ENOMEM; 248 249 buf->map = map; 250 map->q = q; 251 252 buf->baddr = vma->vm_start; 253 254 mem = buf->priv; 255 BUG_ON(!mem); 256 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 257 258 pages = PAGE_ALIGN(vma->vm_end - vma->vm_start); 259 mem->vaddr = vmalloc_user(pages); 260 if (!mem->vaddr) { 261 printk(KERN_ERR "vmalloc (%d pages) failed\n", pages); 262 goto error; 263 } 264 dprintk(1, "vmalloc is at addr %p (%d pages)\n", mem->vaddr, pages); 265 266 /* Try to remap memory */ 267 retval = remap_vmalloc_range(vma, mem->vaddr, 0); 268 if (retval < 0) { 269 printk(KERN_ERR "mmap: remap failed with error %d. ", retval); 270 vfree(mem->vaddr); 271 goto error; 272 } 273 274 vma->vm_ops = &videobuf_vm_ops; 275 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; 276 vma->vm_private_data = map; 277 278 dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", 279 map, q, vma->vm_start, vma->vm_end, 280 (long int)buf->bsize, 281 vma->vm_pgoff, buf->i); 282 283 videobuf_vm_open(vma); 284 285 return 0; 286 287 error: 288 mem = NULL; 289 kfree(map); 290 return -ENOMEM; 291 } 292 293 static struct videobuf_qtype_ops qops = { 294 .magic = MAGIC_QTYPE_OPS, 295 296 .alloc_vb = __videobuf_alloc_vb, 297 .iolock = __videobuf_iolock, 298 .mmap_mapper = __videobuf_mmap_mapper, 299 .vaddr = videobuf_to_vmalloc, 300 }; 301 302 void videobuf_queue_vmalloc_init(struct videobuf_queue *q, 303 const struct videobuf_queue_ops *ops, 304 struct device *dev, 305 spinlock_t *irqlock, 306 enum v4l2_buf_type type, 307 enum v4l2_field field, 308 unsigned int msize, 309 void *priv, 310 struct mutex *ext_lock) 311 { 312 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, 313 priv, &qops, ext_lock); 314 } 315 EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init); 316 317 void *videobuf_to_vmalloc(struct videobuf_buffer *buf) 318 { 319 struct videobuf_vmalloc_memory *mem = buf->priv; 320 BUG_ON(!mem); 321 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 322 323 return mem->vaddr; 324 } 325 EXPORT_SYMBOL_GPL(videobuf_to_vmalloc); 326 327 void videobuf_vmalloc_free(struct videobuf_buffer *buf) 328 { 329 struct videobuf_vmalloc_memory *mem = buf->priv; 330 331 /* mmapped memory can't be freed here, otherwise mmapped region 332 would be released, while still needed. In this case, the memory 333 release should happen inside videobuf_vm_close(). 334 So, it should free memory only if the memory were allocated for 335 read() operation. 336 */ 337 if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr) 338 return; 339 340 if (!mem) 341 return; 342 343 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 344 345 vfree(mem->vaddr); 346 mem->vaddr = NULL; 347 348 return; 349 } 350 EXPORT_SYMBOL_GPL(videobuf_vmalloc_free); 351 352