whats wrong with my mmap code?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'm writing a kernel module for a pci card. This card has some memory which 
should be accessed directly from user space. So I have two ways to access 
this memory:

1st: via ioctl which sends the data to the kernel modul, which is written to 
the card then:

iowrite32(args.bValue3, qcard->memaccess + args.bValue1);

this works fine. args is just the data block passed by the ioctl call

2nd: doing a userspace mmap and accessing this pointer directy

module code in device init:


        qcard->memstart = pci_resource_start(dev, 0);
        qcard->memlen = pci_resource_len(dev, 0);
    
        dbg("request memory at 0x%lx, size=0x%lx", qcard->memstart, 
                qcard->memlen);

        request_mem_region(qcard->memstart, qcard->memlen, 
                    quancom_pci_names[id->driver_data]) == NULL);

in fops_open:

    if (qcard->memstart)
        qcard->memaccess = ioremap(qcard->memstart, qcard->memlen);

and fops_mmap:

#ifndef phys_to_pfn
  #define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
#endif
static int quancom_fops_mmap(struct file *file, struct vm_area_struct *vma)
{
    struct quancom_card *qcard = file->private_data;
    unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
    unsigned long physical = (unsigned long) qcard->memaccess + off;
    unsigned long vsize = vma->vm_end - vma->vm_start;
    unsigned long psize = qcard->memlen - off;

    dbg("trying to mmap 0x%lx bytes at 0x%lx to 0x%lx, PAGE_SIZE: 0x%lx", 
            vsize, physical, vma->vm_start, PAGE_SIZE);

    /* TODO safe remap of memory when PAGE_SIZE > vsize */

    if (!qcard->memstart) /* not in memory access mode */
        return -EINVAL;
    if (vsize > MAX(psize,PAGE_SIZE)) /* spans too high */
        return -EINVAL; 
    
    if (remap_pfn_range(vma, vma->vm_start, phys_to_pfn(physical), vsize, 
                vma->vm_page_prot))
        return -EAGAIN;

    return 0;
}


in user space:

map = mmap(0, (size_t) 0x100, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

*map = data;

Suddenly this does not work. The addresses in kernel output and user space 
match, but no data written to *map appears in the card memory.

Any hints?

Full (not working) code can be found there:  
http://quancom.de/qprod01/deu/files/download.pcittl_1.3.1.tar.gz/$file/pcittl-1.3.1.tar.gz

I slightly changed the fops_mmap function since then...

Bye...Frank

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux