[PATCH] fpga: altera-cvp: Handle truncated bitstream with padding buffer
[email protected] Thu, 18 Jun 2026 21:08:11 -0700
| Newsgroups | org.kernel.vger.linux-fpga,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260619040811.20038-1-muhammad.nazim.amirul.nazle.asmade@altera.com> |
From: Nazim Amirul <[email protected]> The AIB CvP firmware requires a minimum transfer size of 4096 bytes. When a bitstream smaller than this is sent, the firmware DMA engine stalls waiting for the remaining data, causing a hang. Allocate a 4096-byte send_buf at probe time and copy host data into it before each block transfer, ensuring the full block size is always sent regardless of the actual data length. Also improve error detection in write_complete() by checking VSE_CVP_STATUS_CFG_ERR instead of VSE_UNCOR_ERR_CVP_CFG_ERR to catch truncated or mismatched bitstream errors. Signed-off-by: Nazim Amirul <[email protected]> --- drivers/fpga/altera-cvp.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c index 44badfd11e1b..36557c5a0c3f 100644 --- a/drivers/fpga/altera-cvp.c +++ b/drivers/fpga/altera-cvp.c @@ -77,6 +77,7 @@ struct altera_cvp_conf { u8 numclks; u32 sent_packets; u32 vsec_offset; + u8 *send_buf; const struct cvp_priv *priv; }; @@ -449,7 +450,9 @@ static int altera_cvp_write(struct fpga_manager *mgr, const char *buf, } len = min(conf->priv->block_size, remaining); - altera_cvp_send_block(conf, data, len); + memcpy(conf->send_buf, data, len); + altera_cvp_send_block(conf, (const u32 *)conf->send_buf, + conf->priv->block_size); data += len / sizeof(u32); done += len; remaining -= len; @@ -488,10 +491,10 @@ static int altera_cvp_write_complete(struct fpga_manager *mgr, if (ret) return ret; - /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */ - altera_read_config_dword(conf, VSE_UNCOR_ERR_STATUS, &val); - if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) { - dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n"); + /* STEP 16 - check CVP_CONFIG_ERROR bit */ + ret = altera_read_config_dword(conf, VSE_CVP_STATUS, &val); + if (ret || (val & VSE_CVP_STATUS_CFG_ERR)) { + dev_err(&mgr->dev, "CVP_CONFIG_ERROR!\n"); return -EPROTO; } @@ -650,6 +653,11 @@ static int altera_cvp_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, mgr); + conf->send_buf = devm_kzalloc(&pdev->dev, conf->priv->block_size, GFP_KERNEL); + if (!conf->send_buf) { + ret = -ENOMEM; + goto err_unmap; + } return 0; err_unmap: -- 2.43.7