summaryrefslogtreecommitdiff
path: root/sys/dev/ic/sili.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2007-03-30 04:50:55 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2007-03-30 04:50:55 +0000
commitf5fef1bd75714be116ca4531c3200ebfc25afa3f (patch)
tree916cd7754ed6bbbdd6957b6b08f9e02d6e08ebc1 /sys/dev/ic/sili.c
parente5c56117056e7b33082e3589da9a0de65a61d2c1 (diff)
start filling out stuff for managing each port. this allocates it, set a
register window up, and provides access to the port registers.
Diffstat (limited to 'sys/dev/ic/sili.c')
-rw-r--r--sys/dev/ic/sili.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/sys/dev/ic/sili.c b/sys/dev/ic/sili.c
index 2de7cc23b71..b2eae893075 100644
--- a/sys/dev/ic/sili.c
+++ b/sys/dev/ic/sili.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sili.c,v 1.2 2007/03/22 06:54:01 dlg Exp $ */
+/* $OpenBSD: sili.c,v 1.3 2007/03/30 04:50:54 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -35,14 +35,30 @@ struct cfdriver sili_cd = {
NULL, "sili", DV_DULL
};
+struct sili_port {
+ struct sili_softc *sp_sc;
+ bus_space_handle_t sp_ioh;
+};
+
+int sili_ports_alloc(struct sili_softc *);
+void sili_ports_free(struct sili_softc *);
+
u_int32_t sili_read(struct sili_softc *, bus_size_t);
void sili_write(struct sili_softc *, bus_size_t, u_int32_t);
+u_int32_t sili_pread(struct sili_port *, bus_size_t);
+void sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
int
sili_attach(struct sili_softc *sc)
{
printf("\n");
+ sc->sc_nports = 4; /* XXX magic */
+ if (sili_ports_alloc(sc) != 0) {
+ /* error already printed by sili_port_alloc */
+ return (1);
+ }
+
return (0);
}
@@ -62,6 +78,44 @@ sili_intr(void *arg)
return (0);
}
+int
+sili_ports_alloc(struct sili_softc *sc)
+{
+ struct sili_port *sp;
+ int i;
+
+ sc->sc_ports = malloc(sizeof(struct sili_port) * sc->sc_nports,
+ M_DEVBUF, M_WAITOK);
+ bzero(sc->sc_ports, sizeof(struct sili_port) * sc->sc_nports);
+
+ for (i = 0; i < sc->sc_nports; i++) {
+ sp = &sc->sc_ports[i];
+
+ sp->sp_sc = sc;
+ if (bus_space_subregion(sc->sc_iot_port, sc->sc_ioh_port,
+ SILI_PORT_OFFSET(i), SILI_PORT_SIZE, &sp->sp_ioh) != 0) {
+ printf("%s: unable to create register window "
+ "for port %d\n", DEVNAME(sc), i);
+ goto freeports;
+ }
+ }
+
+ return (0);
+
+freeports:
+ /* bus_space(9) says subregions dont have to be freed */
+ free(sp, M_DEVBUF);
+ sc->sc_ports = NULL;
+ return (1);
+}
+
+void
+sili_ports_free(struct sili_softc *sc)
+{
+ /* bus_space(9) says subregions dont have to be freed */
+ free(sc->sc_ports, M_DEVBUF);
+}
+
u_int32_t
sili_read(struct sili_softc *sc, bus_size_t r)
{
@@ -81,3 +135,23 @@ sili_write(struct sili_softc *sc, bus_size_t r, u_int32_t v)
bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
BUS_SPACE_BARRIER_WRITE);
}
+
+u_int32_t
+sili_pread(struct sili_port *sp, bus_size_t r)
+{
+ u_int32_t rv;
+
+ bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
+ BUS_SPACE_BARRIER_READ);
+ rv = bus_space_read_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r);
+
+ return (rv);
+}
+
+void
+sili_pwrite(struct sili_port *sp, bus_size_t r, u_int32_t v)
+{
+ bus_space_write_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, v);
+ bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
+ BUS_SPACE_BARRIER_WRITE);
+}