summaryrefslogtreecommitdiff
path: root/hardsid.c
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2018-12-07 15:22:29 +0000
committerIan C <ianc@noddybox.co.uk>2018-12-07 15:22:29 +0000
commitde32b73eb1a7d414660f418230e3b9137887c13a (patch)
tree0c50d6e85bb8e3e9304e2df5091e974ba276cc59 /hardsid.c
parente077ba7d12bffb9fc1119f03850eb74d7070d535 (diff)
Some more work on driver and added simple test program. Next step implement
the write.
Diffstat (limited to 'hardsid.c')
-rw-r--r--hardsid.c124
1 files changed, 75 insertions, 49 deletions
diff --git a/hardsid.c b/hardsid.c
index 2b514c9..86b1cbe 100644
--- a/hardsid.c
+++ b/hardsid.c
@@ -31,6 +31,9 @@
#include <sys/uio.h>
#include <sys/malloc.h>
#include <sys/bus.h>
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -39,11 +42,17 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
-/* 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<unit>".
- */
- 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),