浏览代码

soc/qman: Fix h/w resource cleanup error path handling

qman_query_fq*() may return other error codes apart from
-ERANGE, in which cases the error handling done by the
resource cleanup callers would be wrong.  The patch
fixes the handling of those cases, and cleans up related
code inside the resource cleanup & release handlers (i.e.
replace hardcoded fqid value with corresponding define).

Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Scott Wood <oss@buserror.net>
Claudiu Manoil 8 年之前
父节点
当前提交
d95cb0d361
共有 1 个文件被更改,包括 11 次插入5 次删除
  1. 11 5
      drivers/soc/fsl/qbman/qman.c

+ 11 - 5
drivers/soc/fsl/qbman/qman.c

@@ -2789,15 +2789,18 @@ static int qpool_cleanup(u32 qp)
 		struct qm_mcr_queryfq_np np;
 		struct qm_mcr_queryfq_np np;
 
 
 		err = qman_query_fq_np(&fq, &np);
 		err = qman_query_fq_np(&fq, &np);
-		if (err)
+		if (err == -ERANGE)
 			/* FQID range exceeded, found no problems */
 			/* FQID range exceeded, found no problems */
 			return 0;
 			return 0;
+		else if (WARN_ON(err))
+			return err;
+
 		if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
 		if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
 			struct qm_fqd fqd;
 			struct qm_fqd fqd;
 
 
 			err = qman_query_fq(&fq, &fqd);
 			err = qman_query_fq(&fq, &fqd);
 			if (WARN_ON(err))
 			if (WARN_ON(err))
-				return 0;
+				return err;
 			if (qm_fqd_get_chan(&fqd) == qp) {
 			if (qm_fqd_get_chan(&fqd) == qp) {
 				/* The channel is the FQ's target, clean it */
 				/* The channel is the FQ's target, clean it */
 				err = qman_shutdown_fq(fq.fqid);
 				err = qman_shutdown_fq(fq.fqid);
@@ -2836,7 +2839,7 @@ static int cgr_cleanup(u32 cgrid)
 	 * error, looking for non-OOS FQDs whose CGR is the CGR being released
 	 * error, looking for non-OOS FQDs whose CGR is the CGR being released
 	 */
 	 */
 	struct qman_fq fq = {
 	struct qman_fq fq = {
-		.fqid = 1
+		.fqid = QM_FQID_RANGE_START
 	};
 	};
 	int err;
 	int err;
 
 
@@ -2844,15 +2847,18 @@ static int cgr_cleanup(u32 cgrid)
 		struct qm_mcr_queryfq_np np;
 		struct qm_mcr_queryfq_np np;
 
 
 		err = qman_query_fq_np(&fq, &np);
 		err = qman_query_fq_np(&fq, &np);
-		if (err)
+		if (err == -ERANGE)
 			/* FQID range exceeded, found no problems */
 			/* FQID range exceeded, found no problems */
 			return 0;
 			return 0;
+		else if (WARN_ON(err))
+			return err;
+
 		if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
 		if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
 			struct qm_fqd fqd;
 			struct qm_fqd fqd;
 
 
 			err = qman_query_fq(&fq, &fqd);
 			err = qman_query_fq(&fq, &fqd);
 			if (WARN_ON(err))
 			if (WARN_ON(err))
-				return 0;
+				return err;
 			if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
 			if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
 			    fqd.cgid == cgrid) {
 			    fqd.cgid == cgrid) {
 				pr_err("CRGID 0x%x is being used by FQID 0x%x, CGR will be leaked\n",
 				pr_err("CRGID 0x%x is being used by FQID 0x%x, CGR will be leaked\n",