--- a/sys/dev/misc/dcons/dcons_crom.c +++ b/sys/dev/misc/dcons/dcons_crom.c @@ dmamap_cb(void *arg, bus_dma_segment_t *segments, int seg, int error) - if (error) + if (error) { kprintf("dcons_dmamap_cb: error=%d\n", error); + /* do not touch segments[] (uninitialized on error) and do + * not publish a garbage address into the ConfigROM */ + sc->load_error = error; + return; + } sc = (struct dcons_crom_softc *)arg; @@ dcons_crom_attach(device_t dev) @@ struct dcons_crom_softc *sc; @@ @@ sc = (struct dcons_crom_softc *) device_get_softc(dev); @@ sc->fd.fc = device_get_ivars(dev); @@ sc->fd.dev = dev; @@ sc->fd.post_explore = NULL; @@ sc->fd.post_busreset = (void *) dcons_crom_post_busreset; /* map dcons buffer */ - bus_dma_tag_create( + if (bus_dma_tag_create( /*parent*/ sc->fd.fc->dmat, /*alignment*/ sizeof(u_int32_t), /*boundary*/ 0, @@ /*flags*/ BUS_DMA_ALLOCNOW, - &sc->dma_tag); - bus_dmamap_create(sc->dma_tag, 0, &sc->dma_map); - bus_dmamap_load(sc->dma_tag, sc->dma_map, + &sc->dma_tag) != 0) { + device_printf(dev, "cannot create dma tag\n"); + return (ENXIO); + } + if (bus_dmamap_create(sc->dma_tag, 0, &sc->dma_map) != 0) { + device_printf(dev, "cannot create dma map\n"); + bus_dma_tag_destroy(sc->dma_tag); + return (ENXIO); + } + bus_dmamap_load(sc->dma_tag, sc->dma_map, (void *)dcons_conf->buf, dcons_conf->size, dmamap_cb, sc, 0); + if (sc->load_error) { + device_printf(dev, "dma map load failed (%d)\n", sc->load_error); + bus_dmamap_destroy(sc->dma_tag, sc->dma_map); + bus_dma_tag_destroy(sc->dma_tag); + return (ENXIO); + } return (0); ``` (struct dcons_crom_softc gains `int load_error;`)