1da7fbe58SPierre Ossman /* 270f10482SPierre Ossman * linux/drivers/mmc/core/mmc_ops.h 3da7fbe58SPierre Ossman * 4da7fbe58SPierre Ossman * Copyright 2006-2007 Pierre Ossman 5da7fbe58SPierre Ossman * 6da7fbe58SPierre Ossman * This program is free software; you can redistribute it and/or modify 7da7fbe58SPierre Ossman * it under the terms of the GNU General Public License as published by 8da7fbe58SPierre Ossman * the Free Software Foundation; either version 2 of the License, or (at 9da7fbe58SPierre Ossman * your option) any later version. 10da7fbe58SPierre Ossman */ 11da7fbe58SPierre Ossman 125a0e3ad6STejun Heo #include <linux/slab.h> 13da7fbe58SPierre Ossman #include <linux/types.h> 14da7fbe58SPierre Ossman #include <linux/scatterlist.h> 15da7fbe58SPierre Ossman 16da7fbe58SPierre Ossman #include <linux/mmc/host.h> 17da7fbe58SPierre Ossman #include <linux/mmc/card.h> 18da7fbe58SPierre Ossman #include <linux/mmc/mmc.h> 19da7fbe58SPierre Ossman 20da7fbe58SPierre Ossman #include "core.h" 21da7fbe58SPierre Ossman #include "mmc_ops.h" 22da7fbe58SPierre Ossman 23da7fbe58SPierre Ossman static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) 24da7fbe58SPierre Ossman { 25da7fbe58SPierre Ossman int err; 261278dba1SChris Ball struct mmc_command cmd = {0}; 27da7fbe58SPierre Ossman 28da7fbe58SPierre Ossman BUG_ON(!host); 29da7fbe58SPierre Ossman 30da7fbe58SPierre Ossman cmd.opcode = MMC_SELECT_CARD; 31da7fbe58SPierre Ossman 32da7fbe58SPierre Ossman if (card) { 33da7fbe58SPierre Ossman cmd.arg = card->rca << 16; 34da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 35da7fbe58SPierre Ossman } else { 36da7fbe58SPierre Ossman cmd.arg = 0; 37da7fbe58SPierre Ossman cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; 38da7fbe58SPierre Ossman } 39da7fbe58SPierre Ossman 40da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 4117b0429dSPierre Ossman if (err) 42da7fbe58SPierre Ossman return err; 43da7fbe58SPierre Ossman 4417b0429dSPierre Ossman return 0; 45da7fbe58SPierre Ossman } 46da7fbe58SPierre Ossman 47da7fbe58SPierre Ossman int mmc_select_card(struct mmc_card *card) 48da7fbe58SPierre Ossman { 49da7fbe58SPierre Ossman BUG_ON(!card); 50da7fbe58SPierre Ossman 51da7fbe58SPierre Ossman return _mmc_select_card(card->host, card); 52da7fbe58SPierre Ossman } 53da7fbe58SPierre Ossman 54da7fbe58SPierre Ossman int mmc_deselect_cards(struct mmc_host *host) 55da7fbe58SPierre Ossman { 56da7fbe58SPierre Ossman return _mmc_select_card(host, NULL); 57da7fbe58SPierre Ossman } 58da7fbe58SPierre Ossman 59b1ebe384SJarkko Lavinen int mmc_card_sleepawake(struct mmc_host *host, int sleep) 60b1ebe384SJarkko Lavinen { 611278dba1SChris Ball struct mmc_command cmd = {0}; 62b1ebe384SJarkko Lavinen struct mmc_card *card = host->card; 63b1ebe384SJarkko Lavinen int err; 64b1ebe384SJarkko Lavinen 65b1ebe384SJarkko Lavinen if (sleep) 66b1ebe384SJarkko Lavinen mmc_deselect_cards(host); 67b1ebe384SJarkko Lavinen 68b1ebe384SJarkko Lavinen cmd.opcode = MMC_SLEEP_AWAKE; 69b1ebe384SJarkko Lavinen cmd.arg = card->rca << 16; 70b1ebe384SJarkko Lavinen if (sleep) 71b1ebe384SJarkko Lavinen cmd.arg |= 1 << 15; 72b1ebe384SJarkko Lavinen 73b1ebe384SJarkko Lavinen cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 74b1ebe384SJarkko Lavinen err = mmc_wait_for_cmd(host, &cmd, 0); 75b1ebe384SJarkko Lavinen if (err) 76b1ebe384SJarkko Lavinen return err; 77b1ebe384SJarkko Lavinen 78b1ebe384SJarkko Lavinen /* 79b1ebe384SJarkko Lavinen * If the host does not wait while the card signals busy, then we will 80b1ebe384SJarkko Lavinen * will have to wait the sleep/awake timeout. Note, we cannot use the 81b1ebe384SJarkko Lavinen * SEND_STATUS command to poll the status because that command (and most 82b1ebe384SJarkko Lavinen * others) is invalid while the card sleeps. 83b1ebe384SJarkko Lavinen */ 84b1ebe384SJarkko Lavinen if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) 85b1ebe384SJarkko Lavinen mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000)); 86b1ebe384SJarkko Lavinen 87b1ebe384SJarkko Lavinen if (!sleep) 88b1ebe384SJarkko Lavinen err = mmc_select_card(card); 89b1ebe384SJarkko Lavinen 90b1ebe384SJarkko Lavinen return err; 91b1ebe384SJarkko Lavinen } 92b1ebe384SJarkko Lavinen 93da7fbe58SPierre Ossman int mmc_go_idle(struct mmc_host *host) 94da7fbe58SPierre Ossman { 95da7fbe58SPierre Ossman int err; 961278dba1SChris Ball struct mmc_command cmd = {0}; 97da7fbe58SPierre Ossman 98af517150SDavid Brownell /* 99af517150SDavid Brownell * Non-SPI hosts need to prevent chipselect going active during 100af517150SDavid Brownell * GO_IDLE; that would put chips into SPI mode. Remind them of 101af517150SDavid Brownell * that in case of hardware that won't pull up DAT3/nCS otherwise. 102af517150SDavid Brownell * 103af517150SDavid Brownell * SPI hosts ignore ios.chip_select; it's managed according to 10425985edcSLucas De Marchi * rules that must accommodate non-MMC slaves which this layer 105af517150SDavid Brownell * won't even know about. 106af517150SDavid Brownell */ 107af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 108da7fbe58SPierre Ossman mmc_set_chip_select(host, MMC_CS_HIGH); 109da7fbe58SPierre Ossman mmc_delay(1); 110af517150SDavid Brownell } 111da7fbe58SPierre Ossman 112da7fbe58SPierre Ossman cmd.opcode = MMC_GO_IDLE_STATE; 113da7fbe58SPierre Ossman cmd.arg = 0; 114af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; 115da7fbe58SPierre Ossman 116da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, 0); 117da7fbe58SPierre Ossman 118da7fbe58SPierre Ossman mmc_delay(1); 119da7fbe58SPierre Ossman 120af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 121da7fbe58SPierre Ossman mmc_set_chip_select(host, MMC_CS_DONTCARE); 122da7fbe58SPierre Ossman mmc_delay(1); 123af517150SDavid Brownell } 124af517150SDavid Brownell 125af517150SDavid Brownell host->use_spi_crc = 0; 126da7fbe58SPierre Ossman 127da7fbe58SPierre Ossman return err; 128da7fbe58SPierre Ossman } 129da7fbe58SPierre Ossman 130da7fbe58SPierre Ossman int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) 131da7fbe58SPierre Ossman { 1321278dba1SChris Ball struct mmc_command cmd = {0}; 133da7fbe58SPierre Ossman int i, err = 0; 134da7fbe58SPierre Ossman 135da7fbe58SPierre Ossman BUG_ON(!host); 136da7fbe58SPierre Ossman 137da7fbe58SPierre Ossman cmd.opcode = MMC_SEND_OP_COND; 138af517150SDavid Brownell cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; 139af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; 140da7fbe58SPierre Ossman 141da7fbe58SPierre Ossman for (i = 100; i; i--) { 142da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, 0); 14317b0429dSPierre Ossman if (err) 144da7fbe58SPierre Ossman break; 145da7fbe58SPierre Ossman 146af517150SDavid Brownell /* if we're just probing, do a single pass */ 147af517150SDavid Brownell if (ocr == 0) 148da7fbe58SPierre Ossman break; 149da7fbe58SPierre Ossman 150af517150SDavid Brownell /* otherwise wait until reset completes */ 151af517150SDavid Brownell if (mmc_host_is_spi(host)) { 152af517150SDavid Brownell if (!(cmd.resp[0] & R1_SPI_IDLE)) 153af517150SDavid Brownell break; 154af517150SDavid Brownell } else { 155af517150SDavid Brownell if (cmd.resp[0] & MMC_CARD_BUSY) 156af517150SDavid Brownell break; 157af517150SDavid Brownell } 158af517150SDavid Brownell 15917b0429dSPierre Ossman err = -ETIMEDOUT; 160da7fbe58SPierre Ossman 161da7fbe58SPierre Ossman mmc_delay(10); 162da7fbe58SPierre Ossman } 163da7fbe58SPierre Ossman 164af517150SDavid Brownell if (rocr && !mmc_host_is_spi(host)) 165da7fbe58SPierre Ossman *rocr = cmd.resp[0]; 166da7fbe58SPierre Ossman 167da7fbe58SPierre Ossman return err; 168da7fbe58SPierre Ossman } 169da7fbe58SPierre Ossman 170da7fbe58SPierre Ossman int mmc_all_send_cid(struct mmc_host *host, u32 *cid) 171da7fbe58SPierre Ossman { 172da7fbe58SPierre Ossman int err; 1731278dba1SChris Ball struct mmc_command cmd = {0}; 174da7fbe58SPierre Ossman 175da7fbe58SPierre Ossman BUG_ON(!host); 176da7fbe58SPierre Ossman BUG_ON(!cid); 177da7fbe58SPierre Ossman 178da7fbe58SPierre Ossman cmd.opcode = MMC_ALL_SEND_CID; 179da7fbe58SPierre Ossman cmd.arg = 0; 180da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 181da7fbe58SPierre Ossman 182da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 18317b0429dSPierre Ossman if (err) 184da7fbe58SPierre Ossman return err; 185da7fbe58SPierre Ossman 186da7fbe58SPierre Ossman memcpy(cid, cmd.resp, sizeof(u32) * 4); 187da7fbe58SPierre Ossman 18817b0429dSPierre Ossman return 0; 189da7fbe58SPierre Ossman } 190da7fbe58SPierre Ossman 191da7fbe58SPierre Ossman int mmc_set_relative_addr(struct mmc_card *card) 192da7fbe58SPierre Ossman { 193da7fbe58SPierre Ossman int err; 1941278dba1SChris Ball struct mmc_command cmd = {0}; 195da7fbe58SPierre Ossman 196da7fbe58SPierre Ossman BUG_ON(!card); 197da7fbe58SPierre Ossman BUG_ON(!card->host); 198da7fbe58SPierre Ossman 199da7fbe58SPierre Ossman cmd.opcode = MMC_SET_RELATIVE_ADDR; 200da7fbe58SPierre Ossman cmd.arg = card->rca << 16; 201da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 202da7fbe58SPierre Ossman 203da7fbe58SPierre Ossman err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 20417b0429dSPierre Ossman if (err) 205da7fbe58SPierre Ossman return err; 206da7fbe58SPierre Ossman 20717b0429dSPierre Ossman return 0; 208da7fbe58SPierre Ossman } 209da7fbe58SPierre Ossman 210af517150SDavid Brownell static int 211af517150SDavid Brownell mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) 212da7fbe58SPierre Ossman { 213da7fbe58SPierre Ossman int err; 2141278dba1SChris Ball struct mmc_command cmd = {0}; 215da7fbe58SPierre Ossman 216af517150SDavid Brownell BUG_ON(!host); 217af517150SDavid Brownell BUG_ON(!cxd); 218da7fbe58SPierre Ossman 219af517150SDavid Brownell cmd.opcode = opcode; 220af517150SDavid Brownell cmd.arg = arg; 221da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; 222da7fbe58SPierre Ossman 223af517150SDavid Brownell err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 22417b0429dSPierre Ossman if (err) 225da7fbe58SPierre Ossman return err; 226da7fbe58SPierre Ossman 227af517150SDavid Brownell memcpy(cxd, cmd.resp, sizeof(u32) * 4); 228da7fbe58SPierre Ossman 22917b0429dSPierre Ossman return 0; 230da7fbe58SPierre Ossman } 231da7fbe58SPierre Ossman 232af517150SDavid Brownell static int 233af517150SDavid Brownell mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, 234af517150SDavid Brownell u32 opcode, void *buf, unsigned len) 235da7fbe58SPierre Ossman { 23624f5b53bSChris Ball struct mmc_request mrq = {0}; 2371278dba1SChris Ball struct mmc_command cmd = {0}; 238a61ad2b4SChris Ball struct mmc_data data = {0}; 239da7fbe58SPierre Ossman struct scatterlist sg; 240af517150SDavid Brownell void *data_buf; 241da7fbe58SPierre Ossman 242af517150SDavid Brownell /* dma onto stack is unsafe/nonportable, but callers to this 243af517150SDavid Brownell * routine normally provide temporary on-stack buffers ... 244af517150SDavid Brownell */ 245af517150SDavid Brownell data_buf = kmalloc(len, GFP_KERNEL); 246af517150SDavid Brownell if (data_buf == NULL) 247af517150SDavid Brownell return -ENOMEM; 248da7fbe58SPierre Ossman 249da7fbe58SPierre Ossman mrq.cmd = &cmd; 250da7fbe58SPierre Ossman mrq.data = &data; 251da7fbe58SPierre Ossman 252af517150SDavid Brownell cmd.opcode = opcode; 253da7fbe58SPierre Ossman cmd.arg = 0; 254da7fbe58SPierre Ossman 255af517150SDavid Brownell /* NOTE HACK: the MMC_RSP_SPI_R1 is always correct here, but we 256af517150SDavid Brownell * rely on callers to never use this with "native" calls for reading 257af517150SDavid Brownell * CSD or CID. Native versions of those commands use the R2 type, 258af517150SDavid Brownell * not R1 plus a data block. 259af517150SDavid Brownell */ 260af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; 261af517150SDavid Brownell 262af517150SDavid Brownell data.blksz = len; 263da7fbe58SPierre Ossman data.blocks = 1; 264da7fbe58SPierre Ossman data.flags = MMC_DATA_READ; 265da7fbe58SPierre Ossman data.sg = &sg; 266da7fbe58SPierre Ossman data.sg_len = 1; 267da7fbe58SPierre Ossman 268af517150SDavid Brownell sg_init_one(&sg, data_buf, len); 269da7fbe58SPierre Ossman 270cda56ac2SAdrian Hunter if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) { 2710d3e0460SMatthew Fleming /* 2720d3e0460SMatthew Fleming * The spec states that CSR and CID accesses have a timeout 2730d3e0460SMatthew Fleming * of 64 clock cycles. 2740d3e0460SMatthew Fleming */ 2750d3e0460SMatthew Fleming data.timeout_ns = 0; 2760d3e0460SMatthew Fleming data.timeout_clks = 64; 277cda56ac2SAdrian Hunter } else 278cda56ac2SAdrian Hunter mmc_set_data_timeout(&data, card); 279da7fbe58SPierre Ossman 280af517150SDavid Brownell mmc_wait_for_req(host, &mrq); 281af517150SDavid Brownell 282af517150SDavid Brownell memcpy(buf, data_buf, len); 283af517150SDavid Brownell kfree(data_buf); 284da7fbe58SPierre Ossman 28517b0429dSPierre Ossman if (cmd.error) 286da7fbe58SPierre Ossman return cmd.error; 28717b0429dSPierre Ossman if (data.error) 288da7fbe58SPierre Ossman return data.error; 289da7fbe58SPierre Ossman 29017b0429dSPierre Ossman return 0; 291da7fbe58SPierre Ossman } 292da7fbe58SPierre Ossman 293af517150SDavid Brownell int mmc_send_csd(struct mmc_card *card, u32 *csd) 294af517150SDavid Brownell { 29578e48073SPierre Ossman int ret, i; 29678e48073SPierre Ossman 297af517150SDavid Brownell if (!mmc_host_is_spi(card->host)) 298af517150SDavid Brownell return mmc_send_cxd_native(card->host, card->rca << 16, 299af517150SDavid Brownell csd, MMC_SEND_CSD); 300af517150SDavid Brownell 30178e48073SPierre Ossman ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); 30278e48073SPierre Ossman if (ret) 30378e48073SPierre Ossman return ret; 30478e48073SPierre Ossman 30578e48073SPierre Ossman for (i = 0;i < 4;i++) 30678e48073SPierre Ossman csd[i] = be32_to_cpu(csd[i]); 30778e48073SPierre Ossman 30878e48073SPierre Ossman return 0; 309af517150SDavid Brownell } 310af517150SDavid Brownell 311af517150SDavid Brownell int mmc_send_cid(struct mmc_host *host, u32 *cid) 312af517150SDavid Brownell { 31378e48073SPierre Ossman int ret, i; 31478e48073SPierre Ossman 315af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 316af517150SDavid Brownell if (!host->card) 317af517150SDavid Brownell return -EINVAL; 318af517150SDavid Brownell return mmc_send_cxd_native(host, host->card->rca << 16, 319af517150SDavid Brownell cid, MMC_SEND_CID); 320af517150SDavid Brownell } 321af517150SDavid Brownell 32278e48073SPierre Ossman ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); 32378e48073SPierre Ossman if (ret) 32478e48073SPierre Ossman return ret; 32578e48073SPierre Ossman 32678e48073SPierre Ossman for (i = 0;i < 4;i++) 32778e48073SPierre Ossman cid[i] = be32_to_cpu(cid[i]); 32878e48073SPierre Ossman 32978e48073SPierre Ossman return 0; 330af517150SDavid Brownell } 331af517150SDavid Brownell 332af517150SDavid Brownell int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) 333af517150SDavid Brownell { 334af517150SDavid Brownell return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD, 335af517150SDavid Brownell ext_csd, 512); 336af517150SDavid Brownell } 337af517150SDavid Brownell 338af517150SDavid Brownell int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) 339af517150SDavid Brownell { 3401278dba1SChris Ball struct mmc_command cmd = {0}; 341af517150SDavid Brownell int err; 342af517150SDavid Brownell 343af517150SDavid Brownell cmd.opcode = MMC_SPI_READ_OCR; 344af517150SDavid Brownell cmd.arg = highcap ? (1 << 30) : 0; 345af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R3; 346af517150SDavid Brownell 347af517150SDavid Brownell err = mmc_wait_for_cmd(host, &cmd, 0); 348af517150SDavid Brownell 349af517150SDavid Brownell *ocrp = cmd.resp[1]; 350af517150SDavid Brownell return err; 351af517150SDavid Brownell } 352af517150SDavid Brownell 353af517150SDavid Brownell int mmc_spi_set_crc(struct mmc_host *host, int use_crc) 354af517150SDavid Brownell { 3551278dba1SChris Ball struct mmc_command cmd = {0}; 356af517150SDavid Brownell int err; 357af517150SDavid Brownell 358af517150SDavid Brownell cmd.opcode = MMC_SPI_CRC_ON_OFF; 359af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1; 360af517150SDavid Brownell cmd.arg = use_crc; 361af517150SDavid Brownell 362af517150SDavid Brownell err = mmc_wait_for_cmd(host, &cmd, 0); 363af517150SDavid Brownell if (!err) 364af517150SDavid Brownell host->use_spi_crc = use_crc; 365af517150SDavid Brownell return err; 366af517150SDavid Brownell } 367af517150SDavid Brownell 368d3a8d95dSAndrei Warkentin /** 369d3a8d95dSAndrei Warkentin * mmc_switch - modify EXT_CSD register 370d3a8d95dSAndrei Warkentin * @card: the MMC card associated with the data transfer 371d3a8d95dSAndrei Warkentin * @set: cmd set values 372d3a8d95dSAndrei Warkentin * @index: EXT_CSD register index 373d3a8d95dSAndrei Warkentin * @value: value to program into EXT_CSD register 374d3a8d95dSAndrei Warkentin * @timeout_ms: timeout (ms) for operation performed by register write, 375d3a8d95dSAndrei Warkentin * timeout of zero implies maximum possible timeout 376d3a8d95dSAndrei Warkentin * 377d3a8d95dSAndrei Warkentin * Modifies the EXT_CSD register for selected card. 378d3a8d95dSAndrei Warkentin */ 379d3a8d95dSAndrei Warkentin int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, 380d3a8d95dSAndrei Warkentin unsigned int timeout_ms) 381da7fbe58SPierre Ossman { 382da7fbe58SPierre Ossman int err; 3831278dba1SChris Ball struct mmc_command cmd = {0}; 384ef0b27d4SAdrian Hunter u32 status; 385da7fbe58SPierre Ossman 386da7fbe58SPierre Ossman BUG_ON(!card); 387da7fbe58SPierre Ossman BUG_ON(!card->host); 388da7fbe58SPierre Ossman 389da7fbe58SPierre Ossman cmd.opcode = MMC_SWITCH; 390da7fbe58SPierre Ossman cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | 391da7fbe58SPierre Ossman (index << 16) | 392da7fbe58SPierre Ossman (value << 8) | 393da7fbe58SPierre Ossman set; 394af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; 395d3a8d95dSAndrei Warkentin cmd.cmd_timeout_ms = timeout_ms; 396da7fbe58SPierre Ossman 397da7fbe58SPierre Ossman err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 39817b0429dSPierre Ossman if (err) 399da7fbe58SPierre Ossman return err; 400da7fbe58SPierre Ossman 401ef0b27d4SAdrian Hunter /* Must check status to be sure of no errors */ 402ef0b27d4SAdrian Hunter do { 403ef0b27d4SAdrian Hunter err = mmc_send_status(card, &status); 404ef0b27d4SAdrian Hunter if (err) 405ef0b27d4SAdrian Hunter return err; 406ef0b27d4SAdrian Hunter if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) 407ef0b27d4SAdrian Hunter break; 408ef0b27d4SAdrian Hunter if (mmc_host_is_spi(card->host)) 409ef0b27d4SAdrian Hunter break; 4107435bb79SJaehoon Chung } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); 411ef0b27d4SAdrian Hunter 412ef0b27d4SAdrian Hunter if (mmc_host_is_spi(card->host)) { 413ef0b27d4SAdrian Hunter if (status & R1_SPI_ILLEGAL_COMMAND) 414ef0b27d4SAdrian Hunter return -EBADMSG; 415ef0b27d4SAdrian Hunter } else { 416ef0b27d4SAdrian Hunter if (status & 0xFDFFA000) 417ef0b27d4SAdrian Hunter printk(KERN_WARNING "%s: unexpected status %#x after " 418ef0b27d4SAdrian Hunter "switch", mmc_hostname(card->host), status); 419ef0b27d4SAdrian Hunter if (status & R1_SWITCH_ERROR) 420ef0b27d4SAdrian Hunter return -EBADMSG; 421ef0b27d4SAdrian Hunter } 422ef0b27d4SAdrian Hunter 42317b0429dSPierre Ossman return 0; 424da7fbe58SPierre Ossman } 425d3a8d95dSAndrei Warkentin EXPORT_SYMBOL_GPL(mmc_switch); 426da7fbe58SPierre Ossman 427da7fbe58SPierre Ossman int mmc_send_status(struct mmc_card *card, u32 *status) 428da7fbe58SPierre Ossman { 429da7fbe58SPierre Ossman int err; 4301278dba1SChris Ball struct mmc_command cmd = {0}; 431da7fbe58SPierre Ossman 432da7fbe58SPierre Ossman BUG_ON(!card); 433da7fbe58SPierre Ossman BUG_ON(!card->host); 434da7fbe58SPierre Ossman 435da7fbe58SPierre Ossman cmd.opcode = MMC_SEND_STATUS; 436af517150SDavid Brownell if (!mmc_host_is_spi(card->host)) 437da7fbe58SPierre Ossman cmd.arg = card->rca << 16; 438af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; 439da7fbe58SPierre Ossman 440da7fbe58SPierre Ossman err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 44117b0429dSPierre Ossman if (err) 442da7fbe58SPierre Ossman return err; 443da7fbe58SPierre Ossman 444af517150SDavid Brownell /* NOTE: callers are required to understand the difference 445af517150SDavid Brownell * between "native" and SPI format status words! 446af517150SDavid Brownell */ 447da7fbe58SPierre Ossman if (status) 448da7fbe58SPierre Ossman *status = cmd.resp[0]; 449da7fbe58SPierre Ossman 45017b0429dSPierre Ossman return 0; 451da7fbe58SPierre Ossman } 452da7fbe58SPierre Ossman 45322113efdSAries Lee static int 45422113efdSAries Lee mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, 45522113efdSAries Lee u8 len) 45622113efdSAries Lee { 45724f5b53bSChris Ball struct mmc_request mrq = {0}; 4581278dba1SChris Ball struct mmc_command cmd = {0}; 459a61ad2b4SChris Ball struct mmc_data data = {0}; 46022113efdSAries Lee struct scatterlist sg; 46122113efdSAries Lee u8 *data_buf; 46222113efdSAries Lee u8 *test_buf; 46322113efdSAries Lee int i, err; 46422113efdSAries Lee static u8 testdata_8bit[8] = { 0x55, 0xaa, 0, 0, 0, 0, 0, 0 }; 46522113efdSAries Lee static u8 testdata_4bit[4] = { 0x5a, 0, 0, 0 }; 46622113efdSAries Lee 46722113efdSAries Lee /* dma onto stack is unsafe/nonportable, but callers to this 46822113efdSAries Lee * routine normally provide temporary on-stack buffers ... 46922113efdSAries Lee */ 47022113efdSAries Lee data_buf = kmalloc(len, GFP_KERNEL); 47122113efdSAries Lee if (!data_buf) 47222113efdSAries Lee return -ENOMEM; 47322113efdSAries Lee 47422113efdSAries Lee if (len == 8) 47522113efdSAries Lee test_buf = testdata_8bit; 47622113efdSAries Lee else if (len == 4) 47722113efdSAries Lee test_buf = testdata_4bit; 47822113efdSAries Lee else { 47922113efdSAries Lee printk(KERN_ERR "%s: Invalid bus_width %d\n", 48022113efdSAries Lee mmc_hostname(host), len); 48122113efdSAries Lee kfree(data_buf); 48222113efdSAries Lee return -EINVAL; 48322113efdSAries Lee } 48422113efdSAries Lee 48522113efdSAries Lee if (opcode == MMC_BUS_TEST_W) 48622113efdSAries Lee memcpy(data_buf, test_buf, len); 48722113efdSAries Lee 48822113efdSAries Lee mrq.cmd = &cmd; 48922113efdSAries Lee mrq.data = &data; 49022113efdSAries Lee cmd.opcode = opcode; 49122113efdSAries Lee cmd.arg = 0; 49222113efdSAries Lee 49322113efdSAries Lee /* NOTE HACK: the MMC_RSP_SPI_R1 is always correct here, but we 49422113efdSAries Lee * rely on callers to never use this with "native" calls for reading 49522113efdSAries Lee * CSD or CID. Native versions of those commands use the R2 type, 49622113efdSAries Lee * not R1 plus a data block. 49722113efdSAries Lee */ 49822113efdSAries Lee cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; 49922113efdSAries Lee 50022113efdSAries Lee data.blksz = len; 50122113efdSAries Lee data.blocks = 1; 50222113efdSAries Lee if (opcode == MMC_BUS_TEST_R) 50322113efdSAries Lee data.flags = MMC_DATA_READ; 50422113efdSAries Lee else 50522113efdSAries Lee data.flags = MMC_DATA_WRITE; 50622113efdSAries Lee 50722113efdSAries Lee data.sg = &sg; 50822113efdSAries Lee data.sg_len = 1; 50922113efdSAries Lee sg_init_one(&sg, data_buf, len); 51022113efdSAries Lee mmc_wait_for_req(host, &mrq); 51122113efdSAries Lee err = 0; 51222113efdSAries Lee if (opcode == MMC_BUS_TEST_R) { 51322113efdSAries Lee for (i = 0; i < len / 4; i++) 51422113efdSAries Lee if ((test_buf[i] ^ data_buf[i]) != 0xff) { 51522113efdSAries Lee err = -EIO; 51622113efdSAries Lee break; 51722113efdSAries Lee } 51822113efdSAries Lee } 51922113efdSAries Lee kfree(data_buf); 52022113efdSAries Lee 52122113efdSAries Lee if (cmd.error) 52222113efdSAries Lee return cmd.error; 52322113efdSAries Lee if (data.error) 52422113efdSAries Lee return data.error; 52522113efdSAries Lee 52622113efdSAries Lee return err; 52722113efdSAries Lee } 52822113efdSAries Lee 52922113efdSAries Lee int mmc_bus_test(struct mmc_card *card, u8 bus_width) 53022113efdSAries Lee { 53122113efdSAries Lee int err, width; 53222113efdSAries Lee 53322113efdSAries Lee if (bus_width == MMC_BUS_WIDTH_8) 53422113efdSAries Lee width = 8; 53522113efdSAries Lee else if (bus_width == MMC_BUS_WIDTH_4) 53622113efdSAries Lee width = 4; 53722113efdSAries Lee else if (bus_width == MMC_BUS_WIDTH_1) 53822113efdSAries Lee return 0; /* no need for test */ 53922113efdSAries Lee else 54022113efdSAries Lee return -EINVAL; 54122113efdSAries Lee 54222113efdSAries Lee /* 54322113efdSAries Lee * Ignore errors from BUS_TEST_W. BUS_TEST_R will fail if there 54422113efdSAries Lee * is a problem. This improves chances that the test will work. 54522113efdSAries Lee */ 54622113efdSAries Lee mmc_send_bus_test(card, card->host, MMC_BUS_TEST_W, width); 54722113efdSAries Lee err = mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width); 54822113efdSAries Lee return err; 54922113efdSAries Lee } 550