summaryrefslogtreecommitdiff
path: root/hardsid.c
diff options
context:
space:
mode:
Diffstat (limited to 'hardsid.c')
-rw-r--r--hardsid.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/hardsid.c b/hardsid.c
index 86b1cbe..a7bed75 100644
--- a/hardsid.c
+++ b/hardsid.c
@@ -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,