svn commit: r285071 - in head/tools/bus_space: . C Python

Marcel Moolenaar marcel at FreeBSD.org
Fri Jul 3 02:06:49 UTC 2015


Author: marcel
Date: Fri Jul  3 02:06:47 2015
New Revision: 285071
URL: https://svnweb.freebsd.org/changeset/base/285071

Log:
  Add busdma_md_create, busdma_md_destroy and busdma_md_load.

Modified:
  head/tools/bus_space/C/lang.c
  head/tools/bus_space/C/libbus.h
  head/tools/bus_space/Python/lang.c
  head/tools/bus_space/busdma.c
  head/tools/bus_space/busdma.h

Modified: head/tools/bus_space/C/lang.c
==============================================================================
--- head/tools/bus_space/C/lang.c	Fri Jul  3 01:55:06 2015	(r285070)
+++ head/tools/bus_space/C/lang.c	Fri Jul  3 02:06:47 2015	(r285071)
@@ -156,6 +156,32 @@ busdma_mem_free(busdma_md_t md)
 	return (bd_mem_free(md));
 }
 
+int
+busdma_md_create(busdma_tag_t tag, u_int flags, busdma_md_t *out_p)
+{
+	int res;
+
+	res = bd_md_create(tag, flags);
+	if (res == -1)
+		return (errno);
+	*out_p = res;
+	return (0);
+}
+
+int
+busdma_md_destroy(busdma_md_t md)
+{
+
+	return (bd_md_destroy(md));
+}
+
+int
+busdma_md_load(busdma_md_t md, void *buf, size_t len, u_int flags)
+{
+
+	return (bd_md_load(md, buf, len, flags));
+}
+
 busdma_seg_t
 busdma_md_first_seg(busdma_md_t md, int space)
 {

Modified: head/tools/bus_space/C/libbus.h
==============================================================================
--- head/tools/bus_space/C/libbus.h	Fri Jul  3 01:55:06 2015	(r285070)
+++ head/tools/bus_space/C/libbus.h	Fri Jul  3 02:06:47 2015	(r285071)
@@ -58,6 +58,10 @@ int	busdma_tag_destroy(busdma_tag_t tag)
 int	busdma_mem_alloc(busdma_tag_t tag, u_int flags, busdma_md_t *out_p);
 int	busdma_mem_free(busdma_md_t md);
 
+int	busdma_md_create(busdma_tag_t tag, u_int flags, busdma_md_t *out_p);
+int	busdma_md_destroy(busdma_md_t md);
+int	busdma_md_load(busdma_md_t md, void *buf, size_t len, u_int flags);
+
 #define	BUSDMA_MD_BUS_SPACE	0
 #define	BUSDMA_MD_PHYS_SPACE	1
 #define	BUSDMA_MD_VIRT_SPACE	2

Modified: head/tools/bus_space/Python/lang.c
==============================================================================
--- head/tools/bus_space/Python/lang.c	Fri Jul  3 01:55:06 2015	(r285070)
+++ head/tools/bus_space/Python/lang.c	Fri Jul  3 02:06:47 2015	(r285071)
@@ -229,6 +229,55 @@ busdma_tag_destroy(PyObject *self, PyObj
 }
 
 static PyObject *
+busdma_md_create(PyObject *self, PyObject *args)
+{
+	u_int flags;
+	int error, mdid, tid;
+ 
+	if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
+		return (NULL);
+	mdid = bd_md_create(tid, flags);
+	if (mdid == -1) {
+		PyErr_SetString(PyExc_IOError, strerror(errno));
+		return (NULL);
+	}
+	return (Py_BuildValue("i", mdid));
+}
+
+static PyObject *
+busdma_md_destroy(PyObject *self, PyObject *args)
+{
+	int error, mdid;
+
+	if (!PyArg_ParseTuple(args, "i", &mdid))
+		return (NULL);
+	error = bd_md_destroy(mdid);
+	if (error) {
+		PyErr_SetString(PyExc_IOError, strerror(error));
+		return (NULL);
+	}
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+busdma_md_load(PyObject *self, PyObject *args)
+{
+	void *buf;
+	u_long len;
+	u_int flags;
+	int error, mdid;
+
+	if (!PyArg_ParseTuple(args, "iwkI", &mdid, &buf, &len, &flags))
+		return (NULL);
+	error = bd_md_load(mdid, buf, len, flags);
+	if (error) {
+		PyErr_SetString(PyExc_IOError, strerror(error));
+		return (NULL);
+	}
+	Py_RETURN_NONE;
+}
+
+static PyObject *
 busdma_mem_alloc(PyObject *self, PyObject *args)
 {
 	u_int flags;
@@ -347,6 +396,14 @@ static PyMethodDef busdma_methods[] = {
 	"Derive a child tag." },
     { "tag_destroy", busdma_tag_destroy, METH_VARARGS,
 	"Destroy a tag." },
+
+    { "md_create", busdma_md_create, METH_VARARGS,
+	"Create a new and empty memory descriptor." },
+    { "md_destroy", busdma_md_destroy, METH_VARARGS,
+	"Destroy a previously created memory descriptor." },
+    { "md_load", busdma_md_load, METH_VARARGS,
+	"Load a buffer into a memory descriptor." },
+
     { "mem_alloc", busdma_mem_alloc, METH_VARARGS,
 	"Allocate memory according to the DMA constraints." },
     { "mem_free", busdma_mem_free, METH_VARARGS,

Modified: head/tools/bus_space/busdma.c
==============================================================================
--- head/tools/bus_space/busdma.c	Fri Jul  3 01:55:06 2015	(r285070)
+++ head/tools/bus_space/busdma.c	Fri Jul  3 02:06:47 2015	(r285071)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -137,7 +138,7 @@ obj_lookup(int oid, u_int type)
 	return (obj);
 }
 
-struct obj *
+static struct obj *
 bd_tag_new(struct obj *ptag, int fd, u_long align, u_long bndry,
     u_long maxaddr, u_long maxsz, u_int nsegs, u_long maxsegsz,
     u_int datarate, u_int flags)
@@ -243,12 +244,29 @@ bd_tag_destroy(int tid)
 	return (0);
 }
 
+static int
+bd_md_add_seg(struct obj *md, int type, u_long addr, u_long size)
+{
+	struct obj *seg;
+
+	seg = obj_alloc(OBJ_TYPE_SEG);
+	if (seg == NULL)
+		return (errno);
+	seg->refcnt = 1;
+	seg->parent = md;
+	seg->u.seg.address = addr;
+	seg->u.seg.size = size;
+
+	md->u.md.seg[type] = seg;
+	md->u.md.nsegs[type] = 1;
+	return (0);
+}
+
 int
-bd_mem_alloc(int tid, u_int flags)
+bd_md_create(int tid, u_int flags)
 {
 	struct proto_ioc_busdma ioc;
 	struct obj *md, *tag;
-	struct obj *bseg, *pseg, *vseg;
 
 	tag = obj_lookup(tid, OBJ_TYPE_TAG);
 	if (tag == NULL)
@@ -259,9 +277,9 @@ bd_mem_alloc(int tid, u_int flags)
 		return (-1);
 
 	memset(&ioc, 0, sizeof(ioc));
-	ioc.request = PROTO_IOC_BUSDMA_MEM_ALLOC;
-	ioc.u.mem.tag = tag->key;
-	ioc.u.mem.flags = flags;
+	ioc.request = PROTO_IOC_BUSDMA_MD_CREATE;
+	ioc.u.md.tag = tag->key;
+	ioc.u.md.flags = flags;
 	if (ioctl(tag->fd, PROTO_IOC_BUSDMA, &ioc) == -1) {
 		obj_free(md);
 		return (-1);
@@ -272,56 +290,112 @@ bd_mem_alloc(int tid, u_int flags)
 	md->parent = tag;
 	tag->refcnt++;
 	md->key = ioc.result;
+	return (md->oid);
+}
 
-	/* XXX we need to support multiple segments */
-	assert(ioc.u.mem.phys_nsegs == 1);
-	assert(ioc.u.mem.bus_nsegs == 1);
+int
+bd_md_destroy(int mdid)
+{
+	struct proto_ioc_busdma ioc;
+	struct obj *md;
 
-	bseg = pseg = vseg = NULL;
+	md = obj_lookup(mdid, OBJ_TYPE_MD);
+	if (md == NULL)
+		return (errno);
 
-	bseg = obj_alloc(OBJ_TYPE_SEG);
-	if (bseg == NULL)
-		goto fail;
-	bseg->refcnt = 1;
-	bseg->parent = md;
-	bseg->u.seg.address = ioc.u.mem.bus_addr;
-	bseg->u.seg.size = tag->u.tag.maxsz;
-	md->u.md.seg[BUSDMA_MD_BUS] = bseg;
-	md->u.md.nsegs[BUSDMA_MD_BUS] = ioc.u.mem.bus_nsegs;
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.request = PROTO_IOC_BUSDMA_MD_DESTROY;
+	ioc.key = md->key;
+	if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
+		return (errno);
 
-	pseg = obj_alloc(OBJ_TYPE_SEG);
-	if (pseg == NULL)
-		goto fail;
-	pseg->refcnt = 1;
-	pseg->parent = md;
-	pseg->u.seg.address = ioc.u.mem.phys_addr;
-	pseg->u.seg.size = tag->u.tag.maxsz;
-	md->u.md.seg[BUSDMA_MD_PHYS] = pseg;
-	md->u.md.nsegs[BUSDMA_MD_PHYS] = ioc.u.mem.phys_nsegs;
+	md->parent->refcnt--;
+	obj_free(md);
+	return (0);
+}
 
-	vseg = obj_alloc(OBJ_TYPE_SEG);
-	if (vseg == NULL)
-		goto fail;
-	vseg->refcnt = 1;
-	vseg->parent = md;
-	vseg->u.seg.address = (uintptr_t)mmap(NULL, pseg->u.seg.size,
-	    PROT_READ | PROT_WRITE, MAP_NOCORE | MAP_SHARED, md->fd,
-	    pseg->u.seg.address);
-	if (vseg->u.seg.address == (uintptr_t)MAP_FAILED)
+int
+bd_md_load(int mdid, void *buf, u_long len, u_int flags)
+{
+	struct proto_ioc_busdma ioc;
+	struct obj *md;
+	int error;
+
+	md = obj_lookup(mdid, OBJ_TYPE_MD);
+	if (md == NULL)
+		return (errno);
+
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.request = PROTO_IOC_BUSDMA_MD_LOAD;
+	ioc.key = md->key;
+	ioc.u.md.flags = flags;
+	ioc.u.md.virt_addr = (uintptr_t)buf;
+	ioc.u.md.virt_size = len;
+	if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
+		return (errno);
+
+	printf("XXX: %s: phys(%d, %#lx), bus(%d, %#lx)\n", __func__,
+	    ioc.u.md.phys_nsegs, ioc.u.md.phys_addr,
+	    ioc.u.md.bus_nsegs, ioc.u.md.bus_addr);
+
+	error = bd_md_add_seg(md, BUSDMA_MD_VIRT, ioc.u.md.virt_addr, len);
+	error = bd_md_add_seg(md, BUSDMA_MD_PHYS, ioc.u.md.phys_addr, len);
+	error = bd_md_add_seg(md, BUSDMA_MD_BUS, ioc.u.md.bus_addr, len);
+	return (error);
+}
+
+int
+bd_mem_alloc(int tid, u_int flags)
+{
+	struct proto_ioc_busdma ioc;
+	struct obj *md, *tag;
+	uintptr_t addr;
+	int error;
+
+	tag = obj_lookup(tid, OBJ_TYPE_TAG);
+	if (tag == NULL)
+		return (-1);
+
+	md = obj_alloc(OBJ_TYPE_MD);
+	if (md == NULL)
+		return (-1);
+
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.request = PROTO_IOC_BUSDMA_MEM_ALLOC;
+	ioc.u.md.tag = tag->key;
+	ioc.u.md.flags = flags;
+	if (ioctl(tag->fd, PROTO_IOC_BUSDMA, &ioc) == -1) {
+		obj_free(md);
+		return (-1);
+	}
+
+	md->refcnt = 1;
+	md->fd = tag->fd;
+	md->parent = tag;
+	tag->refcnt++;
+	md->key = ioc.result;
+
+	printf("XXX: %s: phys(%d, %#lx), bus(%d, %#lx)\n", __func__,
+	    ioc.u.md.phys_nsegs, ioc.u.md.phys_addr,
+	    ioc.u.md.bus_nsegs, ioc.u.md.bus_addr);
+
+	/* XXX we need to support multiple segments */
+	assert(ioc.u.md.phys_nsegs == 1);
+	assert(ioc.u.md.bus_nsegs == 1);
+	error = bd_md_add_seg(md, BUSDMA_MD_PHYS, ioc.u.md.phys_addr,
+	    tag->u.tag.maxsz);
+	error = bd_md_add_seg(md, BUSDMA_MD_BUS, ioc.u.md.bus_addr,
+	    tag->u.tag.maxsz);
+
+	addr = (uintptr_t)mmap(NULL, tag->u.tag.maxsz, PROT_READ | PROT_WRITE,
+	    MAP_NOCORE | MAP_SHARED, md->fd, ioc.u.md.phys_addr);
+	if (addr == (uintptr_t)MAP_FAILED)
 		goto fail;
-	vseg->u.seg.size = pseg->u.seg.size;
-	md->u.md.seg[BUSDMA_MD_VIRT] = vseg;
-	md->u.md.nsegs[BUSDMA_MD_VIRT] = 1;
+	error = bd_md_add_seg(md, BUSDMA_MD_VIRT, addr, tag->u.tag.maxsz);
 
 	return (md->oid);
 
  fail:
-	if (vseg != NULL)
-		obj_free(vseg);
-	if (pseg != NULL)
-		obj_free(pseg);
-	if (bseg != NULL)
-		obj_free(bseg);
 	memset(&ioc, 0, sizeof(ioc));
 	ioc.request = PROTO_IOC_BUSDMA_MEM_FREE;
 	ioc.key = md->key;

Modified: head/tools/bus_space/busdma.h
==============================================================================
--- head/tools/bus_space/busdma.h	Fri Jul  3 01:55:06 2015	(r285070)
+++ head/tools/bus_space/busdma.h	Fri Jul  3 02:06:47 2015	(r285071)
@@ -37,6 +37,10 @@ int	bd_tag_derive(int tid, u_long align,
 	    u_int flags);
 int	bd_tag_destroy(int tid);
 
+int	bd_md_create(int tid, u_int flags);
+int	bd_md_destroy(int mdid);
+int	bd_md_load(int mdid, void *buf, u_long len, u_int flags);
+
 int	bd_mem_alloc(int tid, u_int flags);
 int	bd_mem_free(int mdid);
 


More information about the svn-src-head mailing list