/* * Starting point for MMC card init. */ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) { int err; BUG_ON(!host); BUG_ON(!host->claimed); mmc_attach_bus(host, &mmc_ops); /* * Sanity check the voltages that the card claims to * support. */ if (ocr & 0x7F) { printk(KERN_WARNING "%s: card claims to support voltages " "below the defined range. These will be ignored.\n", mmc_hostname(host)); ocr &= ~0x7F; } host->ocr = mmc_select_voltage(host, ocr); /* * Can we support the voltage of the card? */ if (!host->ocr) goto err; /* * Detect and init the card. */ err = mmc_sd_init_card(host, host->ocr, NULL); if (err != MMC_ERR_NONE) goto err; mmc_release_host(host); err = mmc_register_card(host->card); if (err) goto reclaim_host; return 0; reclaim_host: mmc_claim_host(host); mmc_remove_card(host->card); host->card = NULL; err: mmc_detach_bus(host); mmc_release_host(host); return 0; }
/* * Starting point for MMC card init. */ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; BUG_ON(!host); BUG_ON(!host->claimed); mmc_attach_bus(host, &mmc_ops); host->ocr = mmc_select_voltage(host, ocr); /* * Can we support the voltage of the card? */ if (!host->ocr) goto err; /* * 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_go_idle(host); /* The extra bit indicates that we support high capacity */ mmc_send_op_cond(host, host->ocr | (1 << 30), NULL); /* * Fetch CID from card. */ err = mmc_all_send_cid(host, cid); if (err != MMC_ERR_NONE) goto err; /* * Allocate card structure. */ card = mmc_alloc_card(host); if (IS_ERR(card)) goto err; card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); /* * Set card RCA. */ err = mmc_set_relative_addr(card); if (err != MMC_ERR_NONE) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err != MMC_ERR_NONE) goto free_card; mmc_decode_csd(card); mmc_decode_cid(card); /* * Fetch and process extened CSD. * This will switch into high-speed and wide bus modes, * as available. */ err = mmc_select_card(card); if (err != MMC_ERR_NONE) goto free_card; err = mmc_process_ext_csd(card); if (err != MMC_ERR_NONE) goto free_card; /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(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; } mmc_set_clock(host, max_dtr); host->card = card; mmc_release_host(host); err = mmc_register_card(card); if (err) goto reclaim_host; return 0; reclaim_host: mmc_claim_host(host); free_card: mmc_remove_card(card); host->card = NULL; err: mmc_detach_bus(host); mmc_release_host(host); return 0; }