aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2008-05-30 08:18:57 -0400
committerPierre Ossman <drzeus@drzeus.cx>2008-07-15 08:14:42 -0400
commit4ac24a8722b97d5b4cfc48a4fbd0b2489e358d4d (patch)
treef9532aa124b8ab250bf3bec4648ed42621389c3c /drivers/mmc
parentc5a89c6c0805959f813e8342d6f4040860f6d7db (diff)
mmc: at91_mci: update bytes_xfered value once xfer done
Modify bytes_xfered value after a write. That will report, as accurately as possible, the amount of sectors that are effectively written. This update introduces the check of the busy signal given by the card. Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/at91_mci.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index e9242110ce2e..b5a6e250fc1a 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -340,8 +340,6 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
340 340
341 dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); 341 dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
342 342
343 data->bytes_xfered += sg->length;
344
345 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ 343 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
346 unsigned int *buffer; 344 unsigned int *buffer;
347 int index; 345 int index;
@@ -357,6 +355,8 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
357 } 355 }
358 356
359 flush_dcache_page(sg_page(sg)); 357 flush_dcache_page(sg_page(sg));
358
359 data->bytes_xfered += sg->length;
360 } 360 }
361 361
362 /* Is there another transfer to trigger? */ 362 /* Is there another transfer to trigger? */
@@ -397,10 +397,32 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
397 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE); 397 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
398 } else 398 } else
399 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); 399 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
400}
401
402/*
403 * Update bytes tranfered count during a write operation
404 */
405static void at91_mci_update_bytes_xfered(struct at91mci_host *host)
406{
407 struct mmc_data *data;
400 408
401 data->bytes_xfered = host->total_length; 409 /* always deal with the effective request (and not the current cmd) */
410
411 if (host->request->cmd && host->request->cmd->error != 0)
412 return;
413
414 if (host->request->data) {
415 data = host->request->data;
416 if (data->flags & MMC_DATA_WRITE) {
417 /* card is in IDLE mode now */
418 pr_debug("-> bytes_xfered %d, total_length = %d\n",
419 data->bytes_xfered, host->total_length);
420 data->bytes_xfered = host->total_length;
421 }
422 }
402} 423}
403 424
425
404/*Handle after command sent ready*/ 426/*Handle after command sent ready*/
405static int at91_mci_handle_cmdrdy(struct at91mci_host *host) 427static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
406{ 428{
@@ -413,8 +435,7 @@ static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
413 } else return 1; 435 } else return 1;
414 } else if (host->cmd->data->flags & MMC_DATA_WRITE) { 436 } else if (host->cmd->data->flags & MMC_DATA_WRITE) {
415 /*After sendding multi-block-write command, start DMA transfer*/ 437 /*After sendding multi-block-write command, start DMA transfer*/
416 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE); 438 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE | AT91_MCI_BLKE);
417 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
418 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); 439 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
419 } 440 }
420 441
@@ -817,6 +838,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
817 838
818 if (int_status & AT91_MCI_NOTBUSY) { 839 if (int_status & AT91_MCI_NOTBUSY) {
819 pr_debug("Card is ready\n"); 840 pr_debug("Card is ready\n");
841 at91_mci_update_bytes_xfered(host);
820 completed = 1; 842 completed = 1;
821 } 843 }
822 844
@@ -825,7 +847,13 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
825 847
826 if (int_status & AT91_MCI_BLKE) { 848 if (int_status & AT91_MCI_BLKE) {
827 pr_debug("Block transfer has ended\n"); 849 pr_debug("Block transfer has ended\n");
828 completed = 1; 850 if (host->request->data && host->request->data->blocks > 1) {
851 /* multi block write : complete multi write
852 * command and send stop */
853 completed = 1;
854 } else {
855 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
856 }
829 } 857 }
830 858
831 if (int_status & AT91_MCI_TXRDY) 859 if (int_status & AT91_MCI_TXRDY)