diff mbox

[v2,4/4] mmc: host: tmio: fill in response from auto cmd12

Message ID 20170213180342.26172-5-wsa+renesas@sang-engineering.com (mailing list archive)
State Superseded
Delegated to: Geert Uytterhoeven
Headers show

Commit Message

Wolfram Sang Feb. 13, 2017, 6:03 p.m. UTC
After we received the dataend interrupt, R1 response register carries
the value from the automatically generated stop command. Report that
info back to the MMC block layer, so we will be notified in case of e.g.
ECC errors which happened during the last transfer.

Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/tmio_mmc_pio.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Yoshihiro Shimoda Feb. 14, 2017, 10:06 a.m. UTC | #1
Hi,

> From: Wolfram Sang [mailto:wsa+renesas@sang-engineering.com]
> Sent: Tuesday, February 14, 2017 3:04 AM
> 
> After we received the dataend interrupt, R1 response register carries
> the value from the automatically generated stop command. Report that
> info back to the MMC block layer, so we will be notified in case of e.g.
> ECC errors which happened during the last transfer.
> 
> Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

I tested this patch with a SD tester (SGDK320).
As the commit log, this patch could pass the R1 response. So,

Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>


However, I think the MMC block layer should check the brq->stop.resp[0]
because brq->stop.error should be zero in this case and mmc_blk_cmd_recovery()
is not called in mmc_blk_err_check().

Best regards,
Yoshihiro Shimoda

> ---
>  drivers/mmc/host/tmio_mmc_pio.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
> index b47dd9195fe3fe..a08db28b0100d6 100644
> --- a/drivers/mmc/host/tmio_mmc_pio.c
> +++ b/drivers/mmc/host/tmio_mmc_pio.c
> @@ -557,6 +557,9 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
>  			dev_err(&host->pdev->dev, "unsupported stop: CMD%u,0x%x. We did CMD12,0\n",
>  				stop->opcode, stop->arg);
> 
> +		/* fill in response from auto CMD12 */
> +		stop->resp[0] = sd_ctrl_read16_and_16_as_32(host, CTL_RESPONSE);
> +
>  		sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0);
>  	}
> 
> --
> 2.11.0
Wolfram Sang Feb. 14, 2017, 10:52 a.m. UTC | #2
Shimoda-san, Ulf,

On Tue, Feb 14, 2017 at 10:06:47AM +0000, Yoshihiro Shimoda wrote:
> Hi,
> 
> > From: Wolfram Sang [mailto:wsa+renesas@sang-engineering.com]
> > Sent: Tuesday, February 14, 2017 3:04 AM
> > 
> > After we received the dataend interrupt, R1 response register carries
> > the value from the automatically generated stop command. Report that
> > info back to the MMC block layer, so we will be notified in case of e.g.
> > ECC errors which happened during the last transfer.
> > 
> > Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
> > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> 
> I tested this patch with a SD tester (SGDK320).
> As the commit log, this patch could pass the R1 response. So,
> 
> Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Thank you very much for testing!

> However, I think the MMC block layer should check the brq->stop.resp[0]
> because brq->stop.error should be zero in this case and mmc_blk_cmd_recovery()
> is not called in mmc_blk_err_check().

I see. Ulf, do you think it makes sense to extend the condition when to
call mmc_blk_cmd_recovery() with checking if stop.resp[0] has one of the
R1_* bits set which are marked with 'ex' (and probably 'erx', too)? I
agree with Shimoda-san, that the core is a good place to do it, since it
is about parsing the R1 and not the status bits of the host hardware.

Regards,

   Wolfram
Ulf Hansson Feb. 15, 2017, 10:19 a.m. UTC | #3
On 14 February 2017 at 11:52, Wolfram Sang <wsa@the-dreams.de> wrote:
> Shimoda-san, Ulf,
>
> On Tue, Feb 14, 2017 at 10:06:47AM +0000, Yoshihiro Shimoda wrote:
>> Hi,
>>
>> > From: Wolfram Sang [mailto:wsa+renesas@sang-engineering.com]
>> > Sent: Tuesday, February 14, 2017 3:04 AM
>> >
>> > After we received the dataend interrupt, R1 response register carries
>> > the value from the automatically generated stop command. Report that
>> > info back to the MMC block layer, so we will be notified in case of e.g.
>> > ECC errors which happened during the last transfer.
>> >
>> > Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
>> > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
>>
>> I tested this patch with a SD tester (SGDK320).
>> As the commit log, this patch could pass the R1 response. So,
>>
>> Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>
> Thank you very much for testing!
>
>> However, I think the MMC block layer should check the brq->stop.resp[0]
>> because brq->stop.error should be zero in this case and mmc_blk_cmd_recovery()
>> is not called in mmc_blk_err_check().
>
> I see. Ulf, do you think it makes sense to extend the condition when to
> call mmc_blk_cmd_recovery() with checking if stop.resp[0] has one of the
> R1_* bits set which are marked with 'ex' (and probably 'erx', too)? I
> agree with Shimoda-san, that the core is a good place to do it, since it
> is about parsing the R1 and not the status bits of the host hardware.

