X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmmc%2Fmmc.c;h=74eaaee66de0e59532ba5655fddac5aaeea5ba08;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=6201f3086a0226d1810aab52067d0a33e22206fe;hpb=43bc926fffd92024b46cafaf7350d669ba9ca884;p=linux-2.6.git diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6201f3086..74eaaee66 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -9,7 +9,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include #include #include #include @@ -129,7 +128,7 @@ static void mmc_wait_done(struct mmc_request *mrq) int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) { - DECLARE_COMPLETION(complete); + DECLARE_COMPLETION_ONSTACK(complete); mrq->done_data = &complete; mrq->done = mmc_wait_done; @@ -248,6 +247,55 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, EXPORT_SYMBOL(mmc_wait_for_app_cmd); +/** + * mmc_set_data_timeout - set the timeout for a data command + * @data: data phase for command + * @card: the MMC card associated with the data transfer + * @write: flag to differentiate reads from writes + */ +void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, + int write) +{ + unsigned int mult; + + /* + * SD cards use a 100 multiplier rather than 10 + */ + mult = mmc_card_sd(card) ? 100 : 10; + + /* + * Scale up the multiplier (and therefore the timeout) by + * the r2w factor for writes. + */ + if (write) + mult <<= card->csd.r2w_factor; + + data->timeout_ns = card->csd.tacc_ns * mult; + data->timeout_clks = card->csd.tacc_clks * mult; + + /* + * SD cards also have an upper limit on the timeout. + */ + if (mmc_card_sd(card)) { + unsigned int timeout_us, limit_us; + + timeout_us = data->timeout_ns / 1000; + timeout_us += data->timeout_clks * 1000 / + (card->host->ios.clock / 1000); + + if (write) + limit_us = 250000; + else + limit_us = 100000; + + if (timeout_us > limit_us) { + data->timeout_ns = limit_us * 1000; + data->timeout_clks = 0; + } + } +} +EXPORT_SYMBOL(mmc_set_data_timeout); + static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); /** @@ -909,11 +957,9 @@ static void mmc_read_scrs(struct mmc_host *host) { int err; struct mmc_card *card; - struct mmc_request mrq; struct mmc_command cmd; struct mmc_data data; - struct scatterlist sg; list_for_each_entry(card, &host->cards, node) { @@ -948,8 +994,8 @@ static void mmc_read_scrs(struct mmc_host *host) memset(&data, 0, sizeof(struct mmc_data)); - data.timeout_ns = card->csd.tacc_ns * 10; - data.timeout_clks = card->csd.tacc_clks * 10; + mmc_set_data_timeout(&data, card, 0); + data.blksz_bits = 3; data.blksz = 1 << 3; data.blocks = 1;