From owner-svn-src-all@freebsd.org Wed Jan 20 07:53:27 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CBC75A89002; Wed, 20 Jan 2016 07:53:27 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A33031BC1; Wed, 20 Jan 2016 07:53:27 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0K7rQWn027317; Wed, 20 Jan 2016 07:53:26 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0K7rQJH027314; Wed, 20 Jan 2016 07:53:26 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201601200753.u0K7rQJH027314@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Wed, 20 Jan 2016 07:53:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r294383 - stable/10/sys/dev/sfxge/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Jan 2016 07:53:27 -0000 Author: arybchik Date: Wed Jan 20 07:53:26 2016 New Revision: 294383 URL: https://svnweb.freebsd.org/changeset/base/294383 Log: MFC r293895 sfxge: fix common code VPD iterator and duplicate tag verification Fix efx_vpd_hunk_next() which has -- since its inception -- failed to correctly iterate over the tags and keywords contained in the VPD data. Only the first tag or keyword would be returned and the next call with *contp == 1 would walk to the end of the data and finish. This was spotted when fixing up errors spotted by Prefast code analysis (which neglected to set all of the out parameters in all successful cases) Also fix efx_vpd_verify() on Siena and EF10 which (as a side effect of correctly iterating over all the tags and keywords) was failing as it detected that both the static VPD and dynamic VPD storage contained an RV keyword in the VPD-R tag. This is intentional as the static VPD and dynamic VPD are stored separately (firmware merges their contents and computes a new RV keyword checksum for the data readable from the VPD capability in PCIe configuration space). Submitted by: Andrew Lee Reviewed by: gnn Sponsored by: Solarflare Communications, Inc. Modified: stable/10/sys/dev/sfxge/common/efx_vpd.c stable/10/sys/dev/sfxge/common/hunt_vpd.c stable/10/sys/dev/sfxge/common/siena_vpd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/efx_vpd.c ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_vpd.c Wed Jan 20 07:52:24 2016 (r294382) +++ stable/10/sys/dev/sfxge/common/efx_vpd.c Wed Jan 20 07:53:26 2016 (r294383) @@ -669,7 +669,7 @@ efx_vpd_hunk_next( __in size_t size, __out efx_vpd_tag_t *tagp, __out efx_vpd_keyword_t *keywordp, - __out_bcount_opt(*paylenp) unsigned int *payloadp, + __out_opt unsigned int *payloadp, __out_opt uint8_t *paylenp, __inout unsigned int *contp) { @@ -689,12 +689,18 @@ efx_vpd_hunk_next( if ((rc = efx_vpd_next_tag(data, size, &offset, &tag, &taglen)) != 0) goto fail1; - if (tag == EFX_VPD_END) + + if (tag == EFX_VPD_END) { + keyword = 0; + paylen = 0; + index = 0; break; + } if (tag == EFX_VPD_ID) { - if (index == *contp) { + if (index++ == *contp) { EFSYS_ASSERT3U(taglen, <, 0x100); + keyword = 0; paylen = (uint8_t)MIN(taglen, 0xff); goto done; @@ -705,7 +711,7 @@ efx_vpd_hunk_next( taglen, pos, &keyword, &keylen)) != 0) goto fail2; - if (index == *contp) { + if (index++ == *contp) { offset += pos + 3; paylen = keylen; @@ -717,9 +723,6 @@ efx_vpd_hunk_next( offset += taglen; } - *contp = 0; - return (0); - done: *tagp = tag; *keywordp = keyword; @@ -728,7 +731,7 @@ done: if (paylenp != NULL) *paylenp = paylen; - ++(*contp); + *contp = index; return (0); fail2: Modified: stable/10/sys/dev/sfxge/common/hunt_vpd.c ============================================================================== --- stable/10/sys/dev/sfxge/common/hunt_vpd.c Wed Jan 20 07:52:24 2016 (r294382) +++ stable/10/sys/dev/sfxge/common/hunt_vpd.c Wed Jan 20 07:53:26 2016 (r294383) @@ -210,6 +210,13 @@ ef10_vpd_verify( if (dcont == 0) break; + /* + * Skip the RV keyword. It should be present in both the static + * and dynamic cfg sectors. + */ + if (dtag == EFX_VPD_RO && dkey == EFX_VPD_KEYWORD('R', 'V')) + continue; + scont = 0; _NOTE(CONSTANTCONDITION) while (1) { Modified: stable/10/sys/dev/sfxge/common/siena_vpd.c ============================================================================== --- stable/10/sys/dev/sfxge/common/siena_vpd.c Wed Jan 20 07:52:24 2016 (r294382) +++ stable/10/sys/dev/sfxge/common/siena_vpd.c Wed Jan 20 07:53:26 2016 (r294383) @@ -326,6 +326,13 @@ siena_vpd_verify( if (dcont == 0) break; + /* + * Skip the RV keyword. It should be present in both the static + * and dynamic cfg sectors. + */ + if (dtag == EFX_VPD_RO && dkey == EFX_VPD_KEYWORD('R', 'V')) + continue; + scont = 0; _NOTE(CONSTANTCONDITION) while (1) {