mmc: deprecate mmc bus topology
[firefly-linux-kernel-4.4.55.git] / drivers / mmc / mmc.c
index 9bda3fddad17380771903a39e30da3d371520ce8..3f50b8882c89cae9ff3c58e5547b3fe4711fe0b9 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2003-2004 Russell King, All Rights Reserved.
  *  SD support Copyright (C) 2004 Ian Molton, All Rights Reserved.
- *  SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved.
+ *  Copyright (C) 2005-2007 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
@@ -99,6 +99,10 @@ EXPORT_SYMBOL(mmc_request_done);
 void
 mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 {
+#ifdef CONFIG_MMC_DEBUG
+       unsigned int i, sz;
+#endif
+
        pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
                 mmc_hostname(host), mrq->cmd->opcode,
                 mrq->cmd->arg, mrq->cmd->flags);
@@ -109,6 +113,16 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
        mrq->cmd->mrq = mrq;
        if (mrq->data) {
                BUG_ON(mrq->data->blksz > host->max_blk_size);
+               BUG_ON(mrq->data->blocks > host->max_blk_count);
+               BUG_ON(mrq->data->blocks * mrq->data->blksz >
+                       host->max_req_size);
+
+#ifdef CONFIG_MMC_DEBUG
+               sz = 0;
+               for (i = 0;i < mrq->data->sg_len;i++)
+                       sz += mrq->data->sg[i].length;
+               BUG_ON(sz != mrq->data->blocks * mrq->data->blksz);
+#endif
 
                mrq->cmd->data = mrq->data;
                mrq->data->error = 0;
@@ -302,8 +316,6 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
 }
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
-static int mmc_select_card(struct mmc_host *host, struct mmc_card *card);
-
 /**
  *     __mmc_claim_host - exclusively claim a host
  *     @host: mmc host to claim
@@ -315,11 +327,10 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card);
  *
  *     Note: you should use mmc_card_claim_host or mmc_claim_host.
  */
-int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card)
+void mmc_claim_host(struct mmc_host *host)
 {
        DECLARE_WAITQUEUE(wait, current);
        unsigned long flags;
-       int err = 0;
 
        add_wait_queue(&host->wq, &wait);
        spin_lock_irqsave(&host->lock, flags);
@@ -335,17 +346,9 @@ int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card)
        host->claimed = 1;
        spin_unlock_irqrestore(&host->lock, flags);
        remove_wait_queue(&host->wq, &wait);
-
-       if (card != (void *)-1) {
-               err = mmc_select_card(host, card);
-               if (err != MMC_ERR_NONE)
-                       return err;
-       }
-
-       return err;
 }
 
-EXPORT_SYMBOL(__mmc_claim_host);
+EXPORT_SYMBOL(mmc_claim_host);
 
 /**
  *     mmc_release_host - release a host
@@ -373,31 +376,27 @@ static inline void mmc_set_ios(struct mmc_host *host)
 {
        struct mmc_ios *ios = &host->ios;
 
-       pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
+       pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u "
+               "width %u timing %u\n",
                 mmc_hostname(host), ios->clock, ios->bus_mode,
                 ios->power_mode, ios->chip_select, ios->vdd,
-                ios->bus_width);
+                ios->bus_width, ios->timing);
 
        host->ops->set_ios(host, ios);
 }
 
-static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
+static int mmc_select_card(struct mmc_card *card)
 {
        int err;
        struct mmc_command cmd;
 
-       BUG_ON(!host->claimed);
-
-       if (host->card_selected == card)
-               return MMC_ERR_NONE;
-
-       host->card_selected = card;
+       BUG_ON(!card->host->claimed);
 
        cmd.opcode = MMC_SELECT_CARD;
        cmd.arg = card->rca << 16;
        cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
-       err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
+       err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES);
        if (err != MMC_ERR_NONE)
                return err;
 
@@ -411,49 +410,24 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
         * wider version.
         */
        if (mmc_card_sd(card) &&
-               (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
-
-               /*
-               * Default bus width is 1 bit.
-               */
-               host->ios.bus_width = MMC_BUS_WIDTH_1;
-
-               if (host->caps & MMC_CAP_4_BIT_DATA) {
-                       struct mmc_command cmd;
-                       cmd.opcode = SD_APP_SET_BUS_WIDTH;
-                       cmd.arg = SD_BUS_WIDTH_4;
-                       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-
-                       err = mmc_wait_for_app_cmd(host, card->rca, &cmd,
-                               CMD_RETRIES);
-                       if (err != MMC_ERR_NONE)
-                               return err;
-
-                       host->ios.bus_width = MMC_BUS_WIDTH_4;
-               }
-       }
+               (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) &&
+               (card->host->caps & MMC_CAP_4_BIT_DATA)) {
 
-       mmc_set_ios(host);
-
-       return MMC_ERR_NONE;
-}
-
-/*
- * Ensure that no card is selected.
- */
-static void mmc_deselect_cards(struct mmc_host *host)
-{
-       struct mmc_command cmd;
-
-       if (host->card_selected) {
-               host->card_selected = NULL;
+               struct mmc_command cmd;
+               cmd.opcode = SD_APP_SET_BUS_WIDTH;
+               cmd.arg = SD_BUS_WIDTH_4;
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
-               cmd.opcode = MMC_SELECT_CARD;
-               cmd.arg = 0;
-               cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
+               err = mmc_wait_for_app_cmd(card->host, card->rca,
+                       &cmd, CMD_RETRIES);
+               if (err != MMC_ERR_NONE)
+                       return err;
 
-               mmc_wait_for_cmd(host, &cmd, 0);
+               card->host->ios.bus_width = MMC_BUS_WIDTH_4;
+               mmc_set_ios(card->host);
        }
+
+       return MMC_ERR_NONE;
 }
 
 
