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:
parent
866fe991ac
commit
d91cc9dd63
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=342826
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user