From de32b73eb1a7d414660f418230e3b9137887c13a Mon Sep 17 00:00:00 2001 From: Ian C Date: Fri, 7 Dec 2018 15:22:29 +0000 Subject: Some more work on driver and added simple test program. Next step implement the write. --- hardsid.c | 124 ++++++++++++++++++++++++++++++++++----------------------- test/Makefile | 1 + test/sidtest.c | 77 +++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 49 deletions(-) create mode 100644 test/Makefile create mode 100644 test/sidtest.c diff --git a/hardsid.c b/hardsid.c index 2b514c9..86b1cbe 100644 --- a/hardsid.c +++ b/hardsid.c @@ -31,6 +31,9 @@ #include #include #include +#include +#include +#include #include #include @@ -39,11 +42,17 @@ #include #include -/* The softc holds our per-instance data. */ +/* The softc holds our per-instance data. +*/ struct hardsid_softc { - device_t my_dev; - struct cdev *my_cdev; + device_t dev; + struct cdev *cdev; + int rid; + struct mtx lock; + struct resource *res; + int opened; + int reg; }; /* Function prototypes @@ -65,29 +74,41 @@ static struct cdevsw hardsid_cdevsw = .d_name = "hardsid", }; -/* - * In the cdevsw routines, we find our softc by using the si_drv1 member - * of struct cdev. We set this variable to point to our softc in our - * attach routine when we create the /dev entry. - */ - int hardsid_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { struct hardsid_softc *sc; + int ret; - /* Look up our softc. */ sc = dev->si_drv1; - device_printf(sc->my_dev, "Opened successfully.\n"); - return 0; + + mtx_lock(&sc->lock); + + if (sc->opened) + { + ret = EACCES; + } + else + { + ret = 0; + sc->opened = 1; + sc->reg = -1; + } + + mtx_unlock(&sc->lock); + + return ret; } int hardsid_close(struct cdev *dev, int fflag, int devtype, struct thread *td) { struct hardsid_softc *sc; - /* Look up our softc. */ sc = dev->si_drv1; - device_printf(sc->my_dev, "Closed.\n"); + + mtx_lock(&sc->lock); + sc->opened = 0; + mtx_unlock(&sc->lock); + return 0; } @@ -95,9 +116,8 @@ int hardsid_read(struct cdev *dev, struct uio *uio, int ioflag) { struct hardsid_softc *sc; - /* Look up our softc. */ sc = dev->si_drv1; - device_printf(sc->my_dev, "Asked to read %zd bytes.\n", uio->uio_resid); + return 0; } @@ -105,18 +125,13 @@ int hardsid_write(struct cdev *dev, struct uio *uio, int ioflag) { struct hardsid_softc *sc; - /* Look up our softc. */ sc = dev->si_drv1; - device_printf(sc->my_dev, "Asked to write %zd bytes.\n", uio->uio_resid); + return 0; } /* PCI Support Functions */ -/* - * Compare the device ID of this device against the IDs that this driver - * supports. If there is a match, set the description and return success. - */ static int hardsid_probe(device_t dev) { if ((pci_get_vendor(dev) == 0x6581) && (pci_get_device(dev) == 0x8580)) @@ -128,60 +143,70 @@ static int hardsid_probe(device_t dev) return ENXIO; } -/* Attach function is only called if the probe is successful. */ - +/* Attach function is only called if the probe is successful. +*/ static int hardsid_attach(device_t dev) { struct hardsid_softc *sc; - /* Look up our softc and initialize its fields. */ + /* Look up our softc and initialize its fields. + */ sc = device_get_softc(dev); - sc->my_dev = dev; - - /* - * Create a /dev entry for this device. The kernel will assign us - * a major number automatically. We use the unit number of this - * device as the minor number and name the character device - * "hardsid". - */ - sc->my_cdev = make_dev(&hardsid_cdevsw, device_get_unit(dev), - UID_ROOT, GID_WHEEL, 0666, "hardsid%u", device_get_unit(dev)); - sc->my_cdev->si_drv1 = sc; + sc->dev = dev; + sc->opened = 0; + sc->rid = PCIR_BAR(0); + sc->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->rid, RF_ACTIVE); + mtx_init(&sc->lock, "hardsid", NULL, MTX_DEF); + + if (sc->res == NULL) + { + device_printf(dev, "couldn't configure PCI IO resources\n"); + return ENXIO; + } + + /*Create a /dev entry for this device. + */ + sc->cdev = make_dev(&hardsid_cdevsw, + device_get_unit(dev), + UID_ROOT, GID_WHEEL, 0666, + "hardsid%u", device_get_unit(dev)); + + sc->cdev->si_drv1 = sc; return 0; } -/* Detach device. */ - +/* Detach device. +*/ static int hardsid_detach(device_t dev) { struct hardsid_softc *sc; - /* Teardown the state in our softc created in our attach routine. */ + /* Teardown the state in our softc created in our attach routine. + */ sc = device_get_softc(dev); - destroy_dev(sc->my_cdev); + bus_release_resource(dev, SYS_RES_IOPORT, sc->rid, sc->res); + destroy_dev(sc->cdev); return 0; } -/* Called during system shutdown after sync. */ - +/* Called during system shutdown after sync. +*/ static int hardsid_shutdown(device_t dev) { return 0; } -/* - * Device suspend routine. - */ +/* Device suspend routine. +*/ static int hardsid_suspend(device_t dev) { return 0; } -/* - * Device resume routine. - */ +/* Device resume routine. +*/ static int hardsid_resume(device_t dev) { return 0; @@ -189,7 +214,8 @@ static int hardsid_resume(device_t dev) static device_method_t hardsid_methods[] = { - /* Device interface */ + /* Device interface + */ DEVMETHOD(device_probe, hardsid_probe), DEVMETHOD(device_attach, hardsid_attach), DEVMETHOD(device_detach, hardsid_detach), diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..60e233d --- /dev/null +++ b/test/Makefile @@ -0,0 +1 @@ +sidtest: sidtest.c diff --git a/test/sidtest.c b/test/sidtest.c new file mode 100644 index 0000000..767417c --- /dev/null +++ b/test/sidtest.c @@ -0,0 +1,77 @@ +/* Copyright 2018 Ian Cowburn + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + char setsound[] = + { + 4, 17, + 24, 15, + 5, 97, + 6, 200, + 0, 128, + 1, 127 + }; + + char clearsound[] = + { + 24, 0 + }; + + int fd; + int wrote; + + fd = open("/dev/hardsid0", O_RDWR); + + if (fd == -1) + { + perror("open"); + exit(EXIT_FAILURE); + } + + if ((wrote = write(fd, setsound, sizeof setsound)) != sizeof setsound) + { + printf("Only wrote %d of %zu bytes\n", wrote, sizeof setsound); + perror("write"); + } + + printf("\n"); + getchar(); + + if ((wrote = write(fd, clearsound, sizeof clearsound)) != sizeof clearsound) + { + printf("Only wrote %d of %zu bytes\n", wrote, sizeof clearsound); + perror("write"); + } + + close(fd); + + return EXIT_SUCCESS; +} -- cgit v1.2.3