@@ -717,27 +691,12 @@ static void mmc_decode_scr(struct mmc_card *card)
 }
 
 /*
- * Locate a MMC card on this MMC host given a raw CID.
- */
-static struct mmc_card *mmc_find_card(struct mmc_host *host, u32 *raw_cid)
-{
-       struct mmc_card *card;
-
-       list_for_each_entry(card, &host->cards, node) {
-               if (memcmp(card->raw_cid, raw_cid, sizeof(card->raw_cid)) == 0)
-                       return card;
-       }
-       return NULL;
-}
-
-/*
- * Allocate a new MMC card, and assign a unique RCA.
+ * Allocate a new MMC card
  */
 static struct mmc_card *
-mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, unsigned int *frca)
+mmc_alloc_card(struct mmc_host *host, u32 *raw_cid)
 {
-       struct mmc_card *card, *c;
-       unsigned int rca = *frca;
+       struct mmc_card *card;
 
        card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
        if (!card)
@@ -746,17 +705,6 @@ mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, unsigned int *frca)
        mmc_init_card(card, host);
        memcpy(card->raw_cid, raw_cid, sizeof(card->raw_cid));
 
- again:
-       list_for_each_entry(c, &host->cards, node)
-               if (c->rca == rca) {
-                       rca++;
-                       goto again;
-               }
-
-       card->rca = rca;
-
-       *frca = rca;
-
        return card;
 }
 
@@ -806,6 +754,7 @@ static void mmc_power_up(struct mmc_host *host)
        host->ios.chip_select = MMC_CS_DONTCARE;
        host->ios.power_mode = MMC_POWER_UP;
        host->ios.bus_width = MMC_BUS_WIDTH_1;
+       host->ios.timing = MMC_TIMING_LEGACY;
        mmc_set_ios(host);
 
        mmc_delay(1);
@@ -825,6 +774,7 @@ static void mmc_power_off(struct mmc_host *host)
        host->ios.chip_select = MMC_CS_DONTCARE;
        host->ios.power_mode = MMC_POWER_OFF;
        host->ios.bus_width = MMC_BUS_WIDTH_1;
+       host->ios.timing = MMC_TIMING_LEGACY;
        mmc_set_ios(host);
 }
 
@@ -920,127 +870,128 @@ static int mmc_send_if_cond(struct mmc_host *host, u32 ocr, int *rsd2)
 }
 
 /*
- * Discover cards by requesting their CID.  If this command
- * times out, it is not an error; there are no further cards
- * to be discovered.  Add new cards to the list.
+ * Discover the card by requesting its CID.
  *
- * Create a mmc_card entry for each discovered card, assigning
+ * Create a mmc_card entry for the discovered card, assigning
  * it an RCA, and save the raw CID for decoding later.
  */
