iwlwifi: mvm: accept arbitrary memory dump TLVs

There's no reason to be validating the memory dump types, or
checking them for duplication, or anything, since we really
just pass them through from the TLV to the dump.

Thus, change the way we handle memory dump TLVs to let the
driver just blindly use anything specified there, dumping it
into the memory dump output file.

This makes the system extensible without driver changes.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Este commit está contenido en:
Johannes Berg
2016-10-20 09:41:14 +02:00
cometido por Luca Coelho
padre bac453ab37
commit 2ed1e01910
Se han modificado 4 ficheros con 45 adiciones y 79 borrados

Ver fichero

@@ -179,8 +179,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
kfree(drv->fw.dbg_conf_tlv[i]);
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
kfree(drv->fw.dbg_trigger_tlv[i]);
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++)
kfree(drv->fw.dbg_mem_tlv[i]);
kfree(drv->fw.dbg_mem_tlv);
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
iwl_free_fw_img(drv, drv->fw.img + i);
@@ -276,7 +275,8 @@ struct iwl_firmware_pieces {
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX];
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv;
size_t n_dbg_mem_tlv;
};
/*
@@ -1009,31 +1009,25 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem =
(void *)tlv_data;
u32 type;
size_t size;
struct iwl_fw_dbg_mem_seg_tlv *n;
if (tlv_len != (sizeof(*dbg_mem)))
goto invalid_tlv_len;
type = le32_to_cpu(dbg_mem->data_type);
drv->fw.dbg_dynamic_mem = true;
if (type >= ARRAY_SIZE(drv->fw.dbg_mem_tlv)) {
IWL_ERR(drv,
"Skip unknown dbg mem segment: %u\n",
dbg_mem->data_type);
break;
}
if (pieces->dbg_mem_tlv[type]) {
IWL_ERR(drv,
"Ignore duplicate mem segment: %u\n",
dbg_mem->data_type);
break;
}
IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n",
dbg_mem->data_type);
pieces->dbg_mem_tlv[type] = dbg_mem;
size = sizeof(*pieces->dbg_mem_tlv) *
(pieces->n_dbg_mem_tlv + 1);
n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL);
if (!n)
return -ENOMEM;
pieces->dbg_mem_tlv = n;
pieces->dbg_mem_tlv[pieces->n_dbg_mem_tlv] = *dbg_mem;
pieces->n_dbg_mem_tlv++;
break;
}
default:
@@ -1345,19 +1339,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
}
}
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++) {
if (pieces->dbg_mem_tlv[i]) {
drv->fw.dbg_mem_tlv[i] =
kmemdup(pieces->dbg_mem_tlv[i],
sizeof(*drv->fw.dbg_mem_tlv[i]),
GFP_KERNEL);
if (!drv->fw.dbg_mem_tlv[i])
goto out_free_fw;
}
}
/* Now that we can no longer fail, copy information */
drv->fw.dbg_mem_tlv = pieces->dbg_mem_tlv;
pieces->dbg_mem_tlv = NULL;
drv->fw.n_dbg_mem_tlv = pieces->n_dbg_mem_tlv;
/*
* The (size - 16) / 12 formula is based on the information recorded
* for each event, which is of mode 1 (including timestamp) for all
@@ -1441,25 +1428,25 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
op->name, err);
#endif
}
kfree(pieces);
return;
goto free;
try_again:
/* try next, if any */
release_firmware(ucode_raw);
if (iwl_request_firmware(drv, false))
goto out_unbind;
kfree(pieces);
return;
goto free;
out_free_fw:
IWL_ERR(drv, "failed to allocate pci memory\n");
iwl_dealloc_ucode(drv);
release_firmware(ucode_raw);
out_unbind:
kfree(pieces);
complete(&drv->request_firmware_complete);
device_release_driver(drv->trans->dev);
free:
kfree(pieces->dbg_mem_tlv);
kfree(pieces);
}
struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,