aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/dw_mmc.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 08c0592ed9bc..c4bddf6a5f1f 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -625,13 +625,13 @@ static void dw_mci_start_request(struct dw_mci *host,
625 host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); 625 host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
626} 626}
627 627
628/* must be called with host->lock held */
628static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, 629static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
629 struct mmc_request *mrq) 630 struct mmc_request *mrq)
630{ 631{
631 dev_vdbg(&slot->mmc->class_dev, "queue request: state=%d\n", 632 dev_vdbg(&slot->mmc->class_dev, "queue request: state=%d\n",
632 host->state); 633 host->state);
633 634
634 spin_lock_bh(&host->lock);
635 slot->mrq = mrq; 635 slot->mrq = mrq;
636 636
637 if (host->state == STATE_IDLE) { 637 if (host->state == STATE_IDLE) {
@@ -640,8 +640,6 @@ static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
640 } else { 640 } else {
641 list_add_tail(&slot->queue_node, &host->queue); 641 list_add_tail(&slot->queue_node, &host->queue);
642 } 642 }
643
644 spin_unlock_bh(&host->lock);
645} 643}
646 644
647static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) 645static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -651,14 +649,23 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
651 649
652 WARN_ON(slot->mrq); 650 WARN_ON(slot->mrq);
653 651
652 /*
653 * The check for card presence and queueing of the request must be
654 * atomic, otherwise the card could be removed in between and the
655 * request wouldn't fail until another card was inserted.
656 */
657 spin_lock_bh(&host->lock);
658
654 if (!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)) { 659 if (!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)) {
660 spin_unlock_bh(&host->lock);
655 mrq->cmd->error = -ENOMEDIUM; 661 mrq->cmd->error = -ENOMEDIUM;
656 mmc_request_done(mmc, mrq); 662 mmc_request_done(mmc, mrq);
657 return; 663 return;
658 } 664 }
659 665
660 /* We don't support multiple blocks of weird lengths. */
661 dw_mci_queue_request(host, slot, mrq); 666 dw_mci_queue_request(host, slot, mrq);
667
668 spin_unlock_bh(&host->lock);
662} 669}
663 670
664static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 671static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)