Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Jul 2015 05:47:56 +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: r285075 - in head/tools/bus_space: . C Python
Message-ID:  <201507030547.t635luev074933@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Fri Jul  3 05:47:56 2015
New Revision: 285075
URL: https://svnweb.freebsd.org/changeset/base/285075

Log:
  Implement busdma_md_unload() and busdma_sync().
  
  While here:
  1.  have the Python bindings contain constants for the space
      identifiers and the sync operation.
  2.  change the segment iterators to return None when done,
      not ENXIO.

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 05:44:58 2015	(r285074)
+++ head/tools/bus_space/C/lang.c	Fri Jul  3 05:47:56 2015	(r285075)
@@ -182,6 +182,13 @@ busdma_md_load(busdma_md_t md, void *buf
 	return (bd_md_load(md, buf, len, flags));
 }
 
+int
+busdma_md_unload(busdma_md_t md)
+{
+
+	return (bd_md_unload(md));
+}
+
 busdma_seg_t
 busdma_md_first_seg(busdma_md_t md, int space)
 {
@@ -218,3 +225,10 @@ busdma_seg_get_size(busdma_seg_t seg)
 	error = bd_seg_get_size(seg, &size);
 	return ((error) ? ~0UL : size);
 }
+
+int
+busdma_sync(busdma_md_t md, int op, bus_addr_t base, bus_size_t size)
+{
+
+	return (bd_sync(md, op, base, size));
+}

Modified: head/tools/bus_space/C/libbus.h
==============================================================================
--- head/tools/bus_space/C/libbus.h	Fri Jul  3 05:44:58 2015	(r285074)
+++ head/tools/bus_space/C/libbus.h	Fri Jul  3 05:47:56 2015	(r285075)
@@ -61,6 +61,7 @@ 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);
+int	busdma_md_unload(busdma_md_t md);
 
 #define	BUSDMA_MD_BUS_SPACE	0
 #define	BUSDMA_MD_PHYS_SPACE	1
