summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2005-08-03 23:08:23 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2005-08-03 23:08:23 +0000
commitd3e82ec52862cbf0dc9aaa9b40b852d0cc74a721 (patch)
tree22d8dc93171072a9f1c26cf3bb6c1ebde3e2d584 /sys
parent2b0583dd83f86f8782065844553f3d2a80187e72 (diff)
enforce 10-bit width for i/o addresses when start address is assigned by
the driver and calcule address line mask when is not. from haya@netbsd.org. tested by several ppl.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/pccbb.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/sys/dev/pci/pccbb.c b/sys/dev/pci/pccbb.c
index 7d2f064f439..6e837d6cc64 100644
--- a/sys/dev/pci/pccbb.c
+++ b/sys/dev/pci/pccbb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pccbb.c,v 1.35 2005/01/27 17:03:23 millert Exp $ */
+/* $OpenBSD: pccbb.c,v 1.36 2005/08/03 23:08:22 fgsch Exp $ */
/* $NetBSD: pccbb.c,v 1.96 2004/03/28 09:49:31 nakayama Exp $ */
/*
@@ -1958,6 +1958,7 @@ pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
int flags = 0;
bus_space_tag_t iot;
bus_space_handle_t ioh;
+ bus_addr_t mask;
#if rbus
rbus_tag_t rb;
#endif
@@ -1965,6 +1966,34 @@ pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
align = size; /* XXX: funny??? */
}
+ if (start != 0) {
+ /* XXX: assume all card decode lower 10 bits by its hardware */
+ mask = 0x3ff;
+ /* enforce to use only masked address */
+ start &= mask;
+ } else {
+ /*
+ * calculate mask:
+ * 1. get the most significant bit of size (call it msb).
+ * 2. compare msb with the value of size.
+ * 3. if size is larger, shift msb left once.
+ * 4. obtain mask value to decrement msb.
+ */
+ bus_size_t size_tmp = size;
+ int shifts = 0;
+
+ mask = 1;
+ while (size_tmp) {
+ ++shifts;
+ size_tmp >>= 1;
+ }
+ mask = (1 << shifts);
+ if (mask < size) {
+ mask <<= 1;
+ }
+ mask--;
+ }
+
/*
* Allocate some arbitrary I/O space.
*/
@@ -1973,8 +2002,7 @@ pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
#if rbus
rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
- /* XXX: I assume all card decode lower 10 bits by its hardware */
- if (rbus_space_alloc(rb, start, size, 0x3ff, align, 0, &ioaddr, &ioh)) {
+ if (rbus_space_alloc(rb, start, size, mask, align, 0, &ioaddr, &ioh)) {
return 1;
}
#else
@@ -1983,7 +2011,7 @@ pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
if (bus_space_map(iot, start, size, 0, &ioh)) {
return 1;
}
- DPRINTF(("pccbb_pcmcia_io_alloc map port %lx+%lx\n",
+ DPRINTF(("pccbb_pcmcia_io_alloc map port 0x%lx+0x%lx\n",
(u_long) ioaddr, (u_long) size));
} else {
flags |= PCMCIA_IO_ALLOCATED;