Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Jun 2015 21:47:45 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r284168 - head/sys/dev/proto
Message-ID:  <201506082147.t58LljFN076490@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506082147.t58LljFN076490>