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_ */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to