lang.c revision 285071
1265056Smarcel/*- 2284253Smarcel * Copyright (c) 2014, 2015 Marcel Moolenaar 3265056Smarcel * All rights reserved. 4265056Smarcel * 5265056Smarcel * Redistribution and use in source and binary forms, with or without 6265056Smarcel * modification, are permitted provided that the following conditions 7265056Smarcel * are met: 8265056Smarcel * 9265056Smarcel * 1. Redistributions of source code must retain the above copyright 10265056Smarcel * notice, this list of conditions and the following disclaimer. 11265056Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12265056Smarcel * notice, this list of conditions and the following disclaimer in the 13265056Smarcel * documentation and/or other materials provided with the distribution. 14265056Smarcel * 15265056Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16265056Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17265056Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18265056Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19265056Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20265056Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21265056Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22265056Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23265056Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24265056Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25265056Smarcel */ 26265056Smarcel 27265056Smarcel#include <sys/cdefs.h> 28265056Smarcel__FBSDID("$FreeBSD: head/tools/bus_space/Python/lang.c 285071 2015-07-03 02:06:47Z marcel $"); 29265056Smarcel 30265056Smarcel#include <Python.h> 31265056Smarcel 32284228Smarcel#include "bus.h" 33284080Smarcel#include "busdma.h" 34265056Smarcel 35265056Smarcelstatic PyObject * 36265056Smarcelbus_read_1(PyObject *self, PyObject *args) 37265056Smarcel{ 38265056Smarcel long ofs; 39265056Smarcel int rid; 40265056Smarcel uint8_t val; 41265056Smarcel 42265056Smarcel if (!PyArg_ParseTuple(args, "il", &rid, &ofs)) 43265056Smarcel return (NULL); 44265056Smarcel if (!bs_read(rid, ofs, &val, sizeof(val))) { 45265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 46265056Smarcel return (NULL); 47265056Smarcel } 48265056Smarcel return (Py_BuildValue("B", val)); 49265056Smarcel} 50265056Smarcel 51265056Smarcelstatic PyObject * 52265056Smarcelbus_read_2(PyObject *self, PyObject *args) 53265056Smarcel{ 54265056Smarcel long ofs; 55265056Smarcel int rid; 56265056Smarcel uint16_t val; 57265056Smarcel 58265056Smarcel if (!PyArg_ParseTuple(args, "il", &rid, &ofs)) 59265056Smarcel return (NULL); 60265056Smarcel if (!bs_read(rid, ofs, &val, sizeof(val))) { 61265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 62265056Smarcel return (NULL); 63265056Smarcel } 64265056Smarcel return (Py_BuildValue("H", val)); 65265056Smarcel} 66265056Smarcel 67265056Smarcelstatic PyObject * 68265056Smarcelbus_read_4(PyObject *self, PyObject *args) 69265056Smarcel{ 70265056Smarcel long ofs; 71265056Smarcel int rid; 72265056Smarcel uint32_t val; 73265056Smarcel 74265056Smarcel if (!PyArg_ParseTuple(args, "il", &rid, &ofs)) 75265056Smarcel return (NULL); 76265056Smarcel if (!bs_read(rid, ofs, &val, sizeof(val))) { 77265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 78265056Smarcel return (NULL); 79265056Smarcel } 80265056Smarcel return (Py_BuildValue("I", val)); 81265056Smarcel} 82265056Smarcel 83265056Smarcelstatic PyObject * 84265056Smarcelbus_write_1(PyObject *self, PyObject *args) 85265056Smarcel{ 86265056Smarcel long ofs; 87265056Smarcel int rid; 88265056Smarcel uint8_t val; 89265056Smarcel 90265056Smarcel if (!PyArg_ParseTuple(args, "ilB", &rid, &ofs, &val)) 91265056Smarcel return (NULL); 92265056Smarcel if (!bs_write(rid, ofs, &val, sizeof(val))) { 93265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 94265056Smarcel return (NULL); 95265056Smarcel } 96265056Smarcel Py_RETURN_NONE; 97265056Smarcel} 98265056Smarcel 99265056Smarcelstatic PyObject * 100265056Smarcelbus_write_2(PyObject *self, PyObject *args) 101265056Smarcel{ 102265056Smarcel long ofs; 103265056Smarcel int rid; 104265056Smarcel uint16_t val; 105265056Smarcel 106265056Smarcel if (!PyArg_ParseTuple(args, "ilH", &rid, &ofs, &val)) 107265056Smarcel return (NULL); 108265056Smarcel if (!bs_write(rid, ofs, &val, sizeof(val))) { 109265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 110265056Smarcel return (NULL); 111265056Smarcel } 112265056Smarcel Py_RETURN_NONE; 113265056Smarcel} 114265056Smarcel 115265056Smarcelstatic PyObject * 116265056Smarcelbus_write_4(PyObject *self, PyObject *args) 117265056Smarcel{ 118265056Smarcel long ofs; 119265056Smarcel int rid; 120265056Smarcel uint32_t val; 121265056Smarcel 122265056Smarcel if (!PyArg_ParseTuple(args, "ilI", &rid, &ofs, &val)) 123265056Smarcel return (NULL); 124265056Smarcel if (!bs_write(rid, ofs, &val, sizeof(val))) { 125265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 126265056Smarcel return (NULL); 127265056Smarcel } 128265056Smarcel Py_RETURN_NONE; 129265056Smarcel} 130265056Smarcel 131265056Smarcelstatic PyObject * 132265056Smarcelbus_map(PyObject *self, PyObject *args) 133265056Smarcel{ 134265056Smarcel char *dev; 135265056Smarcel int rid; 136265056Smarcel 137265056Smarcel if (!PyArg_ParseTuple(args, "s", &dev)) 138265056Smarcel return (NULL); 139265056Smarcel rid = bs_map(dev); 140265056Smarcel if (rid == -1) { 141265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 142265056Smarcel return (NULL); 143265056Smarcel } 144265056Smarcel return (Py_BuildValue("i", rid)); 145265056Smarcel} 146265056Smarcel 147265056Smarcelstatic PyObject * 148265056Smarcelbus_unmap(PyObject *self, PyObject *args) 149265056Smarcel{ 150265056Smarcel int rid; 151265056Smarcel 152265056Smarcel if (!PyArg_ParseTuple(args, "i", &rid)) 153265056Smarcel return (NULL); 154265056Smarcel if (!bs_unmap(rid)) { 155265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 156265056Smarcel return (NULL); 157265056Smarcel } 158265056Smarcel Py_RETURN_NONE; 159265056Smarcel} 160265056Smarcel 161265056Smarcelstatic PyObject * 162265056Smarcelbus_subregion(PyObject *self, PyObject *args) 163265056Smarcel{ 164265056Smarcel long ofs, sz; 165265056Smarcel int rid0, rid; 166265056Smarcel 167265056Smarcel if (!PyArg_ParseTuple(args, "ill", &rid0, &ofs, &sz)) 168265056Smarcel return (NULL); 169265056Smarcel rid = bs_subregion(rid0, ofs, sz); 170265056Smarcel if (rid == -1) { 171265056Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 172265056Smarcel return (NULL); 173265056Smarcel } 174265056Smarcel return (Py_BuildValue("i", rid)); 175265056Smarcel} 176265056Smarcel 177284080Smarcelstatic PyObject * 178284080Smarcelbusdma_tag_create(PyObject *self, PyObject *args) 179284080Smarcel{ 180284080Smarcel char *dev; 181284146Smarcel u_long align, bndry, maxaddr, maxsz, maxsegsz; 182284146Smarcel u_int nsegs, datarate, flags; 183284146Smarcel int tid; 184284080Smarcel 185284146Smarcel if (!PyArg_ParseTuple(args, "skkkkIkII", &dev, &align, &bndry, 186284080Smarcel &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags)) 187284146Smarcel return (NULL); 188284080Smarcel tid = bd_tag_create(dev, align, bndry, maxaddr, maxsz, nsegs, 189284080Smarcel maxsegsz, datarate, flags); 190284080Smarcel if (tid == -1) { 191284080Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 192284080Smarcel return (NULL); 193284080Smarcel } 194284080Smarcel return (Py_BuildValue("i", tid)); 195284080Smarcel} 196284080Smarcel 197284080Smarcelstatic PyObject * 198284080Smarcelbusdma_tag_derive(PyObject *self, PyObject *args) 199284080Smarcel{ 200284146Smarcel u_long align, bndry, maxaddr, maxsz, maxsegsz; 201284146Smarcel u_int nsegs, datarate, flags; 202284146Smarcel int ptid, tid; 203284080Smarcel 204284146Smarcel if (!PyArg_ParseTuple(args, "ikkkkIkII", &ptid, &align, &bndry, 205284080Smarcel &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags)) 206284080Smarcel return (NULL); 207284080Smarcel tid = bd_tag_derive(ptid, align, bndry, maxaddr, maxsz, nsegs, 208284080Smarcel maxsegsz, datarate, flags); 209284080Smarcel if (tid == -1) { 210284080Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 211284080Smarcel return (NULL); 212284080Smarcel } 213284080Smarcel return (Py_BuildValue("i", tid)); 214284080Smarcel} 215284080Smarcel 216284080Smarcelstatic PyObject * 217284080Smarcelbusdma_tag_destroy(PyObject *self, PyObject *args) 218284080Smarcel{ 219284080Smarcel int error, tid; 220284080Smarcel 221284080Smarcel if (!PyArg_ParseTuple(args, "i", &tid)) 222284080Smarcel return (NULL); 223284080Smarcel error = bd_tag_destroy(tid); 224284080Smarcel if (error) { 225284080Smarcel PyErr_SetString(PyExc_IOError, strerror(error)); 226284080Smarcel return (NULL); 227284080Smarcel } 228284080Smarcel Py_RETURN_NONE; 229284080Smarcel} 230284080Smarcel 231284146Smarcelstatic PyObject * 232285071Smarcelbusdma_md_create(PyObject *self, PyObject *args) 233285071Smarcel{ 234285071Smarcel u_int flags; 235285071Smarcel int error, mdid, tid; 236285071Smarcel 237285071Smarcel if (!PyArg_ParseTuple(args, "iI", &tid, &flags)) 238285071Smarcel return (NULL); 239285071Smarcel mdid = bd_md_create(tid, flags); 240285071Smarcel if (mdid == -1) { 241285071Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 242285071Smarcel return (NULL); 243285071Smarcel } 244285071Smarcel return (Py_BuildValue("i", mdid)); 245285071Smarcel} 246285071Smarcel 247285071Smarcelstatic PyObject * 248285071Smarcelbusdma_md_destroy(PyObject *self, PyObject *args) 249285071Smarcel{ 250285071Smarcel int error, mdid; 251285071Smarcel 252285071Smarcel if (!PyArg_ParseTuple(args, "i", &mdid)) 253285071Smarcel return (NULL); 254285071Smarcel error = bd_md_destroy(mdid); 255285071Smarcel if (error) { 256285071Smarcel PyErr_SetString(PyExc_IOError, strerror(error)); 257285071Smarcel return (NULL); 258285071Smarcel } 259285071Smarcel Py_RETURN_NONE; 260285071Smarcel} 261285071Smarcel 262285071Smarcelstatic PyObject * 263285071Smarcelbusdma_md_load(PyObject *self, PyObject *args) 264285071Smarcel{ 265285071Smarcel void *buf; 266285071Smarcel u_long len; 267285071Smarcel u_int flags; 268285071Smarcel int error, mdid; 269285071Smarcel 270285071Smarcel if (!PyArg_ParseTuple(args, "iwkI", &mdid, &buf, &len, &flags)) 271285071Smarcel return (NULL); 272285071Smarcel error = bd_md_load(mdid, buf, len, flags); 273285071Smarcel if (error) { 274285071Smarcel PyErr_SetString(PyExc_IOError, strerror(error)); 275285071Smarcel return (NULL); 276285071Smarcel } 277285071Smarcel Py_RETURN_NONE; 278285071Smarcel} 279285071Smarcel 280285071Smarcelstatic PyObject * 281284146Smarcelbusdma_mem_alloc(PyObject *self, PyObject *args) 282284146Smarcel{ 283284146Smarcel u_int flags; 284284146Smarcel int mdid, tid; 285284146Smarcel 286284146Smarcel if (!PyArg_ParseTuple(args, "iI", &tid, &flags)) 287284146Smarcel return (NULL); 288284146Smarcel mdid = bd_mem_alloc(tid, flags); 289284146Smarcel if (mdid == -1) { 290284146Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 291284146Smarcel return (NULL); 292284146Smarcel } 293284146Smarcel return (Py_BuildValue("i", mdid)); 294284146Smarcel} 295284146Smarcel 296284146Smarcelstatic PyObject * 297284146Smarcelbusdma_mem_free(PyObject *self, PyObject *args) 298284146Smarcel{ 299284146Smarcel int error, mdid; 300284146Smarcel 301284146Smarcel if (!PyArg_ParseTuple(args, "i", &mdid)) 302284146Smarcel return (NULL); 303284146Smarcel error = bd_mem_free(mdid); 304284146Smarcel if (error) { 305284146Smarcel PyErr_SetString(PyExc_IOError, strerror(error)); 306284146Smarcel return (NULL); 307284146Smarcel } 308284146Smarcel Py_RETURN_NONE; 309284146Smarcel} 310284146Smarcel 311284253Smarcelstatic PyObject * 312284253Smarcelbusdma_md_first_seg(PyObject *self, PyObject *args) 313284253Smarcel{ 314284253Smarcel int error, mdid, sid, what; 315284253Smarcel 316284253Smarcel if (!PyArg_ParseTuple(args, "ii", &mdid, &what)) 317284253Smarcel return (NULL); 318284253Smarcel sid = bd_md_first_seg(mdid, what); 319284253Smarcel if (sid == -1) { 320284253Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 321284253Smarcel return (NULL); 322284253Smarcel } 323284253Smarcel return (Py_BuildValue("i", sid)); 324284253Smarcel} 325284253Smarcel 326284253Smarcelstatic PyObject * 327284253Smarcelbusdma_md_next_seg(PyObject *self, PyObject *args) 328284253Smarcel{ 329284253Smarcel int error, mdid, sid; 330284253Smarcel 331284253Smarcel if (!PyArg_ParseTuple(args, "ii", &mdid, &sid)) 332284253Smarcel return (NULL); 333284253Smarcel sid = bd_md_next_seg(mdid, sid); 334284253Smarcel if (sid == -1) { 335284253Smarcel PyErr_SetString(PyExc_IOError, strerror(errno)); 336284253Smarcel return (NULL); 337284253Smarcel } 338284253Smarcel return (Py_BuildValue("i", sid)); 339284253Smarcel} 340284253Smarcel 341284253Smarcelstatic PyObject * 342284253Smarcelbusdma_seg_get_addr(PyObject *self, PyObject *args) 343284253Smarcel{ 344284253Smarcel u_long addr; 345284253Smarcel int error, sid; 346284253Smarcel 347284253Smarcel if (!PyArg_ParseTuple(args, "i", &sid)) 348284253Smarcel return (NULL); 349284253Smarcel error = bd_seg_get_addr(sid, &addr); 350284253Smarcel if (error) { 351284253Smarcel PyErr_SetString(PyExc_IOError, strerror(error)); 352284253Smarcel return (NULL); 353284253Smarcel } 354284253Smarcel return (Py_BuildValue("k", addr)); 355284253Smarcel} 356284253Smarcel 357284253Smarcelstatic PyObject * 358284253Smarcelbusdma_seg_get_size(PyObject *self, PyObject *args) 359284253Smarcel{ 360284253Smarcel u_long size; 361284253Smarcel int error, sid; 362284253Smarcel 363284253Smarcel if (!PyArg_ParseTuple(args, "i", &sid)) 364284253Smarcel return (NULL); 365284253Smarcel error = bd_seg_get_size(sid, &size); 366284253Smarcel if (error) { 367284253Smarcel PyErr_SetString(PyExc_IOError, strerror(error)); 368284253Smarcel return (NULL); 369284253Smarcel } 370284253Smarcel return (Py_BuildValue("k", size)); 371284253Smarcel} 372284253Smarcel 373284228Smarcelstatic PyMethodDef bus_methods[] = { 374265056Smarcel { "read_1", bus_read_1, METH_VARARGS, "Read a 1-byte data item." }, 375265056Smarcel { "read_2", bus_read_2, METH_VARARGS, "Read a 2-byte data item." }, 376265056Smarcel { "read_4", bus_read_4, METH_VARARGS, "Read a 4-byte data item." }, 377265056Smarcel 378265056Smarcel { "write_1", bus_write_1, METH_VARARGS, "Write a 1-byte data item." }, 379265056Smarcel { "write_2", bus_write_2, METH_VARARGS, "Write a 2-byte data item." }, 380265056Smarcel { "write_4", bus_write_4, METH_VARARGS, "Write a 4-byte data item." }, 381265056Smarcel 382265056Smarcel { "map", bus_map, METH_VARARGS, 383265056Smarcel "Return a resource ID for a device file created by proto(4)" }, 384265056Smarcel { "unmap", bus_unmap, METH_VARARGS, 385265056Smarcel "Free a resource ID" }, 386265056Smarcel { "subregion", bus_subregion, METH_VARARGS, 387265056Smarcel "Return a resource ID for a subregion of another resource ID" }, 388265056Smarcel 389265056Smarcel { NULL, NULL, 0, NULL } 390265056Smarcel}; 391265056Smarcel 392284080Smarcelstatic PyMethodDef busdma_methods[] = { 393284146Smarcel { "tag_create", busdma_tag_create, METH_VARARGS, 394284146Smarcel "Create a root tag." }, 395284146Smarcel { "tag_derive", busdma_tag_derive, METH_VARARGS, 396284146Smarcel "Derive a child tag." }, 397284146Smarcel { "tag_destroy", busdma_tag_destroy, METH_VARARGS, 398284146Smarcel "Destroy a tag." }, 399285071Smarcel 400285071Smarcel { "md_create", busdma_md_create, METH_VARARGS, 401285071Smarcel "Create a new and empty memory descriptor." }, 402285071Smarcel { "md_destroy", busdma_md_destroy, METH_VARARGS, 403285071Smarcel "Destroy a previously created memory descriptor." }, 404285071Smarcel { "md_load", busdma_md_load, METH_VARARGS, 405285071Smarcel "Load a buffer into a memory descriptor." }, 406285071Smarcel 407284146Smarcel { "mem_alloc", busdma_mem_alloc, METH_VARARGS, 408284146Smarcel "Allocate memory according to the DMA constraints." }, 409284146Smarcel { "mem_free", busdma_mem_free, METH_VARARGS, 410284146Smarcel "Free allocated memory." }, 411284253Smarcel 412284253Smarcel { "md_first_seg", busdma_md_first_seg, METH_VARARGS, 413284253Smarcel "Return first segment in one of the segment lists." }, 414284253Smarcel { "md_next_seg", busdma_md_next_seg, METH_VARARGS, 415284253Smarcel "Return next segment in the segment list." }, 416284253Smarcel { "seg_get_addr", busdma_seg_get_addr, METH_VARARGS, 417284253Smarcel "Return the address of the segment." }, 418284253Smarcel { "seg_get_size", busdma_seg_get_size, METH_VARARGS, 419284253Smarcel "Return the size of the segment." }, 420284080Smarcel { NULL, NULL, 0, NULL } 421284080Smarcel}; 422284080Smarcel 423265056SmarcelPyMODINIT_FUNC 424284228Smarcelinitbus(void) 425265056Smarcel{ 426265056Smarcel 427284228Smarcel Py_InitModule("bus", bus_methods); 428284080Smarcel Py_InitModule("busdma", busdma_methods); 429265056Smarcel} 430