|
@@ -166,8 +166,9 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
|
|
|
static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
|
|
|
{
|
|
|
int i;
|
|
|
- for (i = 0; i < IWL_UCODE_SECTION_MAX; i++)
|
|
|
+ for (i = 0; i < img->num_sec; i++)
|
|
|
iwl_free_fw_desc(drv, &img->sec[i]);
|
|
|
+ kfree(img->sec);
|
|
|
}
|
|
|
|
|
|
static void iwl_dealloc_ucode(struct iwl_drv *drv)
|
|
@@ -240,7 +241,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
|
|
}
|
|
|
|
|
|
struct fw_img_parsing {
|
|
|
- struct fw_sec sec[IWL_UCODE_SECTION_MAX];
|
|
|
+ struct fw_sec *sec;
|
|
|
int sec_counter;
|
|
|
};
|
|
|
|
|
@@ -383,6 +384,7 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
|
|
|
struct fw_img_parsing *img;
|
|
|
struct fw_sec *sec;
|
|
|
struct fw_sec_parsing *sec_parse;
|
|
|
+ size_t alloc_size;
|
|
|
|
|
|
if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX))
|
|
|
return -1;
|
|
@@ -390,6 +392,13 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
|
|
|
sec_parse = (struct fw_sec_parsing *)data;
|
|
|
|
|
|
img = &pieces->img[type];
|
|
|
+
|
|
|
+ alloc_size = sizeof(*img->sec) * (img->sec_counter + 1);
|
|
|
+ sec = krealloc(img->sec, alloc_size, GFP_KERNEL);
|
|
|
+ if (!sec)
|
|
|
+ return -ENOMEM;
|
|
|
+ img->sec = sec;
|
|
|
+
|
|
|
sec = &img->sec[img->sec_counter];
|
|
|
|
|
|
sec->offset = le32_to_cpu(sec_parse->offset);
|
|
@@ -1089,12 +1098,18 @@ static int iwl_alloc_ucode(struct iwl_drv *drv,
|
|
|
enum iwl_ucode_type type)
|
|
|
{
|
|
|
int i;
|
|
|
- for (i = 0;
|
|
|
- i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
|
|
|
- i++)
|
|
|
- if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
|
|
|
- get_sec(pieces, type, i)))
|
|
|
+ struct fw_desc *sec;
|
|
|
+
|
|
|
+ sec = kcalloc(pieces->img[type].sec_counter, sizeof(*sec), GFP_KERNEL);
|
|
|
+ if (!sec)
|
|
|
+ return -ENOMEM;
|
|
|
+ drv->fw.img[type].sec = sec;
|
|
|
+ drv->fw.img[type].num_sec = pieces->img[type].sec_counter;
|
|
|
+
|
|
|
+ for (i = 0; i < pieces->img[type].sec_counter; i++)
|
|
|
+ if (iwl_alloc_fw_desc(drv, &sec[i], get_sec(pieces, type, i)))
|
|
|
return -ENOMEM;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1457,6 +1472,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
|
|
complete(&drv->request_firmware_complete);
|
|
|
device_release_driver(drv->trans->dev);
|
|
|
free:
|
|
|
+ for (i = 0; i < ARRAY_SIZE(pieces->img); i++)
|
|
|
+ kfree(pieces->img[i].sec);
|
|
|
kfree(pieces->dbg_mem_tlv);
|
|
|
kfree(pieces);
|
|
|
}
|