mmc: core: Detect card removal on I/O error
To prevent I/O as soon as possible at card removal, a new detect work is re-scheduled without a delay to let a rescan remove the card device as soon as possible. Additionally, MMC_CAP2_DETECT_ON_ERR can now be used to handle "slowly" removed cards that a scheduled detect work did not detect as removed. To prevent further I/O requests for these lingering removed cards, check if card has been removed and then schedule a detect work to properly remove it. Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> Reviewed-by: Namjae Jeon <linkinjeon@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
		
							parent
							
								
									885c3e800c
								
							
						
					
					
						commit
						f0cc9cf993
					
				@ -2121,18 +2121,36 @@ int _mmc_detect_card_removed(struct mmc_host *host)
 | 
			
		||||
int mmc_detect_card_removed(struct mmc_host *host)
 | 
			
		||||
{
 | 
			
		||||
	struct mmc_card *card = host->card;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	WARN_ON(!host->claimed);
 | 
			
		||||
 | 
			
		||||
	if (!card)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	ret = mmc_card_removed(card);
 | 
			
		||||
	/*
 | 
			
		||||
	 * The card will be considered unchanged unless we have been asked to
 | 
			
		||||
	 * detect a change or host requires polling to provide card detection.
 | 
			
		||||
	 */
 | 
			
		||||
	if (card && !host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL))
 | 
			
		||||
		return mmc_card_removed(card);
 | 
			
		||||
	if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) &&
 | 
			
		||||
	    !(host->caps2 & MMC_CAP2_DETECT_ON_ERR))
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	host->detect_change = 0;
 | 
			
		||||
	if (!ret) {
 | 
			
		||||
		ret = _mmc_detect_card_removed(host);
 | 
			
		||||
		if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) {
 | 
			
		||||
			/*
 | 
			
		||||
			 * Schedule a detect work as soon as possible to let a
 | 
			
		||||
			 * rescan handle the card removal.
 | 
			
		||||
			 */
 | 
			
		||||
			cancel_delayed_work(&host->detect);
 | 
			
		||||
			mmc_detect_change(host, 0);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return _mmc_detect_card_removed(host);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(mmc_detect_card_removed);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -258,6 +258,7 @@ struct mmc_host {
 | 
			
		||||
#define MMC_CAP2_HS200		(MMC_CAP2_HS200_1_8V_SDR | \
 | 
			
		||||
				 MMC_CAP2_HS200_1_2V_SDR)
 | 
			
		||||
#define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 | 
			
		||||
#define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 | 
			
		||||
 | 
			
		||||
	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 | 
			
		||||
	unsigned int        power_notify_type;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user