Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Jan 2016 09:11:20 +0000 (UTC)
From:      Andrew Rybchenko <arybchik@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r293895 - head/sys/dev/sfxge/common
Message-ID:  <201601140911.u0E9BKpr019875@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: arybchik
Date: Thu Jan 14 09:11:20 2016
New Revision: 293895
URL: https://svnweb.freebsd.org/changeset/base/293895

Log:
  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 <alee at solarflare.com>
  Reviewed by:    gnn
  Sponsored by:   Solarflare Communications, Inc.
  MFC after:      2 days
  Differential Revision: https://reviews.freebsd.org/D4915

Modified:
  head/sys/dev/sfxge/common/efx_vpd.c
  head/sys/dev/sfxge/common/hunt_vpd.c
  head/sys/dev/sfxge/common/siena_vpd.c

Modified: head/sys/dev/sfxge/common/efx_vpd.c
==============================================================================
--- head/sys/dev/sfxge/common/efx_vpd.c	Thu Jan 14 09:11:16 2016	(r293894)
+++ head/sys/dev/sfxge/common/efx_vpd.c	Thu Jan 14 09:11:20 2016	(r293895)
@@ -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: head/sys/dev/sfxge/common/hunt_vpd.c
==============================================================================
--- head/sys/dev/sfxge/common/hunt_vpd.c	Thu Jan 14 09:11:16 2016	(r293894)
+++ head/sys/dev/sfxge/common/hunt_vpd.c	Thu Jan 14 09:11:20 2016	(r293895)
@@ -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: head/sys/dev/sfxge/common/siena_vpd.c
==============================================================================
--- head/sys/dev/sfxge/common/siena_vpd.c	Thu Jan 14 09:11:16 2016	(r293894)
+++ head/sys/dev/sfxge/common/siena_vpd.c	Thu Jan 14 09:11:20 2016	(r293895)
@@ -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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601140911.u0E9BKpr019875>