aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkos Chandras <markos.chandras@imgtec.com>2013-03-22 12:50:05 -0400
committerChris Ball <cjb@laptop.org>2013-03-22 12:50:05 -0400
commit3e4b0d8bdc6ddd68fdc1f4592822af2ae5cc2859 (patch)
tree2a6b44f788d9bcaa235a11db0332e9e263c049cc
parent1fb5f68addde6d8b79dd7d747814aa1770e6cf21 (diff)
mmc: dw_mmc: Avoid adding the number of transmitted bytes twice
Previously, it was possible to add either 0 bytes or add nbytes twice if we broke out of the outer loop and then carry on to the "done" label. This is now fixed by adding the transferred bytes right after the pull/pop operation Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Acked-by: Jaehoon Chung <jh80.chung@samsung.com> Acked-by: Seungwon Jeon <tgih.jun@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/dw_mmc.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index e7be4023382c..a23b262f9cdd 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1454,7 +1454,7 @@ static void dw_mci_read_data_pio(struct dw_mci *host, bool dto)
1454 struct mmc_data *data = host->data; 1454 struct mmc_data *data = host->data;
1455 int shift = host->data_shift; 1455 int shift = host->data_shift;
1456 u32 status; 1456 u32 status;
1457 unsigned int nbytes = 0, len; 1457 unsigned int len;
1458 unsigned int remain, fcnt; 1458 unsigned int remain, fcnt;
1459 1459
1460 do { 1460 do {
@@ -1473,8 +1473,8 @@ static void dw_mci_read_data_pio(struct dw_mci *host, bool dto)
1473 if (!len) 1473 if (!len)
1474 break; 1474 break;
1475 dw_mci_pull_data(host, (void *)(buf + offset), len); 1475 dw_mci_pull_data(host, (void *)(buf + offset), len);
1476 data->bytes_xfered += len;
1476 offset += len; 1477 offset += len;
1477 nbytes += len;
1478 remain -= len; 1478 remain -= len;
1479 } while (remain); 1479 } while (remain);
1480 1480
@@ -1484,7 +1484,6 @@ static void dw_mci_read_data_pio(struct dw_mci *host, bool dto)
1484 /* if the RXDR is ready read again */ 1484 /* if the RXDR is ready read again */
1485 } while ((status & SDMMC_INT_RXDR) || 1485 } while ((status & SDMMC_INT_RXDR) ||
1486 (dto && SDMMC_GET_FCNT(mci_readl(host, STATUS)))); 1486 (dto && SDMMC_GET_FCNT(mci_readl(host, STATUS))));
1487 data->bytes_xfered += nbytes;
1488 1487
1489 if (!remain) { 1488 if (!remain) {
1490 if (!sg_miter_next(sg_miter)) 1489 if (!sg_miter_next(sg_miter))
@@ -1495,7 +1494,6 @@ static void dw_mci_read_data_pio(struct dw_mci *host, bool dto)
1495 return; 1494 return;
1496 1495
1497done: 1496done:
1498 data->bytes_xfered += nbytes;
1499 sg_miter_stop(sg_miter); 1497 sg_miter_stop(sg_miter);
1500 host->sg = NULL; 1498 host->sg = NULL;
1501 smp_wmb(); 1499 smp_wmb();
@@ -1510,7 +1508,7 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
1510 struct mmc_data *data = host->data; 1508 struct mmc_data *data = host->data;
1511 int shift = host->data_shift; 1509 int shift = host->data_shift;
1512 u32 status; 1510 u32 status;
1513 unsigned int nbytes = 0, len; 1511 unsigned int len;
1514 unsigned int fifo_depth = host->fifo_depth; 1512 unsigned int fifo_depth = host->fifo_depth;
1515 unsigned int remain, fcnt; 1513 unsigned int remain, fcnt;
1516 1514
@@ -1531,8 +1529,8 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
1531 if (!len) 1529 if (!len)
1532 break; 1530 break;
1533 host->push_data(host, (void *)(buf + offset), len); 1531 host->push_data(host, (void *)(buf + offset), len);
1532 data->bytes_xfered += len;
1534 offset += len; 1533 offset += len;
1535 nbytes += len;
1536 remain -= len; 1534 remain -= len;
1537 } while (remain); 1535 } while (remain);
1538 1536
@@ -1540,7 +1538,6 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
1540 status = mci_readl(host, MINTSTS); 1538 status = mci_readl(host, MINTSTS);
1541 mci_writel(host, RINTSTS, SDMMC_INT_TXDR); 1539 mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
1542 } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ 1540 } while (status & SDMMC_INT_TXDR); /* if TXDR write again */
1543 data->bytes_xfered += nbytes;
1544 1541
1545 if (!remain) { 1542 if (!remain) {
1546 if (!sg_miter_next(sg_miter)) 1543 if (!sg_miter_next(sg_miter))
@@ -1551,7 +1548,6 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
1551 return; 1548 return;
1552 1549
1553done: 1550done:
1554 data->bytes_xfered += nbytes;
1555 sg_miter_stop(sg_miter); 1551 sg_miter_stop(sg_miter);
1556 host->sg = NULL; 1552 host->sg = NULL;
1557 smp_wmb(); 1553 smp_wmb();