From patchwork Wed Feb 4 06:59:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neelesh Gupta X-Patchwork-Id: 436164 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 74CA0140216 for ; Wed, 4 Feb 2015 18:14:58 +1100 (AEDT) Received: from ozlabs.org (ozlabs.org [103.22.144.67]) by lists.ozlabs.org (Postfix) with ESMTP id 64E8A1A09EE for ; Wed, 4 Feb 2015 18:14:58 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e28smtp03.in.ibm.com (e28smtp03.in.ibm.com [122.248.162.3]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id E838D1A09C4 for ; Wed, 4 Feb 2015 18:14:54 +1100 (AEDT) Received: from /spool/local by e28smtp03.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 4 Feb 2015 12:44:52 +0530 Received: from d28dlp02.in.ibm.com (9.184.220.127) by e28smtp03.in.ibm.com (192.168.1.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 4 Feb 2015 12:44:49 +0530 Received: from d28relay01.in.ibm.com (d28relay01.in.ibm.com [9.184.220.58]) by d28dlp02.in.ibm.com (Postfix) with ESMTP id 468403940049 for ; Wed, 4 Feb 2015 12:44:49 +0530 (IST) Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay01.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t1476pMm23593024 for ; Wed, 4 Feb 2015 12:44:47 +0530 Received: from d28av01.in.ibm.com (localhost [127.0.0.1]) by d28av01.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t1471oAR029514 for ; Wed, 4 Feb 2015 12:31:50 +0530 Received: from localhost.localdomain ([9.124.35.239]) by d28av01.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t1471oJT029471 for ; Wed, 4 Feb 2015 12:31:50 +0530 To: skiboot@lists.ozlabs.org From: Neelesh Gupta Date: Wed, 04 Feb 2015 12:29:45 +0530 Message-ID: <20150204065930.3278.38032.stgit@localhost.localdomain> In-Reply-To: <20150204065108.3278.92169.stgit@localhost.localdomain> References: <20150204065108.3278.92169.stgit@localhost.localdomain> User-Agent: StGit/0.16 MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15020407-0009-0000-0000-000003CE5B1F Subject: [Skiboot] [PATCH v3 2/3] vpd: Use slca parent-child relationship to create vpd tree X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" SLCA entries available through hdat have parent-child relationship of various FRUs of the system, the patch makes use of this data to create VPD nodes in hierarchial fashion. This is further useful for the user space tools like 'lshw'/'lsvpd' to plug-in the support easily on POWER. Signed-off-by: Neelesh Gupta --- hdata/spira.h | 2 + hdata/vpd.c | 217 ++++++++++++++++++++------------------------------------- 2 files changed, 77 insertions(+), 142 deletions(-) diff --git a/hdata/spira.h b/hdata/spira.h index fa73452..a1ed79d 100644 --- a/hdata/spira.h +++ b/hdata/spira.h @@ -599,6 +599,8 @@ struct cpu_ctl_init_data { */ #define SLCA_IDATA_ARRAY 0 +#define SLCA_ROOT_INDEX 0 + /* Note: An "index" (or idx) is always an index into the SLCA array * and "id" is a reference to some other object. */ diff --git a/hdata/vpd.c b/hdata/vpd.c index e568a06..38b0737 100644 --- a/hdata/vpd.c +++ b/hdata/vpd.c @@ -70,6 +70,9 @@ static const struct card_info card_table[] = { /* Other cards */ }; +static struct dt_node *dt_create_vpd_node(struct dt_node *parent, + const struct slca_entry *entry); + static const struct card_info *card_info_lookup(char *ccin) { int i; @@ -425,88 +428,6 @@ static const char *vpd_map_name(const char *vpd_name) static bool valid_child_entry(const struct slca_entry *entry) { - if (!entry) - return false; - - /* - * Skip entries with independent ntuple FRUVPD/MSVPD, etc., - * representations, since they have a unique PN, FN, SN, et al. - * We add details for those devices via the ntuple walk. - */ - switch (entry->fru_id[0]) { - case 'A': - switch (entry->fru_id[1]) { - case 'V': /* AV */ - return false; - } - break; - case 'B': - switch (entry->fru_id[1]) { - case 'P': /* BP */ - case 'X': /* BX */ - return false; - } - break; - case 'C': - switch (entry->fru_id[1]) { - case 'C': /* CC */ - return false; - } - break; - case 'D': - switch (entry->fru_id[1]) { - case 'B': /* DB */ - return false; - } - break; - case 'E': - switch (entry->fru_id[1]) { - case 'V': /* EV */ - return false; - } - break; - case 'M': - switch (entry->fru_id[1]) { - case 'S': /* MS */ - return false; - } - break; - case 'O': - switch (entry->fru_id[1]) { - case 'P': /* OP */ - return false; - } - break; - case 'R': - switch (entry->fru_id[1]) { - case 'I': /* RI */ - return false; - } - break; - case 'P': - switch (entry->fru_id[1]) { - case '2': /* P2 */ - case '5': /* P5 */ - case 'F': /* PF */ - return false; - } - break; - case 'S': - switch (entry->fru_id[1]) { - case 'P': /* SP */ - return false; - } - break; - case 'T': - switch (entry->fru_id[1]) { - case 'P': /* TP */ - return false; - } - break; - default: - break; - } - if ((entry->install_indic == SLCA_INSTALL_INSTALLED) && (entry->vpd_collected == SLCA_VPD_COLLECTED)) return true; @@ -546,26 +467,11 @@ static void vpd_add_children(struct dt_node *parent, uint16_t slca_index) return; if (valid_child_entry(child)) { - const char *name; - uint64_t addr; struct dt_node *node; - /* create new node, add location code */ - name = vpd_map_name(child->fru_id); - addr = (uint64_t)be16_to_cpu(child->rsrc_id); - node = dt_new_addr(parent, name, addr); - if (!node) { - prerror("VPD: Creating node at %s@%llx failed\n", - name, addr); + node = dt_create_vpd_node(parent, child); + if (!node) return; - } - slca_vpd_add_loc_code(node, be16_to_cpu(child->my_index)); - - /* Add child FRU type */ - dt_add_property(node, "fru-type", child->fru_id, 2); - - /* recursively add children */ - vpd_add_children(node, be16_to_cpu(child->my_index)); } /* Skip dups -- currently we presume dups are contiguous */ @@ -576,83 +482,110 @@ static void vpd_add_children(struct dt_node *parent, uint16_t slca_index) return; } +/* Create the vpd node and add its children */ +static struct dt_node *dt_create_vpd_node(struct dt_node *parent, + const struct slca_entry *entry) +{ + struct dt_node *node; + const char *name; + uint64_t addr; + + name = vpd_map_name(entry->fru_id); + addr = (uint64_t)be16_to_cpu(entry->rsrc_id); + node = dt_new_addr(parent, name, addr); + if (!node) { + prerror("VPD: Creating node at %s@%llx failed\n", name, addr); + return NULL; + } + + /* Add location code */ + slca_vpd_add_loc_code(node, be16_to_cpu(entry->my_index)); + /* Add FRU label */ + dt_add_property(node, "fru-type", entry->fru_id, 2); + /* Recursively add children */ + vpd_add_children(node, be16_to_cpu(entry->my_index)); + + return node; +} + struct dt_node *dt_add_vpd_node(const struct HDIF_common_hdr *hdr, int indx_fru, int indx_vpd) { - const void *fruvpd; - unsigned int fruvpd_sz; - unsigned int fru_id_sz; - uint64_t addr; - struct dt_node *dt_vpd; - struct dt_node *node; const struct spira_fru_id *fru_id; - const struct slca_entry *s_entry; - const char *vpd_name; + unsigned int fruvpd_sz, fru_id_sz; + const struct slca_entry *entry; + struct dt_node *dt_vpd, *node; + static bool first = true; + const void *fruvpd; const char *name; - int len; + uint64_t addr; char *lname; + int len; fru_id = HDIF_get_idata(hdr, indx_fru, &fru_id_sz); if (!fru_id) return NULL; - s_entry = slca_get_entry(be16_to_cpu(fru_id->slca_index)); - if (valid_child_entry(s_entry)) /* Don't populate child VPD here */ - return NULL; - fruvpd = HDIF_get_idata(hdr, indx_vpd, &fruvpd_sz); if (!CHECK_SPPTR(fruvpd)) return NULL; - vpd_name = slca_get_vpd_name(be16_to_cpu(fru_id->slca_index)); - if (!vpd_name) { - prerror("VPD: VPD name at index %d couldn't be found\n", - fru_id->slca_index); + dt_vpd = dt_find_by_path(dt_root, "/vpd"); + if (!dt_vpd) return NULL; + + if (first) { + entry = slca_get_entry(SLCA_ROOT_INDEX); + if (!entry) { + prerror("VPD: Could not find the slca root entry\n"); + return NULL; + } + + node = dt_create_vpd_node(dt_vpd, entry); + if (!node) + return NULL; + + first = false; } - dt_vpd = dt_find_by_path(dt_root, "/vpd"); - if (!dt_vpd) + entry = slca_get_entry(fru_id->slca_index); + if (!entry) return NULL; - /* Get node name */ - name = vpd_map_name(vpd_name); - addr = (uint64_t)be16_to_cpu(fru_id->rsrc_id); + name = vpd_map_name(entry->fru_id); + addr = (uint64_t)be16_to_cpu(entry->rsrc_id); len = strlen(name) + STR_MAX_CHARS(addr) + 2; lname = zalloc(len); if (!lname) { prerror("VPD: Failed to allocate memory\n"); return NULL; } + snprintf(lname, len, "%s@%llx", name, (long long)addr); + /* Get the node already created */ + node = dt_find_by_name(dt_vpd, lname); + free(lname); /* - * FRU can be a child of some other FRU. Make sure - * we have not added this node already. + * It is unlikely that node not found because vpd nodes have the + * corresponding slca entry which we would have used to populate the vpd + * tree during the 'first' pass above so that we just need to perform + * VINI parse and add the vpd data.. + * Still, we consider this case and create fresh node under '/vpd' if + * 'node' not found. */ - node = dt_find_by_path(dt_vpd, lname); - if (node) { - free(lname); - return NULL; - } - - node = dt_new(dt_vpd, lname); if (!node) { - free(lname); - return NULL; + node = dt_create_vpd_node(dt_vpd, entry); + if (!node) + return NULL; } - /* Parse VPD fields */ - dt_add_property(node, "ibm,vpd", fruvpd, fruvpd_sz); - vpd_vini_parse(node, fruvpd, fruvpd_sz); - - /* Location code */ - slca_vpd_add_loc_code(node, be16_to_cpu(fru_id->slca_index)); - /* Add FRU label */ - dt_add_property(node, "fru-type", vpd_name, 2); - vpd_add_children(node, be16_to_cpu(fru_id->slca_index)); + /* Parse VPD fields, ensure that it has not been added already */ + if (!dt_find_property(node, "ibm,vpd")) { + dt_add_property(node, "ibm,vpd", fruvpd, fruvpd_sz); + vpd_vini_parse(node, fruvpd, fruvpd_sz); + } - free(lname); return node; }