diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2012-06-12 18:43:27 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2012-06-12 18:43:27 +0000 |
commit | b4e045eb8db7d94ad8390a2a9884fa79145dbecc (patch) | |
tree | fe1ad5b1adb4df019372d3a5687dde0a33496852 | |
parent | 82fa559ed49d427920649b5b1403ed10f95ddb35 (diff) |
Explicitly check whether a BAR is big enough for a particular port instead
of relying on bus_space_subregion(9) to fail. Fixes double console attachment
seen by otto@
-rw-r--r-- | sys/dev/pci/puc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c index 89dd0181be8..f52c0dabe31 100644 --- a/sys/dev/pci/puc.c +++ b/sys/dev/pci/puc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: puc.c,v 1.21 2012/05/15 20:30:05 kettenis Exp $ */ +/* $OpenBSD: puc.c,v 1.22 2012/06/12 18:43:26 kettenis Exp $ */ /* $NetBSD: puc.c,v 1.3 1999/02/06 06:29:54 cgd Exp $ */ /* @@ -207,19 +207,20 @@ puc_pci_attach(struct device *parent, struct device *self, void *aux) void puc_common_attach(struct puc_softc *sc, struct puc_attach_args *paa) { + const struct puc_device_description *desc = sc->sc_desc; int i, bar; /* Configure each port. */ for (i = 0; i < PUC_MAX_PORTS; i++) { - if (sc->sc_desc->ports[i].type == 0) /* neither com or lpt */ + if (desc->ports[i].type == 0) /* neither com or lpt */ continue; /* make sure the base address register is mapped */ - bar = PUC_PORT_BAR_INDEX(sc->sc_desc->ports[i].bar); + bar = PUC_PORT_BAR_INDEX(desc->ports[i].bar); if (!sc->sc_bar_mappings[bar].mapped) { printf("%s: %s port uses unmapped BAR (0x%x)\n", sc->sc_dev.dv_xname, - puc_port_type_name(sc->sc_desc->ports[i].type), - sc->sc_desc->ports[i].bar); + puc_port_type_name(desc->ports[i].type), + desc->ports[i].bar); continue; } @@ -228,11 +229,12 @@ puc_common_attach(struct puc_softc *sc, struct puc_attach_args *paa) paa->a = sc->sc_bar_mappings[bar].a; paa->t = sc->sc_bar_mappings[bar].t; - paa->type = sc->sc_desc->ports[i].type; + paa->type = desc->ports[i].type; - if (bus_space_subregion(sc->sc_bar_mappings[bar].t, - sc->sc_bar_mappings[bar].h, sc->sc_desc->ports[i].offset, - sc->sc_bar_mappings[bar].s - sc->sc_desc->ports[i].offset, + if (desc->ports[i].offset >= sc->sc_bar_mappings[bar].s || + bus_space_subregion(sc->sc_bar_mappings[bar].t, + sc->sc_bar_mappings[bar].h, desc->ports[i].offset, + sc->sc_bar_mappings[bar].s - desc->ports[i].offset, &paa->h)) { printf("%s: couldn't get subregion for port %d\n", sc->sc_dev.dv_xname, i); |