The method we use to indicate a stop command error to the mmc core, is
to set ->stop.error in the host driver before completing the request.
Perhaps set it to -EIO or -EILSEQ.

In that way mmc_blk_err_check() sees the error and invokes the
mmc_blk_cmd_recovery() to deal with it (response parsing etc).

Does that work for you?

Kind regards
Uffe
Wolfram Sang Feb. 15, 2017, 3:02 p.m. UTC | #4
> > I see. Ulf, do you think it makes sense to extend the condition when to
> > call mmc_blk_cmd_recovery() with checking if stop.resp[0] has one of the
> > R1_* bits set which are marked with 'ex' (and probably 'erx', too)? I
> > agree with Shimoda-san, that the core is a good place to do it, since it
> > is about parsing the R1 and not the status bits of the host hardware.
> 
> The method we use to indicate a stop command error to the mmc core, is
> to set ->stop.error in the host driver before completing the request.
> Perhaps set it to -EIO or -EILSEQ.
> 
> In that way mmc_blk_err_check() sees the error and invokes the
> mmc_blk_cmd_recovery() to deal with it (response parsing etc).
> 
> Does that work for you?

It would work, yes. Since R1 response format is hardware independent, I
wondered if checking for ECC errors wouldn't be better suited in the
core. We roughly need something like this:

	if (stop.resp[0] & R1_CARD_ECC_FAILED)
		stop.error = -EIO;

We can copy this into every driver, of course. Yet, I wondered if we
couldn't have a helper function mapping the R1 error bits to an
apropriate error value and call that just before the check in
mmc_blk_err_check().

Do you get what I mean?

Thanks,

   Wolfram
Ulf Hansson Feb. 16, 2017, 7:57 a.m. UTC | #5
On 15 February 2017 at 16:02, Wolfram Sang <wsa@the-dreams.de> wrote:
>
>> > I see. Ulf, do you think it makes sense to extend the condition when to
>> > call mmc_blk_cmd_recovery() with checking if stop.resp[0] has one of the
>> > R1_* bits set which are marked with 'ex' (and probably 'erx', too)? I
>> > agree with Shimoda-san, that the core is a good place to do it, since it
>> > is about parsing the R1 and not the status bits of the host hardware.
>>
>> The method we use to indicate a stop command error to the mmc core, is
>> to set ->stop.error in the host driver before completing the request.
>> Perhaps set it to -EIO or -EILSEQ.
>>
>> In that way mmc_blk_err_check() sees the error and invokes the
>> mmc_blk_cmd_recovery() to deal with it (response parsing etc).
>>
>> Does that work for you?
>
> It would work, yes. Since R1 response format is hardware independent, I
> wondered if checking for ECC errors wouldn't be better suited in the
> core. We roughly need something like this:
>
>         if (stop.resp[0] & R1_CARD_ECC_FAILED)
>                 stop.error = -EIO;
>
> We can copy this into every driver, of course. Yet, I wondered if we
> couldn't have a helper function mapping the R1 error bits to an
> apropriate error value and call that just before the check in
> mmc_blk_err_check().
>
> Do you get what I mean?

I get it - and yes you have a point.

By looking at the code in mmc_blk_err_check() and
mmc_blk_cmd_recovery(), it deserves a clean-up. That said, I don't
want to treat R1_CARD_ECC_FAILED as a special case.

So if you decide to add this check in the core (which I am open to),
we should also add checks the other potential R1 errors, to be
consistent.

Kind regards
Uffe
Wolfram Sang Feb. 16, 2017, 8:37 a.m. UTC | #6
Hi Ulf,

