Linux MultiMedia Card development
 help / color / mirror / Atom feed
From: Christian Loehle <christian.loehle@arm.com>
To: Prasad Koya <prasad@arista.com>
Cc: Baptiste Covolato <baptiste@arista.com>,
	Sushrut Shirole <sushrut@arista.com>,
	linux-mmc@vger.kernel.org
Subject: Re: eMMC timeout reproduction. Can I send a block of data from the host to the card with invalid CRC?
Date: Tue, 22 Apr 2025 22:53:59 +0100	[thread overview]
Message-ID: <2343cad4-89aa-48c6-86e7-0c8847ecfe60@arm.com> (raw)
In-Reply-To: <CAKh1g55ErQRRsJSe6zEmp6mT6nAhEP_Br+HA8x5RvUa4B=4ERA@mail.gmail.com>

On 4/22/25 18:37, Prasad Koya wrote:
> Hi Christian
> 
> Thanks for going over and replying.
> 
> I couldn't find any ioctl() that changed host's block size in the 6.14
> tree. We are using 5.10 kernel.

Works on any kernel since a long time.
You can find a caller instance in mmc-utils: mmc_cmds.c, the field is
called blksz, if you've already familiarized yourself with the test
module I'd say don't bother though.

> 
> I did try mmc_test module so I can modify an existing test case and
> make it a simple one. Hacking this module, I could call CMD16 via
> mmc_test_set_blksize() and set the block size to 514 (0x202). Below
> are the eMMC traces for this test. A CMD16, followed by CMD25 with
> data, stop opcode and then CMD13. The multi-block write seems to go
> fine.

Sorry, misunderstanding here. I meant changing the blocksize of the
transfer for the host *without* letting the card know (by issuing CMD16).
So leave out the CMD16 part and you should achieve what you want.

> 
>             bash-3958  [001] .... 34861.450688: mmc_request_start:
> mmc0: start struct mmc_request[00000000fe878338]: cmd_opcode=16
> cmd_arg=0x202 cmd_flags=0x95 cmd_retries=5 stop_opcode=0 stop_arg=0x0
> stop_flags=0x0 stop_retries=0 sbc_opcode=0 sbc_arg=0x0 sbc_flags=0x0
> sbc_retires=0 blocks=0 block_size=0 blk_addr=0 data_flags=0x0 tag=0
> can_retune=0 doing_retune=0 retune_now=0 need_retune=0 hold_retune=1
> retune_period=0
>        in:imklog-2971  [000] ..s. 34861.450737: mmc_request_done:
> mmc0: end struct mmc_request[00000000fe878338]: cmd_opcode=16
> cmd_err=0 cmd_resp=0x20000900 0x0 0x0 0x0 cmd_retries=5 stop_opcode=0
> stop_err=0 stop_resp=0x0 0x0 0x0 0x0 stop_retries=0 sbc_opcode=0
> sbc_err=0 sbc_resp=0x0 0x0 0x0 0x0 sbc_retries=0 bytes_xfered=0
> data_err=0 tag=0 can_retune=0 doing_retune=0 retune_now=0
> need_retune=0 hold_retune=1 retune_period=0
>             bash-3958  [001] .... 34861.451064: mmc_request_start:
> mmc0: start struct mmc_request[00000000c2f30356]: cmd_opcode=25
> cmd_arg=0x3a0000 cmd_flags=0x35 cmd_retries=0 stop_opcode=12
> stop_arg=0x0 stop_flags=0x1d stop_retries=0 sbc_opcode=0 sbc_arg=0x0
> sbc_flags=0x0 sbc_retires=0 blocks=128 block_size=512 blk_addr=0
> data_flags=0x100 tag=0 can_retune=0 doing_retune=0 retune_now=0
> need_retune=0 hold_retune=1 retune_period=0
>           <idle>-0     [000] ..s1 34861.456533: mmc_request_done:
> mmc0: end struct mmc_request[00000000c2f30356]: cmd_opcode=25
> cmd_err=0 cmd_resp=0x900 0x0 0x0 0x0 cmd_retries=0 stop_opcode=12
> stop_err=0 stop_resp=0xc00 0x0 0x0 0x0 stop_retries=0 sbc_opcode=0
> sbc_err=0 sbc_resp=0x0 0x0 0x0 0x0 sbc_retries=0 bytes_xfered=65536
> data_err=0 tag=0 can_retune=0 doing_retune=0 retune_now=0
> need_retune=0 hold_retune=1 retune_period=0
>             bash-3958  [001] .... 34861.456562: mmc_request_start:
> mmc0: start struct mmc_request[00000000e93d6161]: cmd_opcode=13
> cmd_arg=0x10000 cmd_flags=0x15 cmd_retries=0 stop_opcode=0
> stop_arg=0x0 stop_flags=0x0 stop_retries=0 sbc_opcode=0 sbc_arg=0x0
> sbc_flags=0x0 sbc_retires=0 blocks=0 block_size=0 blk_addr=0
> data_flags=0x0 tag=0 can_retune=0 doing_retune=0 retune_now=0
> need_retune=0 hold_retune=1 retune_period=0
>    rs:main Q:Reg-2972  [000] ..s. 34861.456688: mmc_request_done:
> mmc0: end struct mmc_request[00000000e93d6161]: cmd_opcode=13
> cmd_err=0 cmd_resp=0x900 0x0 0x0 0x0 cmd_retries=0 stop_opcode=0
> stop_err=0 stop_resp=0x0 0x0 0x0 0x0 stop_retries=0 sbc_opcode=0
> sbc_err=0 sbc_resp=0x0 0x0 0x0 0x0 sbc_retries=0 bytes_xfered=0
> data_err=0 tag=0 can_retune=0 doing_retune=0 retune_now=0
> need_retune=0 hold_retune=1 retune_period=0
> 
> What we believe could be happening is an SEU that flips a bit in the
> data block after the host controller has sent the block on the DAT
> lines. Card should reject that after CRC mismatch. Does the card
> reject the command right when it sees a CRC mismatch or does it have
> to wait till all blocks and CMD12 is sent by the host?

