mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 23:53:55 +08:00
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: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
12da64300f
commit
3366463513
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user