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),  | 
