Check the return values of contigmalloc(9) as well as bus_dma(9)
functions and stop attaching of dcons(4) and dcons_crom(4) if they indicate failure. This fixes a panic seen on sparc64 machines with no free physical memory in the requested 32-bit region but still doesn't make dcons(4)/dcons_crom(4) these work. I think the latter can be fixed by simply specifying ~0UL as the upper limit for contigmalloc(9) and letting the bounce pages and the IOMMU respectively handle limitations of the DMA engine. I didn't want to change that without the consensus of simokawa@ though, who unfortunately didn't reply so far. MFC after: 1 week
This commit is contained in:
parent
c412d503cf
commit
3da80d3a0e
@ -205,7 +205,10 @@ dcons_crom_attach(device_t dev)
|
||||
return (-1);
|
||||
#else
|
||||
struct dcons_crom_softc *sc;
|
||||
int error;
|
||||
|
||||
if (dcons_conf->buf == NULL)
|
||||
return (ENXIO);
|
||||
sc = (struct dcons_crom_softc *) device_get_softc(dev);
|
||||
sc->fd.fc = device_get_ivars(dev);
|
||||
sc->fd.dev = dev;
|
||||
@ -213,7 +216,7 @@ dcons_crom_attach(device_t dev)
|
||||
sc->fd.post_busreset = (void *) dcons_crom_post_busreset;
|
||||
|
||||
/* map dcons buffer */
|
||||
bus_dma_tag_create(
|
||||
error = bus_dma_tag_create(
|
||||
/*parent*/ sc->fd.fc->dmat,
|
||||
/*alignment*/ sizeof(u_int32_t),
|
||||
/*boundary*/ 0,
|
||||
@ -229,10 +232,16 @@ dcons_crom_attach(device_t dev)
|
||||
/*lockarg*/&Giant,
|
||||
#endif
|
||||
&sc->dma_tag);
|
||||
bus_dmamap_create(sc->dma_tag, BUS_DMA_COHERENT, &sc->dma_map);
|
||||
bus_dmamap_load(sc->dma_tag, sc->dma_map,
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = bus_dmamap_create(sc->dma_tag, BUS_DMA_COHERENT, &sc->dma_map);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = bus_dmamap_load(sc->dma_tag, sc->dma_map,
|
||||
(void *)dcons_conf->buf, dcons_conf->size,
|
||||
dmamap_cb, sc, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
sc->ehand = EVENTHANDLER_REGISTER(dcons_poll, dcons_crom_poll,
|
||||
(void *)sc, 0);
|
||||
return (0);
|
||||
|
@ -336,6 +336,8 @@ dcons_drv_init(int stage)
|
||||
*/
|
||||
dg.buf = (struct dcons_buf *) contigmalloc(dg.size,
|
||||
M_DEVBUF, 0, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
|
||||
if (dg.buf == NULL)
|
||||
return (-1);
|
||||
dcons_init(dg.buf, dg.size, sc);
|
||||
}
|
||||
|
||||
@ -400,8 +402,8 @@ dcons_modevent(module_t mode, int type, void *data)
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
ret = dcons_drv_init(1);
|
||||
dcons_attach();
|
||||
if (ret == 0) {
|
||||
dcons_attach();
|
||||
dcons_cnprobe(&dcons_consdev);
|
||||
dcons_cninit(&dcons_consdev);
|
||||
cnadd(&dcons_consdev);
|
||||
@ -409,13 +411,15 @@ dcons_modevent(module_t mode, int type, void *data)
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
printf("dcons: unload\n");
|
||||
callout_stop(&dcons_callout);
|
||||
cnremove(&dcons_consdev);
|
||||
dcons_detach(DCONS_CON);
|
||||
dcons_detach(DCONS_GDB);
|
||||
dg.buf->magic = 0;
|
||||
if (drv_init == 1) {
|
||||
callout_stop(&dcons_callout);
|
||||
cnremove(&dcons_consdev);
|
||||
dcons_detach(DCONS_CON);
|
||||
dcons_detach(DCONS_GDB);
|
||||
dg.buf->magic = 0;
|
||||
|
||||
contigfree(dg.buf, DCONS_BUF_SIZE, M_DEVBUF);
|
||||
contigfree(dg.buf, DCONS_BUF_SIZE, M_DEVBUF);
|
||||
}
|
||||
|
||||
break;
|
||||
case MOD_SHUTDOWN:
|
||||
|
Loading…
Reference in New Issue
Block a user