diff options
Diffstat (limited to 'drivers/mmc/core/core.c')
| -rw-r--r-- | drivers/mmc/core/core.c | 41 | 
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 01ced4c5a61..3ee5b8c3b5c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -3,7 +3,7 @@   *   *  Copyright (C) 2003-2004 Russell King, All Rights Reserved.   *  SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. - *  Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. + *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.   *  MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.   *   * This program is free software; you can redistribute it and/or modify @@ -295,6 +295,33 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)  EXPORT_SYMBOL(mmc_set_data_timeout);  /** + *	mmc_align_data_size - pads a transfer size to a more optimal value + *	@card: the MMC card associated with the data transfer + *	@sz: original transfer size + * + *	Pads the original data size with a number of extra bytes in + *	order to avoid controller bugs and/or performance hits + *	(e.g. some controllers revert to PIO for certain sizes). + * + *	Returns the improved size, which might be unmodified. + * + *	Note that this function is only relevant when issuing a + *	single scatter gather entry. + */ +unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) +{ +	/* +	 * FIXME: We don't have a system for the controller to tell +	 * the core about its problems yet, so for now we just 32-bit +	 * align the size. +	 */ +	sz = ((sz + 3) / 4) * 4; + +	return sz; +} +EXPORT_SYMBOL(mmc_align_data_size); + +/**   *	__mmc_claim_host - exclusively claim a host   *	@host: mmc host to claim   *	@abort: whether or not the operation should be aborted @@ -638,6 +665,9 @@ void mmc_rescan(struct work_struct *work)  		 */  		mmc_bus_put(host); +		if (host->ops->get_cd && host->ops->get_cd(host) == 0) +			goto out; +  		mmc_claim_host(host);  		mmc_power_up(host); @@ -652,7 +682,7 @@ void mmc_rescan(struct work_struct *work)  		if (!err) {  			if (mmc_attach_sdio(host, ocr))  				mmc_power_off(host); -			return; +			goto out;  		}  		/* @@ -662,7 +692,7 @@ void mmc_rescan(struct work_struct *work)  		if (!err) {  			if (mmc_attach_sd(host, ocr))  				mmc_power_off(host); -			return; +			goto out;  		}  		/* @@ -672,7 +702,7 @@ void mmc_rescan(struct work_struct *work)  		if (!err) {  			if (mmc_attach_mmc(host, ocr))  				mmc_power_off(host); -			return; +			goto out;  		}  		mmc_release_host(host); @@ -683,6 +713,9 @@ void mmc_rescan(struct work_struct *work)  		mmc_bus_put(host);  	} +out: +	if (host->caps & MMC_CAP_NEEDS_POLL) +		mmc_schedule_delayed_work(&host->detect, HZ);  }  void mmc_start_host(struct mmc_host *host)  |