On 25 Sep 2001, Gerd Knorr wrote: > Other way around: bttv _requires_ shared mappings. As usual, Steve debugs by the jumping to conclusions technique. My excuse is that the "!" was very little. By the way - how does MAP_SHARED relate to VM_SHARED? (Excuse my ignorance) Nevertheless, mp1e's call to mmap() is still being rewarded with EINVAL. The code appears to follow the v4l2 speci to my untutored eye, and does work against Justin's bttv2 driver. Relevant code looks like so: vrbuf.type = V4L2_BUF_TYPE_CAPTURE; vrbuf.count = MAX(cap_buffers, min_cap_buffers); ASSERT("request capture buffers", ioctl(fd, VIDIOC_REQBUFS, &vrbuf) == 0); if (vrbuf.count == 0) FAIL("No capture buffers granted"); printv(2, "%d capture buffers granted\n", vrbuf.count); ASSERT("init capture fifo", init_callback_fifo( &cap_fifo, "video-v4l2", wait_full, send_empty, vrbuf.count, 0)); cap_fifo.start = capture_on; // Map capture buffers cap_fifo.num_buffers = 0; while (cap_fifo.num_buffers < vrbuf.count) { unsigned char *p; vbuf.type = V4L2_BUF_TYPE_CAPTURE; vbuf.index = cap_fifo.num_buffers; printv(3, "Mapping capture buffer #%d\n", cap_fifo.num_buffers); ASSERT("query capture buffer #%d", ioctl(fd, VIDIOC_QUERYBUF, &vbuf) == 0, cap_fifo.num_buffers); p = mmap(NULL, vbuf.length, PROT_READ, MAP_SHARED, fd, vbuf.offset); if ((int) p == -1) { if (errno == ENOMEM && cap_fifo.num_buffers > 0) break; else ASSERT("map capture buffer #%d", 0, cap_fifo.num_buffers); } else cap_fifo.buffers[cap_fifo.num_buffers].data = p; ASSERT("enqueue capture buffer #%d", ioctl(fd, VIDIOC_QBUF, &vbuf) == 0, vbuf.index); cap_fifo.num_buffers++; } if (cap_fifo.num_buffers < min_cap_buffers) FAIL("Cannot allocate enough (%d) capture buffers", min_cap_buffers); It appears that the length and offset passed to mmap don't match this test in bttv-driver.c: if (fh->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT) && fh->bufs[i]->bsize == (vma->vm_end - vma->vm_start)) { Seeing that these parameters came directly back from VIDIOC_QUERYBUF: fill_buffer(struct v4l2_buffer *b, struct bttv_buffer *buf) { b->index = buf->i; b->type = V4L2_BUF_TYPE_CAPTURE; b->offset = buf->boff; b->length = buf->bsize; ... } I'm not sure why the mismatch, unless its that a returned offset may not be a multiple of 2^PAGE_SHIFT? Steve