All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* mmap not working in device driver
@ 2020-04-06 18:30 s.achterop
  0 siblings, 0 replies; only message in thread
From: s.achterop @ 2020-04-06 18:30 UTC (permalink / raw
  To: kernelnewbies

   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@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-04-06 18:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-06 18:30 mmap not working in device driver s.achterop

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.