From: "Figo.zhang" <figo1802@gmail.com>
To: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: linux-media <linux-media@vger.kernel.org>,
Mauro Carvalho Chehab <mchehab@redhat.com>
Subject: Re: how to mmap in videobuf-dma-sg.c
Date: Wed, 10 Jun 2009 23:06:20 +0800 [thread overview]
Message-ID: <1244646380.15773.15.camel@myhost> (raw)
In-Reply-To: <1242902911.12072.3.camel@myhost>
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@gmail.com> 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;
}
next prev parent reply other threads:[~2009-06-10 15:06 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-21 4:46 how to mmap in videobuf-dma-sg.c Figo.zhang
2009-05-21 10:35 ` Mauro Carvalho Chehab
2009-05-21 10:48 ` Figo.zhang
2009-06-10 15:06 ` Figo.zhang [this message]
2010-07-24 13:43 ` Figo.zhang
[not found] ` <AANLkTimExb4hh8K5lRCRiM0IMIgsOpCw69bFvqLlQCDc@mail.gmail.com>
2010-07-25 17:46 ` Mauro Carvalho Chehab
2010-07-26 8:16 ` Laurent Pinchart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1244646380.15773.15.camel@myhost \
--to=figo1802@gmail.com \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@infradead.org \
--cc=mchehab@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox