svn commit: r340823 - head/sys/dev/sfxge/common

Andrew Rybchenko arybchik at FreeBSD.org
Fri Nov 23 10:21:40 UTC 2018


Author: arybchik
Date: Fri Nov 23 10:21:36 2018
New Revision: 340823
URL: https://svnweb.freebsd.org/changeset/base/340823

Log:
  sfxge(4): precheck and verify flash writes
  
  Read existing flash content before writing, so the flash write can be
  avoided if the existing partition content matches the new image. This
  avoids unnecessary write cycles for the flash device, and may also be
  faster. If the flash does need to be updated, verify the content after
  writing.
  
  Note that reading the flash content after writing but before calling
  efx_nvram-rw_finish() avoids firmware bug68170, which can lead to
  signed image updates failing on Medford.
  
  Submitted by:   Andy Moreton <amoreton at solarflare.com>
  Sponsored by:   Solarflare Communications, Inc.
  Differential Revision:  https://reviews.freebsd.org/D18093

Modified:
  head/sys/dev/sfxge/common/ef10_impl.h
  head/sys/dev/sfxge/common/ef10_nvram.c
  head/sys/dev/sfxge/common/efx.h
  head/sys/dev/sfxge/common/efx_impl.h
  head/sys/dev/sfxge/common/efx_nvram.c

Modified: head/sys/dev/sfxge/common/ef10_impl.h
==============================================================================
--- head/sys/dev/sfxge/common/ef10_impl.h	Fri Nov 23 10:21:28 2018	(r340822)
+++ head/sys/dev/sfxge/common/ef10_impl.h	Fri Nov 23 10:21:36 2018	(r340823)
@@ -445,6 +445,14 @@ ef10_nvram_partn_read(
 	__in			size_t size);
 
 extern	__checkReturn		efx_rc_t
+ef10_nvram_partn_read_backup(
+	__in			efx_nic_t *enp,
+	__in			uint32_t partn,
+	__in			unsigned int offset,
+	__out_bcount(size)	caddr_t data,
+	__in			size_t size);
+
+extern	__checkReturn		efx_rc_t
 ef10_nvram_partn_erase(
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn,

Modified: head/sys/dev/sfxge/common/ef10_nvram.c
==============================================================================
--- head/sys/dev/sfxge/common/ef10_nvram.c	Fri Nov 23 10:21:28 2018	(r340822)
+++ head/sys/dev/sfxge/common/ef10_nvram.c	Fri Nov 23 10:21:36 2018	(r340823)
@@ -1940,11 +1940,34 @@ ef10_nvram_partn_read(
 	__in			size_t size)
 {
 	/*
-	 * Read requests which come in through the EFX API expect to
-	 * read the current, active partition.
+	 * An A/B partition has two data stores (current and backup).
+	 * Read requests which come in through the EFX API expect to read the
+	 * current, active store of an A/B partition. For non A/B partitions,
+	 * there is only a single store and so the mode param is ignored.
 	 */
 	return ef10_nvram_partn_read_mode(enp, partn, offset, data, size,
 			    MC_CMD_NVRAM_READ_IN_V2_TARGET_CURRENT);
+}
+
+	__checkReturn		efx_rc_t
+ef10_nvram_partn_read_backup(
+	__in			efx_nic_t *enp,
+	__in			uint32_t partn,
+	__in			unsigned int offset,
+	__out_bcount(size)	caddr_t data,
+	__in			size_t size)
+{
+	/*
+	 * An A/B partition has two data stores (current and backup).
+	 * Read the backup store of an A/B partition (i.e. the store currently
+	 * being written to if the partition is locked).
+	 *
+	 * This is needed when comparing the existing partition content to avoid
+	 * unnecessary writes, or to read back what has been written to check
+	 * that the writes have succeeded.
+	 */
+	return ef10_nvram_partn_read_mode(enp, partn, offset, data, size,
+			    MC_CMD_NVRAM_READ_IN_V2_TARGET_BACKUP);
 }
 
 	__checkReturn		efx_rc_t

Modified: head/sys/dev/sfxge/common/efx.h
==============================================================================
--- head/sys/dev/sfxge/common/efx.h	Fri Nov 23 10:21:28 2018	(r340822)
+++ head/sys/dev/sfxge/common/efx.h	Fri Nov 23 10:21:36 2018	(r340823)
@@ -1437,6 +1437,14 @@ efx_nvram_read_chunk(
 	__in			size_t size);
 
 extern	__checkReturn		efx_rc_t
+efx_nvram_read_backup(
+	__in			efx_nic_t *enp,
+	__in			efx_nvram_type_t type,
+	__in			unsigned int offset,
+	__out_bcount(size)	caddr_t data,
+	__in			size_t size);
+
+extern	__checkReturn		efx_rc_t
 efx_nvram_set_version(
 	__in			efx_nic_t *enp,
 	__in			efx_nvram_type_t type,

Modified: head/sys/dev/sfxge/common/efx_impl.h
==============================================================================
--- head/sys/dev/sfxge/common/efx_impl.h	Fri Nov 23 10:21:28 2018	(r340822)
+++ head/sys/dev/sfxge/common/efx_impl.h	Fri Nov 23 10:21:36 2018	(r340823)
@@ -471,6 +471,8 @@ typedef struct efx_nvram_ops_s {
 	efx_rc_t	(*envo_partn_rw_start)(efx_nic_t *, uint32_t, size_t *);
 	efx_rc_t	(*envo_partn_read)(efx_nic_t *, uint32_t,
 					    unsigned int, caddr_t, size_t);
+	efx_rc_t	(*envo_partn_read_backup)(efx_nic_t *, uint32_t,
+					    unsigned int, caddr_t, size_t);
 	efx_rc_t	(*envo_partn_erase)(efx_nic_t *, uint32_t,
 					    unsigned int, size_t);
 	efx_rc_t	(*envo_partn_write)(efx_nic_t *, uint32_t,

Modified: head/sys/dev/sfxge/common/efx_nvram.c
==============================================================================
--- head/sys/dev/sfxge/common/efx_nvram.c	Fri Nov 23 10:21:28 2018	(r340822)
+++ head/sys/dev/sfxge/common/efx_nvram.c	Fri Nov 23 10:21:36 2018	(r340823)
@@ -48,6 +48,7 @@ static const efx_nvram_ops_t	__efx_nvram_siena_ops = {
 	siena_nvram_partn_size,		/* envo_partn_size */
 	siena_nvram_partn_rw_start,	/* envo_partn_rw_start */
 	siena_nvram_partn_read,		/* envo_partn_read */
+	siena_nvram_partn_read,		/* envo_partn_read_backup */
 	siena_nvram_partn_erase,	/* envo_partn_erase */
 	siena_nvram_partn_write,	/* envo_partn_write */
 	siena_nvram_partn_rw_finish,	/* envo_partn_rw_finish */
@@ -68,6 +69,7 @@ static const efx_nvram_ops_t	__efx_nvram_ef10_ops = {
 	ef10_nvram_partn_size,		/* envo_partn_size */
 	ef10_nvram_partn_rw_start,	/* envo_partn_rw_start */
 	ef10_nvram_partn_read,		/* envo_partn_read */
+	ef10_nvram_partn_read_backup,	/* envo_partn_read_backup */
 	ef10_nvram_partn_erase,		/* envo_partn_erase */
 	ef10_nvram_partn_write,		/* envo_partn_write */
 	ef10_nvram_partn_rw_finish,	/* envo_partn_rw_finish */
@@ -278,6 +280,48 @@ efx_nvram_read_chunk(
 	EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, partn);
 
 	if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
+		goto fail2;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+/*
+ * Read from the backup (writeable) store of an A/B partition.
+ * For non A/B partitions, there is only a single store, and so this
+ * function has the same behaviour as efx_nvram_read_chunk().
+ */
+	__checkReturn		efx_rc_t
+efx_nvram_read_backup(
+	__in			efx_nic_t *enp,
+	__in			efx_nvram_type_t type,
+	__in			unsigned int offset,
+	__out_bcount(size)	caddr_t data,
+	__in			size_t size)
+{
+	const efx_nvram_ops_t *envop = enp->en_envop;
+	uint32_t partn;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
+
+	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
+	EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
+
+	if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
+		goto fail1;
+
+	EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, partn);
+
+	if ((rc = envop->envo_partn_read_backup(enp, partn, offset,
+		    data, size)) != 0)
 		goto fail2;
 
 	return (0);


More information about the svn-src-all mailing list