2008-03-12 05:21:55 mmap failure in 2008R1_RC2
C.C Lu (TAIWAN)
Message: 52380 I am porting linux-uvc driver to 2008R1_RC2 for bf527.
When I call mmap function, kernel shows follow message.
BUG: failure at mm/nommu.c:838/do_mmap_private()!
Kernel panic - not syncing: BUG!
-------------------------------------------------------
The driver implements mmap function as follow:
static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
{
struct video_device *vdev = video_devdata(file);
struct uvc_video_device *video = video_get_drvdata(vdev);
struct uvc_buffer *buffer = NULL;
struct page *page;
unsigned long addr, start, size;
unsigned int i;
int ret = 0;
pr_debug("%s:\n",__func__);
uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
start = vma->vm_start;
size = vma->vm_end - vma->vm_start;
mutex_lock(&video->queue.mutex);
for (i = 0; i < video->queue.count; ++i) {
if ((video->queue.buffer[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) {
buffer = &video->queue.buffer[i];
break;
}
}
if (buffer == NULL || size != video->queue.buf_size) {
pr_debug("%s:%s\n",__func__,"buffer == NULL");
ret = -EINVAL;
goto done;
}
/*
* VM_IO marks the area as being an mmaped region for I/O to a
* device. It also prevents the region from being core dumped.
*/
vma->vm_flags |= VM_IO;
addr = (unsigned long)video->queue.mem + buffer->buf.m.offset;
while (size > 0) {
page = vmalloc_to_page((void*)addr);
if(remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)){
goto done;
}
start += PAGE_SIZE;
addr += PAGE_SIZE;
size -= PAGE_SIZE;
}
vma->vm_ops = &uvc_vm_ops;
vma->vm_private_data = buffer;
uvc_vm_open(vma);
done:
mutex_unlock(&video->queue.mutex);
return ret;
}
----------------------------------------------------------
The program as follow
static void init_mmap(void)
{
struct v4l2_requestbuffers req;
CLEAR (req);
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf (stderr, "%s does not support "
"memory mapping\n", dev_name);
exit (EXIT_FAILURE);
} else {
errno_exit ("VIDIOC_REQBUFS");
}
}
if (req.count < 2) {
fprintf (stderr, "Insufficient buffer memory on %s\n",
dev_name);
exit (EXIT_FAILURE);
}
buffers = calloc (req.count, sizeof (*buffers));
if (!buffers) {
fprintf (stderr, "Out of memory\n");
exit (EXIT_FAILURE);
}
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
struct v4l2_buffer buf;
CLEAR (buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))
errno_exit ("VIDIOC_QUERYBUF");
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =
mmap (NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */, MAP_PRIVATE,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start){
errno_exit ("mmap");
}
}
}
QuoteReplyEditDelete
2008-03-12 05:47:02 Re: mmap failure in 2008R1_RC2
Mike Frysinger (UNITED STATES)
Message: 52382 BUG() is only called on invalid scenarios ... and it includes a source file / line number for you to go into the source and read what is going wrong
QuoteReplyEditDelete
2008-03-14 09:14:55 Re: mmap failure in 2008R1_RC2
C.C Lu (TAIWAN)
Message: 52543 I solved that problem.
But, I run the capture program, linux-uvc driver returns a error code "-91, message too long" in usb_submit_urb().