Jan Kiszka wrote: > Hi all, > > this is a first attempt to add the requested mmap functionality to the > RTDM driver API.
... and this version is even more useful than the previous one (now with EXPORT_SYMBOL!). Be warned: I just compiled it, I count on third-party testers. Jan
Index: include/rtdm/rtdm_driver.h
===================================================================
--- include/rtdm/rtdm_driver.h (Revision 556)
+++ include/rtdm/rtdm_driver.h (Arbeitskopie)
@@ -995,6 +995,10 @@
xnfree(ptr);
}
+int rtdm_mmap_to_user(rtdm_user_info_t *user_info, void *src_addr, size_t len,
+ int prot, void **pptr);
+int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len);
+
static inline int rtdm_read_user_ok(rtdm_user_info_t *user_info,
const void __user *ptr, size_t size)
{
Index: ksrc/skins/rtdm/drvlib.c
===================================================================
--- ksrc/skins/rtdm/drvlib.c (Revision 556)
+++ ksrc/skins/rtdm/drvlib.c (Arbeitskopie)
@@ -31,7 +31,9 @@
#include <linux/delay.h>
+#include <linux/mman.h>
+#define XENO_HEAP_MODULE
#include <rtdm/rtdm_driver.h>
@@ -1286,7 +1288,7 @@
* Rescheduling: never.
*/
int rtdm_irq_disable(rtdm_irq_t *irq_handle);
-/** @} */
+/** @} Interrupt Management Services */
/*!
@@ -1358,16 +1360,133 @@
* environments.
*/
void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig);
-/** @} */
+/** @} Non-Real-Time Signalling Services */
+#endif /* DOXYGEN_CPP */
+
/*!
* @ingroup driverapi
* @defgroup util Utility Services
* @{
*/
+static int rtdm_mmap_buffer(struct file *filp, struct vm_area_struct *vma)
+{
+ return xnarch_remap_page_range(vma, vma->vm_start,
+ virt_to_phys(filp->private_data),
+ vma->vm_end - vma->vm_start, PAGE_SHARED);
+}
+
+static struct file_operations rtdm_mmap_fops = {
+ .mmap = rtdm_mmap_buffer,
+};
+
/**
+ * Map a kernel memory range into the address space of the user.
+ *
+ * @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] len Length of the memory range
+ * @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
+ * address or NULL on entry and the finally assigned address on return
+ *
+ * @return 0 on success, otherwise:
+ *
+ * - -EXXX is returned if .
+ *
+ * @note An RTDM driver is expected to invoke rtdm_munmap on every mapped
+ * memory range either when the user requests it explicitly or when the
+ * related device is closed.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - User-space task (non-RT)
+ *
+ * Rescheduling: possible.
+ */
+int rtdm_mmap_to_user(rtdm_user_info_t *user_info, void *src_addr, size_t len,
+ int prot, void **pptr)
+{
+ struct file *filp;
+ struct file_operations *old_fops;
+ void *old_priv_data;
+ void *user_ptr;
+
+ filp = filp_open("/dev/zero", O_RDWR, 0);
+ if (IS_ERR(filp))
+ return PTR_ERR(filp);
+
+ old_fops = filp->f_op;
+ filp->f_op = &rtdm_mmap_fops;
+
+ old_priv_data = filp->private_data;
+ filp->private_data = src_addr;
+
+ down_write(&user_info->mm->mmap_sem);
+ user_ptr = (void *)do_mmap(filp, (unsigned long)*pptr, len, prot,
+ MAP_SHARED, 0);
+ up_write(&user_info->mm->mmap_sem);
+
+ filp->f_op = old_fops;
+ filp->private_data = old_priv_data;
+
+ filp_close(filp, user_info->files);
+
+ if (IS_ERR(user_ptr))
+ return PTR_ERR(user_ptr);
+
+ *pptr = user_ptr;
+ return 0;
+}
+
+EXPORT_SYMBOL(rtdm_mmap_to_user);
+
+
+/**
+ * Unmap a user memory range.
+ *
+ * @param[in] user_info User information pointer as passed to
+ * rtdm_mmap_to_user() when requesting to map the memory range
+ * @param[in] ptr User address or the memory range
+ * @param[in] len Length of the memory range
+ *
+ * @return 0 on success, otherwise:
+ *
+ * - -EXXX is returned if .
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - User-space task (non-RT)
+ *
+ * Rescheduling: possible.
+ */
+int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len)
+{
+ int err;
+
+ down_write(&user_info->mm->mmap_sem);
+ err = do_munmap(user_info->mm, (unsigned long)ptr, len);
+ up_write(&user_info->mm->mmap_sem);
+
+ return err;
+}
+
+EXPORT_SYMBOL(rtdm_munmap);
+
+
+#ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
+
+/**
* Real-time safe message printing on kernel console
*
* @param[in] format Format string (conforming standard @c printf())
@@ -1583,6 +1702,6 @@
*/
int rtdm_in_rt_context(void);
-/** @} */
+#endif /* DOXYGEN_CPP */
-#endif /* DOXYGEN_CPP */
+/** @} Utility Services */
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Xenomai-core mailing list [email protected] https://mail.gna.org/listinfo/xenomai-core
