* [PATCH 1/1] CMD12 error recovery support for SD cards [not found] <bd31ea570909160334u1b17a068hd8be89c7035232f9@mail.gmail.com> @ 2009-09-16 10:39 ` Mahadev Cholachagudda 2009-09-23 8:50 ` Mahadev Cholachagudda 2009-09-23 10:27 ` Matt Fleming 0 siblings, 2 replies; 6+ messages in thread From: Mahadev Cholachagudda @ 2009-09-16 10:39 UTC (permalink / raw) To: linux-mmc Dear All, I've a kernel code base of 2.6.28.9, where in I find that CMD12 error recovery is not been implemented. It is a wise idea to implement CMD12 error recovery, that involves sending CMD13 to get the status of the card. If the card is in "trans" state, it means CMD12 error shall be treated as successfull. If card state is not in "trans", then we have to send CMD12 again to stop the data transfer and then checking of the card status through CMD13. This sequence is detailed in the "Simplified Host Controller specification" on SDCard website. I believe this is the case for any controller, though I may be wrong. With the modification done to the code which is attached as patch to the latest mmc git, it is working at our site. And we do see some errors with the SDIO controller (proprietary but meets Standard SD host controller specification) that we are using. Request you to comment on the patch. diff -urNd linux-orig/drivers/mmc/card/block.c linux-current/drivers/mmc/card/block.c --- linux-orig/drivers/mmc/card/block.c 2009-09-16 15:43:03.667274139 +0530 +++ linux-current/drivers/mmc/card/block.c 2009-09-16 15:36:24.722272962 +0530 @@ -335,6 +335,76 @@ * until later as we need to wait for the card to leave * programming mode even when things go wrong. */ + + /* cmd12 error recovery fix */ + if( (brq.stop.error) && (brq.data.blocks > 1) && !mmc_host_is_spi(card->host) && + mmc_card_sd(card) ) { + + struct mmc_request my_mrq; + struct mmc_command my_cmd; + + /* + * if there is an error for CMD12, get the state of the card by + * sending cmd13 and then check the state of the card. + * If the card state is "tran", consider the cmd12 is successfull + * If not, then send again CMD12 to stop the data transfer. This time, + * any failure to get response, will result in to the card being + * non-recoverable. + */ + + memset(&my_mrq, 0, sizeof(struct mmc_request)); + memset(&my_cmd, 0, sizeof(struct mmc_command)); + my_cmd.opcode = MMC_SEND_STATUS; + my_cmd.arg = card->rca << 16; + my_cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + my_mrq.cmd = &my_cmd; + mmc_wait_for_req(card->host, &my_mrq); + + if(!my_mrq.cmd->error) { + if(R1_CURRENT_STATE(my_cmd.resp[0]) == 4) { + /* card is in "trans" state, so treat the CMD12 as succesfull */ + brq.stop.error = 0; + } + else { + /* + * card is not still in trans state. Now send CMD12 again and repeat + * the process of checking the card status using CMD13 + */ + memset(&my_cmd, 0, sizeof(struct mmc_command)); + my_cmd.opcode = MMC_STOP_TRANSMISSION; + my_cmd.arg = 0; + my_cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + my_mrq.cmd = &my_cmd; + mmc_wait_for_req(card->host, &my_mrq); + + /* get the card status */ + memset(&my_cmd, 0, sizeof(struct mmc_command)); + my_cmd.opcode = MMC_SEND_STATUS; + my_cmd.arg = card->rca << 16; + my_cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + my_mrq.cmd = &my_cmd; + mmc_wait_for_req(card->host, &my_mrq); + + if(!my_mrq.cmd->error) { + if(R1_CURRENT_STATE(my_cmd.resp[0]) == 4) { + /* card is in "trans" state, so treat the CMD12 as succesfull */ + brq.stop.error = 0; + } + else { + /* + * card is not in "trans" state yet. Just post an error and + * error is not recoverable + */ + } + } + else { + /* error for cmd13!!, then something is wrong with the card */ + } + } + } + } + /* cmd12 error recovery fix */ + if (brq.cmd.error || brq.data.error || brq.stop.error) { if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { /* Redo read one sector at a time */ Regards, Mahadev Cholachagudda ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] CMD12 error recovery support for SD cards 2009-09-16 10:39 ` [PATCH 1/1] CMD12 error recovery support for SD cards Mahadev Cholachagudda @ 2009-09-23 8:50 ` Mahadev Cholachagudda 2009-09-23 10:27 ` Matt Fleming 1 sibling, 0 replies; 6+ messages in thread From: Mahadev Cholachagudda @ 2009-09-23 8:50 UTC (permalink / raw) To: linux-mmc; +Cc: Pierre Ossman, Pierre Ossman, madhu.sudhana Dear Sir, Any comments on this. Regards, Mahadev 2009/9/16 Mahadev Cholachagudda <mgudda@gmail.com>: > Dear All, > > I've a kernel code base of 2.6.28.9, where in I find that CMD12 error > recovery is not been implemented. It is a wise idea to implement CMD12 > error recovery, that involves sending CMD13 to get the status of the > card. If the card is in "trans" state, it means CMD12 error shall be > treated as successfull. If card state is not in "trans", then we have > to send CMD12 again to stop the data transfer and then checking of the > card status through CMD13. This sequence is detailed in the > "Simplified Host Controller specification" on SDCard website. I > believe this is the case for any controller, though I may be wrong. > > With the modification done to the code which is attached as patch to > the latest mmc git, it is working at our site. And we do see some > errors with the SDIO controller (proprietary but meets Standard SD > host controller specification) that we are using. > > Request you to comment on the patch. > > diff -urNd linux-orig/drivers/mmc/card/block.c > linux-current/drivers/mmc/card/block.c > --- linux-orig/drivers/mmc/card/block.c 2009-09-16 15:43:03.667274139 +0530 > +++ linux-current/drivers/mmc/card/block.c 2009-09-16 > 15:36:24.722272962 +0530 > @@ -335,6 +335,76 @@ > * until later as we need to wait for the card to leave > * programming mode even when things go wrong. > */ > + > + /* cmd12 error recovery fix */ > + if( (brq.stop.error) && (brq.data.blocks > 1) && > !mmc_host_is_spi(card->host) && > + mmc_card_sd(card) ) { > + > + struct mmc_request my_mrq; > + struct mmc_command my_cmd; > + > + /* > + * if there is an error for CMD12, get the state of the card by > + * sending cmd13 and then check the state of the card. > + * If the card state is "tran", consider the cmd12 is successfull > + * If not, then send again CMD12 to stop the data transfer. This time, > + * any failure to get response, will result in to the card being > + * non-recoverable. > + */ > + > + memset(&my_mrq, 0, sizeof(struct mmc_request)); > + memset(&my_cmd, 0, sizeof(struct mmc_command)); > + my_cmd.opcode = MMC_SEND_STATUS; > + my_cmd.arg = card->rca << 16; > + my_cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; > + my_mrq.cmd = &my_cmd; > + mmc_wait_for_req(card->host, &my_mrq); > + > + if(!my_mrq.cmd->error) { > + if(R1_CURRENT_STATE(my_cmd.resp[0]) == 4) { > + /* card is in "trans" state, so treat the CMD12 as succesfull */ > + brq.stop.error = 0; > + } > + else { > + /* > + * card is not still in trans state. Now send CMD12 again and repeat > + * the process of checking the card status using CMD13 > + */ > + memset(&my_cmd, 0, sizeof(struct mmc_command)); > + my_cmd.opcode = MMC_STOP_TRANSMISSION; > + my_cmd.arg = 0; > + my_cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; > + my_mrq.cmd = &my_cmd; > + mmc_wait_for_req(card->host, &my_mrq); > + > + /* get the card status */ > + memset(&my_cmd, 0, sizeof(struct mmc_command)); > + my_cmd.opcode = MMC_SEND_STATUS; > + my_cmd.arg = card->rca << 16; > + my_cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; > + my_mrq.cmd = &my_cmd; > + mmc_wait_for_req(card->host, &my_mrq); > + > + if(!my_mrq.cmd->error) { > + if(R1_CURRENT_STATE(my_cmd.resp[0]) == 4) { > + /* card is in "trans" state, so treat the CMD12 as succesfull */ > + brq.stop.error = 0; > + } > + else { > + /* > + * card is not in "trans" state yet. Just post an error and > + * error is not recoverable > + */ > + } > + } > + else { > + /* error for cmd13!!, then something is wrong with the card */ > + } > + } > + } > + } > + /* cmd12 error recovery fix */ > + > if (brq.cmd.error || brq.data.error || brq.stop.error) { > if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { > /* Redo read one sector at a time */ > > Regards, > Mahadev Cholachagudda > -- Cheers, Mahadev ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] CMD12 error recovery support for SD cards 2009-09-16 10:39 ` [PATCH 1/1] CMD12 error recovery support for SD cards Mahadev Cholachagudda 2009-09-23 8:50 ` Mahadev Cholachagudda @ 2009-09-23 10:27 ` Matt Fleming 2009-09-30 11:18 ` Mahadev Cholachagudda 1 sibling, 1 reply; 6+ messages in thread From: Matt Fleming @ 2009-09-23 10:27 UTC (permalink / raw) To: Mahadev Cholachagudda; +Cc: linux-mmc On Wed, Sep 16, 2009 at 04:09:11PM +0530, Mahadev Cholachagudda wrote: > Dear All, > > I've a kernel code base of 2.6.28.9, where in I find that CMD12 error > recovery is not been implemented. It is a wise idea to implement CMD12 > error recovery, that involves sending CMD13 to get the status of the > card. If the card is in "trans" state, it means CMD12 error shall be > treated as successfull. If card state is not in "trans", then we have > to send CMD12 again to stop the data transfer and then checking of the > card status through CMD13. This sequence is detailed in the > "Simplified Host Controller specification" on SDCard website. I > believe this is the case for any controller, though I may be wrong. > > With the modification done to the code which is attached as patch to > the latest mmc git, it is working at our site. And we do see some > errors with the SDIO controller (proprietary but meets Standard SD > host controller specification) that we are using. > > Request you to comment on the patch. > In principal this patch seems OK. However, I recommend reading Documentation/CodingStyle and sending this patch again once you've fixed up the coding style and whitespace errors. Is there a specific reason that you have used mmc_wait_for_req() instead of mmc_wait_for_cmd() and reusing the "cmd" local variable? The empty "else" clauses can also probably be deleted. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] CMD12 error recovery support for SD cards 2009-09-23 10:27 ` Matt Fleming @ 2009-09-30 11:18 ` Mahadev Cholachagudda 2009-10-02 10:20 ` Matt Fleming 0 siblings, 1 reply; 6+ messages in thread From: Mahadev Cholachagudda @ 2009-09-30 11:18 UTC (permalink / raw) To: Matt Fleming, linux-mmc; +Cc: Pierre Ossman, Pierre Ossman Dear Matt, Thank you very much. Attached is the re-written patch with comments included. This has been tested in our platform, where it recovers from CMD12 cmd_conflict errors. Regards, Mahadev diff -urNd linux-orig/drivers/mmc/card/block.c linux-current/drivers/mmc/card/block.c --- linux-orig/drivers/mmc/card/block.c 2009-09-16 15:43:03.667274139 +0530 +++ linux-current/drivers/mmc/card/block.c 2009-09-30 16:41:50.605273759 +0530 @@ -330,6 +330,67 @@ mmc_queue_bounce_post(mq); + /* cmd12 error recovery fix */ + if( (brq.stop.error) && (brq.data.blocks > 1) && + !mmc_host_is_spi(card->host) && mmc_card_sd(card) ) { + + /* + * if there is an error for CMD12, get the state of the card by + * sending cmd13 and then check the state of the card. + * If the card state is "tran", consider the cmd12 is successfull + * If not, then send again CMD12 to stop the data transfer. This + * time, any failure to get response, will result in to the card + * being non-recoverable. + */ + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_SEND_STATUS; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + mmc_wait_for_cmd(card->host, &cmd, 0); + + if(!cmd.error && R1_CURRENT_STATE(cmd.resp[0]) == 4) { + /* card is in "trans" state, so treat the CMD12 as succesfull */ + brq.stop.error = 0; + } else { + /* + * card is not still in trans state. Now send CMD12 again and + * repeat the process of checking the card status using CMD13 + */ + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_STOP_TRANSMISSION; + cmd.arg = 0; + cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + mmc_wait_for_cmd(card->host, &cmd, 0); + + /* get the card status */ + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_SEND_STATUS; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + mmc_wait_for_cmd(card->host, &cmd, 0); + + if(!cmd.error) { + if(R1_CURRENT_STATE(cmd.resp[0]) == 4) { + /* card is in "trans" state, so treat the CMD12 as succesfull */ + brq.stop.error = 0; + } else { + printk(KERN_ERR "%s: CMD12 error not recoverable\n", + req->rq_disk->disk_name ); + /* + * card is not in "trans" state yet. Just post an error and + * error is not recoverable + */ + } + } else { + printk(KERN_ERR "%s: CMD13 returns an error!!\n", + req->rq_disk->disk_name ); + /* error for cmd13!!, then something is wrong with the card */ + } + } + } + /* cmd12 error recovery fix */ + + /* * Check for errors here, but don't jump to cmd_err * until later as we need to wait for the card to leave 2009/9/23 Matt Fleming <matt@console-pimps.org>: > On Wed, Sep 16, 2009 at 04:09:11PM +0530, Mahadev Cholachagudda wrote: >> Dear All, >> >> I've a kernel code base of 2.6.28.9, where in I find that CMD12 error >> recovery is not been implemented. It is a wise idea to implement CMD12 >> error recovery, that involves sending CMD13 to get the status of the >> card. If the card is in "trans" state, it means CMD12 error shall be >> treated as successfull. If card state is not in "trans", then we have >> to send CMD12 again to stop the data transfer and then checking of the >> card status through CMD13. This sequence is detailed in the >> "Simplified Host Controller specification" on SDCard website. I >> believe this is the case for any controller, though I may be wrong. >> >> With the modification done to the code which is attached as patch to >> the latest mmc git, it is working at our site. And we do see some >> errors with the SDIO controller (proprietary but meets Standard SD >> host controller specification) that we are using. >> >> Request you to comment on the patch. >> > > In principal this patch seems OK. However, I recommend reading > Documentation/CodingStyle and sending this patch again once you've fixed > up the coding style and whitespace errors. > > Is there a specific reason that you have used mmc_wait_for_req() instead > of mmc_wait_for_cmd() and reusing the "cmd" local variable? The empty > "else" clauses can also probably be deleted. > -- Cheers, Mahadev ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] CMD12 error recovery support for SD cards 2009-09-30 11:18 ` Mahadev Cholachagudda @ 2009-10-02 10:20 ` Matt Fleming 2009-10-05 4:23 ` Mahadev Cholachagudda 0 siblings, 1 reply; 6+ messages in thread From: Matt Fleming @ 2009-10-02 10:20 UTC (permalink / raw) To: Mahadev Cholachagudda; +Cc: linux-mmc, Pierre Ossman [Pierre, I dropped your old email address from CC, hope that's OK] On Wed, Sep 30, 2009 at 04:48:26PM +0530, Mahadev Cholachagudda wrote: > Dear Matt, > Thank you very much. Attached is the re-written patch with comments > included. This has been tested in our platform, where it recovers from > CMD12 cmd_conflict errors. > I may be looking at an out of date SD Host Controller Spec, but can you point me at the place where it says that it's ok to retry the CMD12 if it failed? I can find the part explaining that you can issue CMD13 to see if CMD12 really failed or not, but not the place where it says you can reissue CMD12. In your testcase, do you always end up issuing the second CMD12? > > diff -urNd linux-orig/drivers/mmc/card/block.c > linux-current/drivers/mmc/card/block.c > --- linux-orig/drivers/mmc/card/block.c 2009-09-16 15:43:03.667274139 +0530 > +++ linux-current/drivers/mmc/card/block.c 2009-09-30 16:41:50.605273759 +0530 > @@ -330,6 +330,67 @@ > > mmc_queue_bounce_post(mq); > > + /* cmd12 error recovery fix */ > + if( (brq.stop.error) && (brq.data.blocks > 1) && > + !mmc_host_is_spi(card->host) && mmc_card_sd(card) ) { Are you sure that this recovery procedure is not valid over SPI when doing a multiblock read? > + > + /* > + * if there is an error for CMD12, get the state of the card by > + * sending cmd13 and then check the state of the card. > + * If the card state is "tran", consider the cmd12 is successfull "successfull" should be "successful" > + * If not, then send again CMD12 to stop the data transfer. This > + * time, any failure to get response, will result in to the card > + * being non-recoverable. > + */ > + memset(&cmd, 0, sizeof(struct mmc_command)); > + cmd.opcode = MMC_SEND_STATUS; > + cmd.arg = card->rca << 16; > + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; > + mmc_wait_for_cmd(card->host, &cmd, 0); > + > + if(!cmd.error && R1_CURRENT_STATE(cmd.resp[0]) == 4) { > + /* card is in "trans" state, so treat the CMD12 as succesfull */ > + brq.stop.error = 0; > + } else { > + /* > + * card is not still in trans state. Now send CMD12 again and > + * repeat the process of checking the card status using CMD13 > + */ > + memset(&cmd, 0, sizeof(struct mmc_command)); > + cmd.opcode = MMC_STOP_TRANSMISSION; > + cmd.arg = 0; > + cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; > + mmc_wait_for_cmd(card->host, &cmd, 0); > + > + /* get the card status */ > + memset(&cmd, 0, sizeof(struct mmc_command)); > + cmd.opcode = MMC_SEND_STATUS; > + cmd.arg = card->rca << 16; > + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; > + mmc_wait_for_cmd(card->host, &cmd, 0); > + > + if(!cmd.error) { > + if(R1_CURRENT_STATE(cmd.resp[0]) == 4) { > + /* card is in "trans" state, so treat the CMD12 as succesfull */ > + brq.stop.error = 0; > + } else { > + printk(KERN_ERR "%s: CMD12 error not recoverable\n", > + req->rq_disk->disk_name ); > + /* > + * card is not in "trans" state yet. Just post an error and > + * error is not recoverable > + */ > + } > + } else { > + printk(KERN_ERR "%s: CMD13 returns an error!!\n", > + req->rq_disk->disk_name ); > + /* error for cmd13!!, then something is wrong with the card */ I'm not entirely sure any of these errors are needed. The code below this in drivers/mmc/card/block.c will print an error message if brq.stop.error is non-zero (and we will have left it non-zero if we haven't recovered). ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] CMD12 error recovery support for SD cards 2009-10-02 10:20 ` Matt Fleming @ 2009-10-05 4:23 ` Mahadev Cholachagudda 0 siblings, 0 replies; 6+ messages in thread From: Mahadev Cholachagudda @ 2009-10-05 4:23 UTC (permalink / raw) To: Matt Fleming; +Cc: linux-mmc, Pierre Ossman 2009/10/2 Matt Fleming <matt@console-pimps.org>: > > I may be looking at an out of date SD Host Controller Spec, but can you > point me at the place where it says that it's ok to retry the CMD12 if > it failed? I can find the part explaining that you can issue CMD13 to > see if CMD12 really failed or not, but not the place where it says you > can reissue CMD12. > > In your testcase, do you always end up issuing the second CMD12? > In SD HostController Simplified Spec, page 106, tells about CMD12 failure and CMD13 to check the status. Page 110, section 3.10.2, tells about AutoCMD12 error recovery, but we can safely include this for checking with normal CMD12 error recovery. Yep, In our target board, some-times, we end up issuing the second CMD12. > > Are you sure that this recovery procedure is not valid over SPI when > doing a multiblock read? > I'm not able to get the details of recovery procedure for SPI. Moreover the host controller spec 2.0 does not support SPI mode. > "successfull" should be "successful" Shall be updated. > > I'm not entirely sure any of these errors are needed. The code below > this in drivers/mmc/card/block.c will print an error message if > brq.stop.error is non-zero (and we will have left it non-zero if we > haven't recovered). > OK. I shall update this too. Regards, Mahadev ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-10-05 4:24 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <bd31ea570909160334u1b17a068hd8be89c7035232f9@mail.gmail.com>
2009-09-16 10:39 ` [PATCH 1/1] CMD12 error recovery support for SD cards Mahadev Cholachagudda
2009-09-23 8:50 ` Mahadev Cholachagudda
2009-09-23 10:27 ` Matt Fleming
2009-09-30 11:18 ` Mahadev Cholachagudda
2009-10-02 10:20 ` Matt Fleming
2009-10-05 4:23 ` Mahadev Cholachagudda
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox