Nikolaus Rath <[email protected]> writes:
> Hello,
>
> I am trying to make a DMA transfer from userspace. My code looks like
> this (data.vi_buf is a pointer to the userspace address):
>
>     down_read(&current->mm->mmap_sem);
>     rc = get_user_pages(current, current->mm, (unsigned long) data.vi_buf,
>               1, 1, 0, &acq_dev->vi_pg, NULL);
>     up_read(&current->mm->mmap_sem);
>     if (rc != 1) {
>       err("get_user_pages failed for VI.");
>       return -EINVAL;
>     }
>     acq_dev->vi_d = dma_map_page(dev, acq_dev->vi_pg, 0, PAGE_SIZE,
>                                    DMA_TO_DEVICE);
>     if (acq_dev->vi_d == 0) {
>       err("dma_map_page failed for VI.");
>       goto cleanup_vi_2;
>     }
>     info("VI bus address: 0x%0lx", (unsigned long) acq_dev->vi_d);
>
> But when my PCI device then reads data from the bus address
> acq_dev->vi_d, it just gets \0 bytes rather then the contents of the
> acq_dev->userspace buffer.
>
> I tried to debug this with an additional
>
>     info("VI Start: 0x%0x", ((uint32_t*) page_address(acq_dev->vi_pg))[0]);
>
> to print out the first byte of the mapped page, but this actually
> results in a kernel crash:
>
>     BUG: unable to handle kernel NULL pointer dereference at (null)

I figured this one out myself, get_user_pages and dma_map_page do not
create a mapping in kernel space for the buffer. With

    info("VI Start: 0x%0x", ((uint32_t*) kmap(acq_dev->vi_pg))[0]);
    kunmap(acq_dev->vi_pg);

it works just fine. And for some reason, now my original problem has
magically disappeared as well. Maybe it got scared by the suddenly
immediate threat of being debugged :-).


Best,

   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C

_______________________________________________
Kernelnewbies mailing list
[email protected]
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

Reply via email to