2 * Copyright (c) 2014, 2015 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
36 bus_read_1(PyObject *self, PyObject *args)
42 if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
44 if (!bs_read(rid, ofs, &val, sizeof(val))) {
45 PyErr_SetString(PyExc_IOError, strerror(errno));
48 return (Py_BuildValue("B", val));
52 bus_read_2(PyObject *self, PyObject *args)
58 if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
60 if (!bs_read(rid, ofs, &val, sizeof(val))) {
61 PyErr_SetString(PyExc_IOError, strerror(errno));
64 return (Py_BuildValue("H", val));
68 bus_read_4(PyObject *self, PyObject *args)
74 if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
76 if (!bs_read(rid, ofs, &val, sizeof(val))) {
77 PyErr_SetString(PyExc_IOError, strerror(errno));
80 return (Py_BuildValue("I", val));
84 bus_write_1(PyObject *self, PyObject *args)
90 if (!PyArg_ParseTuple(args, "ilB", &rid, &ofs, &val))
92 if (!bs_write(rid, ofs, &val, sizeof(val))) {
93 PyErr_SetString(PyExc_IOError, strerror(errno));
100 bus_write_2(PyObject *self, PyObject *args)
106 if (!PyArg_ParseTuple(args, "ilH", &rid, &ofs, &val))
108 if (!bs_write(rid, ofs, &val, sizeof(val))) {
109 PyErr_SetString(PyExc_IOError, strerror(errno));
116 bus_write_4(PyObject *self, PyObject *args)
122 if (!PyArg_ParseTuple(args, "ilI", &rid, &ofs, &val))
124 if (!bs_write(rid, ofs, &val, sizeof(val))) {
125 PyErr_SetString(PyExc_IOError, strerror(errno));
132 bus_map(PyObject *self, PyObject *args)
134 char *dev, *resource;
137 if (!PyArg_ParseTuple(args, "ss", &dev, &resource))
139 rid = bs_map(dev, resource);
141 PyErr_SetString(PyExc_IOError, strerror(errno));
144 return (Py_BuildValue("i", rid));
148 bus_unmap(PyObject *self, PyObject *args)
152 if (!PyArg_ParseTuple(args, "i", &rid))
154 if (!bs_unmap(rid)) {
155 PyErr_SetString(PyExc_IOError, strerror(errno));
162 bus_subregion(PyObject *self, PyObject *args)
167 if (!PyArg_ParseTuple(args, "ill", &rid0, &ofs, &sz))
169 rid = bs_subregion(rid0, ofs, sz);
171 PyErr_SetString(PyExc_IOError, strerror(errno));
174 return (Py_BuildValue("i", rid));
178 busdma_tag_create(PyObject *self, PyObject *args)
181 u_long align, bndry, maxaddr, maxsz, maxsegsz;
182 u_int nsegs, datarate, flags;
185 if (!PyArg_ParseTuple(args, "skkkkIkII", &dev, &align, &bndry,
186 &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
188 tid = bd_tag_create(dev, align, bndry, maxaddr, maxsz, nsegs,
189 maxsegsz, datarate, flags);
191 PyErr_SetString(PyExc_IOError, strerror(errno));
194 return (Py_BuildValue("i", tid));
198 busdma_tag_derive(PyObject *self, PyObject *args)
200 u_long align, bndry, maxaddr, maxsz, maxsegsz;
201 u_int nsegs, datarate, flags;
204 if (!PyArg_ParseTuple(args, "ikkkkIkII", &ptid, &align, &bndry,
205 &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
207 tid = bd_tag_derive(ptid, align, bndry, maxaddr, maxsz, nsegs,
208 maxsegsz, datarate, flags);
210 PyErr_SetString(PyExc_IOError, strerror(errno));
213 return (Py_BuildValue("i", tid));
217 busdma_tag_destroy(PyObject *self, PyObject *args)
221 if (!PyArg_ParseTuple(args, "i", &tid))
223 error = bd_tag_destroy(tid);
225 PyErr_SetString(PyExc_IOError, strerror(error));
232 busdma_md_create(PyObject *self, PyObject *args)
235 int error, mdid, tid;
237 if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
239 mdid = bd_md_create(tid, flags);
241 PyErr_SetString(PyExc_IOError, strerror(errno));
244 return (Py_BuildValue("i", mdid));
248 busdma_md_destroy(PyObject *self, PyObject *args)
252 if (!PyArg_ParseTuple(args, "i", &mdid))
254 error = bd_md_destroy(mdid);
256 PyErr_SetString(PyExc_IOError, strerror(error));
263 busdma_md_load(PyObject *self, PyObject *args)
270 if (!PyArg_ParseTuple(args, "iwkI", &mdid, &buf, &len, &flags))
272 error = bd_md_load(mdid, buf, len, flags);
274 PyErr_SetString(PyExc_IOError, strerror(error));
281 busdma_md_unload(PyObject *self, PyObject *args)
285 if (!PyArg_ParseTuple(args, "i", &mdid))
287 error = bd_md_unload(mdid);
289 PyErr_SetString(PyExc_IOError, strerror(error));
296 busdma_mem_alloc(PyObject *self, PyObject *args)
301 if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
303 mdid = bd_mem_alloc(tid, flags);
305 PyErr_SetString(PyExc_IOError, strerror(errno));
308 return (Py_BuildValue("i", mdid));
312 busdma_mem_free(PyObject *self, PyObject *args)
316 if (!PyArg_ParseTuple(args, "i", &mdid))
318 error = bd_mem_free(mdid);
320 PyErr_SetString(PyExc_IOError, strerror(error));
327 busdma_md_first_seg(PyObject *self, PyObject *args)
329 int error, mdid, sid, what;
331 if (!PyArg_ParseTuple(args, "ii", &mdid, &what))
333 sid = bd_md_first_seg(mdid, what);
336 return (Py_BuildValue("i", sid));
340 busdma_md_next_seg(PyObject *self, PyObject *args)
342 int error, mdid, sid;
344 if (!PyArg_ParseTuple(args, "ii", &mdid, &sid))
346 sid = bd_md_next_seg(mdid, sid);
349 return (Py_BuildValue("i", sid));
353 busdma_seg_get_addr(PyObject *self, PyObject *args)
358 if (!PyArg_ParseTuple(args, "i", &sid))
360 error = bd_seg_get_addr(sid, &addr);
362 PyErr_SetString(PyExc_IOError, strerror(error));
365 return (Py_BuildValue("k", addr));
369 busdma_seg_get_size(PyObject *self, PyObject *args)
374 if (!PyArg_ParseTuple(args, "i", &sid))
376 error = bd_seg_get_size(sid, &size);
378 PyErr_SetString(PyExc_IOError, strerror(error));
381 return (Py_BuildValue("k", size));
385 busdma_sync(PyObject *self, PyObject *args)
389 if (!PyArg_ParseTuple(args, "ii", &mdid, &op))
391 error = bd_sync(mdid, op, 0UL, ~0UL);
393 PyErr_SetString(PyExc_IOError, strerror(error));
400 busdma_sync_range(PyObject *self, PyObject *args)
405 if (!PyArg_ParseTuple(args, "iikk", &mdid, &op, &ofs, &len))
407 error = bd_sync(mdid, op, ofs, len);
409 PyErr_SetString(PyExc_IOError, strerror(error));
415 static PyMethodDef bus_methods[] = {
416 { "read_1", bus_read_1, METH_VARARGS, "Read a 1-byte data item." },
417 { "read_2", bus_read_2, METH_VARARGS, "Read a 2-byte data item." },
418 { "read_4", bus_read_4, METH_VARARGS, "Read a 4-byte data item." },
420 { "write_1", bus_write_1, METH_VARARGS, "Write a 1-byte data item." },
421 { "write_2", bus_write_2, METH_VARARGS, "Write a 2-byte data item." },
422 { "write_4", bus_write_4, METH_VARARGS, "Write a 4-byte data item." },
424 { "map", bus_map, METH_VARARGS,
425 "Return a resource ID for a device file created by proto(4)" },
426 { "unmap", bus_unmap, METH_VARARGS,
427 "Free a resource ID" },
428 { "subregion", bus_subregion, METH_VARARGS,
429 "Return a resource ID for a subregion of another resource ID" },
431 { NULL, NULL, 0, NULL }
434 static PyMethodDef busdma_methods[] = {
435 { "tag_create", busdma_tag_create, METH_VARARGS,
436 "Create a root tag." },
437 { "tag_derive", busdma_tag_derive, METH_VARARGS,
438 "Derive a child tag." },
439 { "tag_destroy", busdma_tag_destroy, METH_VARARGS,
442 { "md_create", busdma_md_create, METH_VARARGS,
443 "Create a new and empty memory descriptor." },
444 { "md_destroy", busdma_md_destroy, METH_VARARGS,
445 "Destroy a previously created memory descriptor." },
446 { "md_load", busdma_md_load, METH_VARARGS,
447 "Load a buffer into a memory descriptor." },
448 { "md_unload", busdma_md_unload, METH_VARARGS,
449 "Unload a memory descriptor." },
451 { "mem_alloc", busdma_mem_alloc, METH_VARARGS,
452 "Allocate memory according to the DMA constraints." },
453 { "mem_free", busdma_mem_free, METH_VARARGS,
454 "Free allocated memory." },
456 { "md_first_seg", busdma_md_first_seg, METH_VARARGS,
457 "Return first segment in one of the segment lists." },
458 { "md_next_seg", busdma_md_next_seg, METH_VARARGS,
459 "Return next segment in the segment list." },
460 { "seg_get_addr", busdma_seg_get_addr, METH_VARARGS,
461 "Return the address of the segment." },
462 { "seg_get_size", busdma_seg_get_size, METH_VARARGS,
463 "Return the size of the segment." },
465 { "sync", busdma_sync, METH_VARARGS,
466 "Make the entire memory descriptor coherent WRT to DMA." },
467 { "sync_range", busdma_sync_range, METH_VARARGS,
468 "Make part of the memory descriptor coherent WRT to DMA." },
470 { NULL, NULL, 0, NULL }
476 PyObject *bus, *busdma;
478 bus = Py_InitModule("bus", bus_methods);
481 busdma = Py_InitModule("busdma", busdma_methods);
484 PyModule_AddObject(bus, "dma", busdma);
486 PyModule_AddObject(busdma, "MD_BUS_SPACE", Py_BuildValue("i", 0));
487 PyModule_AddObject(busdma, "MD_PHYS_SPACE", Py_BuildValue("i", 1));
488 PyModule_AddObject(busdma, "MD_VIRT_SPACE", Py_BuildValue("i", 2));
490 PyModule_AddObject(busdma, "SYNC_PREREAD", Py_BuildValue("i", 1));
491 PyModule_AddObject(busdma, "SYNC_POSTREAD", Py_BuildValue("i", 2));
492 PyModule_AddObject(busdma, "SYNC_PREWRITE", Py_BuildValue("i", 4));
493 PyModule_AddObject(busdma, "SYNC_POSTWRITE", Py_BuildValue("i", 8));