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

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
...@@ -6046,22 +6046,25 @@ static const struct efx_ef10_nvram_type_info efx_ef10_nvram_types[] = { ...@@ -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_EXPANSION_UEFI, 0, 0, "sfc_uefi" },
{ NVRAM_PARTITION_TYPE_STATUS, 0, 0, "sfc_status" } { 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, static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
struct efx_mcdi_mtd_partition *part, 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(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN);
MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_METADATA_OUT_LENMAX); MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_METADATA_OUT_LENMAX);
const struct efx_ef10_nvram_type_info *info; const struct efx_ef10_nvram_type_info *info;
size_t size, erase_size, outlen; size_t size, erase_size, outlen;
int type_idx = 0;
bool protected; bool protected;
int rc; int rc;
for (info = efx_ef10_nvram_types; ; info++) { for (type_idx = 0; ; type_idx++) {
if (info == if (type_idx == EF10_NVRAM_PARTITION_COUNT)
efx_ef10_nvram_types + ARRAY_SIZE(efx_ef10_nvram_types))
return -ENODEV; return -ENODEV;
info = efx_ef10_nvram_types + type_idx;
if ((type & ~info->type_mask) == info->type) if ((type & ~info->type_mask) == info->type)
break; break;
} }
...@@ -6074,6 +6077,13 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx, ...@@ -6074,6 +6077,13 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
if (protected) if (protected)
return -ENODEV; /* hide it */ 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; part->nvram_type = type;
MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_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, ...@@ -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) static int efx_ef10_mtd_probe(struct efx_nic *efx)
{ {
MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX); MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
DECLARE_BITMAP(found, EF10_NVRAM_PARTITION_COUNT);
struct efx_mcdi_mtd_partition *parts; struct efx_mcdi_mtd_partition *parts;
size_t outlen, n_parts_total, i, n_parts; size_t outlen, n_parts_total, i, n_parts;
unsigned int type; unsigned int type;
...@@ -6133,11 +6144,13 @@ static int efx_ef10_mtd_probe(struct efx_nic *efx) ...@@ -6133,11 +6144,13 @@ static int efx_ef10_mtd_probe(struct efx_nic *efx)
for (i = 0; i < n_parts_total; i++) { for (i = 0; i < n_parts_total; i++) {
type = MCDI_ARRAY_DWORD(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID, type = MCDI_ARRAY_DWORD(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID,
i); i);
rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type); rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type,
if (rc == 0) found);
n_parts++; if (rc == -EEXIST || rc == -ENODEV)
else if (rc != -ENODEV) continue;
if (rc)
goto fail; goto fail;
n_parts++;
} }
rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts)); rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment