Fix use of busdma(9) KPI in ahci(4).

Use BUS_DMA_NOWAIT for loads at initialization time.
Report actual numeric error code if any problem occurs at the
initialization.

Reported and tested by:	pho
Reviewed by:	mav
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D18741
This commit is contained in:
Konstantin Belousov 2019-01-07 02:39:40 +00:00
parent 866fe991ac
commit d91cc9dd63
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=342826

View File

@ -982,18 +982,22 @@ ahci_dmainit(device_t dev)
struct ahci_channel *ch = device_get_softc(dev);
struct ahci_dc_cb_args dcba;
size_t rfsize;
int error;
/* Command area. */
if (bus_dma_tag_create(bus_get_dma_tag(dev), 1024, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), 1024, 0,
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
NULL, NULL, AHCI_WORK_SIZE, 1, AHCI_WORK_SIZE,
0, NULL, NULL, &ch->dma.work_tag))
0, NULL, NULL, &ch->dma.work_tag);
if (error != 0)
goto error;
if (bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work,
BUS_DMA_ZERO, &ch->dma.work_map))
error = bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work,
BUS_DMA_ZERO, &ch->dma.work_map);
if (error != 0)
goto error;
if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work,
AHCI_WORK_SIZE, ahci_dmasetupc_cb, &dcba, 0) || dcba.error) {
error = bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work,
AHCI_WORK_SIZE, ahci_dmasetupc_cb, &dcba, BUS_DMA_NOWAIT);
if (error != 0 || (error = dcba.error) != 0) {
bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
goto error;
}
@ -1003,33 +1007,37 @@ ahci_dmainit(device_t dev)
rfsize = 4096;
else
rfsize = 256;
if (bus_dma_tag_create(bus_get_dma_tag(dev), rfsize, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), rfsize, 0,
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
NULL, NULL, rfsize, 1, rfsize,
0, NULL, NULL, &ch->dma.rfis_tag))
0, NULL, NULL, &ch->dma.rfis_tag);
if (error != 0)
goto error;
if (bus_dmamem_alloc(ch->dma.rfis_tag, (void **)&ch->dma.rfis, 0,
&ch->dma.rfis_map))
error = bus_dmamem_alloc(ch->dma.rfis_tag, (void **)&ch->dma.rfis, 0,
&ch->dma.rfis_map);
if (error != 0)
goto error;
if (bus_dmamap_load(ch->dma.rfis_tag, ch->dma.rfis_map, ch->dma.rfis,
rfsize, ahci_dmasetupc_cb, &dcba, 0) || dcba.error) {
error = bus_dmamap_load(ch->dma.rfis_tag, ch->dma.rfis_map, ch->dma.rfis,
rfsize, ahci_dmasetupc_cb, &dcba, BUS_DMA_NOWAIT);
if (error != 0 || (error = dcba.error) != 0) {
bus_dmamem_free(ch->dma.rfis_tag, ch->dma.rfis, ch->dma.rfis_map);
goto error;
}
ch->dma.rfis_bus = dcba.maddr;
/* Data area. */
if (bus_dma_tag_create(bus_get_dma_tag(dev), 2, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), 2, 0,
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
NULL, NULL,
AHCI_SG_ENTRIES * PAGE_SIZE * ch->numslots,
AHCI_SG_ENTRIES, AHCI_PRD_MAX,
0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) {
0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag);
if (error != 0)
goto error;
}
return;
error:
device_printf(dev, "WARNING - DMA initialization failed\n");
device_printf(dev, "WARNING - DMA initialization failed, error %d\n",
error);
ahci_dmafini(dev);
}