Tue Dec 31 11:42:46 2019 UTC ()
The DMA restrictions may not be defined in the direct parent of a device,
so search up the tree for a module device.


(jmcneill)
diff -r1.15 -r1.16 src/sys/arch/arm/acpi/acpi_machdep.c

cvs diff -r1.15 -r1.16 src/sys/arch/arm/acpi/acpi_machdep.c (expand / switch to unified diff)

--- src/sys/arch/arm/acpi/acpi_machdep.c 2019/12/30 19:50:29 1.15
+++ src/sys/arch/arm/acpi/acpi_machdep.c 2019/12/31 11:42:46 1.16
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: acpi_machdep.c,v 1.15 2019/12/30 19:50:29 jmcneill Exp $ */ 1/* $NetBSD: acpi_machdep.c,v 1.16 2019/12/31 11:42:46 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 The NetBSD Foundation, Inc. 4 * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jared McNeill <jmcneill@invisible.ca>. 8 * by Jared McNeill <jmcneill@invisible.ca>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include "pci.h" 32#include "pci.h"
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.15 2019/12/30 19:50:29 jmcneill Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.16 2019/12/31 11:42:46 jmcneill Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/bus.h> 39#include <sys/bus.h>
40#include <sys/cpu.h> 40#include <sys/cpu.h>
41#include <sys/device.h> 41#include <sys/device.h>
42 42
43#include <uvm/uvm_extern.h> 43#include <uvm/uvm_extern.h>
44 44
45#include <dev/fdt/fdtvar.h> 45#include <dev/fdt/fdtvar.h>
46 46
47#include <dev/acpi/acpica.h> 47#include <dev/acpi/acpica.h>
48#include <dev/acpi/acpivar.h> 48#include <dev/acpi/acpivar.h>
@@ -400,41 +400,62 @@ arm_acpi_dma_tag_subregion(struct acpi_s @@ -400,41 +400,62 @@ arm_acpi_dma_tag_subregion(struct acpi_s
400 if (error != 0) { 400 if (error != 0) {
401 aprint_error_dev(sc->sc_dev, 401 aprint_error_dev(sc->sc_dev,
402 "_DMA subregion failed: %d\n", error); 402 "_DMA subregion failed: %d\n", error);
403 goto done; 403 goto done;
404 } 404 }
405 dmat = newtag; 405 dmat = newtag;
406 406
407done: 407done:
408 acpi_resource_cleanup(&res); 408 acpi_resource_cleanup(&res);
409 409
410 return dmat; 410 return dmat;
411} 411}
412 412
 413static ACPI_HANDLE
 414arm_acpi_dma_module(struct acpi_softc *sc, struct acpi_devnode *ad)
 415{
 416 ACPI_HANDLE tmp;
 417 ACPI_STATUS rv;
 418
 419 /*
 420 * Search up the tree for a module device with a _DMA method.
 421 */
 422 for (; ad != NULL; ad = ad->ad_parent) {
 423 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
 424 continue;
 425 if (!acpi_match_hid(ad->ad_devinfo, module_hid))
 426 continue;
 427 rv = AcpiGetHandle(ad->ad_handle, "_DMA", &tmp);
 428 if (ACPI_SUCCESS(rv))
 429 return ad->ad_handle;
 430 }
 431
 432 return NULL;
 433}
 434
413bus_dma_tag_t 435bus_dma_tag_t
414arm_acpi_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad) 436arm_acpi_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad)
415{ 437{
 438 ACPI_HANDLE module;
416 ACPI_INTEGER cca; 439 ACPI_INTEGER cca;
417 bus_dma_tag_t dmat; 440 bus_dma_tag_t dmat;
418 441
419 if (ACPI_FAILURE(acpi_eval_integer(ad->ad_handle, "_CCA", &cca))) 442 if (ACPI_FAILURE(acpi_eval_integer(ad->ad_handle, "_CCA", &cca)))
420 cca = 1; 443 cca = 1;
421 444
422 if (cca) 445 if (cca)
423 dmat = &acpi_coherent_dma_tag; 446 dmat = &acpi_coherent_dma_tag;
424 else 447 else
425 dmat = &arm_generic_dma_tag; 448 dmat = &arm_generic_dma_tag;
426 449
427 /* 450 /*
428 * If the parent device is a bus, it may define valid DMA ranges 451 * If a parent device is a bus, it may define valid DMA ranges
429 * and translations for child nodes. 452 * and translations for child nodes.
430 */ 453 */
431 if (ad->ad_parent != NULL && 454 module = arm_acpi_dma_module(sc, ad);
432 acpi_match_hid(ad->ad_parent->ad_devinfo, module_hid)) { 455 if (module != NULL)
433 dmat = arm_acpi_dma_tag_subregion(sc, dmat, 456 dmat = arm_acpi_dma_tag_subregion(sc, dmat, module);
434 ad->ad_parent->ad_handle); 
435 } 
436 457
437 return dmat; 458 return dmat;
438} 459}
439__strong_alias(acpi_get_dma_tag,arm_acpi_dma_tag); 460__strong_alias(acpi_get_dma_tag,arm_acpi_dma_tag);
440__strong_alias(acpi_get_dma64_tag,arm_acpi_dma_tag); 461__strong_alias(acpi_get_dma64_tag,arm_acpi_dma_tag);