2014-08-26 13:01 GMT+08:00 Minda Chen <minda.c...@csr.com>: > > > -----Original Message----- > From: Ulf Hansson [mailto:ulf.hans...@linaro.org] > Sent: Friday, August 22, 2014 6:00 PM > To: Barry Song > Cc: Chris Ball; linux-mmc; linux-arm-ker...@lists.infradead.org; Minda Chen; > DL-SHA-WorkGroupLinux > Subject: Re: [PATCH] mmc: core: sd: check card write-protect lock while > resuming > > On 22 August 2014 08:55, Barry Song <barry.s...@csr.com> wrote: >>> -----Original Message----- >>> From: Ulf Hansson [mailto:ulf.hans...@linaro.org] >>> Sent: Monday, August 18, 2014 7:58 PM >>> To: Barry Song >>> Cc: Chris Ball; linux-mmc; linux-arm-ker...@lists.infradead.org; >>> DL-SHA- WorkGroupLinux; Minda Chen; Barry Song >>> Subject: Re: [PATCH] mmc: core: sd: check card write-protect lock >>> while resuming >>> >>> On 18 August 2014 12:00, Barry Song <barry.s...@csr.com> wrote: >>> > From: Minda Chen <minda.c...@csr.com> >>> > >>> > After suspending, unplug the sdcard, and set sd WP lock, insert it >>> > again, then resume the system. resume codes do not check the the >>> > sdcard write-proctect lock. now check it. >>> > >>> > Signed-off-by: Minda Chen <minda.c...@csr.com> >>> > Signed-off-by: Barry Song <baohua.s...@csr.com> >>> > --- >>> > drivers/mmc/core/sd.c | 7 +++++++ >>> > 1 file changed, 7 insertions(+) >>> > >>> > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index >>> > 0c44510..890557a 100644 >>> > --- a/drivers/mmc/core/sd.c >>> > +++ b/drivers/mmc/core/sd.c >>> > @@ -910,6 +910,7 @@ static int mmc_sd_init_card(struct mmc_host >>> *host, u32 ocr, >>> > int err; >>> > u32 cid[4]; >>> > u32 rocr = 0; >>> > + bool oldro, ro; >>> > >>> > BUG_ON(!host); >>> > WARN_ON(!host->claimed); >>> > @@ -922,6 +923,12 @@ static int mmc_sd_init_card(struct mmc_host >>> *host, u32 ocr, >>> > if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) >>> > return -ENOENT; >>> > >>> > + if (host->ops->get_ro) { >>> > + ro = host->ops->get_ro(host) ? true : false; >>> > + oldro = mmc_card_readonly(oldcard) ? true : false; >>> > + if (oldro ^ ro) >>> > + return -ENOENT; >>> > + } >>> >>> Seems like this code belongs better in mmc_sd_setup_card(). Could you >>> try moving it there. >> [Barry Song] >> Well. How about: >> >> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index >> 0c44510..643bc82d8 100644 >> --- a/drivers/mmc/core/sd.c >> +++ b/drivers/mmc/core/sd.c >> @@ -815,6 +815,7 @@ int mmc_sd_setup_card(struct mmc_host *host, struct >> mmc_card *card, >> bool reinit) >> { >> int err; >> + int oldro, ro = -1; >> >> if (!reinit) { >> /* >> @@ -861,23 +862,28 @@ int mmc_sd_setup_card(struct mmc_host *host, struct >> mmc_card *card, >> /* >> * Check if read-only switch is active. >> */ >> - if (!reinit) { >> - int ro = -1; >> >> - if (host->ops->get_ro) { >> - mmc_host_clk_hold(card->host); >> - ro = host->ops->get_ro(host); >> - mmc_host_clk_release(card->host); >> - } >> + if (host->ops->get_ro) { >> + mmc_host_clk_hold(card->host); >> + ro = host->ops->get_ro(host); >> + mmc_host_clk_release(card->host); >> + } >> >> - if (ro < 0) { >> - pr_warning("%s: host does not " >> - "support reading read-only " >> - "switch. assuming write-enable.\n", >> - mmc_hostname(host)); >> - } else if (ro > 0) { >> - mmc_card_set_readonly(card); >> - } >> + if (ro < 0) >> + pr_warning("%s: host does not " >> + "support reading read-only " >> + "switch. assuming write-enable.\n", >> + mmc_hostname(host)); > > I don't wont this pr_warning to spam the log each resume. > I suppose we could print it only for !reinit, right? > ok >> + >> + if (!reinit && (ro > 0)) >> + mmc_card_set_readonly(card); >> + else if (reinit && (ro >= 0)) { >> + /* check if the write-protection lock is changed */ >> + oldro = mmc_card_readonly(card) ? 1 : 0; >> + ro = (ro > 0) ? 1 : 0; >> + >> + if (oldro ^ ro) >> + return -ENOENT; > > This will have the effect of quickly returning an error to the mmc bus' > ->suspend callback. That path are not able remove the card device, which I > guess is what you would like to happen, right? > > I am not completely sure, but I believe the card will still be operational > after resuming. Moreover it will be using the initialization frequency and > 1-bit bus width and thus performing poorly. This is definitely not what we > want. > > How did you test this patch? Can you confirm my theory above? Sorry, I didn't check it carefully.
> > The card may only be removed from the mmc_rescan work, scheduled at > PM_POST_SUSPEND phase. What I think you should do here, is to also set the > card state into MMC_CARD_REMOVED, by invoking mmc_card_set_removed(). Thus > the SD's bus_ops->detect callback will remove the card during this phase. > > Kind regards > Uffe > > To report this email as spam click > https://www.mailcontrol.com/sr/MZbqvYs5QwJvpeaetUwhCQ== . > > > Member of the CSR plc group of companies. CSR plc registered in England and > Wales, registered number 4187346, registered office Churchill House, > Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom > More information can be found at www.csr.com. Keep up to date with CSR on our > technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, > YouTube, www.youtube.com/user/CSRplc, Facebook, > www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at > www.twitter.com/CSR_plc. > New for 2014, you can now access the wide range of products powered by aptX > at www.aptx.com. I have a suggestion. Compared with first patch ,mmc_sd_setup_card function select card command (cmd7) is executed. So In mmc_rescan function the card can not be removed. How about reset the card in this case? diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 0c44510..7db61dc 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -815,6 +815,7 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, bool reinit) { int err; + int oldro, ro = -1; if (!reinit) { /* @@ -858,18 +859,16 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, return err; } + if (host->ops->get_ro) { + mmc_host_clk_hold(card->host); + ro = host->ops->get_ro(host); + mmc_host_clk_release(card->host); + } + /* * Check if read-only switch is active. */ if (!reinit) { - int ro = -1; - - if (host->ops->get_ro) { - mmc_host_clk_hold(card->host); - ro = host->ops->get_ro(host); - mmc_host_clk_release(card->host); - } - if (ro < 0) { pr_warning("%s: host does not " "support reading read-only " @@ -878,6 +877,15 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, } else if (ro > 0) { mmc_card_set_readonly(card); } + } else if (reinit && (ro >= 0)) { + /* check if the write-protection lock is changed */ + oldro = mmc_card_readonly(card) ? 1 : 0; + ro = (ro > 0) ? 1 : 0; + + if (oldro ^ ro) { + mmc_go_idle(host); + return -ENOENT; + } } return 0; -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html