@@ -77,16 +77,17 @@ EXPORT_SYMBOL_GPL(fpga_image_info_free);
*/
static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,
struct fpga_image_info *info,
+ const struct fpga_manager_update_ops *uops,
const char *buf, size_t count)
{
int ret;
mgr->state = FPGA_MGR_STATE_WRITE_INIT;
if (!mgr->mops->initial_header_size)
- ret = mgr->mops->reconfig.write_init(mgr, info, NULL, 0);
+ ret = uops->write_init(mgr, info, NULL, 0);
else
- ret = mgr->mops->reconfig.write_init(
- mgr, info, buf, min(mgr->mops->initial_header_size, count));
+ ret = uops->write_init(
+ mgr, info, buf, min(mgr->mops->initial_header_size, count));
if (ret) {
dev_err(&mgr->dev, "Error preparing FPGA for writing\n");
@@ -99,6 +100,7 @@ static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,
static int fpga_mgr_write_init_sg(struct fpga_manager *mgr,
struct fpga_image_info *info,
+ const struct fpga_manager_update_ops *uops,
struct sg_table *sgt)
{
struct sg_mapping_iter miter;
@@ -107,7 +109,7 @@ static int fpga_mgr_write_init_sg(struct fpga_manager *mgr,
int ret;
if (!mgr->mops->initial_header_size)
- return fpga_mgr_write_init_buf(mgr, info, NULL, 0);
+ return fpga_mgr_write_init_buf(mgr, info, uops, NULL, 0);
/*
* First try to use miter to map the first fragment to access the
@@ -116,7 +118,7 @@ static int fpga_mgr_write_init_sg(struct fpga_manager *mgr,
sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
if (sg_miter_next(&miter) &&
miter.length >= mgr->mops->initial_header_size) {
- ret = fpga_mgr_write_init_buf(mgr, info, miter.addr,
+ ret = fpga_mgr_write_init_buf(mgr, info, uops, miter.addr,
miter.length);
sg_miter_stop(&miter);
return ret;
@@ -130,7 +132,7 @@ static int fpga_mgr_write_init_sg(struct fpga_manager *mgr,
len = sg_copy_to_buffer(sgt->sgl, sgt->nents, buf,
mgr->mops->initial_header_size);
- ret = fpga_mgr_write_init_buf(mgr, info, buf, len);
+ ret = fpga_mgr_write_init_buf(mgr, info, uops, buf, len);
kfree(buf);
@@ -142,12 +144,13 @@ static int fpga_mgr_write_init_sg(struct fpga_manager *mgr,
* finish and set the FPGA into operating mode.
*/
static int fpga_mgr_write_complete(struct fpga_manager *mgr,
- struct fpga_image_info *info)
+ struct fpga_image_info *info,
+ const struct fpga_manager_update_ops *uops)
{
int ret;
mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
- ret = mgr->mops->reconfig.write_complete(mgr, info);
+ ret = uops->write_complete(mgr, info);
if (ret) {
dev_err(&mgr->dev, "Error after writing image data to FPGA\n");
mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
@@ -162,6 +165,7 @@ static int fpga_mgr_write_complete(struct fpga_manager *mgr,
* fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list
* @mgr: fpga manager
* @info: fpga image specific information
+ * @uops: which update ops to use
* @sgt: scatterlist table
*
* Step the low level fpga manager through the device-specific steps of getting
@@ -177,24 +181,25 @@ static int fpga_mgr_write_complete(struct fpga_manager *mgr,
*/
static int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
struct fpga_image_info *info,
+ const struct fpga_manager_update_ops *uops,
struct sg_table *sgt)
{
int ret;
- ret = fpga_mgr_write_init_sg(mgr, info, sgt);
+ ret = fpga_mgr_write_init_sg(mgr, info, uops, sgt);
if (ret)
return ret;
/* Write the FPGA image to the FPGA. */
mgr->state = FPGA_MGR_STATE_WRITE;
- if (mgr->mops->reconfig.write_sg) {
- ret = mgr->mops->reconfig.write_sg(mgr, sgt);
+ if (uops->write_sg) {
+ ret = uops->write_sg(mgr, sgt);
} else {
struct sg_mapping_iter miter;
sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
while (sg_miter_next(&miter)) {
- ret = mgr->mops->reconfig.write(mgr, miter.addr, miter.length);
+ ret = uops->write(mgr, miter.addr, miter.length);
if (ret)
break;
}
@@ -207,16 +212,17 @@ static int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
return ret;
}
- return fpga_mgr_write_complete(mgr, info);
+ return fpga_mgr_write_complete(mgr, info, uops);
}
static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
struct fpga_image_info *info,
+ const struct fpga_manager_update_ops *uops,
const char *buf, size_t count)
{
int ret;
- ret = fpga_mgr_write_init_buf(mgr, info, buf, count);
+ ret = fpga_mgr_write_init_buf(mgr, info, uops, buf, count);
if (ret)
return ret;
@@ -224,20 +230,21 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
* Write the FPGA image to the FPGA.
*/
mgr->state = FPGA_MGR_STATE_WRITE;
- ret = mgr->mops->reconfig.write(mgr, buf, count);
+ ret = uops->write(mgr, buf, count);
if (ret) {
dev_err(&mgr->dev, "Error while writing image data to FPGA\n");
mgr->state = FPGA_MGR_STATE_WRITE_ERR;
return ret;
}
- return fpga_mgr_write_complete(mgr, info);
+ return fpga_mgr_write_complete(mgr, info, uops);
}
/**
* fpga_mgr_buf_load - load fpga from image in buffer
* @mgr: fpga manager
* @info: fpga image info
+ * @uops: which update ops to use
* @buf: buffer contain fpga image
* @count: byte count of buf
*
@@ -250,6 +257,7 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
*/
static int fpga_mgr_buf_load(struct fpga_manager *mgr,
struct fpga_image_info *info,
+ const struct fpga_manager_update_ops *uops,
const char *buf, size_t count)
{
struct page **pages;
@@ -264,8 +272,8 @@ static int fpga_mgr_buf_load(struct fpga_manager *mgr,
* contiguous kernel buffer and the driver doesn't require SG, non-SG
* drivers will still work on the slow path.
*/
- if (mgr->mops->reconfig.write)
- return fpga_mgr_buf_load_mapped(mgr, info, buf, count);
+ if (uops->write)
+ return fpga_mgr_buf_load_mapped(mgr, info, uops, buf, count);
/*
* Convert the linear kernel pointer into a sg_table of pages for use
@@ -300,7 +308,7 @@ static int fpga_mgr_buf_load(struct fpga_manager *mgr,
if (rc)
return rc;
- rc = fpga_mgr_buf_load_sg(mgr, info, &sgt);
+ rc = fpga_mgr_buf_load_sg(mgr, info, uops, &sgt);
sg_free_table(&sgt);
return rc;
@@ -322,6 +330,7 @@ static int fpga_mgr_buf_load(struct fpga_manager *mgr,
*/
static int fpga_mgr_firmware_load(struct fpga_manager *mgr,
struct fpga_image_info *info,
+ const struct fpga_manager_update_ops *uops,
const char *image_name)
{
struct device *dev = &mgr->dev;
@@ -339,7 +348,7 @@ static int fpga_mgr_firmware_load(struct fpga_manager *mgr,
return ret;
}
- ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size);
+ ret = fpga_mgr_buf_load(mgr, info, uops, fw->data, fw->size);
release_firmware(fw);
@@ -358,12 +367,14 @@ static int fpga_mgr_firmware_load(struct fpga_manager *mgr,
*/
int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info)
{
+ const struct fpga_manager_update_ops *uops = &mgr->mops->reconfig;
+
if (info->sgt)
- return fpga_mgr_buf_load_sg(mgr, info, info->sgt);
+ return fpga_mgr_buf_load_sg(mgr, info, uops, info->sgt);
if (info->buf && info->count)
- return fpga_mgr_buf_load(mgr, info, info->buf, info->count);
+ return fpga_mgr_buf_load(mgr, info, uops, info->buf, info->count);
if (info->firmware_name)
- return fpga_mgr_firmware_load(mgr, info, info->firmware_name);
+ return fpga_mgr_firmware_load(mgr, info, uops, info->firmware_name);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(fpga_mgr_load);