mmc: at91_mci: rework to allow better transfer
Subsystems (2)
cover mmc: at91_mci: rework to allow better transfer
Hi Pierre,
Following your announce of future removal of the MMC multiwrite switch and the contributions of several people of the AT91 community, here is a patches series :
Those patches should enhance transfer of data and setup a sane base for a working SDIO support.
Several of those contributions are around since the beginning of this year. I thank all of you for your patient and valuable testing effort. Here are some discussions that led to this patch series:
"mmc: at91_mci: support for block size not modulo 4"
http://lists.arm.linux.org.uk/lurker/message/20080107.141550.ea58119f.en.html
AT91 SDIO + 8686
http://lists.arm.linux.org.uk/lurker/message/20071114.094824.3ebcbe04.en.html
"8686 with SDIO on AT91SAM9263"
http://lists.arm.linux.org.uk/lurker/message/20080123.182026.f3c54a8a.en.html
"[PATCH 0/2] at91_mci: manage timeouts"
http://lists.arm.linux.org.uk/lurker/message/20080125.075058.257a2582.en.html
"[PATCH 0/3] at91_mci: fix SD filesystem corruption on sam9261"
http://lists.arm.linux.org.uk/lurker/message/20080318.145450.7b443217.en.html
Regards,
Signature · 1 line
Nicolas Ferre
PATCH 1/7 mmc: at91_mci: support for block size not modulo 4
From: Marc Pignat <[email protected]>
Implement transfer with size not modulo 4 for at91sam9*. Please note that the at91rm9200 simply can't handle this.
---drivers/mmc/host/at91_mci.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
drivers/mmc/host/at91_mci.c +0 -0
@@ -233,11 +233,11 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
if (i == 0) {
at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
- at91_mci_write(host, ATMEL_PDC_RCR, sg->length / 4);
+ at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
}
else {
at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
- at91_mci_write(host, ATMEL_PDC_RNCR, sg->length / 4);
+ at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
}
}@@ -430,7 +430,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
if (data) {- if ( data->blksz & 0x3 ) {
+ if ( cpu_is_at91rm9200() && (data->blksz & 0x3) ) {
pr_debug("Unsupported block size\n");
cmd->error = -EINVAL;
mmc_request_done(host->mmc, host->request);
@@ -482,7 +482,10 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
} else {
/* zero block length and PDC mode */
mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
- at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
+ mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0;
+ mr |= (block_length << 16);
+ mr |= AT91_MCI_PDCMODE;+ at91_mci_write(host, AT91_MCI_MR, mr);
/*
* Disable the PDC controller
@@ -517,7 +520,9 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
pr_debug("Transmitting %d bytes\n", host->total_length);
at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);- at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
+ at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ?
+ host->total_length : host->total_length / 4);
+
ier = AT91_MCI_CMDRDY; } }
Signature · 1 line
1.5.3.7
PATCH 2/7 mmc: at91_mci: show timeouts
In reply to Nicolas FerreFrom: Marc Pignat <[email protected]>
Detect command timeout (or mci controller hangs).
---drivers/mmc/host/at91_mci.c | 35 +++++++++++++++++++++++++++++++++--
1 files changed, 33 insertions(+), 2 deletions(-)
drivers/mmc/host/at91_mci.c +0 -0
@@ -125,8 +125,33 @@ struct at91mci_host
/* Latest in the scatterlist that has been enabled for transfer */ int transfer_index;
+
+ /* Timer for timeouts */
+ struct timer_list timer;
};
+static void at91_timeout_timer(unsigned long data)
+{
+ struct at91mci_host *host;
+
+ host = (struct at91mci_host *)data;
+
+ if (host->request) {
+ dev_err(host->mmc->parent, "Timeout waiting end of packet\n");
+
+ if (host->cmd && host->cmd->data) {
+ host->cmd->data->error = -ETIMEDOUT;
+ } else {
+ if (host->cmd)
+ host->cmd->error = -ETIMEDOUT;
+ else
+ host->request->cmd->error = -ETIMEDOUT;
+ }
+
+ mmc_request_done(host->mmc, host->request);
+ }
+}
+
/*
* Copy from sg to a dma block - used for transfers
*/
@@ -557,9 +582,10 @@ static void at91_mci_process_next(struct at91mci_host *host)
else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
host->flags |= FL_SENT_STOP;
at91_mci_send_command(host, host->request->stop);
- }
- else
+ } else {
+ del_timer(&host->timer);
mmc_request_done(host->mmc, host->request);+ }
}
/*
@@ -618,6 +644,8 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->request = mrq; host->flags = 0;
+ mod_timer(&host->timer, jiffies + HZ);
+
at91_mci_process_next(host); }
@@ -940,6 +968,8 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc_add_host(mmc);
+ setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host);
+
/* * monitor card insertion/removal if we can */ @@ -1000,6 +1030,7 @@ static int __exit at91_mci_remove(struct platform_device *pdev) } at91_mci_disable(host); + del_timer_sync(&host->timer); mmc_remove_host(mmc); free_irq(host->irq, host);
Signature · 1 line
1.5.3.7
PATCH 3/7 mmc: at91_mci: avoid timeouts
In reply to Nicolas FerreFrom: Marc Pignat <[email protected]>
The at91 mci controller internal state machine seems to often crash. This can be fixed by resetting the controller after each command for at91rm9200 and by setting the MCI_BLKR register on at91sam926*.
---drivers/mmc/host/at91_mci.c | 48 ++++++++++++++++++++++++++++++++++include/asm-arm/arch-at91/at91_mci.h | 4 +++
2 files changed, 52 insertions(+), 0 deletions(-)
drivers/mmc/host/at91_mci.c +0 -0
@@ -130,6 +130,43 @@ struct at91mci_host
struct timer_list timer; };
+/*
+ * Reset the controller and restore most of the state
+ */
+static void at91_reset_host(struct at91mci_host *host) +{
+ unsigned long flags;
+ u32 mr;
+ u32 sdcr;
+ u32 dtor;
+ u32 imr;
+
+ local_irq_save(flags);
+ imr = at91_mci_read(host, AT91_MCI_IMR);
+
+ at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
+
+ /* save current state */
+ mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
+ sdcr = at91_mci_read(host, AT91_MCI_SDCR);
+ dtor = at91_mci_read(host, AT91_MCI_DTOR);
+
+ /* reset the controller */
+ at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
+
+ /* restore state */
+ at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
+ at91_mci_write(host, AT91_MCI_MR, mr);
+ at91_mci_write(host, AT91_MCI_SDCR, sdcr);
+ at91_mci_write(host, AT91_MCI_DTOR, dtor);
+ at91_mci_write(host, AT91_MCI_IER, imr);
+
+ /* make sure sdio interrupts will fire */
+ at91_mci_read(host, AT91_MCI_SR);
+
+ local_irq_restore(flags);
+}
+
static void at91_timeout_timer(unsigned long data)
{
struct at91mci_host *host;
@@ -148,6 +185,7 @@ static void at91_timeout_timer(unsigned long data)
host->request->cmd->error = -ETIMEDOUT;
}+ at91_reset_host(host); mmc_request_done(host->mmc, host->request); } } @@ -512,6 +550,11 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command mr |= AT91_MCI_PDCMODE; at91_mci_write(host, AT91_MCI_MR, mr);
+ if (!cpu_is_at91rm9200())
+ at91_mci_write(host, AT91_MCI_BLKR,
+ AT91_MCI_BLKR_BCNT(blocks) |
+ AT91_MCI_BLKR_BLKLEN(block_length));
+
/*
* Disable the PDC controller
*/
@@ -584,6 +627,11 @@ static void at91_mci_process_next(struct at91mci_host *host)
at91_mci_send_command(host, host->request->stop);
} else {
del_timer(&host->timer);+ /* the at91rm9200 mci controller hangs after some transfers,
+ * and the workaround is to reset it after each transfer.
+ */
+ if (cpu_is_at91rm9200())
+ at91_reset_host(host); mmc_request_done(host->mmc, host->request); } }
include/asm-arm/arch-at91/at91_mci.h +0 -0
@@ -75,6 +75,10 @@
#define AT91_MCI_TRTYP_MULTIPLE (1 << 19)
#define AT91_MCI_TRTYP_STREAM (2 << 19)
+#define AT91_MCI_BLKR 0x18 /* Block Register */
+#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
+#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block lenght */
+
#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */
#define AT91_MCR_RDR 0x30 /* Receive Data Register */
#define AT91_MCR_TDR 0x34 /* Transmit Data Register */
Signature · 1 line
1.5.3.7
PATCH 4/7 mmc: at91_mci: add multiwrite switch
In reply to Nicolas Ferreat91_mci is capable of multiwrite. Enable it before it disappears.
---drivers/mmc/host/at91_mci.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
drivers/mmc/host/at91_mci.c +0 -0
@@ -923,6 +923,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc->f_min = 375000; mmc->f_max = 25000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_MULTIWRITE;
mmc->max_blk_size = 4095; mmc->max_blk_count = mmc->max_req_size;
Signature · 1 line
1.5.3.7
PATCH 5/7 mmc: at91_mci: update bytes_xfered value once xfer done
In reply to Nicolas FerreModify 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.
---drivers/mmc/host/at91_mci.c | 40 ++++++++++++++++++++++++++++++++++------
1 files changed, 34 insertions(+), 6 deletions(-)
drivers/mmc/host/at91_mci.c +0 -0
@@ -340,8 +340,6 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
- data->bytes_xfered += sg->length;
-
if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
unsigned int *buffer;
int index;
@@ -357,6 +355,8 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
}
flush_dcache_page(sg_page(sg));
+
+ data->bytes_xfered += sg->length;
}
/* Is there another transfer to trigger? */
@@ -397,10 +397,32 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
} else
at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);+}
+
+/*
+ * Update bytes tranfered count during a write operation
+ */
+static void at91_mci_update_bytes_xfered(struct at91mci_host *host) +{
+ struct mmc_data *data;
- data->bytes_xfered = host->total_length;
+ /* always deal with the effective request (and not the current cmd) */
+
+ if (host->request->cmd && host->request->cmd->error != 0)
+ return;
+
+ if (host->request->data) {
+ data = host->request->data;
+ if (data->flags & MMC_DATA_WRITE) {
+ /* card is in IDLE mode now */
+ pr_debug("-> bytes_xfered %d, total_length = %d\n",
+ data->bytes_xfered, host->total_length);
+ data->bytes_xfered = host->total_length;
+ }
+ }
}
+
/*Handle after command sent ready*/
static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
{
@@ -413,8 +435,7 @@ static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
} else return 1;
} else if (host->cmd->data->flags & MMC_DATA_WRITE) {
/*After sendding multi-block-write command, start DMA transfer*/
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE);
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE | AT91_MCI_BLKE);
at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
}@@ -817,6 +838,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
if (int_status & AT91_MCI_NOTBUSY) {
pr_debug("Card is ready\n");
+ at91_mci_update_bytes_xfered(host);
completed = 1;
}@@ -825,7 +847,13 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
if (int_status & AT91_MCI_BLKE) {
pr_debug("Block transfer has ended\n");- completed = 1;
+ if (host->request->data && host->request->data->blocks > 1) {
+ /* multi block write : complete multi write
+ * command and send stop */
+ completed = 1;
+ } else {
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+ }
} if (int_status & AT91_MCI_TXRDY)
Signature · 1 line
1.5.3.7
Re: [PATCH 5/7] mmc: at91_mci: update bytes_xfered value once xfer done
Quoted 9 lines · Nicolas Ferre
Modify
bytes_xferedvalue 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 <[email protected]>
Doesn't this patch depend on patch 4? IOW, shouldn't you be correcting this before you enable the features which require this to be accurate?
PATCH 6/7 mmc: at91_mci: add sdio irq management
In reply to Nicolas FerreFrom: Eric Benard <[email protected]>
Enable SDIO interrupt handling.
---drivers/mmc/host/at91_mci.c | 26 ++++++++++++++++++++++----
1 files changed, 22 insertions(+), 4 deletions(-)
drivers/mmc/host/at91_mci.c +0 -0
@@ -665,7 +665,7 @@ static void at91_mci_completed_command(struct at91mci_host *host)
struct mmc_command *cmd = host->cmd; unsigned int status;
- at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
+ at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0)); cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1)); @@ -856,6 +856,12 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) } }
+ if (int_status & AT91_MCI_SDIOIRQA)
+ mmc_signal_sdio_irq(host->mmc);
+
+ if (int_status & AT91_MCI_SDIOIRQB)
+ mmc_signal_sdio_irq(host->mmc);
+
if (int_status & AT91_MCI_TXRDY)
pr_debug("Ready to transmit\n");@@ -870,10 +876,10 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
if (completed) {
pr_debug("Completed command\n");
- at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
+ at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
at91_mci_completed_command(host);
} else- at91_mci_write(host, AT91_MCI_IDR, int_status);
+ at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
return IRQ_HANDLED; } @@ -917,10 +923,22 @@ static int at91_mci_get_ro(struct mmc_host *mmc) return read_only; }
+static void at91_mci_enable_sdio_irq(struct mmc_host *mmc, int enable) +{
+ struct at91mci_host *host = mmc_priv(mmc);
+
+ pr_debug("%s: sdio_irq %c : %s\n", mmc_hostname(host->mmc),
+ host->board->slot_b ? 'B':'A', enable ? "enable" : "disable");
+ at91_mci_write(host, enable ? AT91_MCI_IER : AT91_MCI_IDR,
+ host->board->slot_b ? AT91_MCI_SDIOIRQB : AT91_MCI_SDIOIRQA);
+
+}
+
static const struct mmc_host_ops at91_mci_ops = {
.request = at91_mci_request,
.set_ios = at91_mci_set_ios,
.get_ro = at91_mci_get_ro,+ .enable_sdio_irq = at91_mci_enable_sdio_irq,
};
/*
@@ -951,7 +969,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc->f_min = 375000; mmc->f_max = 25000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps = MMC_CAP_MULTIWRITE;
+ mmc->caps = MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ;
mmc->max_blk_size = 4095; mmc->max_blk_count = mmc->max_req_size;
Signature · 1 line
1.5.3.7
PATCH 7/7 mmc: at91_mci: do not read irq status twice as it will forget some errors
In reply to Nicolas FerreReading AT91_MCI_SR again at the end of transfer can corrupt the error reporting. Some fields in the SR register are read-and-clear.
---drivers/mmc/host/at91_mci.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
drivers/mmc/host/at91_mci.c +0 -0
@@ -660,10 +660,9 @@ static void at91_mci_process_next(struct at91mci_host *host)
/*
* Handle a command that has been completed
*/
-static void at91_mci_completed_command(struct at91mci_host *host) +static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status)
{
struct mmc_command *cmd = host->cmd;- unsigned int status;
at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
@@ -677,10 +676,9 @@ static void at91_mci_completed_command(struct at91mci_host *host)
host->buffer = NULL; }
- status = at91_mci_read(host, AT91_MCI_SR);
-
- pr_debug("Status = %08X [%08X %08X %08X %08X]\n",
- status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
+ pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
+ status, at91_mci_read(host, AT91_MCI_SR),
+ cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
if (status & AT91_MCI_ERRORS) {
if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
@@ -877,7 +875,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
if (completed) {
pr_debug("Completed command\n");
at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
- at91_mci_completed_command(host);
+ at91_mci_completed_command(host, int_status);
} else
at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));Signature · 1 line
1.5.3.7
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 1/7] mmc: at91_mci: support for block size not modulo 4
Hi Nicolas!
On Friday 30 May 2008, Nicolas Ferre wrote:> From: Marc Pignat <[email protected]>> > Implement transfer with size not modulo 4 for at91sam9*. Please note that the> at91rm9200 simply can't handle this.> > Signed-off-by: Marc Pignat <[email protected]>> Signed-off-by: Nicolas Ferre <[email protected]>> ---
I just want we don't forget that at91sam9260 errata, pointed by someone when Iposted this patch...
44.2.4.4 Data Write Operation and number of bytes The Data Write operation with a number of bytes less than 12 is impossible. Problem Fix/Workaround The PDC counters must always be equal to 12 bytes for data transfers lower than 12 bytes. The BLKLEN or BCNT field are used to specify the real count number. We should probably fix that thing in the next release and verify if otherchips are affected!
Quoted 1 line
drivers/mmc/host/at91_mci.c | 15 ++++++++++-----> 1 files changed, 10 insertions(+), 5 deletions(-)> > diff --git
a/drivers/mmc/host/at91_mci.cb/drivers/mmc/host/at91_mci.c> index 8979ad3..543b64b 100644> ---a/drivers/mmc/host/at91_mci.c> +++b/drivers/mmc/host/at91_mci.c> @@ -233,11 +233,11 @@ static voidat91_mci_pre_dma_read(struct at91mci_host *host)> > if (i == 0) {> at91_mci_write(host,ATMEL_PDC_RPR,sg->dma_address);> - at91_mci_write(host,ATMEL_PDC_RCR,sg->length/ 4);> + at91_mci_write(host,ATMEL_PDC_RCR, (data->blksz&0x3) ?sg->length:sg->length/ 4);> }> else {> at91_mci_write(host,ATMEL_PDC_RNPR,sg->dma_address);> - at91_mci_write(host,ATMEL_PDC_RNCR,sg->length/ 4);> + at91_mci_write(host,ATMEL_PDC_RNCR, (data->blksz&0x3) ?sg->length:sg->length/ 4);> }> }> > @@ -430,7 +430,7 @@ static void at91_mci_send_command(structat91mci_host*host, structmmc_command> > if (data) {> > - if (data->blksz&0x3) {> + if (cpu_is_at91rm9200()&& (data->blksz&0x3) ) {> pr_debug("Unsupported block size\n");> cmd->error =-EINVAL;> mmc_request_done(host->mmc,host->request);> @@ -482,7 +482,10 @@ static void at91_mci_send_command(structat91mci_host*host, structmmc_command> } else {> /* zero block length and PDC mode */> mr =at91_mci_read(host, AT91_MCI_MR)&0x7fff;> - at91_mci_write(host,AT91_MCI_MR, mr | (block_length<< 16) | AT91_MCI_PDCMODE);here, we should do something like{ /* blocks smaller than 16 will be rounded up to 16 at91sam9260, and 16 is modulo 4 :) */ if (!(cpu_is_at91sam9260() && size < 16)) mr |= (data->blksz&0x3) ?AT91_MCI_PDCFBYTE: 0;}> + mr |= (block_length<< 16);> + mr |=AT91_MCI_PDCMODE;> + at91_mci_write(host,AT91_MCI_MR, mr);> > /*> * Disable the PDC controller> @@ -517,7 +520,9 @@ static void at91_mci_send_command(structat91mci_host*host, structmmc_command> pr_debug("Transmitting %d bytes\n",host->total_length);> > at91_mci_write(host,ATMEL_PDC_TPR,host->physical_address);> - at91_mci_write(host,ATMEL_PDC_TCR,host->total_length/ 4);> + at91_mci_write(host,ATMEL_PDC_TCR, (data->blksz&0x3) ?> + host->total_length :host->total_length/ 4);here, we should add something like{ unsigned long size = data->blksz; if (cpu_is_at91sam9260()&& size < 16 ) size = 16; at91_mci_write(host,ATMEL_PDC_TCR, (size &0x3) ? size : size / 4);}> +> ier =AT91_MCI_CMDRDY;> }> }
Best regards Marcÿôèº{.nÇ+‰·Ÿ®‰†+%ŠËÿ±éݶ¥Šwÿº{.nÇ+‰·¥Š{±þG«�éÿŠ{ayºÊ‡Ú™ë,j¢f£¢·hš�ï�êÿ‘êçz_è®(階ŠÝ¢j"�ú¶m§ÿÿ¾«þG«�éÿ¢¸?™¨èÚ&£ø§~�á¶iO•æ¬z·švØ^¶m§ÿÿÃÿ¶ìÿ¢¸?–I¥
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 4/7] mmc: at91_mci: add multiwrite switch
Quoted 1 line · Nicolas Ferre
at91_mciis capable of multiwrite. Enable it before it disappears.
This doesn't look safe. MULTIWRITE is not about whether you can do multi-writes, but whether you can properly report how many bytes were successfully written to the card _and_ the card acknowledged as having been successfully written.
It looks to me as if the AT91 MMC driver reports no bytes, or all bytes if the FIFO reports that it became empty, which presumably it may do if you're unable to keep the FIFO full?
(Dropped Hans-JA¼rgen from the CC list since my mailer seems to corrupt the address.)
If Pierre wants to remove the MULTIWRITE flag, I'd like to hear his solution for the pxamci driver, where the only way to ascertain how many bytes were transmitted may be to walk the SG list comparing the DMA pointer with what was in the hardware DMA engine at the time. Maybe.
Re: [PATCH 4/7] mmc: at91_mci: add multiwrite switch
Quoted 5 lines · On Sun, 1 Jun 2008 15:42:52 +0100 Russell King - ARM Linux…
If Pierre wants to remove the MULTIWRITE flag, I'd like to hear his solution for the pxamci driver, where the only way to ascertain how many bytes were transmitted may be to walk the SG list comparing the DMA pointer with what was in the hardware DMA engine at the time. Maybe.
You set bytes_xfered to 0. As mentioned in my previous mail, I had a chat with Jens about this and upper layers can only expect to get the lower bound in how many bytes were written. Other hardware/drivers already behaves like this so there is no point in crippling the MMC layer in an effort to give nicer guarantees.
This is why I asked people to audit their drivers to make sure it's the lower bound that's returned, but I've not received much in the way of replies.
Rgds
Pierre
Re: [PATCH 4/7] mmc: at91_mci: add multiwrite switch
Quoted 15 lines · Pierre Ossman
Quoted 5 lines · On Sun, 1 Jun 2008 15:42:52 +0100 Russell King - ARM Linux…
If Pierre wants to remove the MULTIWRITE flag, I'd like to hear his solution for the pxamci driver, where the only way to ascertain how many bytes were transmitted may be to walk the SG list comparing the DMA pointer with what was in the hardware DMA engine at the time. Maybe.
You set
bytes_xferedto 0. As mentioned in my previous mail, I had a chat with Jens about this and upper layers can only expect to get the lower bound in how many bytes were written. Other hardware/drivers already behaves like this so there is no point in crippling the MMC layer in an effort to give nicer guarantees.
Quoted 3 lines
This is why I asked people to audit their drivers to make sure it's the lower bound that's returned, but I've not received much in the way of replies.
You won't do from me concerning pxamci - I don't look after it anymore after one of my MMC cards got eaten by the misbehaving bugger. I don't think anyone else is looking after it, so that means the driver's effectively unmaintained.
Re: [PATCH 4/7] mmc: at91_mci: add multiwrite switch
Quoted 10 lines · On Mon, 9 Jun 2008 14:08:31 +0100 Russell King - ARM Linux…
Quoted 4 lines · Pierre Ossman
This is why I asked people to audit their drivers to make sure it's the lower bound that's returned, but I've not received much in the way of replies.
You won't do from me concerning pxamci - I don't look after it anymore after one of my MMC cards got eaten by the misbehaving bugger. I don't think anyone else is looking after it, so that means the driver's effectively unmaintained.
pxamxi is marked as orphaned in MAINTAINERS, so I didn't expect an answer about that one from anyone. :)
You're still listed for the primecell driver though. What's the status on that one?
Rgds
Pierre
Re: [PATCH 4/7] mmc: at91_mci: add multiwrite switch
Quoted 2 lines · Pierre Ossman
You're still listed for the primecell driver though. What's the status on that one?
It's always reported the number of bytes transferred to/from the card (which I think includes the wait for the busy signal to deassert.)
Probably the best thing is to mark MMCI as orphaned as well - for much the same reason. I've only one remaining MMC card which I use for other purposes. I'm not willing to sacrifice that one for further testing, neither am I willing to buy another card to just be used for testing purposes.
Re: [PATCH 4/7] mmc: at91_mci: add multiwrite switch
Quoted 7 lines · On Mon, 9 Jun 2008 14:53:57 +0100 Russell King - ARM Linux…
Quoted 2 lines · Pierre Ossman
You're still listed for the primecell driver though. What's the status on that one?
It's always reported the number of bytes transferred to/from the card (which I think includes the wait for the busy signal to deassert.)
If only all hardware was like that...
Quoted 5 lines
Probably the best thing is to mark MMCI as orphaned as well - for much the same reason. I've only one remaining MMC card which I use for other purposes. I'm not willing to sacrifice that one for further testing, neither am I willing to buy another card to just be used for testing purposes.
Fair enough. Could you send a patch, preferably with some relevant list(s) cc:d in case someone else wants to take over the work?
Rgds
Pierre
Quoted 8 lines · On Fri, 30 May 2008 13:49:59 +0200 Nicolas Ferre <[email protected]>…
Hi Pierre,
Following your announce of future removal of the MMC multiwrite switch and the contributions of several people of the AT91 community, here is a patches series :
Those patches should enhance transfer of data and setup a sane base for a working SDIO support.
I have no big concerns about the patches. There were some comments from other people though. Do you want to have a look at those first?
Rgds
Pierre
Pierre Ossman :
Quoted 10 lines
Quoted 5 lines · On Fri, 30 May 2008 13:49:59 +0200 Nicolas Ferre <[email protected]>…
Hi Pierre,
Following your announce of future removal of the MMC multiwrite switch and the contributions of several people of the AT91 community, here is a patches series :
Those patches should enhance transfer of data and setup a sane base for a working SDIO support.I have no big concerns about the patches.
Ok, good !
Quoted 2 lines
There were some comments from
other people though. Do you want to have a look at those first?
Russell King highlights that patch #4 is not well inserted in the series : it have to be after #5 (after correcting bytes_xfered update).
If you want I can reorder them... or you manage to do it.
I will take into account Marc's comment and new Ville patch series in another round ;-)
Btw, you can also add the "manage cmd error and data error independently" patch I have just sent.
Kind regards,
Signature · 1 line
Nicolas Ferre
Quoted 8 lines · On Tue, 10 Jun 2008 11:54:41 +0200 Nicolas Ferre <[email protected]>…
Russell King highlights that patch #4 is not well inserted in the series : it have to be after #5 (after correcting
bytes_xferedupdate).If you want I can reorder them... or you manage to do it.
I will take into account Marc's comment and new Ville patch series in another round ;-)
Will you redo this series, or are you planning further patches? (i.e. should I merge this set or wait for an update?)
Pierre Ossman :
Quoted 11 lines
Quoted 5 lines · On Tue, 10 Jun 2008 11:54:41 +0200 Nicolas Ferre <[email protected]>…
Russell King highlights that patch #4 is not well inserted in the series : it have to be after #5 (after correcting
bytes_xferedupdate).If you want I can reorder them... or you manage to do it.
I will take into account Marc's comment and new Ville patch series in another round ;-)
Will you redo this series, or are you planning further patches? (i.e. should I merge this set or wait for an update?)
You can merge this patch series (7 patches)
You can also merge
http://lists.arm.linux.org.uk/lurker/message/20080610.092729.beef9e64.en.html
"at91_mci: manage cmd error and data error independently" (1 patch)
And 3 patches from Ville Syrjälä that I have just signed:
http://lists.arm.linux.org.uk/lurker/message/20080614.172720.dd0e776e.en.html
"at91_mci: AT91SAM9260/9263 12 byte write erratum (v2)"
http://lists.arm.linux.org.uk/lurker/message/20080609.190644.3f64ff91.en.html
"at91_mci: Cover more AT91RM9200 and AT91SAM9261 errata."
http://lists.arm.linux.org.uk/lurker/message/20080609.190645.2998e511.en.html
"at91_mci: Fix byte mode transitions."
=> 11 patches.
Thanks a lot, regards,
Signature · 1 line
Nicolas Ferre
On Wed, Jun 18, 2008 at 12:04:49PM +0200, Nicolas Ferre wrote:
[...]
Could you all drop =?ISO-8859-1?Q?Hans-J=FCrgen_?= from the Cc list in this thread? The address is invalid because it has no domain part and hence causes quite some bounces on the list because some strict email checkers reject invalid addresses in the Cc list.
I'm trying to figure out what went wrong, but in the mean time please drop =?ISO-8859-1?Q?Hans-J=FCrgen_?= from the Cc list.
Erik
[linux-arm-kernel-owner #2]
Signature · 1 line
Erik Mouw -- [email protected]
Quoted 11 lines · Erik Mouw
On Wed, Jun 18, 2008 at 12:04:49PM +0200, Nicolas Ferre wrote:
[...]
Could you all drop =?ISO-8859-1?Q?Hans-J=FCrgen_?= from the Cc list in this thread? The address is invalid because it has no domain part and hence causes quite some bounces on the list because some strict email checkers reject invalid addresses in the Cc list.
I'm trying to figure out what went wrong, but in the mean time please drop =?ISO-8859-1?Q?Hans-J=FCrgen_?= from the Cc list.
Found it, Mailman is to blame. On the linux-kernel mailing list, the address shows up ok: "=?ISO-8859-1?Q?Hans-J=FCrgen_?= =?ISO-8859-1?Q?Koch?= <[email protected]>".
What probably happens: Mailman tries to check if the addresses in the To and CC fields are subscribed to the list (linux-arm-kernel). If that is the case and the subscriber enabled "prevent doubles", it won't send that particular subscriber the message. Of course, this should have been implemented by a simple strncmp() on the To and CC fields, but I guess Mailman first breaks up the To and CC fields, then does the "prevent double" check, and then reassembles the To and CC fields. Apparently there is an error in the break up or reassembly. Now how to fix this without breaking Mailman alltogether...
In the mean time, could you just use Hans-Jürgen's address ([email protected]>) and not his name in the CC field?
Erik
[linux-arm-kernel-owner #2]
(thanks to David Woodhouse for helping to debug the problem)
Signature · 1 line
Erik Mouw -- [email protected]
Quoted 27 lines · Erik Mouw
Quoted 11 lines · Erik Mouw
On Wed, Jun 18, 2008 at 12:04:49PM +0200, Nicolas Ferre wrote:
[...]
Could you all drop =?ISO-8859-1?Q?Hans-J=FCrgen_?= from the Cc list in this thread? The address is invalid because it has no domain part and hence causes quite some bounces on the list because some strict email checkers reject invalid addresses in the Cc list.
I'm trying to figure out what went wrong, but in the mean time please drop =?ISO-8859-1?Q?Hans-J=FCrgen_?= from the Cc list.
Found it, Mailman is to blame. On the linux-kernel mailing list, the address shows up ok: "=?ISO-8859-1?Q?Hans-J=FCrgen_?= =?ISO-8859-1?Q?Koch?= <[email protected]>".
What probably happens: Mailman tries to check if the addresses in the To and CC fields are subscribed to the list (linux-arm-kernel). If that is the case and the subscriber enabled "prevent doubles", it won't send that particular subscriber the message. Of course, this should have been implemented by a simple
strncmp()on the To and CC fields, but I guess Mailman first breaks up the To and CC fields, then does the "prevent double" check, and then reassembles the To and CC fields. Apparently there is an error in the break up or reassembly. Now how to fix this without breaking Mailman alltogether...
Quoted 2 lines
In the mean time, could you just use Hans-J?rgen's address ([email protected]>) and not his name in the CC field?
I avoided the German umlaut in my name by using the abbreviation "Hans J. Koch" on mailing lists. Unfortunately, I still have one mail client that uses the full name. I'll fix that to avoid similar trouble.
On the other hand, I used that for quite a while now, and didn't have problems. It shouldn't be too difficult to have these programs use UTF-8 (or any other charset) properly these days.
Thanks,
Hans
Quoted 8 lines
Erik
[linux-arm-kernel-owner #2]
(thanks to David Woodhouse for helping to debug the problem)Signature · 1 line
Erik Mouw -- [email protected]
Quoted 8 lines · Hans J. Koch
I avoided the German umlaut in my name by using the abbreviation "Hans J. Koch" on mailing lists. Unfortunately, I still have one mail client that uses the full name. I'll fix that to avoid similar trouble.
On the other hand, I used that for quite a while now, and didn't have problems. It shouldn't be too difficult to have these programs use UTF-8 (or any other charset) properly these days.
I'm not convinced it's a problem with rfc2047 handling; I think it's simpler brain-damage than that on mailman's part. It's to do with line wrapping, iirc -- if an address spans two lines, like: David Woodhouse
<[email protected]>, then mailman will brokenly insert a comma where
the line break happened -- or something like that.
Signature · 1 line
dwmw2
Quoted 10 lines · David Woodhouse
Quoted 8 lines · Hans J. Koch
I avoided the German umlaut in my name by using the abbreviation "Hans J. Koch" on mailing lists. Unfortunately, I still have one mail client that uses the full name. I'll fix that to avoid similar trouble.
On the other hand, I used that for quite a while now, and didn't have problems. It shouldn't be too difficult to have these programs use UTF-8 (or any other charset) properly these days.
Quoted 5 lines
I'm not convinced it's a problem with rfc2047 handling; I think it's simpler brain-damage than that on mailman's part. It's to do with line wrapping, iirc -- if an address spans two lines, like: David Woodhouse
<[email protected]>, then mailman will brokenly insert a comma where
the line break happened -- or something like that.
It's a bit more complicated cause Mailman gets this right:
ARM Linux Mailing List
<[email protected]>,
It also gets RFC2407 right:
=?ISO-8859-1?Q?Ville_Syrj=E4l=E4?= <[email protected]>
I guess it's a combination that goes wrong:
=?ISO-8859-1?Q?Hans-J=FCrgen_?= =?ISO-8859-1?Q?Koch?= <[email protected]>
Maybe if Jürgen's mailer made that something like:
=?ISO-8859-1Q!Hans-J=FCrgen_Koch?=
Mailman wouldn't have crippled the address?
Oh well, rmk isn't available for a few days so I can't really debug the Mailman version on lists.arm.linux.org.uk :(
Erik
Signature · 1 line
Erik Mouw -- [email protected]
Quoted 2 lines · Erik Mouw
Oh well, rmk isn't available for a few days so I can't really debug the Mailman version on lists.arm.linux.org.uk :(
I can set up a test list for you to screw around with if you like.
Signature · 1 line
dwmw2
Quoted 5 lines · David Woodhouse
Quoted 2 lines · Erik Mouw
Oh well, rmk isn't available for a few days so I can't really debug the Mailman version on lists.arm.linux.org.uk :(
I can set up a test list for you to screw around with if you like.
No need for that, I can install Mailman on my laptop. Thanks for the offer, though.
Erik
Signature · 1 line
Erik Mouw -- [email protected]
Quoted 3 lines · On Wed, 18 Jun 2008 12:04:49 +0200 Nicolas Ferre <[email protected]>…
You can merge this patch series (7 patches)
Everything merged up. It'll be hitting kernel.org soon.
Rgds
Signature · 5 lines
-- Pierre Ossman WARNING: This correspondence is being monitored by the Swedish government. Use end-to-end encryption where possible.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 6 lines · On Fri, 20 Jun 2008 10:05:51 -0700 "Ram kumar" <[email protected]>…
Will it be available on maxim.org.za also.? Because i have downloaded the linux 2.6.24 patches from maxim website.I dont know where the arm patches are in the http://kernel.org can you just tell me where the patches are ?
What about the 6 series patches ? Will it be available too....?
This will be in my -next branch, based on mainline linux. For anything else, you'll have to ask the maintainer of the relevant tree.
Signature · 5 lines
-- Pierre Ossman WARNING: This correspondence is being monitored by the Swedish government. Use end-to-end encryption where possible.