03-23-2009 06:05 AM
Compiling nirlpk.c from the DDK with a 2.6.27-3-rt (Ubuntu 8.10) kernel produces the following errors:
nirlpk.c:48:28: error: linux/config.h: No such file or directory
nirlpk.c:111: error: unknown field ‘enable_wake’ specified in initializer
nirlpk.c:324: error: unknown field ‘nopage’ specified in initializer
nirlpk.c:407: error: ‘VM_SHM’ undeclared (first use in this function)
Most error lines can be commented out (see http://forums.ni.com/ni/board/message?board.id=90&thread.id=1477) but not the the 'nopage' field of vm_operations_struct (now changed to 'fault').
Is there a patched version of nirlpk.c?
03-23-2009 09:24 AM
I don't have a patch for nirlpk.c, but the conversion to from nopage to fault shouldn't be too difficult. If you haven't already you may want to read:
http://lwn.net/Articles/242625/
If you have any questions about the conversion let me know, and I can probably help you out.
Shawn Bohrer
National Instruments
03-23-2009 03:42 PM
Here's what I hope is a patch for this. Can you confirm this is right?
I'm not confident that it's the correct thing to do here, but it sort of looks right. Inspired somewhat by ieee1394/dma.c
I'm not even sure how to test this properly...
Anyways, the new function looks like:
/*
nNIRLP_vmaFault
Description: virtual memory area (vma) page fault handler.
(*fault)() replaced (*nopage)() in 2.6.23
*/
static int nNIRLP_vmaFault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct nNIRLP_tDMA *dma = vma->vm_private_data;
vmf->page = virt_to_page(dma->address.cpu + (vmf->pgoff << PAGE_SHIFT));
get_page(vmf->page);
return 0;
}
03-23-2009 11:31 PM
Thanks. It looks right. As far as I understand, we need to calculate the virtual address of the dma buffer page that's missing, then load it, which it does as far as I can tell (there's a bit of info on virt_to_page() here that I found useful too). Note I also added VM_CAN_NONLINEAR to the vm_fault flags field as suggested here (thanks Shawn).
The complete patch for nirlpk.c based on yours is attached. It compiles and installs OK now, but I haven't tested it either yet (and won't be able to for a while).
For anyone else interested, the steps I took were:
In the /.../nimhddk_linux26/Linux26/nirlpk directory
1. Patch the nirlpk.c file: patch nirlpk.c < nirlpk-patch-2.6.27
2. Change the #!bin/sh header line in files install.sh, uninstall.sh and nirlp to read #!bin/bash. This is to suit Ubuntu that runs dash as the default shell. These scripts need bash not dash it seems.
3. Run make
4. Run make install
🙂
03-24-2009 11:37 AM
OK, I lied when I said this was easy to convert. I spent some time thinking about it and I think it you want:
vmf->page = virt_to_page(dma->address.cpu + ((vmf->pgoff - vma->vm_pgoff) << PAGE_SHIFT));
The code in 'drivers/ieee1394/dma.c' works because they guarantee that vma->vm_pgoff == 0 in their mmap implementation. In the nirlpk.c case vma->vm_pgoff is the bus address of the DMA buffer. Therefore (vmf->pgoff - vma->vm_pgoff) gives you the offset into the buffer where the fault occured.
Now since you are touching more than just vmf->pgoff I'm not sure if you can set VM_CAN_NONLINEAR.
Keep in mind this is all from me just looking at the code, and I have not tested anything myself. I would think that if you want to test this all you would need to do is mmap() a DMA buffer and try to do some DMA.
Shawn Bohrer
National Instruments