diff options
Diffstat (limited to 'hardsid.c')
-rw-r--r-- | hardsid.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -42,6 +42,10 @@ #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> +/* The maximum amount we support in a write call +*/ +#define MAXREADBUFF 256 + /* The softc holds our per-instance data. */ struct hardsid_softc @@ -51,6 +55,8 @@ struct hardsid_softc int rid; struct mtx lock; struct resource *res; + bus_space_tag_t res_bt; + bus_space_handle_t res_bh; int opened; int reg; }; @@ -74,6 +80,13 @@ static struct cdevsw hardsid_cdevsw = .d_name = "hardsid", }; +/* Set a SID register +*/ +static void SetSIDReg(struct hardsid_softc *sc, int reg, int value) +{ + bus_space_write_2(sc->res_bt, sc->res_bh, 3, reg << 8 | value); +} + int hardsid_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { struct hardsid_softc *sc; @@ -124,9 +137,34 @@ int hardsid_read(struct cdev *dev, struct uio *uio, int ioflag) int hardsid_write(struct cdev *dev, struct uio *uio, int ioflag) { struct hardsid_softc *sc; + unsigned char buff[MAXREADBUFF]; + int len; + int f; + + if (uio->uio_resid > MAXREADBUFF) + { + return EINVAL; + } sc = dev->si_drv1; + len = uio->uio_resid; + + uiomove(buff, len, uio); + + for(f = 0; f < len; f++) + { + if (sc->reg == -1) + { + sc->reg = buff[f]; + } + else + { + SetSIDReg(sc, sc->reg, buff[f]); + sc->reg = -1; + } + } + return 0; } @@ -164,6 +202,9 @@ static int hardsid_attach(device_t dev) return ENXIO; } + sc->res_bt = rman_get_bustag(sc->res); + sc->res_bh = rman_get_bushandle(sc->res); + /*Create a /dev entry for this device. */ sc->cdev = make_dev(&hardsid_cdevsw, |