On Thu, Feb 16, 2017 at 08:57:36AM +0100, Ulf Hansson wrote:
> On 15 February 2017 at 16:02, Wolfram Sang <wsa@the-dreams.de> wrote:
> >
> >> > I see. Ulf, do you think it makes sense to extend the condition when to
> >> > call mmc_blk_cmd_recovery() with checking if stop.resp[0] has one of the
> >> > R1_* bits set which are marked with 'ex' (and probably 'erx', too)? I
> >> > agree with Shimoda-san, that the core is a good place to do it, since it
> >> > is about parsing the R1 and not the status bits of the host hardware.
> >>
> >> The method we use to indicate a stop command error to the mmc core, is
> >> to set ->stop.error in the host driver before completing the request.
> >> Perhaps set it to -EIO or -EILSEQ.
> >>
> >> In that way mmc_blk_err_check() sees the error and invokes the
> >> mmc_blk_cmd_recovery() to deal with it (response parsing etc).
> >>
> >> Does that work for you?
> >
> > It would work, yes. Since R1 response format is hardware independent, I
> > wondered if checking for ECC errors wouldn't be better suited in the
> > core. We roughly need something like this:
> >
> >         if (stop.resp[0] & R1_CARD_ECC_FAILED)
> >                 stop.error = -EIO;
> >
> > We can copy this into every driver, of course. Yet, I wondered if we
> > couldn't have a helper function mapping the R1 error bits to an
> > apropriate error value and call that just before the check in
> > mmc_blk_err_check().
> >
> > Do you get what I mean?
> 
> I get it - and yes you have a point.

Cool.

> By looking at the code in mmc_blk_err_check() and
> mmc_blk_cmd_recovery(), it deserves a clean-up. That said, I don't

What do you mean with clean-up here? I would have just added the helper
function checking R1 error bits and setting stop.error accordingly.

> want to treat R1_CARD_ECC_FAILED as a special case.
> 
> So if you decide to add this check in the core (which I am open to),
> we should also add checks the other potential R1 errors, to be
> consistent.

I agree. That's what I meant with "checking if stop.resp[0] has one of
the R1_* bits set which are marked with 'ex' (and probably 'erx',
too)?". I think these are the candidates we care about.

Thanks,

   Wolfram
Ulf Hansson Feb. 16, 2017, 8:57 a.m. UTC | #7
On 16 February 2017 at 09:37, Wolfram Sang <wsa@the-dreams.de> wrote:
> Hi Ulf,
>
> On Thu, Feb 16, 2017 at 08:57:36AM +0100, Ulf Hansson wrote:
>> On 15 February 2017 at 16:02, Wolfram Sang <wsa@the-dreams.de> wrote:
>> >
>> >> > I see. Ulf, do you think it makes sense to extend the condition when to
>> >> > call mmc_blk_cmd_recovery() with checking if stop.resp[0] has one of the
>> >> > R1_* bits set which are marked with 'ex' (and probably 'erx', too)? I
>> >> > agree with Shimoda-san, that the core is a good place to do it, since it
>> >> > is about parsing the R1 and not the status bits of the host hardware.
>> >>
>> >> The method we use to indicate a stop command error to the mmc core, is
>> >> to set ->stop.error in the host driver before completing the request.
>> >> Perhaps set it to -EIO or -EILSEQ.
>> >>
>> >> In that way mmc_blk_err_check() sees the error and invokes the
>> >> mmc_blk_cmd_recovery() to deal with it (response parsing etc).
>> >>
>> >> Does that work for you?
>> >
>> > It would work, yes. Since R1 response format is hardware independent, I
>> > wondered if checking for ECC errors wouldn't be better suited in the
>> > core. We roughly need something like this:
>> >
>> >         if (stop.resp[0] & R1_CARD_ECC_FAILED)
>> >                 stop.error = -EIO;
>> >
>> > We can copy this into every driver, of course. Yet, I wondered if we
>> > couldn't have a helper function mapping the R1 error bits to an
>> > apropriate error value and call that just before the check in
>> > mmc_blk_err_check().
>> >
>> > Do you get what I mean?
>>
>> I get it - and yes you have a point.
>
> Cool.
>
>> By looking at the code in mmc_blk_err_check() and
>> mmc_blk_cmd_recovery(), it deserves a clean-up. That said, I don't
>
> What do you mean with clean-up here? I would have just added the helper

...perhaps some re-factoring as the functions do lots of stuff.

> function checking R1 error bits and setting stop.error accordingly.

That's ok, I don't require you to do the clean up, but it would be nice. :-)

>
>> want to treat R1_CARD_ECC_FAILED as a special case.
>>
>> So if you decide to add this check in the core (which I am open to),
>> we should also add checks the other potential R1 errors, to be
>> consistent.
>
> I agree. That's what I meant with "checking if stop.resp[0] has one of
> the R1_* bits set which are marked with 'ex' (and probably 'erx',
> too)?". I think these are the candidates we care about.
>
> Thanks,
>
>    Wolfram

Kind regards
Uffe
diff mbox

Patch

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index b47dd9195fe3fe..a08db28b0100d6 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -557,6 +557,9 @@  void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
 			dev_err(&host->pdev->dev, "unsupported stop: CMD%u,0x%x. We did CMD12,0\n",
 				stop->opcode, stop->arg);
 
+		/* fill in response from auto CMD12 */
+		stop->resp[0] = sd_ctrl_read16_and_16_as_32(host, CTL_RESPONSE);
+
 		sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0);
 	}