Re: [QUESTION] mmap() error for UIO Device (uio_pci_generic)

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

 



On Fri, Apr 20, 2018 at 03:51:42PM +0300, Alper Yazar wrote:
> Hi,
> 
> I am trying to communicate a custom PCIe device in Linux. I didn't
> have experience on programming with using system calls and writing
> Linux device drivers.
> 
> I loaded uio_pci_generic driver for the device and /dev/uio0 was
> generated as character device. Then I wrote the following C program to
> dump 128K data from the device to a file. The device has only BAR0
> with size 128K.

...


>     #include <sys/stat.h>
>     #include <fcntl.h>
>     #include <sys/mman.h>
>     #include <stdio.h>
> 
>     #define MMBLOCK_SIZE (1024*128)
>     #define PCI_FILE "/dev/uio0"
>     #define BIN_FILE "dump.bin"
> 
>     int main() {
> 
>         int f;
>         FILE * fdumpptr;
>         char *ptr;
> 
>         printf("PCI FILE: %s\n", PCI_FILE);
>         printf("BIN FILE: %s\n", BIN_FILE);
> 
>         f = open(PCI_FILE, O_RDWR);
> 
>         fdumpptr = fopen("dump.bin","w");
> 
>         if(NULL == fdumpptr)
>         {
>             perror("Can't open BIN FILE");
>             return 1;
>         }
> 
>         if(-1 == f)
>         {
>             perror("Can't open PCI FILE");
>             return 1;
>         }
>         else
>         {
>             printf("PCI FILE opened successfully\n");
>         }
> 
>         ptr = mmap(NULL, MMBLOCK_SIZE, PROT_READ, MAP_SHARED, f, 0);
> 
>         if (MAP_FAILED == ptr)
>         {
>             perror("Can't do memory map on PCI FILE");
>             return 1;
>         }
>         else
>         {
>             printf("memory map succesfull\n");
>         }
> 
>         if (MMBLOCK_SIZE == fwrite(ptr, 1, MMBLOCK_SIZE, fdumpptr))
>         {
>             printf("Content dumpped succesffully\n");
>         }
>         else
>         {
>             printf("Can't write dump file\n");
>             return 1;
>         }
> 
>         return 0;
>     }
> 
> However `mmap()` returned `MAP_FAILED`. If I access to device using
> sysFS by changing `#define PCI_FILE
> "/sys/bus/pci/devices/0000:08:00.0/resource0"` everything works.

I think that's expected.

> So as far as I understood, I could mmap() the /dev/uio0 device but it
> gives an error. errno is 22 after failed mmap() call which corresponds
> to "Invalid argument". Is it possible to mmap() character device? What
> would be the problem?

Right but which BAR would we map? A generic device can have up to 6 of these.
For this reason uio pci generic just doesn't support mmap - you are
supposed to mmap the correct BAR through sysfs.

> Nothing happens in dmesg when I modprobe uio_pci_generic, relate my
> major and minor number with the driver, run the working or non working
> code.
> 
> There is no `maps` directory under `/sys/class/uio/ui0/`. Is this a
> problem indicator?

It's not a problem I think - we could add these as the driver is generic
using a minimal interface was deemed best for security. So just follow
the device link to get at the BAR:

/sys/class/uio/ui0/device/resource0

and mmap that.



-- 
MST



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux