summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev/upa.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-03-05 18:58:31 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-03-05 18:58:31 +0000
commit625b76eca8bb200e9283add6603637b32e685228 (patch)
tree3e1decc6680e678af1afce6ceb73440cd46b0ae8 /sys/arch/sparc64/dev/upa.c
parent101c78092f0c01561618ccdbc0743c0ee26ce618 (diff)
Add mmap for upa(4). Makes the X wsfb(4) driver actually work instead of
crashing the machine on UltraSPARC-III machines with creator(4) framebuffers. ok jason@, tsi@
Diffstat (limited to 'sys/arch/sparc64/dev/upa.c')
-rw-r--r--sys/arch/sparc64/dev/upa.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/sys/arch/sparc64/dev/upa.c b/sys/arch/sparc64/dev/upa.c
index a4dd7971763..8b55ea4dfb4 100644
--- a/sys/arch/sparc64/dev/upa.c
+++ b/sys/arch/sparc64/dev/upa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: upa.c,v 1.4 2003/06/02 20:02:49 jason Exp $ */
+/* $OpenBSD: upa.c,v 1.5 2007/03/05 18:58:30 kettenis Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -83,8 +83,10 @@ struct cfdriver upa_cd = {
int upa_print(void *, const char *);
bus_space_tag_t upa_alloc_bus_tag(struct upa_softc *);
-int __upa_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t,
+int upa_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t,
bus_size_t, int, bus_space_handle_t *);
+paddr_t upa_bus_mmap(bus_space_tag_t, bus_space_tag_t,
+ bus_addr_t, off_t, int, int);
int
upa_match(struct device *parent, void *match, void *aux)
@@ -172,14 +174,14 @@ upa_alloc_bus_tag(struct upa_softc *sc)
bt->parent = sc->sc_bt;
bt->asi = bt->parent->asi;
bt->sasi = bt->parent->sasi;
- bt->sparc_bus_map = __upa_bus_map;
- /* XXX bt->sparc_bus_mmap = upa_bus_mmap; */
+ bt->sparc_bus_map = upa_bus_map;
+ bt->sparc_bus_mmap = upa_bus_mmap;
/* XXX bt->sparc_intr_establish = upa_intr_establish; */
return (bt);
}
int
-__upa_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset,
+upa_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset,
bus_size_t size, int flags, bus_space_handle_t *hp)
{
struct upa_softc *sc = t->cookie;
@@ -211,7 +213,39 @@ __upa_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset,
offset -= sc->sc_range[i].ur_space;
offset += sc->sc_range[i].ur_addr;
-
return ((*t->sparc_bus_map)(t, t0, offset, size, flags, hp));
}
+paddr_t
+upa_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr,
+ off_t off, int prot, int flags)
+{
+ struct upa_softc *sc = t->cookie;
+ int i;
+
+ if (t->parent == 0 || t->parent->sparc_bus_map == 0) {
+ printf("\n__upa_bus_map: invalid parent");
+ return (EINVAL);
+ }
+
+ t = t->parent;
+
+ if (flags & BUS_SPACE_MAP_PROMADDRESS)
+ return ((*t->sparc_bus_mmap)(t, t0, paddr, off, prot, flags));
+
+ for (i = 0; i < sc->sc_nrange; i++) {
+ if (paddr + off < sc->sc_range[i].ur_space)
+ continue;
+ if (paddr + off >= (sc->sc_range[i].ur_space +
+ sc->sc_range[i].ur_space))
+ continue;
+ break;
+ }
+ if (i == sc->sc_nrange)
+ return (EINVAL);
+
+ paddr -= sc->sc_range[i].ur_space;
+ paddr += sc->sc_range[i].ur_addr;
+
+ return ((*t->sparc_bus_mmap)(t, t0, paddr, off, prot, flags));
+}