forked from Minki/linux
staging: vt6656: clean error path for firmware management
Avoid discarding return value of functions called during firmware management process. Handle such return value and return 0 on success or a negative errno value on error. Signed-off-by: Quentin Deslandes <quentin.deslandes@itdev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7156f7d9c3
commit
cc81234ad7
@ -30,98 +30,87 @@ int vnt_download_firmware(struct vnt_private *priv)
|
||||
{
|
||||
struct device *dev = &priv->usb->dev;
|
||||
const struct firmware *fw;
|
||||
int status;
|
||||
void *buffer = NULL;
|
||||
bool result = false;
|
||||
u16 length;
|
||||
int ii, rc;
|
||||
int ii;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(dev, "---->Download firmware\n");
|
||||
|
||||
rc = request_firmware(&fw, FIRMWARE_NAME, dev);
|
||||
if (rc) {
|
||||
ret = request_firmware(&fw, FIRMWARE_NAME, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "firmware file %s request failed (%d)\n",
|
||||
FIRMWARE_NAME, rc);
|
||||
goto out;
|
||||
FIRMWARE_NAME, ret);
|
||||
goto end;
|
||||
}
|
||||
|
||||
buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
if (!buffer) {
|
||||
ret = -ENOMEM;
|
||||
goto free_fw;
|
||||
}
|
||||
|
||||
for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
|
||||
length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
|
||||
memcpy(buffer, fw->data + ii, length);
|
||||
|
||||
status = vnt_control_out(priv,
|
||||
0,
|
||||
0x1200 + ii,
|
||||
0x0000,
|
||||
length,
|
||||
buffer);
|
||||
ret = vnt_control_out(priv, 0, 0x1200 + ii, 0x0000, length,
|
||||
buffer);
|
||||
if (ret)
|
||||
goto free_buffer;
|
||||
|
||||
dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
|
||||
|
||||
if (status != STATUS_SUCCESS)
|
||||
goto free_fw;
|
||||
}
|
||||
|
||||
result = true;
|
||||
free_buffer:
|
||||
kfree(buffer);
|
||||
free_fw:
|
||||
release_firmware(fw);
|
||||
|
||||
out:
|
||||
kfree(buffer);
|
||||
|
||||
return result;
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
MODULE_FIRMWARE(FIRMWARE_NAME);
|
||||
|
||||
int vnt_firmware_branch_to_sram(struct vnt_private *priv)
|
||||
{
|
||||
int status;
|
||||
|
||||
dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");
|
||||
|
||||
status = vnt_control_out(priv,
|
||||
1,
|
||||
0x1200,
|
||||
0x0000,
|
||||
0,
|
||||
NULL);
|
||||
return status == STATUS_SUCCESS;
|
||||
return vnt_control_out(priv, 1, 0x1200, 0x0000, 0, NULL);
|
||||
}
|
||||
|
||||
int vnt_check_firmware_version(struct vnt_private *priv)
|
||||
{
|
||||
int status;
|
||||
int ret = 0;
|
||||
|
||||
status = vnt_control_in(priv,
|
||||
MESSAGE_TYPE_READ,
|
||||
0,
|
||||
MESSAGE_REQUEST_VERSION,
|
||||
2,
|
||||
(u8 *)&priv->firmware_version);
|
||||
ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0,
|
||||
MESSAGE_REQUEST_VERSION, 2,
|
||||
(u8 *)&priv->firmware_version);
|
||||
if (ret) {
|
||||
dev_dbg(&priv->usb->dev,
|
||||
"Could not get firmware version: %d.\n", ret);
|
||||
goto end;
|
||||
}
|
||||
|
||||
dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
|
||||
priv->firmware_version);
|
||||
|
||||
if (status != STATUS_SUCCESS) {
|
||||
dev_dbg(&priv->usb->dev, "Firmware Invalid.\n");
|
||||
return false;
|
||||
}
|
||||
if (priv->firmware_version == 0xFFFF) {
|
||||
dev_dbg(&priv->usb->dev, "In Loader.\n");
|
||||
return false;
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
|
||||
priv->firmware_version);
|
||||
|
||||
if (priv->firmware_version < FIRMWARE_VERSION) {
|
||||
/* branch to loader for download new firmware */
|
||||
vnt_firmware_branch_to_sram(priv);
|
||||
return false;
|
||||
ret = vnt_firmware_branch_to_sram(priv);
|
||||
if (ret) {
|
||||
dev_dbg(&priv->usb->dev,
|
||||
"Could not branch to SRAM: %d.\n", ret);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user