From 2342f3323c9a76367a1d7f9a35525ee3cb3911df Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sat, 30 Jun 2007 16:21:52 +0200 Subject: sdio: allow for mmc_claim_host to be aborted It is sometimes necessary to give up on trying to claim the host lock, especially if that happens in a thread that has to be stopped. While at it, fix the description for mmc_claim_host() which was wrong. Signed-off-by: Nicolas Pitre Signed-off-by: Pierre Ossman --- drivers/mmc/core/core.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b8f27e5ade9..d1e4b0849e3 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -273,15 +273,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) EXPORT_SYMBOL(mmc_set_data_timeout); /** - * mmc_claim_host - exclusively claim a host + * __mmc_claim_host - exclusively claim a host * @host: mmc host to claim + * @abort: whether or not the operation should be aborted * - * Claim a host for a set of operations. + * Claim a host for a set of operations. If @abort is non null and + * dereference a non-zero value then this will return prematurely with + * that non-zero value without acquiring the lock. Returns zero + * with the lock held otherwise. */ -void mmc_claim_host(struct mmc_host *host) +int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) { DECLARE_WAITQUEUE(wait, current); unsigned long flags; + int stop; might_sleep(); @@ -289,19 +294,24 @@ void mmc_claim_host(struct mmc_host *host) spin_lock_irqsave(&host->lock, flags); while (1) { set_current_state(TASK_UNINTERRUPTIBLE); - if (!host->claimed) + stop = abort ? atomic_read(abort) : 0; + if (stop || !host->claimed) break; spin_unlock_irqrestore(&host->lock, flags); schedule(); spin_lock_irqsave(&host->lock, flags); } set_current_state(TASK_RUNNING); - host->claimed = 1; + if (!stop) + host->claimed = 1; + else + wake_up(&host->wq); spin_unlock_irqrestore(&host->lock, flags); remove_wait_queue(&host->wq, &wait); + return stop; } -EXPORT_SYMBOL(mmc_claim_host); +EXPORT_SYMBOL(__mmc_claim_host); /** * mmc_release_host - release a host -- cgit v1.2.3