From patchwork Mon Oct 14 05:17:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitay Isaacs X-Patchwork-Id: 1175965 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46s6L85Ylkz9sR0 for ; Mon, 14 Oct 2019 16:19:12 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="ph+wZoQy"; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 46s6L83qMKzDqWy for ; Mon, 14 Oct 2019 16:19:12 +1100 (AEDT) X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [203.11.71.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 46s6Jy2zC4zDqW5 for ; Mon, 14 Oct 2019 16:18:10 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="ph+wZoQy"; dkim-atps=neutral Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail.ozlabs.org (Postfix) with ESMTPSA id 46s6Jx6tg8z9sPh; Mon, 14 Oct 2019 16:18:09 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1571030290; bh=Duevb5mY31qJDYsoDF438B+N/TREDLz/LPoGJ8vtuYw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ph+wZoQyvGWwKaZT22q8xfqff8oqiJpw29P7loa2z7n99i6pW2nQbrBM0szpVTvSk amfZUE8OxQGKxGzLD8ujVIjOqU7BirNLUHv1QVWZ9ZQ7pgcCQJXy5iqZNETogBitPe wVOywWuwTjtjffe2XYcaujtVSbu16vYcxYnizJAFX45FetmFD4kYgJu4ot3qMDOhs1 KxoY/McZnIhKn1HdD5etZYoSMVPI09rtD94g/neeLYp9sGsXZ1jSAtVx58c4k9YOH3 9OVnwlVfCTjIWGhTQBEDJxp1rwAWfVVgg0AQH/Woe16LtViGc40u3uGORENKXGe+bc bH+txfV951jTw== From: Amitay Isaacs To: pdbg@lists.ozlabs.org Date: Mon, 14 Oct 2019 16:17:31 +1100 Message-Id: <20191014051748.20190-14-amitay@ozlabs.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191014051748.20190-1-amitay@ozlabs.org> References: <20191014051748.20190-1-amitay@ozlabs.org> MIME-Version: 1.0 Subject: [Pdbg] [PATCH v5 13/30] libpdbg: Child traversal should handle virtual nodes correctly X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Amitay Isaacs Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" When traversing system device tree view (system == true), the children are calculated based on the system device tree view (using the virtual node attachments). When traversing backend device tree (system == false), the virtual nodes are ignored except if they are part of the backend device tree itself. Signed-off-by: Amitay Isaacs Reviewed-by: Alistair Popple --- libpdbg/libpdbg.c | 96 ++++++++++++++++++++++++++++++++++++++++++++--- libpdbg/libpdbg.h | 6 +-- 2 files changed, 93 insertions(+), 9 deletions(-) diff --git a/libpdbg/libpdbg.c b/libpdbg/libpdbg.c index aade5d3..0653197 100644 --- a/libpdbg/libpdbg.c +++ b/libpdbg/libpdbg.c @@ -43,18 +43,102 @@ retry: } } -struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last) +static struct pdbg_target *target_map_child(struct pdbg_target *next, bool system) { - if (!parent || list_empty(&parent->children)) + /* + * Map a target in system tree: + * + * - If there is no virtual node assiociated, then return the target + * (the target itself can be virtual or real) + * + * - If there is virtual node associated, + * - If the target is virtual, return the associated node + * - If the target is real, return NULL + * (this target is already covered by previous condition) + * + * Map a target in backend tree: + * + * - If the target is real, return the target + * + * - If the target is virtual, return NULL + * (no virtual nodes in backend tree) + */ + if (system) { + if (!next->vnode) + return next; + else + if (target_is_virtual(next)) + return next->vnode; + } else { + if (!target_is_virtual(next)) + return next; + } + + return NULL; +} + +struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last, bool system) +{ + struct pdbg_target *next, *child = NULL; + + if (!parent) return NULL; - if (!last) - return list_top(&parent->children, struct pdbg_target, list); + /* + * Parent node can be virtual or real. + * + * If the parent node doesn't have any children, + * - If there is associated virtual node, + * Use that node as parent + * + * - If there is no associated virtual node, + * No children + */ + if (list_empty(&parent->children)) { + if (parent->vnode) + parent = parent->vnode; + else + return NULL; + } + + /* + * If the parent node has children, + * - Traverse the children + * (map the children in system or backend tree) + */ + if (!last) { + list_for_each(&parent->children, child, list) + if ((next = target_map_child(child, system))) + return next; - if (last->list.next == &parent->children.n) return NULL; + } - return list_entry(last->list.next, struct pdbg_target, list); + /* + * In a system tree traversal, virtual targets with associated + * nodes, get mapped to real targets. + * + * When the last child is specified: + * - If in a system tree traverse, and + * the last child has associated node, and + * the last child is real + * Then the last child is not the actual child of the parent + * (the associated virtual node is the actual child) + */ + if (system) + last = target_to_virtual(last, false); + + if (last == list_tail(&parent->children, struct pdbg_target, list)) + return NULL; + + child = last; + do { + child = list_entry(child->list.next, struct pdbg_target, list); + if ((next = target_map_child(child, system))) + return next; + } while (child != list_tail(&parent->children, struct pdbg_target, list)); + + return NULL; } enum pdbg_target_status pdbg_target_status(struct pdbg_target *target) diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h index 722ddc2..4eec123 100644 --- a/libpdbg/libpdbg.h +++ b/libpdbg/libpdbg.h @@ -20,7 +20,7 @@ struct pdbg_target *__pdbg_next_compatible_node(struct pdbg_target *root, struct pdbg_target *prev, const char *compat); struct pdbg_target *__pdbg_next_target(const char *klass, struct pdbg_target *parent, struct pdbg_target *last); -struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last); +struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last, bool system); /* * Each target has a status associated with it. This is what each status means: @@ -71,9 +71,9 @@ enum pdbg_backend { PDBG_DEFAULT_BACKEND = 0, PDBG_BACKEND_FSI, PDBG_BACKEND_I2C target = __pdbg_next_target(class, NULL, target)) #define pdbg_for_each_child_target(parent, target) \ - for (target = __pdbg_next_child_target(parent, NULL); \ + for (target = __pdbg_next_child_target(parent, NULL, true); \ target; \ - target = __pdbg_next_child_target(parent, target)) + target = __pdbg_next_child_target(parent, target, true)) /* Return the first parent target of the given class, or NULL if the given * target does not have a parent of the given class. */