summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1999-01-03 10:05:53 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1999-01-03 10:05:53 +0000
commitc927ef63f817a120fc4dac001b8575de3ba0ad74 (patch)
tree88e064c1033b76d3c50db60ae303c1467aa829e8
parentfa79b12122e966be5518c9d5de1aa22f1b431020 (diff)
provide pcmcia IO bus mapper with list of blocks where it should
preferentially map; idea by me, code by niklas
-rw-r--r--sys/dev/ic/i82365.c55
-rw-r--r--sys/dev/ic/i82365var.h8
-rw-r--r--sys/dev/isa/i82365_isasubr.c12
3 files changed, 67 insertions, 8 deletions
diff --git a/sys/dev/ic/i82365.c b/sys/dev/ic/i82365.c
index fc5a3458d06..c06a9e4e428 100644
--- a/sys/dev/ic/i82365.c
+++ b/sys/dev/ic/i82365.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i82365.c,v 1.2 1998/12/15 07:12:57 fgsch Exp $ */
+/* $OpenBSD: i82365.c,v 1.3 1999/01/03 10:05:51 deraadt Exp $ */
/* $NetBSD: i82365.c,v 1.10 1998/06/09 07:36:55 thorpej Exp $ */
/*
@@ -767,8 +767,8 @@ pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
busaddr = pcmhp->addr;
/*
- * compute the address offset to the pcmcia address space for the
- * pcic. this is intentionally signed. The masks and shifts below
+ * Compute the address offset to the pcmcia address space for the
+ * pcic. This is intentionally signed. The masks and shifts below
* will cause TRT to happen in the pcic registers. Deal with making
* sure the address is aligned, and return the alignment offset.
*/
@@ -827,8 +827,9 @@ pcic_chip_io_alloc(pch, start, size, align, pcihp)
struct pcic_handle *h = (struct pcic_handle *) pch;
bus_space_tag_t iot;
bus_space_handle_t ioh;
- bus_addr_t ioaddr;
+ bus_addr_t ioaddr = 0, beg, fin;
int flags = 0;
+ struct pcic_ranges *range;
/*
* Allocate some arbitrary I/O space.
@@ -841,7 +842,49 @@ pcic_chip_io_alloc(pch, start, size, align, pcihp)
if (bus_space_map(iot, start, size, 0, &ioh))
return (1);
DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
- (u_long) ioaddr, (u_long) size));
+ (u_long)ioaddr, (u_long)size));
+ } else if (h->sc->ranges) {
+ flags |= PCMCIA_IO_ALLOCATED;
+
+ /*
+ * In this case, we know the "size" and "align" that
+ * we want. So we need to start walking down
+ * h->sc->ranges, searching for a similar space that
+ * is (1) large enough for the size and alignment
+ * (2) then we need to try to allocate
+ * (3) if it fails to allocate, we try next range.
+ *
+ * We must also check that the start/size of each
+ * allocation we are about to do is within the bounds
+ * of "h->sc->iobase" and "h->sc->iosize".
+ * (Some pcmcia controllers handle a 12 bits of addressing,
+ * but we want to use the same range structure)
+ */
+ for (range = h->sc->ranges; range->start; range++) {
+ /* Potentially trim the range because of bounds. */
+ beg = max(range->start, h->sc->iobase);
+ fin = min(range->start + range->len,
+ h->sc->iobase + h->sc->iosize);
+
+ /* Short-circuit easy case. */
+ if (fin - beg < size)
+ continue;
+
+ /*
+ * This call magically fulfills our alignment
+ * requirements.
+ */
+ DPRINTF(("pcic_chip_io_alloc beg-fin %lx-%lx\n",
+ (u_long)beg, (u_long)fin));
+ if (bus_space_alloc(iot, beg, fin, size, align, 0, 0,
+ &ioaddr, &ioh) == 0)
+ break;
+ }
+ if (range->start == 0)
+ return (1);
+ DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
+ (u_long)ioaddr, (u_long)size));
+
} else {
flags |= PCMCIA_IO_ALLOCATED;
if (bus_space_alloc(iot, h->sc->iobase,
@@ -849,7 +892,7 @@ pcic_chip_io_alloc(pch, start, size, align, pcihp)
&ioaddr, &ioh))
return (1);
DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
- (u_long) ioaddr, (u_long) size));
+ (u_long)ioaddr, (u_long)size));
}
pcihp->iot = iot;
diff --git a/sys/dev/ic/i82365var.h b/sys/dev/ic/i82365var.h
index 7c96d40f90a..7c62228d87e 100644
--- a/sys/dev/ic/i82365var.h
+++ b/sys/dev/ic/i82365var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: i82365var.h,v 1.1 1998/09/11 07:53:58 fgsch Exp $ */
+/* $OpenBSD: i82365var.h,v 1.2 1999/01/03 10:05:52 deraadt Exp $ */
/* $NetBSD: i82365var.h,v 1.4 1998/05/23 18:32:29 matt Exp $ */
/*
@@ -77,6 +77,11 @@ struct pcic_handle {
#define PCIC_NSLOTS 4
+struct pcic_ranges {
+ u_short start;
+ u_short len;
+};
+
struct pcic_softc {
struct device dev;
@@ -105,6 +110,7 @@ struct pcic_softc {
*/
bus_addr_t iobase;
bus_addr_t iosize;
+ struct pcic_ranges *ranges;
int irq;
void *ih;
diff --git a/sys/dev/isa/i82365_isasubr.c b/sys/dev/isa/i82365_isasubr.c
index 5c335864e97..0db52c86088 100644
--- a/sys/dev/isa/i82365_isasubr.c
+++ b/sys/dev/isa/i82365_isasubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i82365_isasubr.c,v 1.4 1998/12/31 09:17:44 deraadt Exp $ */
+/* $OpenBSD: i82365_isasubr.c,v 1.5 1999/01/03 10:05:47 deraadt Exp $ */
/* $NetBSD: i82365_isasubr.c,v 1.1 1998/06/07 18:28:31 sommerfe Exp $ */
/*
@@ -92,6 +92,15 @@ char pcic_isa_intr_list[] = {
int npcic_isa_intr_list =
sizeof(pcic_isa_intr_list) / sizeof(pcic_isa_intr_list[0]);
+struct pcic_ranges pcic_isa_addr[] = {
+ { 0x340, 0x040 },
+ { 0x300, 0x030 },
+ { 0x390, 0x010 },
+ { 0x400, 0xbff },
+ { 0, 0 }, /* terminator */
+};
+
+
/*****************************************************************************
* End of configurable parameters.
*****************************************************************************/
@@ -163,6 +172,7 @@ void pcic_isa_bus_width_probe (sc, iot, ioh, base, length)
* and also a config file option to override the probe.
*/
+ sc->ranges = pcic_isa_addr;
if (iobuswidth == 10) {
sc->iobase = 0x300;
sc->iosize = 0x0ff;