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