Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33664635 authored by Edward Cree's avatar Edward Cree Committed by David S. Miller
Browse files

sfc: suppress duplicate nvmem partition types in efx_ef10_mtd_probe



Use a bitmap to keep track of which partition types we've already seen;
 for duplicates, return -EEXIST from efx_ef10_mtd_probe_partition() and
 thus skip adding that partition.
Duplicate partitions occur because of the A/B backup scheme used by newer
 sfc NICs.  Prior to this patch they cause sysfs_warn_dup errors because
 they have the same name, causing us not to expose any MTDs at all.

Signed-off-by: default avatarEdward Cree <ecree@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 12da6430
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -6046,22 +6046,25 @@ static const struct efx_ef10_nvram_type_info efx_ef10_nvram_types[] = {
	{ NVRAM_PARTITION_TYPE_EXPANSION_UEFI,	   0,    0, "sfc_uefi" },
	{ NVRAM_PARTITION_TYPE_STATUS,		   0,    0, "sfc_status" }
};
#define EF10_NVRAM_PARTITION_COUNT	ARRAY_SIZE(efx_ef10_nvram_types)

static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
					struct efx_mcdi_mtd_partition *part,
					unsigned int type)
					unsigned int type,
					unsigned long *found)
{
	MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN);
	MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_METADATA_OUT_LENMAX);
	const struct efx_ef10_nvram_type_info *info;
	size_t size, erase_size, outlen;
	int type_idx = 0;
	bool protected;
	int rc;

	for (info = efx_ef10_nvram_types; ; info++) {
		if (info ==
		    efx_ef10_nvram_types + ARRAY_SIZE(efx_ef10_nvram_types))
	for (type_idx = 0; ; type_idx++) {
		if (type_idx == EF10_NVRAM_PARTITION_COUNT)
			return -ENODEV;
		info = efx_ef10_nvram_types + type_idx;
		if ((type & ~info->type_mask) == info->type)
			break;
	}
@@ -6074,6 +6077,13 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
	if (protected)
		return -ENODEV; /* hide it */

	/* If we've already exposed a partition of this type, hide this
	 * duplicate.  All operations on MTDs are keyed by the type anyway,
	 * so we can't act on the duplicate.
	 */
	if (__test_and_set_bit(type_idx, found))
		return -EEXIST;

	part->nvram_type = type;

	MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_TYPE, type);
@@ -6105,6 +6115,7 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
static int efx_ef10_mtd_probe(struct efx_nic *efx)
{
	MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
	DECLARE_BITMAP(found, EF10_NVRAM_PARTITION_COUNT);
	struct efx_mcdi_mtd_partition *parts;
	size_t outlen, n_parts_total, i, n_parts;
	unsigned int type;
@@ -6133,11 +6144,13 @@ static int efx_ef10_mtd_probe(struct efx_nic *efx)
	for (i = 0; i < n_parts_total; i++) {
		type = MCDI_ARRAY_DWORD(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID,
					i);
		rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type);
		if (rc == 0)
			n_parts++;
		else if (rc != -ENODEV)
		rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type,
						  found);
		if (rc == -EEXIST || rc == -ENODEV)
			continue;
		if (rc)
			goto fail;
		n_parts++;
	}

	rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));