diff options
author | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2015-07-19 23:46:51 +0000 |
---|---|---|
committer | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2015-07-19 23:46:51 +0000 |
commit | b018d6d16a5b4d0b24d3228eed348e6d0b32051b (patch) | |
tree | c0fc5464c73c03e68f1d35238cba7a90f6e9cafc /sys | |
parent | 21dadcd1d5c8b3f60372f67a53707dbc95c1a3e5 (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/GENERIC | 6 | ||||
-rw-r--r-- | sys/arch/octeon/conf/RAMDISK | 6 | ||||
-rw-r--r-- | sys/arch/octeon/conf/files.octeon | 4 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxgmx.c | 10 | ||||
-rw-r--r-- | sys/arch/octeon/dev/iobusvar.h | 25 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octcf.c | 4 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octeon_iobus.c | 90 |
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 |