Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Jun 2015 03:23:20 +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: r284146 - in head/tools/bus_space: . C Python
Message-ID:  <201506080323.t583NKWB098393@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Mon Jun  8 03:23:20 2015
New Revision: 284146
URL: https://svnweb.freebsd.org/changeset/base/284146

Log:
  Add busdma_mem_alloc & busdma_mem_free.

Modified:
  head/tools/bus_space/C/lang.c
  head/tools/bus_space/C/libbus_space.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	Mon Jun  8 03:01:19 2015	(r284145)
+++ head/tools/bus_space/C/lang.c	Mon Jun  8 03:23:20 2015	(r284146)
@@ -137,3 +137,21 @@ busdma_tag_destroy(busdma_tag_t tag)
 	return (bd_tag_destroy(tag));
 }
 
+int
+busdma_mem_alloc(busdma_tag_t tag, u_int flags, busdma_md_t *out_p)
+{
+	int res;
+
+	res = bd_mem_alloc(tag, flags);
+	if (res == -1)
+		return (errno);
+	*out_p = res;
+	return (0);
+}
+
+int
+busdma_mem_free(busdma_md_t md)
+{
+
+	return (bd_mem_free(md));
+}

Modified: head/tools/bus_space/C/libbus_space.h
==============================================================================
--- head/tools/bus_space/C/libbus_space.h	Mon Jun  8 03:01:19 2015	(r284145)
+++ head/tools/bus_space/C/libbus_space.h	Mon Jun  8 03:23:20 2015	(r284146)
@@ -42,6 +42,7 @@ int	bus_space_write_4(int rid, long ofs,
 typedef unsigned long bus_addr_t;
 typedef unsigned long bus_size_t;
 typedef int busdma_tag_t;
+typedef int busdma_md_t;
 
 int	busdma_tag_create(const char *dev, bus_addr_t align, bus_addr_t bndry,
 	    bus_addr_t maxaddr, bus_size_t maxsz, u_int nsegs,
@@ -53,4 +54,7 @@ int	busdma_tag_derive(busdma_tag_t tag, 
 	    busdma_tag_t *out_p);
 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);
+
 #endif /* _LIBBUS_SPACE_H_ */

Modified: head/tools/bus_space/Python/lang.c
==============================================================================
--- head/tools/bus_space/Python/lang.c	Mon Jun  8 03:01:19 2015	(r284145)
+++ head/tools/bus_space/Python/lang.c	Mon Jun  8 03:23:20 2015	(r284146)
@@ -178,12 +178,13 @@ static PyObject *
 busdma_tag_create(PyObject *self, PyObject *args)
 {
 	char *dev;
-	long align, bndry, maxaddr, maxsz, maxsegsz;
-	int tid, nsegs, datarate, flags;
+	u_long align, bndry, maxaddr, maxsz, maxsegsz;
+	u_int nsegs, datarate, flags;
+	int tid;
 
-	if (!PyArg_ParseTuple(args, "sllllilii", &dev, &align, &bndry,
+	if (!PyArg_ParseTuple(args, "skkkkIkII", &dev, &align, &bndry,
 	    &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
-                return (NULL);
+		return (NULL);
 	tid = bd_tag_create(dev, align, bndry, maxaddr, maxsz, nsegs,
 	    maxsegsz, datarate, flags);
 	if (tid == -1) {
@@ -196,10 +197,11 @@ busdma_tag_create(PyObject *self, PyObje
 static PyObject *
 busdma_tag_derive(PyObject *self, PyObject *args)
 {
-	long align, bndry, maxaddr, maxsz, maxsegsz;
-	int ptid, tid, nsegs, datarate, flags;
+	u_long align, bndry, maxaddr, maxsz, maxsegsz;
+	u_int nsegs, datarate, flags;
+	int ptid, tid;
  
-	if (!PyArg_ParseTuple(args, "illllilii", &ptid, &align, &bndry,
+	if (!PyArg_ParseTuple(args, "ikkkkIkII", &ptid, &align, &bndry,
 	    &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
 		return (NULL);
 	tid = bd_tag_derive(ptid, align, bndry, maxaddr, maxsz, nsegs,
@@ -226,6 +228,37 @@ busdma_tag_destroy(PyObject *self, PyObj
 	Py_RETURN_NONE;
 }
 
+static PyObject *
+busdma_mem_alloc(PyObject *self, PyObject *args)
+{
+	u_int flags;
+	int mdid, tid;
+
+	if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
+		return (NULL);
+	mdid = bd_mem_alloc(tid, flags);
+	if (mdid == -1) {
+		PyErr_SetString(PyExc_IOError, strerror(errno));
+		return (NULL);
+	}
+	return (Py_BuildValue("i", mdid));
+}
+
+static PyObject *
+busdma_mem_free(PyObject *self, PyObject *args)
+{
+	int error, mdid;
+
+	if (!PyArg_ParseTuple(args, "i", &mdid))
+		return (NULL);
+	error = bd_mem_free(mdid);
+	if (error) {
+		PyErr_SetString(PyExc_IOError, strerror(error));
+		return (NULL);
+	}
+	Py_RETURN_NONE;
+}
+
 static PyMethodDef bus_space_methods[] = {
     { "read_1", bus_read_1, METH_VARARGS, "Read a 1-byte data item." },
     { "read_2", bus_read_2, METH_VARARGS, "Read a 2-byte data item." },
@@ -246,9 +279,16 @@ static PyMethodDef bus_space_methods[] =
 };
 
 static PyMethodDef busdma_methods[] = {
-    { "tag_create", busdma_tag_create, METH_VARARGS, "Create a root tag." },
-    { "tag_derive", busdma_tag_derive, METH_VARARGS, "Derive a child tag." },
-    { "tag_destroy", busdma_tag_destroy, METH_VARARGS, "Destroy a tag." },
+    { "tag_create", busdma_tag_create, METH_VARARGS,
+	"Create a root tag." },
+    { "tag_derive", busdma_tag_derive, METH_VARARGS,
+	"Derive a child tag." },
+    { "tag_destroy", busdma_tag_destroy, METH_VARARGS,
+	"Destroy a tag." },
+    { "mem_alloc", busdma_mem_alloc, METH_VARARGS,
+	"Allocate memory according to the DMA constraints." },
+    { "mem_free", busdma_mem_free, METH_VARARGS,
+	"Free allocated memory." },
     { NULL, NULL, 0, NULL }
 };
 

Modified: head/tools/bus_space/busdma.c
==============================================================================
--- head/tools/bus_space/busdma.c	Mon Jun  8 03:01:19 2015	(r284145)
+++ head/tools/bus_space/busdma.c	Mon Jun  8 03:23:20 2015	(r284146)
@@ -40,82 +40,101 @@ __FBSDID("$FreeBSD$");
 
 #include "../../sys/dev/proto/proto_dev.h"
 
-struct tag {
-	int	tid;
+struct obj {
+	int	oid;
+	u_int	type;
+#define	OBJ_TYPE_NONE	0
+#define	OBJ_TYPE_TAG	1
+#define	OBJ_TYPE_MD	2
 	u_int	refcnt;
 	int	fd;
-	struct tag *ptag;
+	struct obj *parent;
 	u_long	key;
-	u_long	align;
-	u_long	bndry;
-	u_long	maxaddr;
+	union {
+		struct {
+			unsigned long	align;
+			unsigned long	bndry;
+			unsigned long	maxaddr;
+			unsigned long	maxsz;
+			unsigned long	maxsegsz;
+			unsigned long	nsegs;
+			unsigned long	datarate;
+		} tag;
+		struct {
+		} md;
+	} u;
 };
 
-static struct tag **tidtbl = NULL;
-static int ntids = 0;
+static struct obj **oidtbl = NULL;
+static int noids = 0;
 
-static struct tag *
-tag_alloc(void)
+static struct obj *
+obj_alloc(u_int type)
 {
-	struct tag **newtbl, *tag;
-	int tid;
+	struct obj **newtbl, *obj;
+	int oid;
 
-	tag = malloc(sizeof(struct tag));
-	tag->refcnt = 0;
+	obj = malloc(sizeof(struct obj));
+	obj->type = type;
+	obj->refcnt = 0;
 
-	for (tid = 0; tid < ntids; tid++) {
-		if (tidtbl[tid] == 0)
+	for (oid = 0; oid < noids; oid++) {
+		if (oidtbl[oid] == 0)
 			break;
 	}
-	if (tid == ntids) {
-		newtbl = realloc(tidtbl, sizeof(struct tag *) * (ntids + 1));
+	if (oid == noids) {
+		newtbl = realloc(oidtbl, sizeof(struct obj *) * (noids + 1));
 		if (newtbl == NULL) {
-			free(tag);
+			free(obj);
 			return (NULL);
 		}
-		tidtbl = newtbl;
-		ntids++;
+		oidtbl = newtbl;
+		noids++;
 	}
-	tidtbl[tid] = tag;
-	tag->tid = tid;
-	return (tag);
+	oidtbl[oid] = obj;
+	obj->oid = oid;
+	return (obj);
 }
 
 static int
-tag_free(struct tag *tag)
+obj_free(struct obj *obj)
 {
 
-	tidtbl[tag->tid] = NULL;
-	free(tag);
+	oidtbl[obj->oid] = NULL;
+	free(obj);
 	return (0);
 }
 
-static struct tag *
-tid_lookup(int tid)
+static struct obj *
+obj_lookup(int oid, u_int type)
 {
-	struct tag *tag;
+	struct obj *obj;
 
-	if (tid < 0 || tid >= ntids) {
+	if (oid < 0 || oid >= noids) {
 		errno = EINVAL;
 		return (NULL);
 	}
-	tag = tidtbl[tid];
-	if (tag->refcnt == 0) {
+	obj = oidtbl[oid];
+	if (obj->refcnt == 0) {
 		errno = ENXIO;
 		return (NULL);
 	}
-	return (tag);
+	if (type != OBJ_TYPE_NONE && obj->type != type) {
+		errno = ENODEV;
+		return (NULL);
+	}
+	return (obj);
 }
 
-struct tag *
-bd_tag_new(struct tag *ptag, int fd, u_long align, u_long bndry,
+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)
 {
 	struct proto_ioc_busdma ioc;
-	struct tag *tag;
+	struct obj *tag;
 
-	tag = tag_alloc();
+	tag = obj_alloc(OBJ_TYPE_TAG);
 	if (tag == NULL)
 		return (NULL);
 
@@ -132,16 +151,20 @@ bd_tag_new(struct tag *ptag, int fd, u_l
 	ioc.u.tag.datarate = datarate;
 	ioc.u.tag.flags = flags;
 	if (ioctl(fd, PROTO_IOC_BUSDMA, &ioc) == -1) {
-		tag_free(tag);
+		obj_free(tag);
 		return (NULL);
 	}
 	tag->refcnt = 1;
 	tag->fd = fd;
-	tag->ptag = ptag;
-	tag->key = ioc.key;
-	tag->align = ioc.u.tag.align;
-	tag->bndry = ioc.u.tag.bndry;
-	tag->maxaddr = ioc.u.tag.maxaddr;
+	tag->parent = ptag;
+	tag->key = ioc.result;
+	tag->u.tag.align = ioc.u.tag.align;
+	tag->u.tag.bndry = ioc.u.tag.bndry;
+	tag->u.tag.maxaddr = ioc.u.tag.maxaddr;
+	tag->u.tag.maxsz = ioc.u.tag.maxsz;
+	tag->u.tag.maxsegsz = ioc.u.tag.maxsegsz;
+	tag->u.tag.nsegs = ioc.u.tag.nsegs;
+	tag->u.tag.datarate = ioc.u.tag.datarate;
 	return (tag);
 }
 
@@ -149,7 +172,7 @@ int
 bd_tag_create(const char *dev, u_long align, u_long bndry, u_long maxaddr,
     u_long maxsz, u_int nsegs, u_long maxsegsz, u_int datarate, u_int flags)
 {
-	struct tag *tag;
+	struct obj *tag;
 	int fd;
 
 	fd = open(dev, O_RDWR);
@@ -162,16 +185,16 @@ bd_tag_create(const char *dev, u_long al
 		close(fd);
 		return (-1);
 	}
-	return (tag->tid);
+	return (tag->oid);
 }
 
 int
 bd_tag_derive(int ptid, u_long align, u_long bndry, u_long maxaddr,
     u_long maxsz, u_int nsegs, u_long maxsegsz, u_int datarate, u_int flags)
 {
-	struct tag *ptag, *tag;
+	struct obj *ptag, *tag;
 
-	ptag = tid_lookup(ptid);
+	ptag = obj_lookup(ptid, OBJ_TYPE_TAG);
 	if (ptag == NULL)
 		return (-1);
 
@@ -179,20 +202,17 @@ bd_tag_derive(int ptid, u_long align, u_
 	    maxsegsz, datarate, flags);
 	if (tag == NULL)
 		return (-1);
-	while (ptag != NULL) {
-		ptag->refcnt++;
-		ptag = ptag->ptag;
-	}
-	return (tag->tid);
+	ptag->refcnt++;
+	return (tag->oid);
 }
 
 int
 bd_tag_destroy(int tid)
 {
 	struct proto_ioc_busdma ioc;
-	struct tag *ptag, *tag;
+	struct obj *ptag, *tag;
 
-	tag = tid_lookup(tid);
+	tag = obj_lookup(tid, OBJ_TYPE_TAG);
 	if (tag == NULL)
 		return (errno);
 	if (tag->refcnt > 1)
@@ -204,15 +224,62 @@ bd_tag_destroy(int tid)
 	if (ioctl(tag->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
 		return (errno);
 
-	ptag = tag->ptag;
-	if (ptag == NULL)
+	if (tag->parent != NULL)
+		tag->parent->refcnt--;
+	else
 		close(tag->fd);
-	else {
-		do {
-			ptag->refcnt--;
-			ptag = ptag->ptag;
-		} while (ptag != NULL);
+	obj_free(tag);
+	return (0);
+}
+
+int
+bd_mem_alloc(int tid, u_int flags)
+{
+	struct proto_ioc_busdma ioc;
+	struct obj *md, *tag;
+
+	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.mem.tag = tag->key;
+	ioc.u.mem.flags = flags;
+	if (ioctl(tag->fd, PROTO_IOC_BUSDMA, &ioc) == -1) {
+		obj_free(md);
+		return (-1);
 	}
-	tag_free(tag);
+
+	md->refcnt = 1;
+	md->fd = tag->fd;
+	md->parent = tag;
+	tag->refcnt++;
+	md->key = ioc.result;
+	return (md->oid);
+}
+
+int
+bd_mem_free(int mdid)
+{
+	struct proto_ioc_busdma ioc;
+	struct obj *md;
+
+	md = obj_lookup(mdid, OBJ_TYPE_MD);
+	if (md == NULL)
+		return (errno);
+
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.request = PROTO_IOC_BUSDMA_MEM_FREE;
+	ioc.key = md->key;
+	if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
+		return (errno);
+
+	md->parent->refcnt--;
+	obj_free(md);
 	return (0);
 }

Modified: head/tools/bus_space/busdma.h
==============================================================================
--- head/tools/bus_space/busdma.h	Mon Jun  8 03:01:19 2015	(r284145)
+++ head/tools/bus_space/busdma.h	Mon Jun  8 03:23:20 2015	(r284146)
@@ -37,4 +37,7 @@ int	bd_tag_derive(int tid, u_long align,
 	    u_int flags);
 int	bd_tag_destroy(int tid);
 
+int	bd_mem_alloc(int tid, u_int flags);
+int	bd_mem_free(int mdid);
+
 #endif /* _TOOLS_BUS_DMA_H_ */



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