diff options
Diffstat (limited to 'hardsid.c')
-rw-r--r-- | hardsid.c | 124 |
1 files changed, 75 insertions, 49 deletions
@@ -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), |