Sfoglia il codice sorgente

!539 Add mmap API for device file
Merge pull request !539 from bernard/bernard_rt-smart

bernard 3 anni fa
parent
commit
316cc7dbfe

+ 13 - 0
components/dfs/include/dfs_file.h

@@ -64,6 +64,17 @@ struct dfs_fd
     void *data;                  /* Specific fd data */
 };
 
+struct dfs_mmap2_args
+{
+    void *addr;
+    size_t length;
+    int prot;
+    int flags;
+    off_t pgoffset;
+
+    void *ret;
+};
+
 void dfs_fnode_mgr_init(void);
 int dfs_file_is_open(const char *pathname);
 int dfs_file_open(struct dfs_fd *fd, const char *path, int flags);
@@ -79,10 +90,12 @@ int dfs_file_lseek(struct dfs_fd *fd, off_t offset);
 int dfs_file_stat(const char *path, struct stat *buf);
 int dfs_file_rename(const char *oldpath, const char *newpath);
 int dfs_file_ftruncate(struct dfs_fd *fd, off_t length);
+int dfs_file_mmap2(struct dfs_fd *fd, struct dfs_mmap2_args *mmap2);
 
 /* 0x5254 is just a magic number to make these relatively unique ("RT") */
 #define RT_FIOFTRUNCATE  0x52540000U
 #define RT_FIOGETADDR    0x52540001U
+#define RT_FIOMMAP2      0x52540002U
 
 #ifdef __cplusplus
 }

+ 24 - 0
components/dfs/src/dfs_file.c

@@ -723,6 +723,30 @@ int dfs_file_ftruncate(struct dfs_fd *fd, off_t length)
     return result;
 }
 
+int dfs_file_mmap2(struct dfs_fd *fd, struct dfs_mmap2_args *mmap2)
+{
+    int ret = 0;
+
+    if (fd && mmap2)
+    {
+        if (fd->fnode->type != FT_DEVICE || !fd->fnode->fops->ioctl)
+        {
+            rt_set_errno(EINVAL);
+        }
+        else if (fd->fnode->type == FT_DEVICE && fd->fnode->fops->ioctl)
+        {
+            ret = fd->fnode->fops->ioctl(fd, RT_FIOMMAP2, mmap2);
+            if (ret != 0)
+            {
+                ret = ret > 0? ret : -ret;
+                rt_set_errno(ret);
+            }
+        }
+    }
+
+    return ret;
+}
+
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 

+ 27 - 6
components/lwp/lwp_user_mm.c

@@ -353,14 +353,13 @@ void* lwp_mmap2(void *addr, size_t length, int prot,
         int flags, int fd, off_t pgoffset)
 {
     void *ret = (void *)-1;
-    struct rt_lwp *lwp = RT_NULL;
 
     if (fd == -1)
     {
-        lwp = rt_thread_self()->lwp;
         rt_mm_lock();
-        ret = lwp_map_user(lwp, addr, length, 0);
+        ret = lwp_map_user(lwp_self(), addr, length, 0);
         rt_mm_unlock();
+
         if (ret)
         {
             if ((flags & MAP_ANONYMOUS) != 0)
@@ -373,18 +372,40 @@ void* lwp_mmap2(void *addr, size_t length, int prot,
             ret = (void *)-1;
         }
     }
+    else
+    {
+        struct dfs_fd *d;
+
+        d = fd_get(fd);
+        if (d && d->fnode->type == FT_DEVICE)
+        {
+            struct dfs_mmap2_args mmap2;
+        
+            mmap2.addr = addr;
+            mmap2.length = length;
+            mmap2.prot = prot;
+            mmap2.flags = flags;
+            mmap2.pgoffset = pgoffset;
+            mmap2.ret = (void*) -1;
+
+            if (dfs_file_mmap2(d, &mmap2) == 0)
+            {
+                ret = mmap2.ret;
+            }
+        }
+    }
+
     return ret;
 }
 
 int lwp_munmap(void *addr)
 {
     int ret = 0;
-    struct rt_lwp *lwp = RT_NULL;
 
     rt_mm_lock();
-    lwp = rt_thread_self()->lwp;
-    ret = lwp_unmap_user(lwp, addr);
+    ret = lwp_unmap_user(lwp_self(), addr);
     rt_mm_unlock();
+
     return ret;
 }