porting mmap file operation

I am trying to port linux device driver to QNX 6.3.

int xx_control_mmap(struct file *filp, struct vm_area_struct *vma) { .... off = (vma->vm_pgoff << PAGE_SHIFT); vsize = vma->vm_end - vma->vm_start; .... if(off >= MMAP_OFFSET_L2_DMA) {//MMAP_OFFSET_L2_DMA==0x70000000 off -= MMAP_OFFSET_L2_DMA; region = &card->l2; ..... ret = remap_page_range(vma, vma->vm_start, physical, vsize, vma->vm_page_prot); } .... }

xx_control_mmap is the original linux file_operations “method”. In QNX there is also mmap function used to handle an IO_MMAP messages. But the received message’s structure io_mmap_t does not contain any variables holding information about number of bytes to map into the caller’s address space. So, my question is how to implement this in QNX.
Thanks for the answer.

What is the “_control_mmap()” exactly do in Linux?

Looks like some one told the device to map to a different DMA memory?
You could wrap this with in a devctl() in QNX.

Don’t use _IO_MMAP() callouts, it’s for a different purpose.

I think it’s actually causing a remap of the client’s address space. This is not possible under QNX. What you will have to is to have the device driver create a shared object that overlays the physical address you want to map into the client, and then have the client map that in itself. You will need to add a few devctls (or your own messages might be easier)

In Linux there is used file_operations structure holding pointers to functions operating on device files. If you then in user space call fread(/dev/…), OS thereafter calls appropriate function from file_operations structure, to return some output from the device to the user.

What I know in QNX there is resmgr_io_funcs_t structure, which have to be filled with almost the same operations, i.e. to handle _IO_READ message I just need to point member read from resmgr_io_funcs_t structure to appropriate function (this is also described here http://www.qnx.com/developers/docs/6.3.0/neutrino/prog/resmgr.html#HANDLING_READ_MSG).

From linux device drivers chapter 13 http://www.xml.com/ldd/chapter/book/ch13.html
…in Linux the mmap method is part of the file_operations structure and is invoked when the mmap system call is issued. With mmap, the kernel performs a good deal of work before the actual method is invoked, and therefore the prototype of the method is quite different from that of the system call. This is unlike calls such as ioctl and poll, where the kernel does not do much before calling the method.

The system call is declared as follows (as described in the mmap(2) manual page):

mmap (caddr_t addr, size_t len, int prot, int flags, int fd, 
off_t offset)

On the other hand, the file operation is declared as

int (*mmap) (struct file *filp, struct vm_area_struct *vma);

In the original Linux driver (which I am porting), is on response on mmap system call executed the code I have posted before ( int xx_control_mmap(struct file *filp, struct vm_area_struct *vma) {… ). This code is used to map hardware memory into kernels memory via remap_page_range function.

Shouldn’t I use _IO_MMAP() callouts to do this in QNX??? And if so, how to get number of bytes to be mapped???

Thanks a lot.


It’s not mapping the physical into kernel memory, it’s mapping it into the user’s memory. This is not possible with QNX6. An _IO_MMAP callout is essentially a special case of _IO_DUP and is actually received from the kernel, when the user did a mmap. The kernel will subsequently _IO_READ in the contents of the file as the user code generates page faults.

we did map physical memory into process space at least, there should be similar possible i guess.
this is for custom pci device, may this help you a bit.
pciInfo.Class = 0x42042 // Your Device Class
pciInfo.DeviceId = … // Your device id
pci_attach_device ( NULL, PCI_INIT_ALL | PCI_SHARE | PCI_SEARCH_CLASS, i, &pciInfo ) ;
pciInfo.BaseAddressSize[i] holds the size, as
pciInfo.CpuBaseAddress[i] holds the physptr
memptr = (off_t) mmap (NULL, (size_t) memsize , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_PHYS, NOFD, physptr);
(Mark this is not complete code, just 3 lines out of 100s ^^)

Thanks!! This is what i was looking for. Don’t you know where can I find some sample PCI device driver or resource manager for QNX (I do not have a license yet so qnx.com is useless…)

Sorry, i have Momentics PE license, so i have a lot of docu ^^
but try looking for
“Writing device drivers” QNX
in Google, will give you some chapters out of the docue delivered with Momentics.