From patchwork Fri Mar 15 10:17:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Hu X-Patchwork-Id: 1912433 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=fwts-devel-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Tx0Yh1Qr4z1yX0 for ; Fri, 15 Mar 2024 21:17:44 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rl4d5-0003V8-7R; Fri, 15 Mar 2024 10:17:35 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rl4ct-0003U5-KH for fwts-devel@lists.ubuntu.com; Fri, 15 Mar 2024 10:17:24 +0000 Received: from canonical.com (unknown [106.104.136.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id 8F1D240ECF for ; Fri, 15 Mar 2024 10:17:22 +0000 (UTC) From: Ivan Hu To: fwts-devel@lists.ubuntu.com Subject: [PATCH] acpi: acpipld: add tests to check _PLD methods only on the connectable ports Date: Fri, 15 Mar 2024 18:17:16 +0800 Message-Id: <20240315101716.118585-1-ivan.hu@canonical.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: "fwts-devel" BugLink: https://bugs.launchpad.net/fwts/+bug/2055855 ACPI specification implies that a port is not connectable and it is assumed to be not visible. Therefore a \_PLD descriptor is not required. Some firmware have _PLD ACPI methods for all USB ports, including unusable USB host ports that are not wired to any connector or internal device. And these unusable ports return similar _PLD objects, with zeroes in their grouptoken and position fields. This confuses the port peering code when pairing USB2 and USB3 ports that are wired to the same connector. And it is results in the linux kernel warning "usb: port power management may be unreliable." Add tests to check the PLD methods existencs on the connectable ports. Signed-off-by: Ivan Hu --- src/Makefile.am | 3 +- src/acpi/acpipld/acpipld.c | 126 +++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/acpi/acpipld/acpipld.c diff --git a/src/Makefile.am b/src/Makefile.am index 0beb17f5..1f48fa2d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,7 +56,8 @@ fwts_SOURCES = main.c \ acpi/ac_adapter/ac_adapter.c \ acpi/acpidump/acpidump.c \ acpi/acpiinfo/acpiinfo.c \ - acpi/acpitables/acpitables.c \ + acpi/acpipld/acpipld.c \ + acpi/acpitables/acpitables.c \ sbbr/acpitables/acpitables.c \ acpi/aest/aest.c \ acpi/apicinstance/apicinstance.c \ diff --git a/src/acpi/acpipld/acpipld.c b/src/acpi/acpipld/acpipld.c new file mode 100644 index 00000000..57462b60 --- /dev/null +++ b/src/acpi/acpipld/acpipld.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2024 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#include "fwts.h" + +#if defined(FWTS_HAS_ACPI) + +#include +#include +#include +#include +#include +#include "fwts_acpi_object_eval.h" + +/* + * acpipld_init() + * initialize ACPI + */ +static int acpipld_init(fwts_framework *fw) +{ + if (fwts_acpi_init(fw) != FWTS_OK) { + fwts_log_error(fw, "Cannot initialise ACPI."); + return FWTS_ERROR; + } + + return FWTS_OK; +} + +/* + * acpipld_deinit + * de-intialize ACPI + */ +static int acpipld_deinit(fwts_framework *fw) +{ + return fwts_acpi_deinit(fw); +} + +static int acpipld_test1(fwts_framework *fw) +{ + fwts_list_link *item; + fwts_list *objects; + const size_t name_len = 4; + bool failed = false; + + if ((objects = fwts_acpi_object_get_names()) == NULL) { + fwts_log_info(fw, "Cannot find any ACPI objects"); + return FWTS_ERROR; + } + + fwts_list_foreach(item, objects) { + char *name = fwts_list_data(char *, item); + const size_t len = strlen(name); + + if (!strncmp("_PLD", name + len - name_len, name_len)) { + fwts_list_link *item_upc; + char *name_cmp; + name_cmp = strdup(name); + strcpy(name_cmp + len - name_len, "_UPC"); + + fwts_list_foreach(item_upc, objects) { + char *name_upc = fwts_list_data(char *, item_upc); + if (!strncmp(name_cmp, name_upc, len)) { + ACPI_OBJECT_LIST arg_list; + ACPI_BUFFER buf; + ACPI_OBJECT *obj; + int ret; + + arg_list.Count = 0; + arg_list.Pointer = NULL; + ret = fwts_acpi_object_evaluate(fw, name_upc, &arg_list, &buf); + if ((ACPI_FAILURE(ret) != AE_OK) || (buf.Pointer == NULL)) + continue; + + obj = buf.Pointer; + if (obj->Package.Elements[0].Integer.Value == 0) { + fwts_failed(fw, LOG_LEVEL_MEDIUM, + "ACPIPLDExistNotConnectable", + "The ACPI method %s exists on the port " + "claimed not connectable by the %s.", + name, name_upc); + failed = true; + } + + free(buf.Pointer); + } + } + free(name_cmp); + } + } + + if (!failed) + fwts_passed(fw, "All _PLD methods exist on the port connectable."); + + return FWTS_OK; +} + +static fwts_framework_minor_test acpipld_tests[] = { + { acpipld_test1, "Check the ACPI _PLD methods exist on the port connectable." }, + { NULL, NULL } +}; + +static fwts_framework_ops acpipld_ops = { + .description = "Check if the ACPI _PLD methods exist on the port connectable.", + .init = acpipld_init, + .deinit = acpipld_deinit, + .minor_tests = acpipld_tests +}; + +FWTS_REGISTER("acpipld", &acpipld_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_BATCH | FWTS_FLAG_ACPI) + +#endif