Add busdma_mem_alloc & busdma_mem_free.
This commit is contained in:
parent
5b53111b63
commit
6f769b730c
@ -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));
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ int bus_space_write_4(int rid, long ofs, uint32_t val);
|
||||
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, bus_addr_t align, bus_addr_t bndry,
|
||||
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_ */
|
||||
|
@ -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, PyObject *args)
|
||||
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, PyObject *args)
|
||||
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 }
|
||||
};
|
||||
|
||||
|
@ -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_long align, u_long bndry,
|
||||
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 align, u_long bndry, u_long maxaddr,
|
||||
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_long bndry, u_long maxaddr,
|
||||
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);
|
||||
}
|
||||
tag_free(tag);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -37,4 +37,7 @@ int bd_tag_derive(int tid, u_long align, u_long bndry, u_long maxaddr,
|
||||
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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user