Skip to content

Commit f6933c0

Browse files
broonierobherring
authored andcommitted
of/address: Return an error when no valid dma-ranges are found
Commit 7a8b64d ("of/address: use range parser for of_dma_get_range") converted the parsing of dma-range properties to use code shared with the PCI range parser. The intent was to introduce no functional changes however in the case where we fail to translate the first resource instead of returning -EINVAL the new code we return 0. Restore the previous behaviour by returning an error if we find no valid ranges, the original code only handled the first range but subsequently support for parsing all supplied ranges was added. This avoids confusing code using the parsed ranges which doesn't expect to successfully parse ranges but have only a list terminator returned, this fixes breakage with so far as I can tell all DMA for on SoC devices on the Socionext Synquacer platform which has a firmware supplied DT. A bisect identified the original conversion as triggering the issues there. Fixes: 7a8b64d ("of/address: use range parser for of_dma_get_range") Signed-off-by: Mark Brown <[email protected]> Cc: Luca Di Stefano <[email protected]> Cc: [email protected] Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rob Herring <[email protected]>
1 parent 241d2fb commit f6933c0

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

drivers/of/address.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -965,8 +965,19 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
965965
}
966966

967967
of_dma_range_parser_init(&parser, node);
968-
for_each_of_range(&parser, &range)
968+
for_each_of_range(&parser, &range) {
969+
if (range.cpu_addr == OF_BAD_ADDR) {
970+
pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n",
971+
range.bus_addr, node);
972+
continue;
973+
}
969974
num_ranges++;
975+
}
976+
977+
if (!num_ranges) {
978+
ret = -EINVAL;
979+
goto out;
980+
}
970981

971982
r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL);
972983
if (!r) {
@@ -975,18 +986,16 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
975986
}
976987

977988
/*
978-
* Record all info in the generic DMA ranges array for struct device.
989+
* Record all info in the generic DMA ranges array for struct device,
990+
* returning an error if we don't find any parsable ranges.
979991
*/
980992
*map = r;
981993
of_dma_range_parser_init(&parser, node);
982994
for_each_of_range(&parser, &range) {
983995
pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n",
984996
range.bus_addr, range.cpu_addr, range.size);
985-
if (range.cpu_addr == OF_BAD_ADDR) {
986-
pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n",
987-
range.bus_addr, node);
997+
if (range.cpu_addr == OF_BAD_ADDR)
988998
continue;
989-
}
990999
r->cpu_start = range.cpu_addr;
9911000
r->dma_start = range.bus_addr;
9921001
r->size = range.size;

0 commit comments

Comments
 (0)