linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
@ 2012-03-01 15:44 Ulf Hansson
  2012-03-01 18:42 ` Linus Walleij
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Ulf Hansson @ 2012-03-01 15:44 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Per Forlin, Ulf Hansson, Johan Rudholm, Lee Jones

Make sure mmc_start_req cancel the prepared job, if the request
was prevented to be started due to the card has been removed.

This bug was introduced in commit:
mmc: allow upper layers to know immediately if card has been removed

Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
---
 drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
 1 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0b317f0..9e562ab 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
 	complete(&mrq->completion);
 }
 
-static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
+static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
 {
 	init_completion(&mrq->completion);
 	mrq->done = mmc_wait_done;
 	if (mmc_card_removed(host->card)) {
 		mrq->cmd->error = -ENOMEDIUM;
 		complete(&mrq->completion);
-		return;
+		return -ENOMEDIUM;
 	}
 	mmc_start_request(host, mrq);
+	return 0;
 }
 
 static void mmc_wait_for_req_done(struct mmc_host *host,
@@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
 				    struct mmc_async_req *areq, int *error)
 {
 	int err = 0;
+	int start_err = 0;
 	struct mmc_async_req *data = host->areq;
 
 	/* Prepare a new request */
@@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
 	if (host->areq) {
 		mmc_wait_for_req_done(host, host->areq->mrq);
 		err = host->areq->err_check(host->card, host->areq);
-		if (err) {
-			/* post process the completed failed request */
-			mmc_post_req(host, host->areq->mrq, 0);
-			if (areq)
-				/*
-				 * Cancel the new prepared request, because
-				 * it can't run until the failed
-				 * request has been properly handled.
-				 */
-				mmc_post_req(host, areq->mrq, -EINVAL);
-
-			host->areq = NULL;
-			goto out;
-		}
 	}
 
-	if (areq)
-		__mmc_start_req(host, areq->mrq);
+	if (!err && areq)
+		start_err = __mmc_start_req(host, areq->mrq);
 
 	if (host->areq)
 		mmc_post_req(host, host->areq->mrq, 0);
 
-	host->areq = areq;
- out:
+	if (err || start_err) {
+		if (areq)
+			/* The prepared request was not started, cancel it. */
+			mmc_post_req(host, areq->mrq, -EINVAL);
+		host->areq = NULL;
+	} else {
+		host->areq = areq;
+	}
+
 	if (error)
 		*error = err;
 	return data;
-- 
1.7.9


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-01 15:44 [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed Ulf Hansson
@ 2012-03-01 18:42 ` Linus Walleij
  2012-03-02  6:38 ` Per Förlin
  2012-03-02  8:28 ` Jaehoon Chung
  2 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2012-03-01 18:42 UTC (permalink / raw)
  To: Ulf Hansson; +Cc: linux-mmc, Chris Ball, Per Forlin, Johan Rudholm, Lee Jones

On Thu, Mar 1, 2012 at 4:44 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote:

