summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJasper Lievisse Adriaanse <jasper@cvs.openbsd.org>2015-07-19 23:46:51 +0000
committerJasper Lievisse Adriaanse <jasper@cvs.openbsd.org>2015-07-19 23:46:51 +0000
commitb018d6d16a5b4d0b24d3228eed348e6d0b32051b (patch)
treec0fc5464c73c03e68f1d35238cba7a90f6e9cafc /sys
parent21dadcd1d5c8b3f60372f67a53707dbc95c1a3e5 (diff)
rework how iobus(4) finds and attaches devices.
this allows us to get rid of the static list of children devices, using only a lookup table for address hints where needed. as a bonus this removes the 'octcf0: [..] not configured' mesage on machines w/o octcf(4). tested by pirofti@ on DSR-500 and ERL by me ok miod@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/octeon/conf/GENERIC6
-rw-r--r--sys/arch/octeon/conf/RAMDISK6
-rw-r--r--sys/arch/octeon/conf/files.octeon4
-rw-r--r--sys/arch/octeon/dev/cn30xxgmx.c10
-rw-r--r--sys/arch/octeon/dev/iobusvar.h25
-rw-r--r--sys/arch/octeon/dev/octcf.c4
-rw-r--r--sys/arch/octeon/dev/octeon_iobus.c90
7 files changed, 86 insertions, 59 deletions
diff --git a/sys/arch/octeon/conf/GENERIC b/sys/arch/octeon/conf/GENERIC
index ffb3d4436dc..0f9580107ef 100644
--- a/sys/arch/octeon/conf/GENERIC
+++ b/sys/arch/octeon/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.20 2015/07/13 19:05:23 miod Exp $
+# $OpenBSD: GENERIC,v 1.21 2015/07/19 23:46:50 jasper Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -46,7 +46,7 @@ pci* at pcibus?
ppb* at pci? # PCI-PCI bridges
pci* at ppb?
-cn30xxgmx* at iobus?
+cn30xxgmx* at iobus? irq 48
cnmac* at cn30xxgmx?
rgephy* at mii?
@@ -61,7 +61,7 @@ pciide* at pci? flags 0x0000
wd* at pciide? flags 0x0000
# USB Controllers
-dwctwo0 at iobus?
+dwctwo0 at iobus? irq 56
# USB bus support
usb* at dwctwo?
diff --git a/sys/arch/octeon/conf/RAMDISK b/sys/arch/octeon/conf/RAMDISK
index 91df52876fc..1e5e2c41e67 100644
--- a/sys/arch/octeon/conf/RAMDISK
+++ b/sys/arch/octeon/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.18 2015/07/17 22:52:29 tedu Exp $
+# $OpenBSD: RAMDISK,v 1.19 2015/07/19 23:46:50 jasper Exp $
machine octeon mips64
maxusers 4
@@ -44,13 +44,13 @@ pci* at pcibus?
ppb* at pci?
pci* at ppb?
-cn30xxgmx* at iobus?
+cn30xxgmx* at iobus? irq 48
cnmac* at cn30xxgmx?
pciide* at pci? flags 0x0000
wd* at pciide? flags 0x0000
-dwctwo0 at iobus0
+dwctwo0 at iobus0 irq 56
usb* at dwctwo?
uhub* at usb?
umass* at uhub?
diff --git a/sys/arch/octeon/conf/files.octeon b/sys/arch/octeon/conf/files.octeon
index c41328fe9c9..7857a6f9ac1 100644
--- a/sys/arch/octeon/conf/files.octeon
+++ b/sys/arch/octeon/conf/files.octeon
@@ -1,4 +1,4 @@
-# $OpenBSD: files.octeon,v 1.22 2015/07/13 19:05:23 miod Exp $
+# $OpenBSD: files.octeon,v 1.23 2015/07/19 23:46:50 jasper Exp $
# Standard stanzas config(8) can't run without
maxpartitions 16
@@ -52,7 +52,7 @@ device octrtc
attach octrtc at mainbus
file arch/octeon/dev/octrtc.c octrtc
-define iobus {[base = -1]}
+define iobus {[base = -1], [irq = 0]}
device iobus
attach iobus at mainbus
file arch/octeon/dev/octeon_iobus.c iobus
diff --git a/sys/arch/octeon/dev/cn30xxgmx.c b/sys/arch/octeon/dev/cn30xxgmx.c
index 70d6c8ac5c7..555579d7f9e 100644
--- a/sys/arch/octeon/dev/cn30xxgmx.c
+++ b/sys/arch/octeon/dev/cn30xxgmx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cn30xxgmx.c,v 1.19 2015/06/24 09:40:53 mpi Exp $ */
+/* $OpenBSD: cn30xxgmx.c,v 1.20 2015/07/19 23:46:50 jasper Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -206,8 +206,8 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
sc->sc_regt = aa->aa_bust; /* XXX why there are iot? */
-
- status = bus_space_map(sc->sc_regt, aa->aa_unit->addr,
+
+ status = bus_space_map(sc->sc_regt, aa->aa_addr,
GMX0_BASE_IF_SIZE, 0, &sc->sc_regh);
if (status != 0)
panic(": can't map register");
@@ -224,7 +224,7 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux)
port_sc->sc_port_type = sc->sc_port_types[i];
port_sc->sc_port_ops = cn30xxgmx_port_ops[port_sc->sc_port_type];
status = bus_space_map(sc->sc_regt,
- aa->aa_unit->addr + GMX0_BASE_PORT_SIZE * i,
+ aa->aa_addr + GMX0_BASE_PORT_SIZE * i,
GMX0_BASE_PORT_SIZE, 0, &port_sc->sc_port_regh);
if (status != 0)
panic(": can't map port register");
@@ -232,7 +232,7 @@ cn30xxgmx_attach(struct device *parent, struct device *self, void *aux)
(void)memset(&gmx_aa, 0, sizeof(gmx_aa));
gmx_aa.ga_regt = aa->aa_bust;
gmx_aa.ga_dmat = aa->aa_dmat;
- gmx_aa.ga_addr = aa->aa_unit->addr;
+ gmx_aa.ga_addr = aa->aa_addr;
gmx_aa.ga_name = "cnmac";
gmx_aa.ga_portno = i;
gmx_aa.ga_port_type = sc->sc_port_types[i];
diff --git a/sys/arch/octeon/dev/iobusvar.h b/sys/arch/octeon/dev/iobusvar.h
index 2fae7850c1c..a6061174f98 100644
--- a/sys/arch/octeon/dev/iobusvar.h
+++ b/sys/arch/octeon/dev/iobusvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iobusvar.h,v 1.2 2015/04/26 12:24:03 jmatthew Exp $ */
+/* $OpenBSD: iobusvar.h,v 1.3 2015/07/19 23:46:50 jasper Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -34,19 +34,20 @@
extern bus_space_t iobus_tag;
extern struct machine_bus_dma_tag iobus_dma_tag;
-struct iobus_unit {
- bus_addr_t addr;
- int irq;
-};
-
struct iobus_attach_args {
char *aa_name;
- int aa_unitno;
-
- const struct iobus_unit *aa_unit;
-
- bus_space_tag_t aa_bust;
- bus_dma_tag_t aa_dmat;
+ int aa_unitno;
+
+ bus_addr_t aa_addr;
+ int aa_irq;
+
+ bus_space_tag_t aa_bust;
+ bus_dma_tag_t aa_dmat;
+};
+
+struct octeon_iobus_addrs {
+ const char *name;
+ bus_addr_t address;
};
int iobus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
diff --git a/sys/arch/octeon/dev/octcf.c b/sys/arch/octeon/dev/octcf.c
index c705eab4002..b813fa07784 100644
--- a/sys/arch/octeon/dev/octcf.c
+++ b/sys/arch/octeon/dev/octcf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: octcf.c,v 1.25 2014/08/11 19:00:50 miod Exp $ */
+/* $OpenBSD: octcf.c,v 1.26 2015/07/19 23:46:50 jasper Exp $ */
/* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */
/*
@@ -180,7 +180,7 @@ octcfattach(struct device *parent, struct device *self, void *aux)
wd->sc_iot = aa->aa_bust;
- if (bus_space_map(wd->sc_iot, aa->aa_unit->addr,
+ if (bus_space_map(wd->sc_iot, aa->aa_addr,
OCTCF_REG_SIZE, BUS_SPACE_MAP_KSEG0, &wd->sc_ioh)) {
printf(": couldn't map registers\n");
return;
diff --git a/sys/arch/octeon/dev/octeon_iobus.c b/sys/arch/octeon/dev/octeon_iobus.c
index 634b8dab397..5b2eca74332 100644
--- a/sys/arch/octeon/dev/octeon_iobus.c
+++ b/sys/arch/octeon/dev/octeon_iobus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: octeon_iobus.c,v 1.12 2015/07/16 02:19:47 jasper Exp $ */
+/* $OpenBSD: octeon_iobus.c,v 1.13 2015/07/19 23:46:50 jasper Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -49,10 +49,11 @@
#include <octeon/dev/cn30xxgmxreg.h>
#include <octeon/dev/octhcireg.h> /* USBN_BASE */
-int iobusmatch(struct device *, void *, void *);
-void iobusattach(struct device *, struct device *, void *);
-int iobusprint(void *, const char *);
-int iobussubmatch(struct device *, void *, void *);
+int iobusmatch(struct device *, void *, void *);
+void iobusattach(struct device *, struct device *, void *);
+int iobusprint(void *, const char *);
+int iobussubmatch(struct device *, void *, void *);
+int iobussearch(struct device *, void *, void *);
u_int8_t iobus_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
u_int16_t iobus_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
@@ -139,26 +140,19 @@ struct machine_bus_dma_tag iobus_bus_dma_tag = {
};
/*
- * List of iobus child devices.
+ * List of iobus child devices whose base addresses are too large to be
+ * recorded in the kernel configuration file. So look them up from here instead.
*/
-#define IOBUSDEV(name, unitno, unit) \
- { name, unitno, unit, &iobus_tag, &iobus_bus_dma_tag }
-const struct iobus_unit iobus_units[] = {
- { OCTEON_CF_BASE, 0 }, /* octcf */
- { 0, 0 }, /* pcibus */
- { GMX0_BASE_PORT0, CIU_INT_GMX_DRP0 }, /* cn30xxgmx */
- { OCTEON_RNG_BASE, 0 }, /* octrng */
- { USBN_BASE, CIU_INT_USB }, /* octdwctwo */
+static const struct octeon_iobus_addrs iobus_addrs[] = {
+ { "octcf", OCTEON_CF_BASE },
+ { "cn30xxgmx", GMX0_BASE_PORT0 },
+ { "octrng", OCTEON_RNG_BASE },
+ { "dwctwo", USBN_BASE },
};
-struct iobus_attach_args iobus_children[] = {
- IOBUSDEV("octcf", 0, &iobus_units[0]),
- IOBUSDEV("pcibus", 0, &iobus_units[1]),
- IOBUSDEV("cn30xxgmx", 0, &iobus_units[2]),
- IOBUSDEV("octrng", 0, &iobus_units[3]),
- IOBUSDEV("dwctwo", 0, &iobus_units[4]),
-};
-#undef IOBUSDEV
+
+/* There can only be one. */
+int iobus_found;
/*
* Match bus only to targets which have this bus.
@@ -166,6 +160,9 @@ struct iobus_attach_args iobus_children[] = {
int
iobusmatch(struct device *parent, void *match, void *aux)
{
+ if (iobus_found)
+ return (0);
+
return (1);
}
@@ -177,10 +174,10 @@ iobusprint(void *aux, const char *iobus)
if (iobus != NULL)
printf("%s at %s", aa->aa_name, iobus);
- if (aa->aa_unit->addr != 0)
- printf(" base 0x%lx", aa->aa_unit->addr);
- if (aa->aa_unit->irq >= 0)
- printf(" irq %d", aa->aa_unit->irq);
+ if (aa->aa_addr != 0)
+ printf(" base 0x%lx", aa->aa_addr);
+ if (aa->aa_irq >= 0)
+ printf(" irq %d", aa->aa_irq);
return (UNCONF);
}
@@ -194,7 +191,7 @@ iobussubmatch(struct device *parent, void *vcf, void *args)
if (strcmp(cf->cf_driver->cd_name, aa->aa_name) != 0)
return 0;
- if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != (int)aa->aa_unit->addr)
+ if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != (int)aa->aa_addr)
return 0;
return (*cf->cf_attach->ca_match)(parent, cf, aa);
@@ -203,8 +200,8 @@ iobussubmatch(struct device *parent, void *vcf, void *args)
void
iobusattach(struct device *parent, struct device *self, void *aux)
{
+ struct device *sc = self;
struct octeon_config oc;
- uint i;
/*
* Map and setup CIU control registers.
@@ -215,6 +212,8 @@ iobusattach(struct device *parent, struct device *self, void *aux)
return;
}
+ iobus_found = 1;
+
printf("\n");
octeon_intr_init();
@@ -228,11 +227,38 @@ iobusattach(struct device *parent, struct device *self, void *aux)
cn30xxpow_bootstrap(&oc);
/*
- * Attach subdevices.
+ * Attach all subdevices as described in the config file.
*/
- for (i = 0; i < nitems(iobus_children); i++)
- config_found_sm(self, iobus_children + i,
- iobusprint, iobussubmatch);
+ config_search(iobussearch, self, sc);
+}
+
+int
+iobussearch(struct device *parent, void *v, void *aux)
+{
+ struct iobus_attach_args aa;
+ struct cfdata *cf = v;
+ int i;
+
+ aa.aa_name = cf->cf_driver->cd_name;
+ aa.aa_bust = &iobus_tag;
+ aa.aa_dmat = &iobus_bus_dma_tag;
+ aa.aa_addr = cf->cf_loc[0];
+ aa.aa_irq = cf->cf_loc[1];
+ aa.aa_unitno = cf->cf_unit;
+
+ /* No address specified, try to look it up. */
+ if (aa.aa_addr == -1) {
+ for (i = 0; i < nitems(iobus_addrs); i++) {
+ if (strcmp(iobus_addrs[i].name, cf->cf_driver->cd_name) == 0)
+ aa.aa_addr = iobus_addrs[i].address;
+ }
+ }
+
+ if (cf->cf_attach->ca_match(parent, cf, &aa) == 0)
+ return 0;
+
+ config_attach(parent, cf, &aa, iobusprint);
+ return 1;
}
int