Get rid of automatic kfree and move allocation down to where it's used. Use kzalloc_flex as we're dealing with a flexible array member.
Use struct_size to avoid some pointer math. Add __counted_by for extra runtime analysis. Move the counting variable assignment to right after allocation as required by __counted_by. Signed-off-by: Rosen Penev <[email protected]> --- drivers/soc/qcom/wcnss_ctrl.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c index 62b424e90d90..ffb31a049d4a 100644 --- a/drivers/soc/qcom/wcnss_ctrl.c +++ b/drivers/soc/qcom/wcnss_ctrl.c @@ -94,7 +94,7 @@ struct wcnss_download_nv_req { u16 seq; u16 last; u32 frag_size; - u8 fragment[]; + u8 fragment[] __counted_by(frag_size); } __packed; /** @@ -201,16 +201,12 @@ static int wcnss_download_nv(struct wcnss_ctrl *wcnss, bool *expect_cbc) { const struct firmware *fw; struct device *dev = wcnss->dev; + struct wcnss_download_nv_req *req; const char *nvbin = NVBIN_FILE; const void *data; ssize_t left; int ret; - struct wcnss_download_nv_req *req __free(kfree) = kzalloc(sizeof(*req) + NV_FRAGMENT_SIZE, - GFP_KERNEL); - if (!req) - return -ENOMEM; - ret = of_property_read_string(dev->of_node, "firmware-name", &nvbin); if (ret < 0 && ret != -EINVAL) return ret; @@ -224,11 +220,15 @@ static int wcnss_download_nv(struct wcnss_ctrl *wcnss, bool *expect_cbc) data = fw->data; left = fw->size; + req = kzalloc_flex(*req, fragment, NV_FRAGMENT_SIZE); + if (!req) + return -ENOMEM; + + req->frag_size = NV_FRAGMENT_SIZE; req->hdr.type = WCNSS_DOWNLOAD_NV_REQ; - req->hdr.len = sizeof(*req) + NV_FRAGMENT_SIZE; + req->hdr.len = struct_size(req, fragment, NV_FRAGMENT_SIZE); req->last = 0; - req->frag_size = NV_FRAGMENT_SIZE; req->seq = 0; do { @@ -264,6 +264,7 @@ static int wcnss_download_nv(struct wcnss_ctrl *wcnss, bool *expect_cbc) release_fw: release_firmware(fw); + kfree(req); return ret; } -- 2.53.0

