static char *maptype(struct mmc_command *cmd) { switch (mmc_spi_resp_type(cmd)) { case MMC_RSP_SPI_R1: return "R1"; case MMC_RSP_SPI_R1B: return "R1B"; case MMC_RSP_SPI_R2: return "R2/R5"; case MMC_RSP_SPI_R3: return "R3/R4/R7"; default: return "?"; } }
/* return zero, else negative errno after setting cmd->error */ static int mmc_spi_response_get(struct mmc_spi_host *host, struct mmc_command *cmd, int cs_on) { u8 *cp = host->data->status; u8 *end = cp + host->t.len; int value = 0; char tag[32]; snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", cmd->opcode, maptype(cmd)); /* Except for data block reads, the whole response will already * be stored in the scratch buffer. It's somewhere after the * command and the first byte we read after it. We ignore that * first byte. After STOP_TRANSMISSION command it may include * two data bits, but otherwise it's all ones. */ cp += 8; while (cp < end && *cp == 0xff) cp++; /* Data block reads (R1 response types) may need more data... */ if (cp == end) { unsigned i; cp = host->data->status; /* Card sends N(CR) (== 1..8) bytes of all-ones then one * status byte ... and we already scanned 2 bytes. * * REVISIT block read paths use nasty byte-at-a-time I/O * so it can always DMA directly into the target buffer. * It'd probably be better to memcpy() the first chunk and * avoid extra i/o calls... */ for (i = 2; i < 9; i++) { value = mmc_spi_readbytes(host, 1); if (value < 0) goto done; if (*cp != 0xff) goto checkstatus; } value = -ETIMEDOUT; goto done; } checkstatus: if (*cp & 0x80) { dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n", tag, *cp); value = -EBADR; goto done; } cmd->resp[0] = *cp++; cmd->error = 0; /* Status byte: the entire seven-bit R1 response. */ if (cmd->resp[0] != 0) { if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS | R1_SPI_ILLEGAL_COMMAND) & cmd->resp[0]) value = -EINVAL; else if (R1_SPI_COM_CRC & cmd->resp[0]) value = -EILSEQ; else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET) & cmd->resp[0]) value = -EIO; /* else R1_SPI_IDLE, "it's resetting" */ } switch (mmc_spi_resp_type(cmd)) { /* SPI R1B == R1 + busy; STOP_TRANSMISSION (for multiblock reads) * and less-common stuff like various erase operations. */ case MMC_RSP_SPI_R1B: /* maybe we read all the busy tokens already */ while (cp < end && *cp == 0) cp++; if (cp == end) mmc_spi_wait_unbusy(host, r1b_timeout); break; /* SPI R2 == R1 + second status byte; SEND_STATUS * SPI R5 == R1 + data byte; IO_RW_DIRECT */ case MMC_RSP_SPI_R2: cmd->resp[0] |= *cp << 8; break; /* SPI R3, R4, or R7 == R1 + 4 bytes */ case MMC_RSP_SPI_R3: cmd->resp[1] = be32_to_cpu(get_unaligned((u32 *)cp)); break; /* SPI R1 == just one status byte */ case MMC_RSP_SPI_R1: break; default: dev_dbg(&host->spi->dev, "bad response type %04x\n", mmc_spi_resp_type(cmd)); if (value >= 0) value = -EINVAL; goto done; } if (value < 0) dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n", tag, cmd->resp[0], cmd->resp[1]); /* disable chipselect on errors and some success cases */ if (value >= 0 && cs_on) return value; done: if (value < 0) cmd->error = value; mmc_cs_off(host); return value; }