mmap not working in device driver

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

 



  Hello list,

I created a simple misc-device platform device driver, including a test program, see
    https://github.com/SietseAchterop/Batradio/blob/master/batradio_module/testfiqtimer.c
    https://github.com/SietseAchterop/Batradio/blob/master/batradio_module/batradio_client.c

This on an raspberry zero with the latest kernel from  https://github.com/raspberrypi/linux,
compiled from source using arm-linux-gnueabihf-gcc (GCC) 8.3.0.

The driver only implements the mmap and ioctl functions.
An area in the driver (fiq_buf) is made available to the user program via mmap.
The problem is that changing data (status value) in the driver via ioctl, is NOT reflected in the user program.

Here a few snippets from the driver:

From the init function:

  batradio_data = devm_kzalloc(&pdev->dev,
			       sizeof(*batradio_data),
			       GFP_KERNEL);
  if (!batradio_data)
    return -ENOMEM;

  batradio_data->fiq_base = devm_kzalloc(&pdev->dev,
					 FIQ_BUFFER_SIZE,   // 256*1024
					 GFP_KERNEL);
  if (!batradio_data->fiq_base) {
    dev_err(&pdev->dev, "Couldn't allocate memory!\n");
    return -ENOMEM;
  }

  fiq_buf = (struct fiq_buffer *)batradio_data->fiq_base;
  fiq_buf->status = 55;

And from the mmap function:

  size_t size = vma->vm_end - vma->vm_start;
  unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

  if (offset + size > FIQ_BUFFER_SIZE)
    return -EINVAL;

  offset += virt_to_phys(batradio_data->fiq_base);

  vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

  if (remap_pfn_range(vma,
		      vma->vm_start,
		      offset >> PAGE_SHIFT,
		      size,
		      vma->vm_page_prot)) {
    return -EAGAIN;
  }

And finally from the client program:

  fiq_fd = open(FIQ_PATH, O_RDWR);
  if (!fiq_fd) {
    ret = errno;
    perror("Couldn't open batradio device, error %d", errno);
    exit(-1);
  }

  fiq_addr = mmap(NULL, FIQ_BUFFER_SIZE, PROT_READ | PROT_WRITE,
		  MAP_SHARED, fiq_fd, 0);
  if (fiq_addr == MAP_FAILED) {
    ret = errno;
    perror("Couldn't map the fiq buffer");
    exit(-2);
  }
  fiq_buf = (struct fiq_buffer*)fiq_addr;

  printf("status %d\n", fiq_buf->status);


All very standard I think.
Why are changes in fiq_buf->status in the driver not shown in the client program?

  Thanks in advance,
      Sietse

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies



[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