[Sorry for the delay, I was quite busy those days and unable to test the patch...]
Le mardi 19 septembre 2006 à 17:34 +0200, Jan Kiszka a écrit : > > > > Or maybe we should lower the API level a little bit, and let the user > > specify the physical address of the mapping instead of the virtual > > one.... > > How would this help? You still need the virtual address for VMA blocks > in order to collect the pages. Actualy we need both the virtual address (for vmalloc case) and the physical address (for ioremap case). > + if (mmap_data->mem_type == RTDM_MEMTYPE_VMALLOC) { [...] This still won't work because for RTDM_MEMTYPE_IOREMAP virt_to_phys((void *)vaddr) doesn't return the physical address. So we still need to either: a) walk the vmlist struct to find out the needed vm->phys_addr (which will probably won't work in 2.4, or even in earlier 2.6 kernels) b) pass both the physical and the virtual adresses in the rtdm_mmap_to_user prototype (the physical address would be used only when RTDM_MEMTYPE_IOREMAP is specified) c) make 'src_addr' be a virtual address in some cases, and a physical address in ioremap case. d) make a special rtdm_mmap_iomem_to_user() function... The (tested) patch below implements the b) case. Index: include/rtdm/rtdm_driver.h =================================================================== --- include/rtdm/rtdm_driver.h (révision 1652) +++ include/rtdm/rtdm_driver.h (copie de travail) @@ -1021,6 +1021,25 @@ /* --- utility functions --- */ +/*! + * @addtogroup util + * @{ + */ + +/*! + * @anchor RTDM_MEMTYPE_xxx @name Memory Types + * Flags defining the type of a memory region + * @{ + */ +/** Allocated with kmalloc() */ +#define RTDM_MEMTYPE_KMALLOC 0x00 +/** Remapped physical memory */ +#define RTDM_MEMTYPE_IOREMAP 0x01 +/** Allocated with vmalloc() */ +#define RTDM_MEMTYPE_VMALLOC 0x02 +/** @} Memory Types */ +/** @} util */ + #define rtdm_printk(format, ...) printk(format, ##__VA_ARGS__) #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */ @@ -1035,8 +1054,9 @@ } #ifdef CONFIG_XENO_OPT_PERVASIVE -int rtdm_mmap_to_user(rtdm_user_info_t *user_info, void *src_addr, size_t len, - int prot, void **pptr, +int rtdm_mmap_to_user(rtdm_user_info_t *user_info, + void *src_vaddr, unsigned long src_paddr, size_t len, + int mem_type, int prot, void **pptr, struct vm_operations_struct *vm_ops, void *vm_private_data); int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len); Index: ksrc/skins/rtdm/drvlib.c =================================================================== --- ksrc/skins/rtdm/drvlib.c (révision 1652) +++ ksrc/skins/rtdm/drvlib.c (copie de travail) @@ -1368,7 +1368,9 @@ #if defined(CONFIG_XENO_OPT_PERVASIVE) || defined(DOXYGEN_CPP) struct rtdm_mmap_data { - void *src_addr; + void *src_vaddr; + unsigned long src_paddr; + int mem_type; struct vm_operations_struct *vm_ops; void *vm_private_data; }; @@ -1376,17 +1378,22 @@ static int rtdm_mmap_buffer(struct file *filp, struct vm_area_struct *vma) { struct rtdm_mmap_data *mmap_data = filp->private_data; - unsigned long vaddr, maddr, size; + unsigned long vaddr, paddr, maddr, size; vma->vm_ops = mmap_data->vm_ops; vma->vm_private_data = mmap_data->vm_private_data; - vaddr = (unsigned long)mmap_data->src_addr; + vaddr = (unsigned long)mmap_data->src_vaddr; maddr = vma->vm_start; size = vma->vm_end - vma->vm_start; + if (mmap_data->mem_type == RTDM_MEMTYPE_IOREMAP) + paddr = mmap_data->src_paddr; + else + paddr = virt_to_phys((void *)vaddr); + #ifdef CONFIG_MMU - if ((vaddr >= VMALLOC_START) && (vaddr < VMALLOC_END)) { + if (mmap_data->mem_type == RTDM_MEMTYPE_VMALLOC) { unsigned long mapped_size = 0; XENO_ASSERT(RTDM, (vaddr == PAGE_ALIGN(vaddr)), return -EINVAL); @@ -1403,8 +1410,7 @@ return 0; } else #endif /* CONFIG_MMU */ - return xnarch_remap_io_page_range(vma, maddr, - virt_to_phys((void *)vaddr), + return xnarch_remap_io_page_range(vma, maddr, paddr, size, PAGE_SHARED); } @@ -1417,8 +1423,12 @@ * * @param[in] user_info User information pointer as passed to the invoked * device operation handler - * @param[in] src_addr Kernel address to be mapped + * @param[in] src_vaddr Kernel virtual address to be mapped + * @param[in] src_paddr Kernel physical address to be mapped (used only for IO + * memory, i.e. mem_type=RTDM_MEMTYPE_IOREMAP) * @param[in] len Length of the memory range + * @param[in] mem_type Type of the passed memory range, see + * @ref RTDM_MEMTYPE_xxx * @param[in] prot Protection flags for the user's memory range, typically * either PROT_READ or PROT_READ|PROT_WRITE * @param[in,out] pptr Address of a pointer containing the desired user @@ -1462,12 +1472,14 @@ * * Rescheduling: possible. */ -int rtdm_mmap_to_user(rtdm_user_info_t *user_info, void *src_addr, size_t len, - int prot, void **pptr, +int rtdm_mmap_to_user(rtdm_user_info_t *user_info, + void *src_vaddr, unsigned long src_paddr, size_t len, + int mem_type, int prot, void **pptr, struct vm_operations_struct *vm_ops, void *vm_private_data) { - struct rtdm_mmap_data mmap_data = {src_addr, vm_ops, vm_private_data}; + struct rtdm_mmap_data mmap_data = { src_vaddr, src_paddr, mem_type, + vm_ops, vm_private_data }; struct file *filp; const struct file_operations *old_fops; void *old_priv_data; -- Stelian Pop <[EMAIL PROTECTED]> _______________________________________________ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core