From d3e82ec52862cbf0dc9aaa9b40b852d0cc74a721 Mon Sep 17 00:00:00 2001 From: "Federico G. Schwindt" Date: Wed, 3 Aug 2005 23:08:23 +0000 Subject: 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. --- sys/dev/pci/pccbb.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'sys') 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; -- cgit v1.2.3