@@ -36,6 +36,12 @@ struct qm_dfx_item {
u32 offset;
};
+struct qm_cmd_dump_item {
+ const char *cmd;
+ char *info_name;
+ int (*dump_fn)(struct hisi_qm *qm, char *cmd, char *info_name);
+};
+
static struct qm_dfx_item qm_dfx_files[] = {
{"err_irq", offsetof(struct qm_dfx, err_irq_cnt)},
{"aeq_irq", offsetof(struct qm_dfx, aeq_irq_cnt)},
@@ -128,7 +134,7 @@ static void dump_show(struct hisi_qm *qm, void *info,
}
}
-static int qm_sqc_dump(struct hisi_qm *qm, const char *s)
+static int qm_sqc_dump(struct hisi_qm *qm, char *s, char *name)
{
struct device *dev = &qm->pdev->dev;
struct qm_sqc *sqc, *sqc_curr;
@@ -169,14 +175,14 @@ static int qm_sqc_dump(struct hisi_qm *qm, const char *s)
goto free_ctx;
}
- dump_show(qm, sqc, sizeof(*sqc), "SQC");
+ dump_show(qm, sqc, sizeof(*sqc), name);
free_ctx:
hisi_qm_ctx_free(qm, sizeof(*sqc), sqc, &sqc_dma);
return 0;
}
-static int qm_cqc_dump(struct hisi_qm *qm, const char *s)
+static int qm_cqc_dump(struct hisi_qm *qm, char *s, char *name)
{
struct device *dev = &qm->pdev->dev;
struct qm_cqc *cqc, *cqc_curr;
@@ -217,31 +223,46 @@ static int qm_cqc_dump(struct hisi_qm *qm, const char *s)
goto free_ctx;
}
- dump_show(qm, cqc, sizeof(*cqc), "CQC");
+ dump_show(qm, cqc, sizeof(*cqc), name);
free_ctx:
hisi_qm_ctx_free(qm, sizeof(*cqc), cqc, &cqc_dma);
return 0;
}
-static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, size_t size,
- int cmd, char *name)
+static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, char *name)
{
struct device *dev = &qm->pdev->dev;
dma_addr_t xeqc_dma;
+ size_t size;
void *xeqc;
int ret;
+ u8 cmd;
if (strsep(&s, " ")) {
dev_err(dev, "Please do not input extra characters!\n");
return -EINVAL;
}
+ if (!strcmp(name, "EQC")) {
+ cmd = QM_MB_CMD_EQC;
+ size = sizeof(struct qm_eqc);
+ } else {
+ cmd = QM_MB_CMD_AEQC;
+ size = sizeof(struct qm_aeqc);
+ }
+
xeqc = hisi_qm_ctx_alloc(qm, size, &xeqc_dma);
if (IS_ERR(xeqc))
return PTR_ERR(xeqc);
- ret = hisi_qm_mb(qm, cmd, xeqc_dma, 0, 1);
+ /* Mailbox and reset cannot be operated at the same time */
+ if (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
+ ret = -EBUSY;
+ } else {
+ ret = hisi_qm_mb(qm, cmd, xeqc_dma, 0, 1);
+ clear_bit(QM_RESETTING, &qm->misc_ctl);
+ }
if (ret)
goto err_free_ctx;
@@ -292,7 +313,7 @@ static int q_dump_param_parse(struct hisi_qm *qm, char *s,
return 0;
}
-static int qm_sq_dump(struct hisi_qm *qm, char *s)
+static int qm_sq_dump(struct hisi_qm *qm, char *s, char *name)
{
u16 sq_depth = qm->qp_array->cq_depth;
void *sqe, *sqe_curr;
@@ -314,14 +335,14 @@ static int qm_sq_dump(struct hisi_qm *qm, char *s)
memset(sqe_curr + qm->debug.sqe_mask_offset, QM_SQE_ADDR_MASK,
qm->debug.sqe_mask_len);
- dump_show(qm, sqe_curr, qm->sqe_size, "SQE");
+ dump_show(qm, sqe_curr, qm->sqe_size, name);
kfree(sqe);
return 0;
}
-static int qm_cq_dump(struct hisi_qm *qm, char *s)
+static int qm_cq_dump(struct hisi_qm *qm, char *s, char *name)
{
struct qm_cqe *cqe_curr;
struct hisi_qp *qp;
@@ -334,15 +355,16 @@ static int qm_cq_dump(struct hisi_qm *qm, char *s)
qp = &qm->qp_array[qp_id];
cqe_curr = qp->cqe + cqe_id;
- dump_show(qm, cqe_curr, sizeof(struct qm_cqe), "CQE");
+ dump_show(qm, cqe_curr, sizeof(struct qm_cqe), name);
return 0;
}
-static int qm_eq_aeq_dump(struct hisi_qm *qm, const char *s,
- size_t size, char *name)
+static int qm_eq_aeq_dump(struct hisi_qm *qm, char *s, char *name)
{
struct device *dev = &qm->pdev->dev;
+ u16 xeq_depth;
+ size_t size;
void *xeqe;
u32 xeqe_id;
int ret;
@@ -354,11 +376,18 @@ static int qm_eq_aeq_dump(struct hisi_qm *qm, const char *s,
if (ret)
return -EINVAL;
- if (!strcmp(name, "EQE") && xeqe_id >= qm->eq_depth) {
- dev_err(dev, "Please input eqe num (0-%u)", qm->eq_depth - 1);
- return -EINVAL;
- } else if (!strcmp(name, "AEQE") && xeqe_id >= qm->aeq_depth) {
- dev_err(dev, "Please input aeqe num (0-%u)", qm->eq_depth - 1);
+ if (!strcmp(name, "EQE")) {
+ xeq_depth = qm->eq_depth;
+ size = sizeof(struct qm_eqe);
+ }
+
+ if (!strcmp(name, "AEQE")) {
+ xeq_depth = qm->aeq_depth;
+ size = sizeof(struct qm_aeqe);
+ }
+
+ if (xeqe_id >= xeq_depth) {
+ dev_err(dev, "Please input eqe or aeqe num (0-%u)", xeq_depth - 1);
return -EINVAL;
}
@@ -402,11 +431,47 @@ static int qm_dbg_help(struct hisi_qm *qm, char *s)
return 0;
}
+static const struct qm_cmd_dump_item qm_cmd_dump_table[] = {
+ {
+ .cmd = "sqc",
+ .info_name = "SQC",
+ .dump_fn = qm_sqc_dump,
+ }, {
+ .cmd = "cqc",
+ .info_name = "CQC",
+ .dump_fn = qm_cqc_dump,
+ }, {
+ .cmd = "eqc",
+ .info_name = "EQC",
+ .dump_fn = qm_eqc_aeqc_dump,
+ }, {
+ .cmd = "aeqc",
+ .info_name = "AEQC",
+ .dump_fn = qm_eqc_aeqc_dump,
+ }, {
+ .cmd = "sq",
+ .info_name = "SQE",
+ .dump_fn = qm_sq_dump,
+ }, {
+ .cmd = "cq",
+ .info_name = "CQE",
+ .dump_fn = qm_cq_dump,
+ }, {
+ .cmd = "eq",
+ .info_name = "EQE",
+ .dump_fn = qm_eq_aeq_dump,
+ }, {
+ .cmd = "aeq",
+ .info_name = "AEQE",
+ .dump_fn = qm_eq_aeq_dump,
+ },
+};
+
static int qm_cmd_write_dump(struct hisi_qm *qm, const char *cmd_buf)
{
struct device *dev = &qm->pdev->dev;
char *presult, *s, *s_tmp;
- int ret;
+ int table_size, i, ret;
s = kstrdup(cmd_buf, GFP_KERNEL);
if (!s)
@@ -419,31 +484,24 @@ static int qm_cmd_write_dump(struct hisi_qm *qm, const char *cmd_buf)
goto err_buffer_free;
}
- if (!strcmp(presult, "sqc"))
- ret = qm_sqc_dump(qm, s);
- else if (!strcmp(presult, "cqc"))
- ret = qm_cqc_dump(qm, s);
- else if (!strcmp(presult, "eqc"))
- ret = qm_eqc_aeqc_dump(qm, s, sizeof(struct qm_eqc),
- QM_MB_CMD_EQC, "EQC");
- else if (!strcmp(presult, "aeqc"))
- ret = qm_eqc_aeqc_dump(qm, s, sizeof(struct qm_aeqc),
- QM_MB_CMD_AEQC, "AEQC");
- else if (!strcmp(presult, "sq"))
- ret = qm_sq_dump(qm, s);
- else if (!strcmp(presult, "cq"))
- ret = qm_cq_dump(qm, s);
- else if (!strcmp(presult, "eq"))
- ret = qm_eq_aeq_dump(qm, s, sizeof(struct qm_eqe), "EQE");
- else if (!strcmp(presult, "aeq"))
- ret = qm_eq_aeq_dump(qm, s, sizeof(struct qm_aeqe), "AEQE");
- else if (!strcmp(presult, "help"))
+ if (!strcmp(presult, "help")) {
ret = qm_dbg_help(qm, s);
- else
- ret = -EINVAL;
+ goto err_buffer_free;
+ }
- if (ret)
+ table_size = ARRAY_SIZE(qm_cmd_dump_table);
+ for (i = 0; i < table_size; i++) {
+ if (!strcmp(presult, qm_cmd_dump_table[i].cmd)) {
+ ret = qm_cmd_dump_table[i].dump_fn(qm, s,
+ qm_cmd_dump_table[i].info_name);
+ break;
+ }
+ }
+
+ if (i == table_size) {
dev_info(dev, "Please echo help\n");
+ ret = -EINVAL;
+ }
err_buffer_free:
kfree(s_tmp);
Reduce the function complexity by use the function table in the process of dumping queue. The function input parameters are unified. And maintainability is enhanced. Signed-off-by: Kai Ye <yekai13@huawei.com> --- drivers/crypto/hisilicon/debugfs.c | 140 ++++++++++++++++++++--------- 1 file changed, 99 insertions(+), 41 deletions(-)