Open writes with CMD25-CMD12 indeed send all blocks until the card
can signal CRC error.

> 
> Thank you.
> 
> 
> 
> On Wed, Apr 16, 2025 at 2:13 AM Christian Loehle
> <christian.loehle@arm.com> wrote:
>>
>> On 4/16/25 01:13, Prasad Koya wrote:
>>> Hi
>>>
>>> We use eMMC as a boot drive. At a random time, maybe a month or an
>>> year of uptime, we run into an issue where we see the eMMC driver
>>> prints this in the kernel logs and the drive no longer responds after
>>> that. We see this issue in the field on linux kernel 4.19.142 and
>>> 5.10.165. From the SDHCI register dump, it looks like CMD25 ran into a
>>> timeout first. After the first timeout, we see CMD12 in the second
>>> SDHCI register dump. Status returned by the card at that point in
>>> card_busy_detect() is 0xE00.
>>>
>>> I looked at the recent commits up to 6.15 and I do not see anything
>>> obvious that addresses issue like below.
>>>
>>> We are trying to reproduce the issue in our lab and understand the
>>> driver code. Is there a way I can send a block of data as part of
>>> CMD25 with invalid CRC?  Appreciate any pointers.
>>
>> CRC is appended by hardware, so it will always be correct.
>> What you can do though is change the blocksize of the transfer on the
>> host side (e.g. from 512 to 514 bytes) without changing it using CMD16.
>> The 2 bytes will be latched in as CRC by the card. Of course you won't
>> see the CRC ACK from the card in that case (as it clashes with the
>> hardware CRC signal from the host).
>> You can do all this using the ioctl interface in userspace btw.


  reply	other threads:[~2025-04-22 21:54 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-16  0:13 eMMC timeout reproduction. Can I send a block of data from the host to the card with invalid CRC? Prasad Koya
2025-04-16  9:13 ` Christian Loehle
2025-04-22 17:37   ` Prasad Koya
2025-04-22 21:53     ` Christian Loehle [this message]
2025-04-25  4:59       ` Prasad Koya
2025-04-25  8:38         ` Christian Loehle
2025-04-29 18:53           ` Prasad Koya
2025-04-29 18:58             ` Christian Loehle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2343cad4-89aa-48c6-86e7-0c8847ecfe60@arm.com \
    --to=christian.loehle@arm.com \
    --cc=baptiste@arista.com \
    --cc=linux-mmc@vger.kernel.org \
    --cc=prasad@arista.com \
    --cc=sushrut@arista.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox