Add busdma_md_create, busdma_md_destroy and busdma_md_load.
This commit is contained in:
parent
e08d13cf83
commit
22900685fd
@ -156,6 +156,32 @@ busdma_mem_free(busdma_md_t md)
|
||||
return (bd_mem_free(md));
|
||||
}
|
||||
|
||||
int
|
||||
busdma_md_create(busdma_tag_t tag, u_int flags, busdma_md_t *out_p)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = bd_md_create(tag, flags);
|
||||
if (res == -1)
|
||||
return (errno);
|
||||
*out_p = res;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
busdma_md_destroy(busdma_md_t md)
|
||||
{
|
||||
|
||||
return (bd_md_destroy(md));
|
||||
}
|
||||
|
||||
int
|
||||
busdma_md_load(busdma_md_t md, void *buf, size_t len, u_int flags)
|
||||
{
|
||||
|
||||
return (bd_md_load(md, buf, len, flags));
|
||||
}
|
||||
|
||||
busdma_seg_t
|
||||
busdma_md_first_seg(busdma_md_t md, int space)
|
||||
{
|
||||
|
@ -58,6 +58,10 @@ 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);
|
||||
|
||||
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);
|
||||
|
||||
#define BUSDMA_MD_BUS_SPACE 0
|
||||
#define BUSDMA_MD_PHYS_SPACE 1
|
||||
#define BUSDMA_MD_VIRT_SPACE 2
|
||||
|
@ -228,6 +228,55 @@ busdma_tag_destroy(PyObject *self, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
busdma_md_create(PyObject *self, PyObject *args)
|
||||
{
|
||||
u_int flags;
|
||||
int error, mdid, tid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
|
||||
return (NULL);
|
||||
mdid = bd_md_create(tid, flags);
|
||||
if (mdid == -1) {
|
||||
PyErr_SetString(PyExc_IOError, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
return (Py_BuildValue("i", mdid));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
busdma_md_destroy(PyObject *self, PyObject *args)
|
||||
{
|
||||
int error, mdid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i", &mdid))
|
||||
return (NULL);
|
||||
error = bd_md_destroy(mdid);
|
||||
if (error) {
|
||||
PyErr_SetString(PyExc_IOError, strerror(error));
|
||||
return (NULL);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
busdma_md_load(PyObject *self, PyObject *args)
|
||||
{
|
||||
void *buf;
|
||||
u_long len;
|
||||
u_int flags;
|
||||
int error, mdid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iwkI", &mdid, &buf, &len, &flags))
|
||||
return (NULL);
|
||||
error = bd_md_load(mdid, buf, len, flags);
|
||||
if (error) {
|
||||
PyErr_SetString(PyExc_IOError, strerror(error));
|
||||
return (NULL);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
busdma_mem_alloc(PyObject *self, PyObject *args)
|
||||
{
|
||||
@ -347,6 +396,14 @@ static PyMethodDef busdma_methods[] = {
|
||||
"Derive a child tag." },
|
||||
{ "tag_destroy", busdma_tag_destroy, METH_VARARGS,
|
||||
"Destroy a tag." },
|
||||
|
||||
{ "md_create", busdma_md_create, METH_VARARGS,
|
||||
"Create a new and empty memory descriptor." },
|
||||
{ "md_destroy", busdma_md_destroy, METH_VARARGS,
|
||||
"Destroy a previously created memory descriptor." },
|
||||
{ "md_load", busdma_md_load, METH_VARARGS,
|
||||
"Load a buffer into a memory descriptor." },
|
||||
|
||||
{ "mem_alloc", busdma_mem_alloc, METH_VARARGS,
|
||||
"Allocate memory according to the DMA constraints." },
|
||||
{ "mem_free", busdma_mem_free, METH_VARARGS,
|
||||
|
@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -137,7 +138,7 @@ obj_lookup(int oid, u_int type)
|
||||
return (obj);
|
||||
}
|
||||
|
||||
struct obj *
|
||||
static 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)
|
||||
@ -243,12 +244,113 @@ bd_tag_destroy(int tid)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bd_md_add_seg(struct obj *md, int type, u_long addr, u_long size)
|
||||
{
|
||||
struct obj *seg;
|
||||
|
||||
seg = obj_alloc(OBJ_TYPE_SEG);
|
||||
if (seg == NULL)
|
||||
return (errno);
|
||||
seg->refcnt = 1;
|
||||
seg->parent = md;
|
||||
seg->u.seg.address = addr;
|
||||
seg->u.seg.size = size;
|
||||
|
||||
md->u.md.seg[type] = seg;
|
||||
md->u.md.nsegs[type] = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bd_md_create(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_MD_CREATE;
|
||||
ioc.u.md.tag = tag->key;
|
||||
ioc.u.md.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_md_destroy(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_MD_DESTROY;
|
||||
ioc.key = md->key;
|
||||
if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
|
||||
return (errno);
|
||||
|
||||
md->parent->refcnt--;
|
||||
obj_free(md);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bd_md_load(int mdid, void *buf, u_long len, u_int flags)
|
||||
{
|
||||
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_LOAD;
|
||||
ioc.key = md->key;
|
||||
ioc.u.md.flags = flags;
|
||||
ioc.u.md.virt_addr = (uintptr_t)buf;
|
||||
ioc.u.md.virt_size = len;
|
||||
if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1)
|
||||
return (errno);
|
||||
|
||||
printf("XXX: %s: phys(%d, %#lx), bus(%d, %#lx)\n", __func__,
|
||||
ioc.u.md.phys_nsegs, ioc.u.md.phys_addr,
|
||||
ioc.u.md.bus_nsegs, ioc.u.md.bus_addr);
|
||||
|
||||
error = bd_md_add_seg(md, BUSDMA_MD_VIRT, ioc.u.md.virt_addr, len);
|
||||
error = bd_md_add_seg(md, BUSDMA_MD_PHYS, ioc.u.md.phys_addr, len);
|
||||
error = bd_md_add_seg(md, BUSDMA_MD_BUS, ioc.u.md.bus_addr, len);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
bd_mem_alloc(int tid, u_int flags)
|
||||
{
|
||||
struct proto_ioc_busdma ioc;
|
||||
struct obj *md, *tag;
|
||||
struct obj *bseg, *pseg, *vseg;
|
||||
uintptr_t addr;
|
||||
int error;
|
||||
|
||||
tag = obj_lookup(tid, OBJ_TYPE_TAG);
|
||||
if (tag == NULL)
|
||||
@ -260,8 +362,8 @@ bd_mem_alloc(int tid, u_int flags)
|
||||
|
||||
memset(&ioc, 0, sizeof(ioc));
|
||||
ioc.request = PROTO_IOC_BUSDMA_MEM_ALLOC;
|
||||
ioc.u.mem.tag = tag->key;
|
||||
ioc.u.mem.flags = flags;
|
||||
ioc.u.md.tag = tag->key;
|
||||
ioc.u.md.flags = flags;
|
||||
if (ioctl(tag->fd, PROTO_IOC_BUSDMA, &ioc) == -1) {
|
||||
obj_free(md);
|
||||
return (-1);
|
||||
@ -273,55 +375,27 @@ bd_mem_alloc(int tid, u_int flags)
|
||||
tag->refcnt++;
|
||||
md->key = ioc.result;
|
||||
|
||||
printf("XXX: %s: phys(%d, %#lx), bus(%d, %#lx)\n", __func__,
|
||||
ioc.u.md.phys_nsegs, ioc.u.md.phys_addr,
|
||||
ioc.u.md.bus_nsegs, ioc.u.md.bus_addr);
|
||||
|
||||
/* XXX we need to support multiple segments */
|
||||
assert(ioc.u.mem.phys_nsegs == 1);
|
||||
assert(ioc.u.mem.bus_nsegs == 1);
|
||||
assert(ioc.u.md.phys_nsegs == 1);
|
||||
assert(ioc.u.md.bus_nsegs == 1);
|
||||
error = bd_md_add_seg(md, BUSDMA_MD_PHYS, ioc.u.md.phys_addr,
|
||||
tag->u.tag.maxsz);
|
||||
error = bd_md_add_seg(md, BUSDMA_MD_BUS, ioc.u.md.bus_addr,
|
||||
tag->u.tag.maxsz);
|
||||
|
||||
bseg = pseg = vseg = NULL;
|
||||
|
||||
bseg = obj_alloc(OBJ_TYPE_SEG);
|
||||
if (bseg == NULL)
|
||||
addr = (uintptr_t)mmap(NULL, tag->u.tag.maxsz, PROT_READ | PROT_WRITE,
|
||||
MAP_NOCORE | MAP_SHARED, md->fd, ioc.u.md.phys_addr);
|
||||
if (addr == (uintptr_t)MAP_FAILED)
|
||||
goto fail;
|
||||
bseg->refcnt = 1;
|
||||
bseg->parent = md;
|
||||
bseg->u.seg.address = ioc.u.mem.bus_addr;
|
||||
bseg->u.seg.size = tag->u.tag.maxsz;
|
||||
md->u.md.seg[BUSDMA_MD_BUS] = bseg;
|
||||
md->u.md.nsegs[BUSDMA_MD_BUS] = ioc.u.mem.bus_nsegs;
|
||||
|
||||
pseg = obj_alloc(OBJ_TYPE_SEG);
|
||||
if (pseg == NULL)
|
||||
goto fail;
|
||||
pseg->refcnt = 1;
|
||||
pseg->parent = md;
|
||||
pseg->u.seg.address = ioc.u.mem.phys_addr;
|
||||
pseg->u.seg.size = tag->u.tag.maxsz;
|
||||
md->u.md.seg[BUSDMA_MD_PHYS] = pseg;
|
||||
md->u.md.nsegs[BUSDMA_MD_PHYS] = ioc.u.mem.phys_nsegs;
|
||||
|
||||
vseg = obj_alloc(OBJ_TYPE_SEG);
|
||||
if (vseg == NULL)
|
||||
goto fail;
|
||||
vseg->refcnt = 1;
|
||||
vseg->parent = md;
|
||||
vseg->u.seg.address = (uintptr_t)mmap(NULL, pseg->u.seg.size,
|
||||
PROT_READ | PROT_WRITE, MAP_NOCORE | MAP_SHARED, md->fd,
|
||||
pseg->u.seg.address);
|
||||
if (vseg->u.seg.address == (uintptr_t)MAP_FAILED)
|
||||
goto fail;
|
||||
vseg->u.seg.size = pseg->u.seg.size;
|
||||
md->u.md.seg[BUSDMA_MD_VIRT] = vseg;
|
||||
md->u.md.nsegs[BUSDMA_MD_VIRT] = 1;
|
||||
error = bd_md_add_seg(md, BUSDMA_MD_VIRT, addr, tag->u.tag.maxsz);
|
||||
|
||||
return (md->oid);
|
||||
|
||||
fail:
|
||||
if (vseg != NULL)
|
||||
obj_free(vseg);
|
||||
if (pseg != NULL)
|
||||
obj_free(pseg);
|
||||
if (bseg != NULL)
|
||||
obj_free(bseg);
|
||||
memset(&ioc, 0, sizeof(ioc));
|
||||
ioc.request = PROTO_IOC_BUSDMA_MEM_FREE;
|
||||
ioc.key = md->key;
|
||||
|
@ -37,6 +37,10 @@ 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_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_mem_alloc(int tid, u_int flags);
|
||||
int bd_mem_free(int mdid);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user