int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
{ int err; struct mmc_command cmd = {};
if (WARN_ON(card && card->host != host)) return -EINVAL;
/* * UHS2 packet has APP bit so only set APP_CMD flag here. * Will set the APP bit when assembling UHS2 packet.
*/ if (host->uhs2_sd_tran) {
host->uhs2_app_cmd = true; return 0;
}
/* * We have to resend MMC_APP_CMD for each attempt so * we cannot use the retries field in mmc_command.
*/ for (i = 0; i <= MMC_CMD_RETRIES; i++) {
err = mmc_app_cmd(host, card); if (err) { /* no point in retrying; no APP commands allowed */ if (mmc_host_is_spi(host)) { if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) break;
} continue;
}
int mmc_send_if_cond_pcie(struct mmc_host *host, u32 ocr)
{
u32 resp = 0;
u8 pcie_bits = 0; int ret;
if (host->caps2 & MMC_CAP2_SD_EXP) { /* Probe card for SD express support via PCIe. */
pcie_bits = 0x10; if (host->caps2 & MMC_CAP2_SD_EXP_1_2V) /* Probe also for 1.2V support. */
pcie_bits = 0x30;
}
ret = __mmc_send_if_cond(host, ocr, pcie_bits, &resp); if (ret) return 0;
/* Continue with the SD express init, if the card supports it. */
resp &= 0x3000; if (pcie_bits && resp) { if (resp == 0x3000)
host->ios.timing = MMC_TIMING_SD_EXP_1_2V; else
host->ios.timing = MMC_TIMING_SD_EXP;
/* * According to the spec the clock shall also be gated, but * let's leave this to the host driver for more flexibility.
*/ return host->ops->init_sd_express(host, &host->ios);
}
return 0;
}
int mmc_send_relative_addr(struct mmc_host *host, unsignedint *rca)
{ int err; struct mmc_command cmd = {};
err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); if (err) return err;
*rca = cmd.resp[0] >> 16;
return 0;
}
int mmc_app_send_scr(struct mmc_card *card)
{ int err; struct mmc_request mrq = {}; struct mmc_command cmd = {}; struct mmc_data data = {}; struct scatterlist sg;
__be32 *scr;
/* NOTE: caller guarantees scr is heap-allocated */
err = mmc_app_cmd(card->host, card); if (err) return err;
/* dma onto stack is unsafe/nonportable, but callers to this * routine normally provide temporary on-stack buffers ...
*/
scr = kmalloc(sizeof(card->raw_scr), GFP_KERNEL); if (!scr) return -ENOMEM;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.