svn commit: r285075 - in head/tools/bus_space: . C Python
Marcel Moolenaar
marcel at FreeBSD.org
Fri Jul 3 05:47:58 UTC 2015
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_ */
More information about the svn-src-head
mailing list