Author: marcel
Date: Mon Jun  8 21:47:44 2015
New Revision: 284168
URL: https://svnweb.freebsd.org/changeset/base/284168

Log:
  Implement mmap(2) for the busdma resource.

Modified:
  head/sys/dev/proto/proto_busdma.c
  head/sys/dev/proto/proto_busdma.h
  head/sys/dev/proto/proto_core.c

Modified: head/sys/dev/proto/proto_busdma.c
==============================================================================
--- head/sys/dev/proto/proto_busdma.c   Mon Jun  8 20:12:44 2015        
(r284167)
+++ head/sys/dev/proto/proto_busdma.c   Mon Jun  8 21:47:44 2015        
(r284168)
@@ -146,16 +146,17 @@ proto_busdma_mem_alloc(struct proto_busd
                free(md, M_PROTO_BUSDMA);
                return (error);
        }
-       error = bus_dmamem_alloc(md->bd_tag, &md->kva, 0, &md->bd_map);
+       error = bus_dmamem_alloc(md->bd_tag, &md->virtaddr, 0, &md->bd_map);
        if (error) {
                bus_dma_tag_destroy(md->bd_tag);
                free(md, M_PROTO_BUSDMA);
                return (error);
        }
+       md->physaddr = pmap_kextract((uintptr_t)(md->virtaddr));
        LIST_INSERT_HEAD(&tag->mds, md, peers);
        LIST_INSERT_HEAD(&busdma->mds, md, mds);
        ioc->u.mem.nsegs = 1;
-       ioc->u.mem.physaddr = pmap_kextract((uintptr_t)(md->kva));
+       ioc->u.mem.physaddr = md->physaddr;
        ioc->result = (uintptr_t)(void *)md;
        return (0);
 }
@@ -166,7 +167,7 @@ proto_busdma_mem_free(struct proto_busdm
 
        LIST_REMOVE(md, mds);
        LIST_REMOVE(md, peers);
-       bus_dmamem_free(md->bd_tag, md->kva, md->bd_map);
+       bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map);
        bus_dma_tag_destroy(md->bd_tag);
        free(md, M_PROTO_BUSDMA);
        return (0);
@@ -267,3 +268,16 @@ proto_busdma_ioctl(struct proto_softc *s
        }
        return (error);
 }
+
+int
+proto_busdma_mmap_allowed(struct proto_busdma *busdma, vm_paddr_t physaddr)
+{
+       struct proto_md *md;
+
+       LIST_FOREACH(md, &busdma->mds, mds) {
+               if (physaddr >= trunc_page(md->physaddr) &&
+                   physaddr <= trunc_page(md->physaddr + md->tag->maxsz))
+                       return (1);
+       }
+       return (0);
+}

Modified: head/sys/dev/proto/proto_busdma.h
==============================================================================
--- head/sys/dev/proto/proto_busdma.h   Mon Jun  8 20:12:44 2015        
(r284167)
+++ head/sys/dev/proto/proto_busdma.h   Mon Jun  8 21:47:44 2015        
(r284168)
@@ -50,7 +50,8 @@ struct proto_md {
        LIST_ENTRY(proto_md)    mds;
        LIST_ENTRY(proto_md)    peers;
        struct proto_tag        *tag;
-       void                    *kva;
+       void                    *virtaddr;
+       vm_paddr_t              physaddr;
        bus_dma_tag_t           bd_tag;
        bus_dmamap_t            bd_map;
 };
@@ -69,4 +70,6 @@ int proto_busdma_cleanup(struct proto_so
 int proto_busdma_ioctl(struct proto_softc *, struct proto_busdma *,
     struct proto_ioc_busdma *);
 
+int proto_busdma_mmap_allowed(struct proto_busdma *, vm_paddr_t);
+
 #endif /* _DEV_PROTO_BUSDMA_H_ */

Modified: head/sys/dev/proto/proto_core.c
==============================================================================
--- head/sys/dev/proto/proto_core.c     Mon Jun  8 20:12:44 2015        
(r284167)
+++ head/sys/dev/proto/proto_core.c     Mon Jun  8 21:47:44 2015        
(r284168)
@@ -402,19 +402,29 @@ proto_mmap(struct cdev *cdev, vm_ooffset
 {
        struct proto_res *r;
 
-       r = cdev->si_drv2;
-
-       if (r->r_type != SYS_RES_MEMORY)
-               return (ENXIO);
        if (offset & PAGE_MASK)
                return (EINVAL);
        if (prot & PROT_EXEC)
                return (EACCES);
-       if (offset >= r->r_size)
-               return (EINVAL);
-       *paddr = rman_get_start(r->r_d.res) + offset;
+
+       r = cdev->si_drv2;
+
+       switch (r->r_type) {
+       case SYS_RES_MEMORY:
+               if (offset >= r->r_size)
+                       return (EINVAL);
+               *paddr = rman_get_start(r->r_d.res) + offset;
 #ifndef __sparc64__
-       *memattr = VM_MEMATTR_UNCACHEABLE;
+               *memattr = VM_MEMATTR_UNCACHEABLE;
 #endif
+               break;
+       case PROTO_RES_BUSDMA:
+               if (!proto_busdma_mmap_allowed(r->r_d.busdma, offset))
+                       return (EINVAL);
+               *paddr = offset;
+               break;
+       default:
+               return (ENXIO);
+       }
        return (0);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to