> Make sure mmc_start_req cancel the prepared job, if the request
> was prevented to be started due to the card has been removed.
>
> This bug was introduced in commit:
> mmc: allow upper layers to know immediately if card has been removed
>
> Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-01 15:44 [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed Ulf Hansson
  2012-03-01 18:42 ` Linus Walleij
@ 2012-03-02  6:38 ` Per Förlin
  2012-03-02  8:28 ` Jaehoon Chung
  2 siblings, 0 replies; 9+ messages in thread
From: Per Förlin @ 2012-03-02  6:38 UTC (permalink / raw)
  To: Ulf HANSSON
  Cc: linux-mmc@vger.kernel.org, Chris Ball, Johan RUDHOLM, Lee Jones

On 03/01/2012 04:44 PM, Ulf HANSSON wrote:
> Make sure mmc_start_req cancel the prepared job, if the request
> was prevented to be started due to the card has been removed.
> 
> This bug was introduced in commit:
> mmc: allow upper layers to know immediately if card has been removed
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
> ---
>  drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
>  1 files changed, 15 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 0b317f0..9e562ab 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
>  	complete(&mrq->completion);
>  }
>  
> -static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
> +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>  {
>  	init_completion(&mrq->completion);
>  	mrq->done = mmc_wait_done;
>  	if (mmc_card_removed(host->card)) {
>  		mrq->cmd->error = -ENOMEDIUM;
>  		complete(&mrq->completion);
> -		return;
> +		return -ENOMEDIUM;
>  	}
>  	mmc_start_request(host, mrq);
> +	return 0;
>  }
>  
>  static void mmc_wait_for_req_done(struct mmc_host *host,
> @@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>  				    struct mmc_async_req *areq, int *error)
>  {
>  	int err = 0;
> +	int start_err = 0;
>  	struct mmc_async_req *data = host->areq;
>  
>  	/* Prepare a new request */
> @@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>  	if (host->areq) {
>  		mmc_wait_for_req_done(host, host->areq->mrq);
>  		err = host->areq->err_check(host->card, host->areq);
> -		if (err) {
> -			/* post process the completed failed request */
> -			mmc_post_req(host, host->areq->mrq, 0);
> -			if (areq)
> -				/*
> -				 * Cancel the new prepared request, because
> -				 * it can't run until the failed
> -				 * request has been properly handled.
> -				 */
> -				mmc_post_req(host, areq->mrq, -EINVAL);
> -
> -			host->areq = NULL;
> -			goto out;
> -		}
>  	}
>  
> -	if (areq)
> -		__mmc_start_req(host, areq->mrq);
> +	if (!err && areq)
> +		start_err = __mmc_start_req(host, areq->mrq);
>  
>  	if (host->areq)
>  		mmc_post_req(host, host->areq->mrq, 0);
>  
> -	host->areq = areq;
> - out:
> +	if (err || start_err) {
> +		if (areq)
> +			/* The prepared request was not started, cancel it. */
> +			mmc_post_req(host, areq->mrq, -EINVAL);
> +		host->areq = NULL;
> +	} else {
> +		host->areq = areq;
> +	}
> +
>  	if (error)
>  		*error = err;
>  	return data;
I have reviewed this patch offline. Patch looks good to me.

Reviewed-by: Per Forlin <per.forlin@stericsson.com>

Br
Per

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-01 15:44 [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed Ulf Hansson
  2012-03-01 18:42 ` Linus Walleij
  2012-03-02  6:38 ` Per Förlin
@ 2012-03-02  8:28 ` Jaehoon Chung
  2012-03-02  8:51   ` Ulf Hansson
  2 siblings, 1 reply; 9+ messages in thread
From: Jaehoon Chung @ 2012-03-02  8:28 UTC (permalink / raw)
  To: Ulf Hansson; +Cc: linux-mmc, Chris Ball, Per Forlin, Johan Rudholm, Lee Jones

Hi Ulf.

I tested with this patch.
But in my environment, this patch didn't work fine before.
1) When remove/insert, didn't entered the suspend.
2) When removed during something write,
[   50.755067] FAT-fs (mmcblk1p1): Directory bread(block 8254) failed
[   50.761235] FAT-fs (mmcblk1p1): Directory bread(block 8255) failed
then at next-time, didn't detect sd-card.

Did you know this?
If you want more information, i will debug, and share the result.

Best Regards,
Jaehoon Chung

On 03/02/2012 12:44 AM, Ulf Hansson wrote:

> Make sure mmc_start_req cancel the prepared job, if the request
> was prevented to be started due to the card has been removed.
> 
> This bug was introduced in commit:
> mmc: allow upper layers to know immediately if card has been removed
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
> ---
>  drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
>  1 files changed, 15 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 0b317f0..9e562ab 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
>  	complete(&mrq->completion);
>  }
>  
> -static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
> +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>  {
>  	init_completion(&mrq->completion);
>  	mrq->done = mmc_wait_done;
>  	if (mmc_card_removed(host->card)) {
>  		mrq->cmd->error = -ENOMEDIUM;
>  		complete(&mrq->completion);
> -		return;
> +		return -ENOMEDIUM;
>  	}
>  	mmc_start_request(host, mrq);
> +	return 0;
>  }
>  
>  static void mmc_wait_for_req_done(struct mmc_host *host,
> @@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>  				    struct mmc_async_req *areq, int *error)
>  {
>  	int err = 0;
> +	int start_err = 0;
>  	struct mmc_async_req *data = host->areq;
>  
>  	/* Prepare a new request */
> @@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>  	if (host->areq) {
>  		mmc_wait_for_req_done(host, host->areq->mrq);
>  		err = host->areq->err_check(host->card, host->areq);
> -		if (err) {
> -			/* post process the completed failed request */
> -			mmc_post_req(host, host->areq->mrq, 0);
> -			if (areq)
> -				/*
> -				 * Cancel the new prepared request, because
> -				 * it can't run until the failed
> -				 * request has been properly handled.
> -				 */
> -				mmc_post_req(host, areq->mrq, -EINVAL);
> -
> -			host->areq = NULL;
> -			goto out;
> -		}
>  	}
>  
> -	if (areq)
> -		__mmc_start_req(host, areq->mrq);
> +	if (!err && areq)
> +		start_err = __mmc_start_req(host, areq->mrq);
>  
>  	if (host->areq)
>  		mmc_post_req(host, host->areq->mrq, 0);
>  
> -	host->areq = areq;
> - out:
> +	if (err || start_err) {
> +		if (areq)
> +			/* The prepared request was not started, cancel it. */
> +			mmc_post_req(host, areq->mrq, -EINVAL);
> +		host->areq = NULL;
> +	} else {
> +		host->areq = areq;
> +	}
> +
>  	if (error)
>  		*error = err;
>  	return data;



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-02  8:28 ` Jaehoon Chung
@ 2012-03-02  8:51   ` Ulf Hansson
  2012-03-02 15:29     ` Per Förlin
  0 siblings, 1 reply; 9+ messages in thread
From: Ulf Hansson @ 2012-03-02  8:51 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: linux-mmc@vger.kernel.org, Chris Ball, Per FORLIN, Johan RUDHOLM,
	Lee Jones

Hi Jaehoon,

I did not know this. Which host driver are you using? I would very much 
appreciate of you could debug and share some result.

Thanks!

BR
Ulf Hansson

On 03/02/2012 09:28 AM, Jaehoon Chung wrote:
> Hi Ulf.
>
> I tested with this patch.
> But in my environment, this patch didn't work fine before.
> 1) When remove/insert, didn't entered the suspend.
> 2) When removed during something write,
> [   50.755067] FAT-fs (mmcblk1p1): Directory bread(block 8254) failed
> [   50.761235] FAT-fs (mmcblk1p1): Directory bread(block 8255) failed
> then at next-time, didn't detect sd-card.
>
> Did you know this?
> If you want more information, i will debug, and share the result.
>
> Best Regards,
> Jaehoon Chung
>
> On 03/02/2012 12:44 AM, Ulf Hansson wrote:
>
>> Make sure mmc_start_req cancel the prepared job, if the request
>> was prevented to be started due to the card has been removed.
>>
>> This bug was introduced in commit:
>> mmc: allow upper layers to know immediately if card has been removed
>>
>> Signed-off-by: Ulf Hansson<ulf.hansson@stericsson.com>
>> ---
>>   drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
>>   1 files changed, 15 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index 0b317f0..9e562ab 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
>>   	complete(&mrq->completion);
>>   }
>>
>> -static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>> +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>   {
>>   	init_completion(&mrq->completion);
>>   	mrq->done = mmc_wait_done;
>>   	if (mmc_card_removed(host->card)) {
>>   		mrq->cmd->error = -ENOMEDIUM;
>>   		complete(&mrq->completion);
>> -		return;
>> +		return -ENOMEDIUM;
>>   	}
>>   	mmc_start_request(host, mrq);
>> +	return 0;
>>   }
>>
>>   static void mmc_wait_for_req_done(struct mmc_host *host,
>> @@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>   				    struct mmc_async_req *areq, int *error)
>>   {
>>   	int err = 0;
>> +	int start_err = 0;
>>   	struct mmc_async_req *data = host->areq;
>>
>>   	/* Prepare a new request */
>> @@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>   	if (host->areq) {
>>   		mmc_wait_for_req_done(host, host->areq->mrq);
>>   		err = host->areq->err_check(host->card, host->areq);
>> -		if (err) {
>> -			/* post process the completed failed request */
>> -			mmc_post_req(host, host->areq->mrq, 0);
>> -			if (areq)
>> -				/*
>> -				 * Cancel the new prepared request, because
>> -				 * it can't run until the failed
>> -				 * request has been properly handled.
>> -				 */
>> -				mmc_post_req(host, areq->mrq, -EINVAL);
>> -
>> -			host->areq = NULL;
>> -			goto out;
>> -		}
>>   	}
>>
>> -	if (areq)
>> -		__mmc_start_req(host, areq->mrq);
>> +	if (!err&&  areq)
>> +		start_err = __mmc_start_req(host, areq->mrq);
>>
>>   	if (host->areq)
>>   		mmc_post_req(host, host->areq->mrq, 0);
>>
>> -	host->areq = areq;
>> - out:
>> +	if (err || start_err) {
>> +		if (areq)
>> +			/* The prepared request was not started, cancel it. */
>> +			mmc_post_req(host, areq->mrq, -EINVAL);
>> +		host->areq = NULL;
>> +	} else {
>> +		host->areq = areq;
>> +	}
>> +
>>   	if (error)
>>   		*error = err;
>>   	return data;
>
>
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-02  8:51   ` Ulf Hansson
@ 2012-03-02 15:29     ` Per Förlin
  2012-03-05  5:08       ` Jaehoon Chung
  0 siblings, 1 reply; 9+ messages in thread
From: Per Förlin @ 2012-03-02 15:29 UTC (permalink / raw)
  To: Ulf HANSSON
  Cc: Jaehoon Chung, linux-mmc@vger.kernel.org, Chris Ball,
	Johan RUDHOLM, Lee Jones

On 03/02/2012 09:51 AM, Ulf HANSSON wrote:
> Hi Jaehoon,
> 
> I did not know this. Which host driver are you using? I would very much 
> appreciate of you could debug and share some result.
> 
> Thanks!
> 
> BR
> Ulf Hansson
> 
> On 03/02/2012 09:28 AM, Jaehoon Chung wrote:
>> Hi Ulf.
>>
>> I tested with this patch.
>> But in my environment, this patch didn't work fine before.
>> 1) When remove/insert, didn't entered the suspend.
>> 2) When removed during something write,
>> [   50.755067] FAT-fs (mmcblk1p1): Directory bread(block 8254) failed
>> [   50.761235] FAT-fs (mmcblk1p1): Directory bread(block 8255) failed
>> then at next-time, didn't detect sd-card.
>>
>> Did you know this?
>> If you want more information, i will debug, and share the result.
>>
>> Best Regards,
>> Jaehoon Chung
>>
>> On 03/02/2012 12:44 AM, Ulf Hansson wrote:
>>
>>> Make sure mmc_start_req cancel the prepared job, if the request
>>> was prevented to be started due to the card has been removed.
>>>
>>> This bug was introduced in commit:
>>> mmc: allow upper layers to know immediately if card has been removed
>>>
>>> Signed-off-by: Ulf Hansson<ulf.hansson@stericsson.com>
>>> ---
>>>   drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
>>>   1 files changed, 15 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index 0b317f0..9e562ab 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
>>>   	complete(&mrq->completion);
>>>   }
>>>
>>> -static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>> +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>>   {
>>>   	init_completion(&mrq->completion);
>>>   	mrq->done = mmc_wait_done;
>>>   	if (mmc_card_removed(host->card)) {
>>>   		mrq->cmd->error = -ENOMEDIUM;
>>>   		complete(&mrq->completion);
>>> -		return;
>>> +		return -ENOMEDIUM;
>>>   	}
>>>   	mmc_start_request(host, mrq);
>>> +	return 0;
>>>   }
>>>
>>>   static void mmc_wait_for_req_done(struct mmc_host *host,
>>> @@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>   				    struct mmc_async_req *areq, int *error)
>>>   {
>>>   	int err = 0;
>>> +	int start_err = 0;
>>>   	struct mmc_async_req *data = host->areq;
>>>
>>>   	/* Prepare a new request */
>>> @@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>   	if (host->areq) {
>>>   		mmc_wait_for_req_done(host, host->areq->mrq);
>>>   		err = host->areq->err_check(host->card, host->areq);
>>> -		if (err) {
>>> -			/* post process the completed failed request */
>>> -			mmc_post_req(host, host->areq->mrq, 0);
>>> -			if (areq)
>>> -				/*
>>> -				 * Cancel the new prepared request, because
>>> -				 * it can't run until the failed
>>> -				 * request has been properly handled.
>>> -				 */
>>> -				mmc_post_req(host, areq->mrq, -EINVAL);
>>> -
>>> -			host->areq = NULL;
>>> -			goto out;
>>> -		}
>>>   	}
>>>
>>> -	if (areq)
>>> -		__mmc_start_req(host, areq->mrq);
>>> +	if (!err&&  areq)
>>> +		start_err = __mmc_start_req(host, areq->mrq);
>>>
>>>   	if (host->areq)
>>>   		mmc_post_req(host, host->areq->mrq, 0);
>>>
>>> -	host->areq = areq;
>>> - out:
>>> +	if (err || start_err) {
>>> +		if (areq)
>>> +			/* The prepared request was not started, cancel it. */
>>> +			mmc_post_req(host, areq->mrq, -EINVAL);
>>> +		host->areq = NULL;
There seems to be an issue when setting host->areq=NULL when __mmc_start_req fails. host->areq == NULL indicates there are no ongoing transfers.
host->areq is used in block.c to check if there are pending requests. 

This seem to work:
...
if (err || start_err) {
	if (areq)
		/* The prepared request was not started, cancel it. */
		mmc_post_req(host, areq->mrq, -EINVAL);
}

if (err)
	host->areq = NULL;
else
	host->areq = areq;
...

This issue will be addressed in version 2. How to resolve it is not decided yet. 

Feel free to comment,
Per

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-02 15:29     ` Per Förlin
@ 2012-03-05  5:08       ` Jaehoon Chung
  2012-03-05  6:08         ` Jaehoon Chung
  0 siblings, 1 reply; 9+ messages in thread
From: Jaehoon Chung @ 2012-03-05  5:08 UTC (permalink / raw)
  To: Per Förlin
  Cc: Ulf HANSSON, Jaehoon Chung, linux-mmc@vger.kernel.org, Chris Ball,
	Johan RUDHOLM, Lee Jones

On 03/03/2012 12:29 AM, Per Förlin wrote:

> On 03/02/2012 09:51 AM, Ulf HANSSON wrote:
>> Hi Jaehoon,
>>
>> I did not know this. Which host driver are you using? I would very much 
>> appreciate of you could debug and share some result.
>>
>> Thanks!
>>
>> BR
>> Ulf Hansson
>>
>> On 03/02/2012 09:28 AM, Jaehoon Chung wrote:
>>> Hi Ulf.
>>>
>>> I tested with this patch.
>>> But in my environment, this patch didn't work fine before.
>>> 1) When remove/insert, didn't entered the suspend.
>>> 2) When removed during something write,
>>> [   50.755067] FAT-fs (mmcblk1p1): Directory bread(block 8254) failed
>>> [   50.761235] FAT-fs (mmcblk1p1): Directory bread(block 8255) failed
>>> then at next-time, didn't detect sd-card.
>>>
>>> Did you know this?
>>> If you want more information, i will debug, and share the result.
>>>
>>> Best Regards,
>>> Jaehoon Chung
>>>
>>> On 03/02/2012 12:44 AM, Ulf Hansson wrote:
>>>
>>>> Make sure mmc_start_req cancel the prepared job, if the request
>>>> was prevented to be started due to the card has been removed.
>>>>
>>>> This bug was introduced in commit:
>>>> mmc: allow upper layers to know immediately if card has been removed
>>>>
>>>> Signed-off-by: Ulf Hansson<ulf.hansson@stericsson.com>
>>>> ---
>>>>   drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
>>>>   1 files changed, 15 insertions(+), 20 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>>> index 0b317f0..9e562ab 100644
>>>> --- a/drivers/mmc/core/core.c
>>>> +++ b/drivers/mmc/core/core.c
>>>> @@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
>>>>   	complete(&mrq->completion);
>>>>   }
>>>>
>>>> -static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>>> +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>>>   {
>>>>   	init_completion(&mrq->completion);
>>>>   	mrq->done = mmc_wait_done;
>>>>   	if (mmc_card_removed(host->card)) {
>>>>   		mrq->cmd->error = -ENOMEDIUM;
>>>>   		complete(&mrq->completion);
>>>> -		return;
>>>> +		return -ENOMEDIUM;
>>>>   	}
>>>>   	mmc_start_request(host, mrq);
>>>> +	return 0;
>>>>   }
>>>>
>>>>   static void mmc_wait_for_req_done(struct mmc_host *host,
>>>> @@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>>   				    struct mmc_async_req *areq, int *error)
>>>>   {
>>>>   	int err = 0;
>>>> +	int start_err = 0;
>>>>   	struct mmc_async_req *data = host->areq;
>>>>
>>>>   	/* Prepare a new request */
>>>> @@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>>   	if (host->areq) {
>>>>   		mmc_wait_for_req_done(host, host->areq->mrq);
>>>>   		err = host->areq->err_check(host->card, host->areq);
>>>> -		if (err) {
>>>> -			/* post process the completed failed request */
>>>> -			mmc_post_req(host, host->areq->mrq, 0);
>>>> -			if (areq)
>>>> -				/*
>>>> -				 * Cancel the new prepared request, because
>>>> -				 * it can't run until the failed
>>>> -				 * request has been properly handled.
>>>> -				 */
>>>> -				mmc_post_req(host, areq->mrq, -EINVAL);
>>>> -
>>>> -			host->areq = NULL;
>>>> -			goto out;
>>>> -		}
>>>>   	}
>>>>
>>>> -	if (areq)
>>>> -		__mmc_start_req(host, areq->mrq);
>>>> +	if (!err&&  areq)
>>>> +		start_err = __mmc_start_req(host, areq->mrq);
>>>>
>>>>   	if (host->areq)
>>>>   		mmc_post_req(host, host->areq->mrq, 0);
>>>>
>>>> -	host->areq = areq;
>>>> - out:
>>>> +	if (err || start_err) {
>>>> +		if (areq)
>>>> +			/* The prepared request was not started, cancel it. */
>>>> +			mmc_post_req(host, areq->mrq, -EINVAL);
>>>> +		host->areq = NULL;
> There seems to be an issue when setting host->areq=NULL when __mmc_start_req fails. host->areq == NULL indicates there are no ongoing transfers.
> host->areq is used in block.c to check if there are pending requests. 
> 
> This seem to work:
> ...
> if (err || start_err) {
> 	if (areq)
> 		/* The prepared request was not started, cancel it. */
> 		mmc_post_req(host, areq->mrq, -EINVAL);
> }
> 
> if (err)
> 	host->areq = NULL;
> else
> 	host->areq = areq;
> ...
> 
> This issue will be addressed in version 2. How to resolve it is not decided yet. 

It seems to work fine. But i didn't test yet.

Best Regards,
Jaehoon Chung

> 
> Feel free to comment,
> Per
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-05  5:08       ` Jaehoon Chung
@ 2012-03-05  6:08         ` Jaehoon Chung
  2012-03-05  8:35           ` Per Förlin
  0 siblings, 1 reply; 9+ messages in thread
From: Jaehoon Chung @ 2012-03-05  6:08 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Per Förlin, Ulf HANSSON, linux-mmc@vger.kernel.org,
	Chris Ball, Johan RUDHOLM, Lee Jones

On 03/05/2012 02:08 PM, Jaehoon Chung wrote:

> On 03/03/2012 12:29 AM, Per Förlin wrote:
> 
>> On 03/02/2012 09:51 AM, Ulf HANSSON wrote:
>>> Hi Jaehoon,
>>>
>>> I did not know this. Which host driver are you using? I would very much 
>>> appreciate of you could debug and share some result.
>>>
>>> Thanks!
>>>
>>> BR
>>> Ulf Hansson
>>>
>>> On 03/02/2012 09:28 AM, Jaehoon Chung wrote:
>>>> Hi Ulf.
>>>>
>>>> I tested with this patch.
>>>> But in my environment, this patch didn't work fine before.
>>>> 1) When remove/insert, didn't entered the suspend.
>>>> 2) When removed during something write,
>>>> [   50.755067] FAT-fs (mmcblk1p1): Directory bread(block 8254) failed
>>>> [   50.761235] FAT-fs (mmcblk1p1): Directory bread(block 8255) failed
>>>> then at next-time, didn't detect sd-card.
>>>>
>>>> Did you know this?
>>>> If you want more information, i will debug, and share the result.
>>>>
>>>> Best Regards,
>>>> Jaehoon Chung
>>>>
>>>> On 03/02/2012 12:44 AM, Ulf Hansson wrote:
>>>>
>>>>> Make sure mmc_start_req cancel the prepared job, if the request
>>>>> was prevented to be started due to the card has been removed.
>>>>>
>>>>> This bug was introduced in commit:
>>>>> mmc: allow upper layers to know immediately if card has been removed
>>>>>
>>>>> Signed-off-by: Ulf Hansson<ulf.hansson@stericsson.com>
>>>>> ---
>>>>>   drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
>>>>>   1 files changed, 15 insertions(+), 20 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>>>> index 0b317f0..9e562ab 100644
>>>>> --- a/drivers/mmc/core/core.c
>>>>> +++ b/drivers/mmc/core/core.c
>>>>> @@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
>>>>>   	complete(&mrq->completion);
>>>>>   }
>>>>>
>>>>> -static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>>>> +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>>>>   {
>>>>>   	init_completion(&mrq->completion);
>>>>>   	mrq->done = mmc_wait_done;
>>>>>   	if (mmc_card_removed(host->card)) {
>>>>>   		mrq->cmd->error = -ENOMEDIUM;
>>>>>   		complete(&mrq->completion);
>>>>> -		return;
>>>>> +		return -ENOMEDIUM;
>>>>>   	}
>>>>>   	mmc_start_request(host, mrq);
>>>>> +	return 0;
>>>>>   }
>>>>>
>>>>>   static void mmc_wait_for_req_done(struct mmc_host *host,
>>>>> @@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>>>   				    struct mmc_async_req *areq, int *error)
>>>>>   {
>>>>>   	int err = 0;
>>>>> +	int start_err = 0;
>>>>>   	struct mmc_async_req *data = host->areq;
>>>>>
>>>>>   	/* Prepare a new request */
>>>>> @@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>>>   	if (host->areq) {
>>>>>   		mmc_wait_for_req_done(host, host->areq->mrq);
>>>>>   		err = host->areq->err_check(host->card, host->areq);
>>>>> -		if (err) {
>>>>> -			/* post process the completed failed request */
>>>>> -			mmc_post_req(host, host->areq->mrq, 0);
>>>>> -			if (areq)
>>>>> -				/*
>>>>> -				 * Cancel the new prepared request, because
>>>>> -				 * it can't run until the failed
>>>>> -				 * request has been properly handled.
>>>>> -				 */
>>>>> -				mmc_post_req(host, areq->mrq, -EINVAL);
>>>>> -
>>>>> -			host->areq = NULL;
>>>>> -			goto out;
>>>>> -		}
>>>>>   	}
>>>>>
>>>>> -	if (areq)
>>>>> -		__mmc_start_req(host, areq->mrq);
>>>>> +	if (!err&&  areq)
>>>>> +		start_err = __mmc_start_req(host, areq->mrq);
>>>>>
>>>>>   	if (host->areq)
>>>>>   		mmc_post_req(host, host->areq->mrq, 0);
>>>>>
>>>>> -	host->areq = areq;
>>>>> - out:
>>>>> +	if (err || start_err) {
>>>>> +		if (areq)
>>>>> +			/* The prepared request was not started, cancel it. */
>>>>> +			mmc_post_req(host, areq->mrq, -EINVAL);
>>>>> +		host->areq = NULL;
>> There seems to be an issue when setting host->areq=NULL when __mmc_start_req fails. host->areq == NULL indicates there are no ongoing transfers.
>> host->areq is used in block.c to check if there are pending requests. 
>>
>> This seem to work:
>> ...
>> if (err || start_err) {
>> 	if (areq)
>> 		/* The prepared request was not started, cancel it. */
>> 		mmc_post_req(host, areq->mrq, -EINVAL);
>> }
>>
>> if (err)
>> 	host->areq = NULL;
>> else
>> 	host->areq = areq;
>> ...
>>
>> This issue will be addressed in version 2. How to resolve it is not decided yet. 

If start_err is set and err didn't set, maybe should be set "host->areq = areq".
Then in block.c, should be check the "status".

But start_err didn't be assigned anywhere, how about this?
...
if (error) {
	*error = err
	if (start_err)
		*error = start_err;
}
...

Best Regards,
Jaehoon Chung

> 
> It seems to work fine. But i didn't test yet.
> 
> Best Regards,
> Jaehoon Chung
> 
>>
>> Feel free to comment,
>> Per
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed
  2012-03-05  6:08         ` Jaehoon Chung
@ 2012-03-05  8:35           ` Per Förlin
  0 siblings, 0 replies; 9+ messages in thread
From: Per Förlin @ 2012-03-05  8:35 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Ulf HANSSON, linux-mmc@vger.kernel.org, Chris Ball, Johan RUDHOLM,
	Lee Jones

On 03/05/2012 07:08 AM, Jaehoon Chung wrote:
> On 03/05/2012 02:08 PM, Jaehoon Chung wrote:
> 
>> On 03/03/2012 12:29 AM, Per Förlin wrote:
>>
>>> On 03/02/2012 09:51 AM, Ulf HANSSON wrote:
>>>> Hi Jaehoon,
>>>>
>>>> I did not know this. Which host driver are you using? I would very much 
>>>> appreciate of you could debug and share some result.
>>>>
>>>> Thanks!
>>>>
>>>> BR
>>>> Ulf Hansson
>>>>
>>>> On 03/02/2012 09:28 AM, Jaehoon Chung wrote:
>>>>> Hi Ulf.
>>>>>
>>>>> I tested with this patch.
>>>>> But in my environment, this patch didn't work fine before.
>>>>> 1) When remove/insert, didn't entered the suspend.
>>>>> 2) When removed during something write,
>>>>> [   50.755067] FAT-fs (mmcblk1p1): Directory bread(block 8254) failed
>>>>> [   50.761235] FAT-fs (mmcblk1p1): Directory bread(block 8255) failed
>>>>> then at next-time, didn't detect sd-card.
>>>>>
>>>>> Did you know this?
>>>>> If you want more information, i will debug, and share the result.
>>>>>
>>>>> Best Regards,
>>>>> Jaehoon Chung
>>>>>
>>>>> On 03/02/2012 12:44 AM, Ulf Hansson wrote:
>>>>>
>>>>>> Make sure mmc_start_req cancel the prepared job, if the request
>>>>>> was prevented to be started due to the card has been removed.
>>>>>>
>>>>>> This bug was introduced in commit:
>>>>>> mmc: allow upper layers to know immediately if card has been removed
>>>>>>
>>>>>> Signed-off-by: Ulf Hansson<ulf.hansson@stericsson.com>
>>>>>> ---
>>>>>>   drivers/mmc/core/core.c |   35 +++++++++++++++--------------------
>>>>>>   1 files changed, 15 insertions(+), 20 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>>>>> index 0b317f0..9e562ab 100644
>>>>>> --- a/drivers/mmc/core/core.c
>>>>>> +++ b/drivers/mmc/core/core.c
>>>>>> @@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
>>>>>>   	complete(&mrq->completion);
>>>>>>   }
>>>>>>
>>>>>> -static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>>>>> +static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
>>>>>>   {
>>>>>>   	init_completion(&mrq->completion);
>>>>>>   	mrq->done = mmc_wait_done;
>>>>>>   	if (mmc_card_removed(host->card)) {
>>>>>>   		mrq->cmd->error = -ENOMEDIUM;
>>>>>>   		complete(&mrq->completion);
>>>>>> -		return;
>>>>>> +		return -ENOMEDIUM;
>>>>>>   	}
>>>>>>   	mmc_start_request(host, mrq);
>>>>>> +	return 0;
>>>>>>   }
>>>>>>
>>>>>>   static void mmc_wait_for_req_done(struct mmc_host *host,
>>>>>> @@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>>>>   				    struct mmc_async_req *areq, int *error)
>>>>>>   {
>>>>>>   	int err = 0;
>>>>>> +	int start_err = 0;
>>>>>>   	struct mmc_async_req *data = host->areq;
>>>>>>
>>>>>>   	/* Prepare a new request */
>>>>>> @@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
>>>>>>   	if (host->areq) {
>>>>>>   		mmc_wait_for_req_done(host, host->areq->mrq);
>>>>>>   		err = host->areq->err_check(host->card, host->areq);
>>>>>> -		if (err) {
>>>>>> -			/* post process the completed failed request */
>>>>>> -			mmc_post_req(host, host->areq->mrq, 0);
>>>>>> -			if (areq)
>>>>>> -				/*
>>>>>> -				 * Cancel the new prepared request, because
>>>>>> -				 * it can't run until the failed
>>>>>> -				 * request has been properly handled.
>>>>>> -				 */
>>>>>> -				mmc_post_req(host, areq->mrq, -EINVAL);
>>>>>> -
>>>>>> -			host->areq = NULL;
>>>>>> -			goto out;
>>>>>> -		}
>>>>>>   	}
>>>>>>
>>>>>> -	if (areq)
>>>>>> -		__mmc_start_req(host, areq->mrq);
>>>>>> +	if (!err&&  areq)
>>>>>> +		start_err = __mmc_start_req(host, areq->mrq);
>>>>>>
>>>>>>   	if (host->areq)
>>>>>>   		mmc_post_req(host, host->areq->mrq, 0);
>>>>>>
>>>>>> -	host->areq = areq;
>>>>>> - out:
>>>>>> +	if (err || start_err) {
>>>>>> +		if (areq)
>>>>>> +			/* The prepared request was not started, cancel it. */
>>>>>> +			mmc_post_req(host, areq->mrq, -EINVAL);
>>>>>> +		host->areq = NULL;
>>> There seems to be an issue when setting host->areq=NULL when __mmc_start_req fails. host->areq == NULL indicates there are no ongoing transfers.
>>> host->areq is used in block.c to check if there are pending requests. 
>>>
>>> This seem to work:
>>> ...
>>> if (err || start_err) {
>>> 	if (areq)
>>> 		/* The prepared request was not started, cancel it. */
>>> 		mmc_post_req(host, areq->mrq, -EINVAL);
>>> }
>>>
>>> if (err)
>>> 	host->areq = NULL;
>>> else
>>> 	host->areq = areq;
>>> ...
>>>
>>> This issue will be addressed in version 2. How to resolve it is not decided yet. 
> 
> If start_err is set and err didn't set, maybe should be set "host->areq = areq".
> Then in block.c, should be check the "status".
> 
> But start_err didn't be assigned anywhere, how about this?
> ...
> if (error) {
> 	*error = err
> 	if (start_err)
> 		*error = start_err;
> }
> ...
Thanks for your feedback.

The execution flow may look like this.
1. mmc_start_req(req1)
2. (request starts)
3. (card is removed)
4. mmc_start(req2)
5. req1 is returned with error code set, but req2 gets start_err.
In this case start_err should not be returned.

If NULL is returned from mmc_start_req the error code is discarded.
I think you may set *error=start_err and return data, but only if err is 0.

if (!err && start_err)
	*error = start_err;

Br
Per

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-03-05  8:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-01 15:44 [PATCH] mmc: core: Clean up after mmc_pre_req if card was removed Ulf Hansson
2012-03-01 18:42 ` Linus Walleij
2012-03-02  6:38 ` Per Förlin
2012-03-02  8:28 ` Jaehoon Chung
2012-03-02  8:51   ` Ulf Hansson
2012-03-02 15:29     ` Per Förlin
2012-03-05  5:08       ` Jaehoon Chung
2012-03-05  6:08         ` Jaehoon Chung
2012-03-05  8:35           ` Per Förlin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).