@@ -72,4 +73,11 @@ int	busdma_md_next_seg(busdma_md_t, busd
 bus_addr_t	busdma_seg_get_addr(busdma_seg_t seg);
 bus_size_t	busdma_seg_get_size(busdma_seg_t seg);
 
+#define	BUSDMA_SYNC_PREREAD     1
+#define	BUSDMA_SYNC_POSTREAD    2
+#define	BUSDMA_SYNC_PREWRITE    4
+#define	BUSDMA_SYNC_POSTWRITE   8
+
+int	busdma_sync(busdma_md_t md, int op, bus_addr_t, bus_size_t);
+
 #endif /* _LIBBUS_SPACE_H_ */

Modified: head/tools/bus_space/Python/lang.c
==============================================================================
--- head/tools/bus_space/Python/lang.c	Fri Jul  3 05:44:58 2015	(r285074)
+++ head/tools/bus_space/Python/lang.c	Fri Jul  3 05:47:56 2015	(r285075)
@@ -278,6 +278,21 @@ busdma_md_load(PyObject *self, PyObject 
 }
 
 static PyObject *
+busdma_md_unload(PyObject *self, PyObject *args)
+{
+	int error, mdid;
+
+	if (!PyArg_ParseTuple(args, "i", &mdid))
+		return (NULL);
+	error = bd_md_unload(mdid);
+	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;
@@ -316,10 +331,8 @@ busdma_md_first_seg(PyObject *self, PyOb
 	if (!PyArg_ParseTuple(args, "ii", &mdid, &what))
 		return (NULL);
 	sid = bd_md_first_seg(mdid, what);
-	if (sid == -1) {
-		PyErr_SetString(PyExc_IOError, strerror(errno));
-		return (NULL);
-	}
+	if (sid == -1)
+		Py_RETURN_NONE;
 	return (Py_BuildValue("i", sid));
 }
 
@@ -331,10 +344,8 @@ busdma_md_next_seg(PyObject *self, PyObj
 	if (!PyArg_ParseTuple(args, "ii", &mdid, &sid))
 		return (NULL);
 	sid = bd_md_next_seg(mdid, sid);
-	if (sid == -1) {
-		PyErr_SetString(PyExc_IOError, strerror(errno));
-		return (NULL);
-	}
+	if (sid == -1)
+		Py_RETURN_NONE;
 	return (Py_BuildValue("i", sid));
 }
 
@@ -370,6 +381,22 @@ busdma_seg_get_size(PyObject *self, PyOb
 	return (Py_BuildValue("k", size));
 }
 
+static PyObject *
+busdma_sync(PyObject *self, PyObject *args)
+{
+	u_long base, size;
+	int error, mdid, op;
+
+	if (!PyArg_ParseTuple(args, "iikk", &mdid, &op, &base, &size))
+		return (NULL);
+	error = bd_sync(mdid, op, base, size);
+	if (error) {
+		PyErr_SetString(PyExc_IOError, strerror(error));
+		return (NULL);
+	}
+	Py_RETURN_NONE;
+}
+
 static PyMethodDef bus_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." },
@@ -403,6 +430,8 @@ static PyMethodDef busdma_methods[] = {
 	"Destroy a previously created memory descriptor." },
     { "md_load", busdma_md_load, METH_VARARGS,
 	"Load a buffer into a memory descriptor." },
+    { "md_unload", busdma_md_unload, METH_VARARGS,
+	"Unload a memory descriptor." },
 
     { "mem_alloc", busdma_mem_alloc, METH_VARARGS,
 	"Allocate memory according to the DMA constraints." },
@@ -417,13 +446,32 @@ static PyMethodDef busdma_methods[] = {
 	"Return the address of the segment." },
     { "seg_get_size", busdma_seg_get_size, METH_VARARGS,
 	"Return the size of the segment." },
+
+    { "sync", busdma_sync, METH_VARARGS,
+	"Keep memory/caches coherent WRT to DMA." },
+
     { NULL, NULL, 0, NULL }
 };
 
 PyMODINIT_FUNC
 initbus(void)
 {
+	PyObject *bus, *busdma;
 
-	Py_InitModule("bus", bus_methods);
-	Py_InitModule("busdma", busdma_methods);
+	bus = Py_InitModule("bus", bus_methods);
+	if (bus == NULL)
+		return;
+	busdma = Py_InitModule("busdma", busdma_methods);
+	if (busdma == NULL)
+		return;
+	PyModule_AddObject(bus, "dma", busdma);
+
+	PyModule_AddObject(busdma, "MD_BUS_SPACE", Py_BuildValue("i", 0));
+	PyModule_AddObject(busdma, "MD_PHYS_SPACE", Py_BuildValue("i", 1));
+	PyModule_AddObject(busdma, "MD_VIRT_SPACE", Py_BuildValue("i", 2));
+
+	PyModule_AddObject(busdma, "SYNC_PREREAD", Py_BuildValue("i", 1));
+	PyModule_AddObject(busdma, "SYNC_POSTREAD", Py_BuildValue("i", 2));
+	PyModule_AddObject(busdma, "SYNC_PREWRITE", Py_BuildValue("i", 4));
+	PyModule_AddObject(busdma, "SYNC_POSTWRITE", Py_BuildValue("i", 8));
 }

Modified: head/tools/bus_space/busdma.c
==============================================================================
--- head/tools/bus_space/busdma.c	Fri Jul  3 05:44:58 2015	(r285074)
+++ head/tools/bus_space/busdma.c	Fri Jul  3 05:47:56 2015	(r285075)
@@ -262,6 +262,20 @@ bd_md_add_seg(struct obj *md, int type, 
 	return (0);
 }
 
+static int
+bd_md_del_segs(struct obj *md, int type, int unmap)
+{
+	struct obj *seg, *seg0;
+
+	for (seg = md->u.md.seg[type]; seg != NULL; seg = seg0) {
+		if (unmap)
+			munmap((void *)seg->u.seg.address, seg->u.seg.size);
+		seg0 = seg->u.seg.next;
+		obj_free(seg);
+	}
+	return (0);
+}
+
 int
 bd_md_create(int tid, u_int flags)
 {
@@ -345,6 +359,29 @@ bd_md_load(int mdid, void *buf, u_long l
 }
 
 int
+bd_md_unload(int mdid)
+{
+	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_UNLOAD;
+	ioc.key = md->key;
+	if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
+		return (errno);
+
+	bd_md_del_segs(md, BUSDMA_MD_VIRT, 0);
+	bd_md_del_segs(md, BUSDMA_MD_PHYS, 0);
+	bd_md_del_segs(md, BUSDMA_MD_BUS, 0);
+	return (0);
+}
+
+int
 bd_mem_alloc(int tid, u_int flags)
 {
 	struct proto_ioc_busdma ioc;
@@ -409,31 +446,21 @@ int
 bd_mem_free(int mdid)
 {
 	struct proto_ioc_busdma ioc;
-	struct obj *md, *seg, *seg0;
+	struct obj *md;
 
 	md = obj_lookup(mdid, OBJ_TYPE_MD);
 	if (md == NULL)
 		return (errno);
 
-	for (seg = md->u.md.seg[BUSDMA_MD_VIRT]; seg != NULL; seg = seg0) {
-		munmap((void *)seg->u.seg.address, seg->u.seg.size);
-		seg0 = seg->u.seg.next;
-		obj_free(seg);
-	}
-	for (seg = md->u.md.seg[BUSDMA_MD_PHYS]; seg != NULL; seg = seg0) {
-		seg0 = seg->u.seg.next;
-		obj_free(seg);
-	}
-	for (seg = md->u.md.seg[BUSDMA_MD_BUS]; seg != NULL; seg = seg0) {
-		seg0 = seg->u.seg.next;
-		obj_free(seg);
-	}
 	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);
 
+	bd_md_del_segs(md, BUSDMA_MD_VIRT, 1);
+	bd_md_del_segs(md, BUSDMA_MD_PHYS, 0);
+	bd_md_del_segs(md, BUSDMA_MD_BUS, 0);
 	md->parent->refcnt--;
 	obj_free(md);
 	return (0);
@@ -509,3 +536,25 @@ bd_seg_get_size(int sid, u_long *size_p)
 	*size_p = seg->u.seg.size;
 	return (0);
 }
+
+int
+bd_sync(int mdid, u_int op, u_long base, u_long size)
+{
+	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_SYNC;
+	ioc.key = md->key;
+	ioc.u.sync.op = op;
+	ioc.u.sync.base = base;
+	ioc.u.sync.size = size;
+	if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
+		return (errno);
+
+	return (0);
+}

Modified: head/tools/bus_space/busdma.h
==============================================================================
--- head/tools/bus_space/busdma.h	Fri Jul  3 05:44:58 2015	(r285074)
+++ head/tools/bus_space/busdma.h	Fri Jul  3 05:47:56 2015	(r285075)
@@ -40,6 +40,7 @@ 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_md_unload(int mdid);
 
 int	bd_mem_alloc(int tid, u_int flags);
 int	bd_mem_free(int mdid);
@@ -50,4 +51,6 @@ int	bd_md_next_seg(int mdid, int sid);
 int	bd_seg_get_addr(int sid, u_long *);
 int	bd_seg_get_size(int sid, u_long *);
 
+int	bd_sync(int mdid, u_int op, u_long base, u_long size);
+
 #endif /* _TOOLS_BUS_DMA_H_ */



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