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

Reply via email to