static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { ... mmc_go_idle(host);
/* * If SD_SEND_IF_COND indicates an SD 2.0 * compliant card and we should set bit 30 * of the ocr to indicate that we can handle * block-addressed SDHC cards. */ err = mmc_send_if_cond(host, ocr); if (!err) ocr |= 1 << 30;
err = mmc_send_app_op_cond(host, ocr, NULL); if (err) goto err;
/* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err;
...
/* * For native busses: get card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_send_relative_addr(host, &card->rca); if (err) goto free_card;
mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); }
if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card;
err = mmc_decode_csd(card); if (err) goto free_card;
mmc_decode_cid(card); }
/* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; }
if (!oldcard) { /* * Fetch SCR from card. */ err = mmc_app_send_scr(card, card->raw_scr); if (err) goto free_card;
err = mmc_decode_scr(card); if (err < 0) goto free_card; /* * Fetch switch information from card. */ #ifdef CONFIG_MMC_PARANOID_SD_INIT for (retries = 1; retries <= 3; retries++) { err = mmc_read_switch(card); if (!err) { if (retries > 1) { printk(KERN_WARNING "%s: recovered\n", mmc_hostname(host)); } break; } else { printk(KERN_WARNING "%s: read switch failed (attempt %d)\n", mmc_hostname(host), retries); } } #else err = mmc_read_switch(card); #endif
if (err) goto free_card; }
...
/* * Attempt to change to high-speed (if supported) */ err = mmc_switch_hs(card); if (err) goto free_card;
/* * Compute bus speed. */ max_dtr = (unsigned int)-1;
if (mmc_card_highspeed(card)) { if (max_dtr > card->sw_caps.hs_max_dtr) max_dtr = card->sw_caps.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; }
mmc_set_clock(host, max_dtr);
/* * Switch to wider bus (if supported). */ if ((host->caps & MMC_CAP_4_BIT_DATA) && (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); if (err) { err = 0; printk(KERN_ERR "HiGH-SPEED MODE NOT AVILABLE FOR YOUR CARD!\n"); mmc_set_timing(card->host,MMC_TIMING_LEGACY); err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); if(err) { err = 0; printk(KERN_ERR "CLOCK TOO HIGH SWITCH TO NORMAL CLOCK!\n"); max_dtr = card->csd.max_dtr; mmc_set_clock(host, max_dtr); err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); if(err) { printk("I don't known why!!\n"); goto free_card; }
} } mmc_set_bus_width(host, MMC_BUS_WIDTH_4); }
/* * Check if read-only switch is active. */ if (!oldcard) { if (!host->ops->get_ro || host->ops->get_ro(host) < 0) { 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) > 0) mmc_card_set_readonly(card); } }
if (!oldcard) host->card = card;
return 0;
free_card: if (!oldcard) mmc_remove_card(card); err:
return err; }
|