浏览代码

mmc: dw_mmc: Improve handling of data transfer failure

In case the data transfer failure happens, instead of returning
immediatelly, make sure the DMA is disabled, status register is
cleared and the bounce buffer is stopped.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
Cc: Tom Rini <trini@konsulko.com>
Marek Vasut 10 年之前
父节点
当前提交
9042d974d2
共有 1 个文件被更改,包括 9 次插入7 次删除
  1. 9 7
      drivers/mmc/dw_mmc.c

+ 9 - 7
drivers/mmc/dw_mmc.c

@@ -110,7 +110,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	struct dwmci_host *host = mmc->priv;
 	ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
 				 data ? DIV_ROUND_UP(data->blocks, 8) : 0);
-	int flags = 0, i;
+	int ret = 0, flags = 0, i;
 	unsigned int timeout = 100000;
 	u32 retry = 10000;
 	u32 mask, ctrl;
@@ -218,20 +218,22 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 			/* Error during data transfer. */
 			if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
 				printf("%s: DATA ERROR!\n", __func__);
-				bounce_buffer_stop(&bbstate);
-				return -1;
+				ret = -EINVAL;
+				break;
 			}
 
 			/* Data arrived correctly. */
-			if (mask & DWMCI_INTMSK_DTO)
+			if (mask & DWMCI_INTMSK_DTO) {
+				ret = 0;
 				break;
+			}
 
 			/* Check for timeout. */
 			if (get_timer(start) > timeout) {
 				printf("%s: Timeout waiting for data!\n",
 				       __func__);
-				bounce_buffer_stop(&bbstate);
-				return TIMEOUT;
+				ret = TIMEOUT;
+				break;
 			}
 		}
 
@@ -246,7 +248,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
 	udelay(100);
 
-	return 0;
+	return ret;
 }
 
 static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)