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>