diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2008-05-30 08:18:57 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-07-15 08:14:42 -0400 |
commit | 4ac24a8722b97d5b4cfc48a4fbd0b2489e358d4d (patch) | |
tree | f9532aa124b8ab250bf3bec4648ed42621389c3c | |
parent | c5a89c6c0805959f813e8342d6f4040860f6d7db (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>
-rw-r--r-- | drivers/mmc/host/at91_mci.c | 40 |
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 | */ | ||
405 | static 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*/ |
405 | static int at91_mci_handle_cmdrdy(struct at91mci_host *host) | 427 | static 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) |