-static void mmc_discover_cards(struct mmc_host *host)
+static void mmc_discover_card(struct mmc_host *host)
 {
-       struct mmc_card *card;
-       unsigned int first_rca = 1, err;
+       unsigned int err;
 
-       while (1) {
-               struct mmc_command cmd;
+       struct mmc_command cmd;
+
+       BUG_ON(host->card);
+
+       cmd.opcode = MMC_ALL_SEND_CID;
+       cmd.arg = 0;
+       cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
+
+       err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
+       if (err == MMC_ERR_TIMEOUT) {
+               err = MMC_ERR_NONE;
+               return;
+       }
+       if (err != MMC_ERR_NONE) {
+               printk(KERN_ERR "%s: error requesting CID: %d\n",
+                       mmc_hostname(host), err);
+               return;
+       }
+
+       host->card = mmc_alloc_card(host, cmd.resp);
+       if (IS_ERR(host->card)) {
+               err = PTR_ERR(host->card);
+               host->card = NULL;
+               return;
+       }
 
-               cmd.opcode = MMC_ALL_SEND_CID;
+       if (host->mode == MMC_MODE_SD) {
+               host->card->type = MMC_TYPE_SD;
+
+               cmd.opcode = SD_SEND_RELATIVE_ADDR;
                cmd.arg = 0;
-               cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
+               cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
 
                err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-               if (err == MMC_ERR_TIMEOUT) {
-                       err = MMC_ERR_NONE;
-                       break;
-               }
-               if (err != MMC_ERR_NONE) {
-                       printk(KERN_ERR "%s: error requesting CID: %d\n",
-                               mmc_hostname(host), err);
-                       break;
-               }
-
-               card = mmc_find_card(host, cmd.resp);
-               if (!card) {
-                       card = mmc_alloc_card(host, cmd.resp, &first_rca);
-                       if (IS_ERR(card)) {
-                               err = PTR_ERR(card);
-                               break;
+               if (err != MMC_ERR_NONE)
+                       mmc_card_set_dead(host->card);
+               else {
+                       host->card->rca = cmd.resp[0] >> 16;
+
+                       if (!host->ops->get_ro) {
+                               printk(KERN_WARNING "%s: host does not "
+                                       "support reading read-only "
+                                       "switch. assuming write-enable.\n",
+                                       mmc_hostname(host));
+                       } else {
+                               if (host->ops->get_ro(host))
+                                       mmc_card_set_readonly(host->card);
                        }
-                       list_add(&card->node, &host->cards);
                }
+       } else {
+               host->card->type = MMC_TYPE_MMC;
+               host->card->rca = 1;
 
-               card->state &= ~MMC_STATE_DEAD;
-
-               if (host->mode == MMC_MODE_SD) {
-                       mmc_card_set_sd(card);
-
-                       cmd.opcode = SD_SEND_RELATIVE_ADDR;
-                       cmd.arg = 0;
-                       cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
-
-                       err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-                       if (err != MMC_ERR_NONE)
-                               mmc_card_set_dead(card);
-                       else {
-                               card->rca = cmd.resp[0] >> 16;
-
-                               if (!host->ops->get_ro) {
-                                       printk(KERN_WARNING "%s: host does not "
-                                               "support reading read-only "
-                                               "switch. assuming write-enable.\n",
-                                               mmc_hostname(host));
-                               } else {
-                                       if (host->ops->get_ro(host))
-                                               mmc_card_set_readonly(card);
-                               }
-                       }
-               } else {
-                       cmd.opcode = MMC_SET_RELATIVE_ADDR;
-                       cmd.arg = card->rca << 16;
-                       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+               cmd.opcode = MMC_SET_RELATIVE_ADDR;
+               cmd.arg = host->card->rca << 16;
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
-                       err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-                       if (err != MMC_ERR_NONE)
-                               mmc_card_set_dead(card);
-               }
+               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
+               if (err != MMC_ERR_NONE)
+                       mmc_card_set_dead(host->card);
        }
 }
 
-static void mmc_read_csds(struct mmc_host *host)
+static void mmc_read_csd(struct mmc_host *host)
 {
-       struct mmc_card *card;
-
-       list_for_each_entry(card, &host->cards, node) {
-               struct mmc_command cmd;
-               int err;
+       struct mmc_command cmd;
+       int err;
 
-               if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
-                       continue;
+       if (!host->card)
+               return;
+       if (mmc_card_dead(host->card))
+               return;
 
-               cmd.opcode = MMC_SEND_CSD;
-               cmd.arg = card->rca << 16;
-               cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
+       cmd.opcode = MMC_SEND_CSD;
+       cmd.arg = host->card->rca << 16;
+       cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
 
-               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-               if (err != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
+       err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
+       if (err != MMC_ERR_NONE) {
+               mmc_card_set_dead(host->card);
+               return;
+       }
 
-               memcpy(card->raw_csd, cmd.resp, sizeof(card->raw_csd));
+       memcpy(host->card->raw_csd, cmd.resp, sizeof(host->card->raw_csd));
 
-               mmc_decode_csd(card);
-               mmc_decode_cid(card);
-       }
+       mmc_decode_csd(host->card);
+       mmc_decode_cid(host->card);
 }
 
-static void mmc_process_ext_csds(struct mmc_host *host)
+static void mmc_process_ext_csd(struct mmc_host *host)
 {
        int err;
-       struct mmc_card *card;
 
        struct mmc_request mrq;
        struct mmc_command cmd;
        struct mmc_data data;
 
+       u8 *ext_csd;
        struct scatterlist sg;
 
+       if (!host->card)
+               return;
+       if (mmc_card_dead(host->card))
+               return;
+       if (mmc_card_sd(host->card))
+               return;
+       if (host->card->csd.mmca_vsn < CSD_SPEC_VER_4)
+               return;
+
        /*
         * As the ext_csd is so large and mostly unused, we don't store the
         * raw block in mmc_card.
         */
-       u8 *ext_csd;
        ext_csd = kmalloc(512, GFP_KERNEL);
        if (!ext_csd) {
                printk("%s: could not allocate a buffer to receive the ext_csd."
@@ -1049,66 +1000,71 @@ static void mmc_process_ext_csds(struct mmc_host *host)
                return;
        }
 
-       list_for_each_entry(card, &host->cards, node) {
-               if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
-                       continue;
-               if (mmc_card_sd(card))
-                       continue;
-               if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
-                       continue;
-
-               err = mmc_select_card(host, card);
-               if (err != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
-
-               memset(&cmd, 0, sizeof(struct mmc_command));
+       memset(&cmd, 0, sizeof(struct mmc_command));
 
-               cmd.opcode = MMC_SEND_EXT_CSD;
-               cmd.arg = 0;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       cmd.opcode = MMC_SEND_EXT_CSD;
+       cmd.arg = 0;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
-               memset(&data, 0, sizeof(struct mmc_data));
+       memset(&data, 0, sizeof(struct mmc_data));
 
-               mmc_set_data_timeout(&data, card, 0);
+       mmc_set_data_timeout(&data, host->card, 0);
 
-               data.blksz = 512;
-               data.blocks = 1;
-               data.flags = MMC_DATA_READ;
-               data.sg = &sg;
-               data.sg_len = 1;
+       data.blksz = 512;
+       data.blocks = 1;
+       data.flags = MMC_DATA_READ;
+       data.sg = &sg;
+       data.sg_len = 1;
 
-               memset(&mrq, 0, sizeof(struct mmc_request));
+       memset(&mrq, 0, sizeof(struct mmc_request));
 
-               mrq.cmd = &cmd;
-               mrq.data = &data;
+       mrq.cmd = &cmd;
+       mrq.data = &data;
 
-               sg_init_one(&sg, ext_csd, 512);
+       sg_init_one(&sg, ext_csd, 512);
 
-               mmc_wait_for_req(host, &mrq);
+       mmc_wait_for_req(host, &mrq);
 
-               if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
+       if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
+               if (host->card->csd.capacity == (4096 * 512)) {
+                       printk(KERN_ERR "%s: unable to read EXT_CSD "
+                               "on a possible high capacity card. "
+                               "Card will be ignored.\n",
+                               mmc_hostname(host));
+                       mmc_card_set_dead(host->card);
+               } else {
+                       printk(KERN_WARNING "%s: unable to read "
+                               "EXT_CSD, performance might "
+                               "suffer.\n",
+                               mmc_hostname(host));
                }
+               goto out;
+       }
 
-               switch (ext_csd[EXT_CSD_CARD_TYPE]) {
-               case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
-                       card->ext_csd.hs_max_dtr = 52000000;
-                       break;
-               case EXT_CSD_CARD_TYPE_26:
-                       card->ext_csd.hs_max_dtr = 26000000;
-                       break;
-               default:
-                       /* MMC v4 spec says this cannot happen */
-                       printk("%s: card is mmc v4 but doesn't support "
-                              "any high-speed modes.\n",
-                               mmc_hostname(card->host));
-                       mmc_card_set_bad(card);
-                       continue;
-               }
+       host->card->ext_csd.sectors =
+               ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
+               ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
+               ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
+               ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
+       if (host->card->ext_csd.sectors)
+               mmc_card_set_blockaddr(host->card);
+
+       switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+       case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
+               host->card->ext_csd.hs_max_dtr = 52000000;
+               break;
+       case EXT_CSD_CARD_TYPE_26:
+               host->card->ext_csd.hs_max_dtr = 26000000;
+               break;
+       default:
+               /* MMC v4 spec says this cannot happen */
+               printk("%s: card is mmc v4 but doesn't support "
+                      "any high-speed modes.\n",
+                       mmc_hostname(host));
+               goto out;
+       }
 
+       if (host->caps & MMC_CAP_MMC_HIGHSPEED) {
                /* Activate highspeed support. */
                cmd.opcode = MMC_SWITCH;
                cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
@@ -1121,17 +1077,18 @@ static void mmc_process_ext_csds(struct mmc_host *host)
                if (err != MMC_ERR_NONE) {
                        printk("%s: failed to switch card to mmc v4 "
                               "high-speed mode.\n",
-                              mmc_hostname(card->host));
-                       continue;
+                              mmc_hostname(host));
+                       goto out;
                }
 
-               mmc_card_set_highspeed(card);
+               mmc_card_set_highspeed(host->card);
 
-               /* Check for host support for wide-bus modes. */
-               if (!(host->caps & MMC_CAP_4_BIT_DATA)) {
-                       continue;
-               }
+               host->ios.timing = MMC_TIMING_MMC_HS;
+               mmc_set_ios(host);
+       }
 
+       /* Check for host support for wide-bus modes. */
+       if (host->caps & MMC_CAP_4_BIT_DATA) {
                /* Activate 4-bit support. */
                cmd.opcode = MMC_SWITCH;
                cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
@@ -1144,100 +1101,101 @@ static void mmc_process_ext_csds(struct mmc_host *host)
                if (err != MMC_ERR_NONE) {
                        printk("%s: failed to switch card to "
                               "mmc v4 4-bit bus mode.\n",
-                              mmc_hostname(card->host));
-                       continue;
+                              mmc_hostname(host));
+                       goto out;
                }
 
                host->ios.bus_width = MMC_BUS_WIDTH_4;
+               mmc_set_ios(host);
        }
 
+out:
        kfree(ext_csd);
-
-       mmc_deselect_cards(host);
 }
 
-static void mmc_read_scrs(struct mmc_host *host)
+static void mmc_read_scr(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) {
-               if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
-                       continue;
-               if (!mmc_card_sd(card))
-                       continue;
-
-               err = mmc_select_card(host, card);
-               if (err != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
-
-               memset(&cmd, 0, sizeof(struct mmc_command));
-
-               cmd.opcode = MMC_APP_CMD;
-               cmd.arg = card->rca << 16;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       if (!host->card)
+               return;
+       if (mmc_card_dead(host->card))
+               return;
+       if (!mmc_card_sd(host->card))
+               return;
 
-               err = mmc_wait_for_cmd(host, &cmd, 0);
-               if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
+       memset(&cmd, 0, sizeof(struct mmc_command));
 
-               memset(&cmd, 0, sizeof(struct mmc_command));
+       cmd.opcode = MMC_APP_CMD;
+       cmd.arg = host->card->rca << 16;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
-               cmd.opcode = SD_APP_SEND_SCR;
-               cmd.arg = 0;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       err = mmc_wait_for_cmd(host, &cmd, 0);
+       if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) {
+               mmc_card_set_dead(host->card);
+               return;
+       }
 
-               memset(&data, 0, sizeof(struct mmc_data));
+       memset(&cmd, 0, sizeof(struct mmc_command));
 
-               mmc_set_data_timeout(&data, card, 0);
+       cmd.opcode = SD_APP_SEND_SCR;
+       cmd.arg = 0;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
-               data.blksz = 1 << 3;
-               data.blocks = 1;
-               data.flags = MMC_DATA_READ;
-               data.sg = &sg;
-               data.sg_len = 1;
+       memset(&data, 0, sizeof(struct mmc_data));
 
-               memset(&mrq, 0, sizeof(struct mmc_request));
+       mmc_set_data_timeout(&data, host->card, 0);
 
-               mrq.cmd = &cmd;
-               mrq.data = &data;
+       data.blksz = 1 << 3;
+       data.blocks = 1;
+       data.flags = MMC_DATA_READ;
+       data.sg = &sg;
+       data.sg_len = 1;
 
-               sg_init_one(&sg, (u8*)card->raw_scr, 8);
+       memset(&mrq, 0, sizeof(struct mmc_request));
 
-               mmc_wait_for_req(host, &mrq);
+       mrq.cmd = &cmd;
+       mrq.data = &data;
 
-               if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
+       sg_init_one(&sg, (u8*)host->card->raw_scr, 8);
 
-               card->raw_scr[0] = ntohl(card->raw_scr[0]);
-               card->raw_scr[1] = ntohl(card->raw_scr[1]);
+       mmc_wait_for_req(host, &mrq);
 
-               mmc_decode_scr(card);
+       if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
+               mmc_card_set_dead(host->card);
+               return;
        }
 
-       mmc_deselect_cards(host);
+       host->card->raw_scr[0] = ntohl(host->card->raw_scr[0]);
+       host->card->raw_scr[1] = ntohl(host->card->raw_scr[1]);
+
+       mmc_decode_scr(host->card);
 }
 
 static void mmc_read_switch_caps(struct mmc_host *host)
 {
-       int err;
-       struct mmc_card *card;
        struct mmc_request mrq;
        struct mmc_command cmd;
        struct mmc_data data;
        unsigned char *status;
        struct scatterlist sg;
 
+       if (!(host->caps & MMC_CAP_SD_HIGHSPEED))
+               return;
+
+       if (!host->card)
+               return;
+       if (mmc_card_dead(host->card))
+               return;
+       if (!mmc_card_sd(host->card))
+               return;
+       if (host->card->scr.sda_vsn < SCR_SPEC_VER_1)
+               return;
+
        status = kmalloc(64, GFP_KERNEL);
        if (!status) {
                printk(KERN_WARNING "%s: Unable to allocate buffer for "
@@ -1246,115 +1204,98 @@ static void mmc_read_switch_caps(struct mmc_host *host)
                return;
        }
 
-       list_for_each_entry(card, &host->cards, node) {
-               if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
-                       continue;
-               if (!mmc_card_sd(card))
-                       continue;
-               if (card->scr.sda_vsn < SCR_SPEC_VER_1)
-                       continue;
-
-               err = mmc_select_card(host, card);
-               if (err != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
-
-               memset(&cmd, 0, sizeof(struct mmc_command));
+       memset(&cmd, 0, sizeof(struct mmc_command));
 
-               cmd.opcode = SD_SWITCH;
-               cmd.arg = 0x00FFFFF1;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       cmd.opcode = SD_SWITCH;
+       cmd.arg = 0x00FFFFF1;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
-               memset(&data, 0, sizeof(struct mmc_data));
+       memset(&data, 0, sizeof(struct mmc_data));
 
-               mmc_set_data_timeout(&data, card, 0);
+       mmc_set_data_timeout(&data, host->card, 0);
 
-               data.blksz = 64;
-               data.blocks = 1;
-               data.flags = MMC_DATA_READ;
-               data.sg = &sg;
-               data.sg_len = 1;
+       data.blksz = 64;
+       data.blocks = 1;
+       data.flags = MMC_DATA_READ;
+       data.sg = &sg;
+       data.sg_len = 1;
 
-               memset(&mrq, 0, sizeof(struct mmc_request));
+       memset(&mrq, 0, sizeof(struct mmc_request));
 
-               mrq.cmd = &cmd;
-               mrq.data = &data;
+       mrq.cmd = &cmd;
+       mrq.data = &data;
 
-               sg_init_one(&sg, status, 64);
+       sg_init_one(&sg, status, 64);
 
-               mmc_wait_for_req(host, &mrq);
+       mmc_wait_for_req(host, &mrq);
 
-               if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
+       if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
+               printk("%s: unable to read switch capabilities, "
+                       "performance might suffer.\n",
+                       mmc_hostname(host));
+               goto out;
+       }
 
-               if (status[13] & 0x02)
-                       card->sw_caps.hs_max_dtr = 50000000;
+       if (status[13] & 0x02)
+               host->card->sw_caps.hs_max_dtr = 50000000;
 
-               memset(&cmd, 0, sizeof(struct mmc_command));
+       memset(&cmd, 0, sizeof(struct mmc_command));
 
-               cmd.opcode = SD_SWITCH;
-               cmd.arg = 0x80FFFFF1;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       cmd.opcode = SD_SWITCH;
+       cmd.arg = 0x80FFFFF1;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
-               memset(&data, 0, sizeof(struct mmc_data));
+       memset(&data, 0, sizeof(struct mmc_data));
 
-               mmc_set_data_timeout(&data, card, 0);
+       mmc_set_data_timeout(&data, host->card, 0);
 
-               data.blksz = 64;
-               data.blocks = 1;
-               data.flags = MMC_DATA_READ;
-               data.sg = &sg;
-               data.sg_len = 1;
+       data.blksz = 64;
+       data.blocks = 1;
+       data.flags = MMC_DATA_READ;
+       data.sg = &sg;
+       data.sg_len = 1;
 
-               memset(&mrq, 0, sizeof(struct mmc_request));
+       memset(&mrq, 0, sizeof(struct mmc_request));
 
-               mrq.cmd = &cmd;
-               mrq.data = &data;
+       mrq.cmd = &cmd;
+       mrq.data = &data;
 
-               sg_init_one(&sg, status, 64);
+       sg_init_one(&sg, status, 64);
 
-               mmc_wait_for_req(host, &mrq);
+       mmc_wait_for_req(host, &mrq);
 
-               if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
-                       mmc_card_set_dead(card);
-                       continue;
-               }
+       if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE ||
+               (status[16] & 0xF) != 1) {
+               printk(KERN_WARNING "%s: Problem switching card "
+                       "into high-speed mode!\n",
+                       mmc_hostname(host));
+               goto out;
+       }
 
-               if ((status[16] & 0xF) != 1) {
-                       printk(KERN_WARNING "%s: Problem switching card "
-                               "into high-speed mode!\n",
-                               mmc_hostname(host));
-                       continue;
-               }
+       mmc_card_set_highspeed(host->card);
 
-               mmc_card_set_highspeed(card);
-       }
+       host->ios.timing = MMC_TIMING_SD_HS;
+       mmc_set_ios(host);
 
+out:
        kfree(status);
-
-       mmc_deselect_cards(host);
 }
 
 static unsigned int mmc_calculate_clock(struct mmc_host *host)
 {
-       struct mmc_card *card;
        unsigned int max_dtr = host->f_max;
 
-       list_for_each_entry(card, &host->cards, node)
-               if (!mmc_card_dead(card)) {
-                       if (mmc_card_highspeed(card) && mmc_card_sd(card)) {
-                               if (max_dtr > card->sw_caps.hs_max_dtr)
-                                       max_dtr = card->sw_caps.hs_max_dtr;
-                       } else if (mmc_card_highspeed(card) && !mmc_card_sd(card)) {
-                               if (max_dtr > card->ext_csd.hs_max_dtr)
-                                       max_dtr = card->ext_csd.hs_max_dtr;
-                       } else if (max_dtr > card->csd.max_dtr) {
-                               max_dtr = card->csd.max_dtr;
-                       }
+       if (host->card && !mmc_card_dead(host->card)) {
+               if (mmc_card_highspeed(host->card) && mmc_card_sd(host->card)) {
+                       if (max_dtr > host->card->sw_caps.hs_max_dtr)
+                               max_dtr = host->card->sw_caps.hs_max_dtr;
+               } else if (mmc_card_highspeed(host->card) && !mmc_card_sd(host->card)) {
+                       if (max_dtr > host->card->ext_csd.hs_max_dtr)
+                               max_dtr = host->card->ext_csd.hs_max_dtr;
+               } else if (max_dtr > host->card->csd.max_dtr) {
+                       max_dtr = host->card->csd.max_dtr;
                }
+       }
 
        pr_debug("%s: selected %d.%03dMHz transfer rate\n",
                 mmc_hostname(host),
@@ -1371,91 +1312,65 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host)
  * A request for status does not cause a state change in data
  * transfer mode.
  */
-static void mmc_check_cards(struct mmc_host *host)
+static void mmc_check_card(struct mmc_card *card)
 {
-       struct list_head *l, *n;
-
-       mmc_deselect_cards(host);
+       struct mmc_command cmd;
+       int err;
 
-       list_for_each_safe(l, n, &host->cards) {
-               struct mmc_card *card = mmc_list_to_card(l);
-               struct mmc_command cmd;
-               int err;
+       BUG_ON(!card);
 
-               cmd.opcode = MMC_SEND_STATUS;
-               cmd.arg = card->rca << 16;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       cmd.opcode = MMC_SEND_STATUS;
+       cmd.arg = card->rca << 16;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
-               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-               if (err == MMC_ERR_NONE)
-                       continue;
+       err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES);
+       if (err == MMC_ERR_NONE)
+               return;
 
-               mmc_card_set_dead(card);
-       }
+       mmc_card_set_dead(card);
 }
 
 static void mmc_setup(struct mmc_host *host)
 {
-       if (host->ios.power_mode != MMC_POWER_ON) {
-               int err;
-               u32 ocr;
-
-               host->mode = MMC_MODE_SD;
-
-               mmc_power_up(host);
-               mmc_idle_cards(host);
+       int err;
+       u32 ocr;
 
-               err = mmc_send_if_cond(host, host->ocr_avail, NULL);
-               if (err != MMC_ERR_NONE) {
-                       return;
-               }
-               err = mmc_send_app_op_cond(host, 0, &ocr);
+       host->mode = MMC_MODE_SD;
 
-               /*
-                * If we fail to detect any SD cards then try
-                * searching for MMC cards.
-                */
-               if (err != MMC_ERR_NONE) {
-                       host->mode = MMC_MODE_MMC;
-
-                       err = mmc_send_op_cond(host, 0, &ocr);
-                       if (err != MMC_ERR_NONE)
-                               return;
-               }
+       mmc_power_up(host);
+       mmc_idle_cards(host);
 
-               host->ocr = mmc_select_voltage(host, ocr);
+       err = mmc_send_if_cond(host, host->ocr_avail, NULL);
+       if (err != MMC_ERR_NONE) {
+               return;
+       }
+       err = mmc_send_app_op_cond(host, 0, &ocr);
 
-               /*
-                * Since we're changing the OCR value, we seem to
-                * need to tell some cards to go back to the idle
-                * state.  We wait 1ms to give cards time to
-                * respond.
-                */
-               if (host->ocr)
-                       mmc_idle_cards(host);
-       } else {
-               host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-               host->ios.clock = host->f_min;
-               mmc_set_ios(host);
+       /*
+        * If we fail to detect any SD cards then try
+        * searching for MMC cards.
+        */
+       if (err != MMC_ERR_NONE) {
+               host->mode = MMC_MODE_MMC;
 
-               /*
-                * We should remember the OCR mask from the existing
-                * cards, and detect the new cards OCR mask, combine
-                * the two and re-select the VDD.  However, if we do
-                * change VDD, we should do an idle, and then do a
-                * full re-initialisation.  We would need to notify
-                * drivers so that they can re-setup the cards as
-                * well, while keeping their queues at bay.
-                *
-                * For the moment, we take the easy way out - if the
-                * new cards don't like our currently selected VDD,
-                * they drop off the bus.
-                */
+               err = mmc_send_op_cond(host, 0, &ocr);
+               if (err != MMC_ERR_NONE)
+                       return;
        }
 
+       host->ocr = mmc_select_voltage(host, ocr);
+
        if (host->ocr == 0)
                return;
 
+       /*
+        * Since we're changing the OCR value, we seem to
+        * need to tell some cards to go back to the idle
+        * state.  We wait 1ms to give cards time to
+        * respond.
+        */
+       mmc_idle_cards(host);
+
        /*
         * Send the selected OCR multiple times... until the cards
         * all get the idea that they should be ready for CMD2.
@@ -1474,10 +1389,11 @@ static void mmc_setup(struct mmc_host *host)
                        mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL);
                }
        } else {
-               mmc_send_op_cond(host, host->ocr, NULL);
+               /* The extra bit indicates that we support high capacity */
+               mmc_send_op_cond(host, host->ocr | (1 << 30), NULL);
        }
 
-       mmc_discover_cards(host);
+       mmc_discover_card(host);
 
        /*
         * Ok, now switch to push-pull mode.
@@ -1485,13 +1401,19 @@ static void mmc_setup(struct mmc_host *host)
        host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
        mmc_set_ios(host);
 
-       mmc_read_csds(host);
+       mmc_read_csd(host);
+
+       if (host->card && !mmc_card_dead(host->card)) {
+               err = mmc_select_card(host->card);
+               if (err != MMC_ERR_NONE)
+                       mmc_card_set_dead(host->card);
+       }
 
        if (host->mode == MMC_MODE_SD) {
-               mmc_read_scrs(host);
+               mmc_read_scr(host);
                mmc_read_switch_caps(host);
        } else
-               mmc_process_ext_csds(host);
+               mmc_process_ext_csd(host);
 }
 
 
@@ -1505,6 +1427,12 @@ static void mmc_setup(struct mmc_host *host)
  */
 void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 {
+#ifdef CONFIG_MMC_DEBUG
+       mmc_claim_host(host);
+       BUG_ON(host->removed);
+       mmc_release_host(host);
+#endif
+
        mmc_schedule_delayed_work(&host->detect, delay);
 }
 
@@ -1515,31 +1443,29 @@ static void mmc_rescan(struct work_struct *work)
 {
        struct mmc_host *host =
                container_of(work, struct mmc_host, detect.work);
-       struct list_head *l, *n;
-       unsigned char power_mode;
 
        mmc_claim_host(host);
 
        /*
-        * Check for removed cards and newly inserted ones. We check for
+        * Check for removed card and newly inserted ones. We check for
         * removed cards first so we can intelligently re-select the VDD.
         */
-       power_mode = host->ios.power_mode;
-       if (power_mode == MMC_POWER_ON)
-               mmc_check_cards(host);
+       if (host->card) {
+               mmc_check_card(host->card);
 
-       mmc_setup(host);
+               mmc_release_host(host);
 
-       /*
-        * Some broken cards process CMD1 even in stand-by state. There is
-        * no reply, but an ILLEGAL_COMMAND error is cached and returned
-        * after next command. We poll for card status here to clear any
-        * possibly pending error.
-        */
-       if (power_mode == MMC_POWER_ON)
-               mmc_check_cards(host);
+               if (mmc_card_dead(host->card)) {
+                       mmc_remove_card(host->card);
+                       host->card = NULL;
+               }
 
-       if (!list_empty(&host->cards)) {
+               goto out;
+       }
+
+       mmc_setup(host);
+
+       if (host->card && !mmc_card_dead(host->card)) {
                /*
                 * (Re-)calculate the fastest clock rate which the
                 * attached cards and the host support.
@@ -1550,33 +1476,28 @@ static void mmc_rescan(struct work_struct *work)
 
        mmc_release_host(host);
 
-       list_for_each_safe(l, n, &host->cards) {
-               struct mmc_card *card = mmc_list_to_card(l);
-
-               /*
-                * If this is a new and good card, register it.
-                */
-               if (!mmc_card_present(card) && !mmc_card_dead(card)) {
-                       if (mmc_register_card(card))
-                               mmc_card_set_dead(card);
-                       else
-                               mmc_card_set_present(card);
-               }
+       /*
+        * If this is a new and good card, register it.
+        */
+       if (host->card && !mmc_card_dead(host->card)) {
+               if (mmc_register_card(host->card))
+                       mmc_card_set_dead(host->card);
+       }
 
-               /*
-                * If this card is dead, destroy it.
-                */
-               if (mmc_card_dead(card)) {
-                       list_del(&card->node);
-                       mmc_remove_card(card);
-               }
+       /*
+        * If this card is dead, destroy it.
+        */
+       if (host->card && mmc_card_dead(host->card)) {
+               mmc_remove_card(host->card);
+               host->card = NULL;
        }
 
+out:
        /*
         * If we discover that there are no cards on the
         * bus, turn off the clock and power down.
         */
-       if (list_empty(&host->cards))
+       if (!host->card)
                mmc_power_off(host);
 }
 
@@ -1596,7 +1517,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        if (host) {
                spin_lock_init(&host->lock);
                init_waitqueue_head(&host->wq);
-               INIT_LIST_HEAD(&host->cards);
                INIT_DELAYED_WORK(&host->detect, mmc_rescan);
 
                /*
@@ -1605,10 +1525,11 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
                 */
                host->max_hw_segs = 1;
                host->max_phys_segs = 1;
-               host->max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
                host->max_seg_size = PAGE_CACHE_SIZE;
 
+               host->max_req_size = PAGE_CACHE_SIZE;
                host->max_blk_size = 512;
+               host->max_blk_count = PAGE_CACHE_SIZE / 512;
        }
 
        return host;
@@ -1644,12 +1565,17 @@ EXPORT_SYMBOL(mmc_add_host);
  */
 void mmc_remove_host(struct mmc_host *host)
 {
-       struct list_head *l, *n;
+#ifdef CONFIG_MMC_DEBUG
+       mmc_claim_host(host);
+       host->removed = 1;
+       mmc_release_host(host);
+#endif
 
-       list_for_each_safe(l, n, &host->cards) {
-               struct mmc_card *card = mmc_list_to_card(l);
+       mmc_flush_scheduled_work();
 
-               mmc_remove_card(card);
+       if (host->card) {
+               mmc_remove_card(host->card);
+               host->card = NULL;
        }
 
        mmc_power_off(host);
@@ -1666,7 +1592,6 @@ EXPORT_SYMBOL(mmc_remove_host);
  */
 void mmc_free_host(struct mmc_host *host)
 {
-       mmc_flush_scheduled_work();
        mmc_free_host_sysfs(host);
 }
 
@@ -1681,10 +1606,14 @@ EXPORT_SYMBOL(mmc_free_host);
  */
 int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
 {
-       mmc_claim_host(host);
-       mmc_deselect_cards(host);
+       mmc_flush_scheduled_work();
+
+       if (host->card) {
+               mmc_remove_card(host->card);
+               host->card = NULL;
+       }
+
        mmc_power_off(host);
-       mmc_release_host(host);
 
        return 0;
 }