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 <npitre@mvista.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
This commit is contained in:
Родитель
55fe77a0a2
Коммит
2342f3323c
|
@ -273,15 +273,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
|
||||||
EXPORT_SYMBOL(mmc_set_data_timeout);
|
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
|
* @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);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int stop;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
|
@ -289,19 +294,24 @@ void mmc_claim_host(struct mmc_host *host)
|
||||||
spin_lock_irqsave(&host->lock, flags);
|
spin_lock_irqsave(&host->lock, flags);
|
||||||
while (1) {
|
while (1) {
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
if (!host->claimed)
|
stop = abort ? atomic_read(abort) : 0;
|
||||||
|
if (stop || !host->claimed)
|
||||||
break;
|
break;
|
||||||
spin_unlock_irqrestore(&host->lock, flags);
|
spin_unlock_irqrestore(&host->lock, flags);
|
||||||
schedule();
|
schedule();
|
||||||
spin_lock_irqsave(&host->lock, flags);
|
spin_lock_irqsave(&host->lock, flags);
|
||||||
}
|
}
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
host->claimed = 1;
|
if (!stop)
|
||||||
|
host->claimed = 1;
|
||||||
|
else
|
||||||
|
wake_up(&host->wq);
|
||||||
spin_unlock_irqrestore(&host->lock, flags);
|
spin_unlock_irqrestore(&host->lock, flags);
|
||||||
remove_wait_queue(&host->wq, &wait);
|
remove_wait_queue(&host->wq, &wait);
|
||||||
|
return stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(mmc_claim_host);
|
EXPORT_SYMBOL(__mmc_claim_host);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mmc_release_host - release a host
|
* mmc_release_host - release a host
|
||||||
|
|
|
@ -114,7 +114,18 @@ extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
|
||||||
|
|
||||||
extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *);
|
extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *);
|
||||||
|
|
||||||
extern void mmc_claim_host(struct mmc_host *host);
|
extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
|
||||||
extern void mmc_release_host(struct mmc_host *host);
|
extern void mmc_release_host(struct mmc_host *host);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmc_claim_host - exclusively claim a host
|
||||||
|
* @host: mmc host to claim
|
||||||
|
*
|
||||||
|
* Claim a host for a set of operations.
|
||||||
|
*/
|
||||||
|
static inline void mmc_claim_host(struct mmc_host *host)
|
||||||
|
{
|
||||||
|
__mmc_claim_host(host, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче