On Thu, 2009-05-21 at 18:48 +0800, Figo.zhang wrote: > On Thu, 2009-05-21 at 07:35 -0300, Mauro Carvalho Chehab wrote: > > Em Thu, 21 May 2009 12:46:04 +0800 > > "Figo.zhang" <figo1802@xxxxxxxxx> escreveu: > > > > > hi,all, > > > I am puzzle that how to mmap ( V4L2_MEMORY_MMAP) in videobuf-dma-sg.c? > > > > > > In this file, it alloc the momery using vmalloc_32() , and put this > > > momery into sglist table,and then use dma_map_sg() to create sg dma at > > > __videobuf_iolock() function. but in __videobuf_mmap_mapper(), i canot > > > understand how it do the mmap? > > > why it not use the remap_vmalloc_range() to do the mmap? > > > > The answer is simple: remap_vmalloc_range() is newer than videobuf code. This > > part of the code was written back to kernel 2.4, and nobody cared to update it > > to use those newer functions, and simplify its code. > > > > If you want, feel free to propose some cleanups on it > > > > > > > > Cheers, > > Mauro > > hi mauro, > Thank you! > But i canot found the similar function code of remap_vmalloc_range() in > the videobuf-dma-contig.c file. So i want to know the how is work in > __videobuf_mmap_mapper() function? > > hi mauro: Thank you. But i still have a puzzle question about mmap() in videobuf-dma-sg.c. I canot find how to remap the dma buffer (which alloc by vmalloc_32()) to the vma area in __videobuf_mmap_mapper()? there is my test driver code about dma-sg,it work well. i use remap_pfn_range() to remap the dma buffer to vma area in mmap method. so would you like to give me some detail about it? Best Regards, Figo.zhang static int mydev_alloc_dma_sg(struct mydev_device *dev, struct mydev_buf *buf) { int nr_pages; int i; struct page *pg; unsigned char * virt; nr_pages = mydev_buffer_pages(buf->size); buf->nr_pages = nr_pages; dprintk("%s:: buf->nr_pages =%d\n", __func__, buf->nr_pages); buf->sglist = kcalloc(buf->nr_pages, sizeof(struct scatterlist), GFP_KERNEL); if (NULL == buf->sglist) return NULL; sg_init_table(buf->sglist, buf->nr_pages); buf->vmalloc = vmalloc_32(buf->nr_pages << PAGE_SHIFT); memset(buf->vmalloc,0,buf->nr_pages << PAGE_SHIFT); virt = buf->vmalloc; for(i = 0; i< buf->nr_pages; i++,virt += PAGE_SIZE){ pg = vmalloc_to_page(virt); if (NULL == pg) goto nopage; BUG_ON(PageHighMem(pg)); sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0); } buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist, buf->nr_pages, DMA_FROM_DEVICE); return 0; nopage: dprintk("sgl: oops - no page\n"); kfree(buf->sglist); return 0; } in mmap(); static int do_mmap_sg(struct mydev_device *dev, struct vm_area_struct * vma) { struct videobuf_mapping *map; unsigned long pos,page; unsigned long start = vma->vm_start; unsigned long size = vma->vm_end - vma->vm_start; unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; unsigned int first, last, end; int retval = -EINVAL; int i; /* look for first buffer to map */ for (first = 0; first < VIDEO_MAX_FRAME; first++) { if (dev->ktbuf[first].boff == (vma->vm_pgoff << PAGE_SHIFT)) break; } if (VIDEO_MAX_FRAME == first) { dprintk("mmap app bug: offset invalid [offset=0x%lx]\n", (vma->vm_pgoff << PAGE_SHIFT)); goto done; } /* create mapping + update buffer list */ retval = -ENOMEM; map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL); if (NULL == map) goto done; pos = (unsigned long)dev->ktbuf[first].vmalloc; while (size > 0) { page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { return -EAGAIN; } start += PAGE_SIZE; pos += PAGE_SIZE; if (size > PAGE_SIZE) size -= PAGE_SIZE; else size = 0; } map->count = 1; map->start = vma->vm_start; map->end = vma->vm_end; vma->vm_ops = &mydev_vm_ops; vma->vm_flags |=/* VM_DONTEXPAND |*/ VM_RESERVED; vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */ vma->vm_private_data = map; mydev_vm_open(vma); retval = 0; done: return retval; } -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html