From e92251762d02a46177d4105d1744041e3f8bc465 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 2 Feb 2006 12:23:12 +0000 Subject: [PATCH] [MMC] Add MMC command type flags Some hosts need to know the command type, so pass it via a set of flags in cmd->flags. Signed-off-by: Russell King --- drivers/mmc/au1xmmc.c | 59 ++++++++++++++++++------------------ drivers/mmc/mmc.c | 28 ++++++++--------- drivers/mmc/mmc_block.c | 8 ++--- drivers/mmc/mmci.c | 11 ++----- drivers/mmc/pxamci.c | 9 +++--- drivers/mmc/wbsd.c | 8 ++--- include/linux/mmc/mmc.h | 35 +++++++++++++-------- include/linux/mmc/protocol.h | 2 +- 8 files changed, 84 insertions(+), 76 deletions(-) diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index aaf0463805..227c39a7c1 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); - switch(cmd->flags) { + switch (mmc_rsp_type(cmd->flags)) { case MMC_RSP_R1: mmccmd |= SD_CMD_RT_1; break; @@ -483,34 +483,35 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) cmd = mrq->cmd; cmd->error = MMC_ERR_NONE; - if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) { - - /* Techincally, we should be getting all 48 bits of the response - * (SD_RESP1 + SD_RESP2), but because our response omits the CRC, - * our data ends up being shifted 8 bits to the right. In this case, - * that means that the OSR data starts at bit 31, so we can just - * read RESP0 and return that - */ - - cmd->resp[0] = au_readl(host->iobase + SD_RESP0); - } - else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) { - u32 r[4]; - int i; - - r[0] = au_readl(host->iobase + SD_RESP3); - r[1] = au_readl(host->iobase + SD_RESP2); - r[2] = au_readl(host->iobase + SD_RESP1); - r[3] = au_readl(host->iobase + SD_RESP0); - - /* The CRC is omitted from the response, so really we only got - * 120 bytes, but the engine expects 128 bits, so we have to shift - * things up - */ - - for(i = 0; i < 4; i++) { - cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; - if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) { + u32 r[4]; + int i; + + r[0] = au_readl(host->iobase + SD_RESP3); + r[1] = au_readl(host->iobase + SD_RESP2); + r[2] = au_readl(host->iobase + SD_RESP1); + r[3] = au_readl(host->iobase + SD_RESP0); + + /* The CRC is omitted from the response, so really + * we only got 120 bytes, but the engine expects + * 128 bits, so we have to shift things up + */ + + for(i = 0; i < 4; i++) { + cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; + if (i != 3) + cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; + } + } else { + /* Techincally, we should be getting all 48 bits of + * the response (SD_RESP1 + SD_RESP2), but because + * our response omits the CRC, our data ends up + * being shifted 8 bits to the right. In this case, + * that means that the OSR data starts at bit 31, + * so we can just read RESP0 and return that + */ + cmd->resp[0] = au_readl(host->iobase + SD_RESP0); } } diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index bfca5c176e..1888060c5e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -211,7 +211,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, appcmd.opcode = MMC_APP_CMD; appcmd.arg = rca << 16; - appcmd.flags = MMC_RSP_R1; + appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; appcmd.retries = 0; memset(appcmd.resp, 0, sizeof(appcmd.resp)); appcmd.data = NULL; @@ -331,7 +331,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) cmd.opcode = MMC_SELECT_CARD; cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); if (err != MMC_ERR_NONE) @@ -358,7 +358,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) struct mmc_command cmd; cmd.opcode = SD_APP_SET_BUS_WIDTH; cmd.arg = SD_BUS_WIDTH_4; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_app_cmd(host, card->rca, &cmd, CMD_RETRIES); @@ -386,7 +386,7 @@ static void mmc_deselect_cards(struct mmc_host *host) cmd.opcode = MMC_SELECT_CARD; cmd.arg = 0; - cmd.flags = MMC_RSP_NONE; + cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; mmc_wait_for_cmd(host, &cmd, 0); } @@ -677,7 +677,7 @@ static void mmc_idle_cards(struct mmc_host *host) cmd.opcode = MMC_GO_IDLE_STATE; cmd.arg = 0; - cmd.flags = MMC_RSP_NONE; + cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; mmc_wait_for_cmd(host, &cmd, 0); @@ -738,7 +738,7 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) cmd.opcode = MMC_SEND_OP_COND; cmd.arg = ocr; - cmd.flags = MMC_RSP_R3; + cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; for (i = 100; i; i--) { err = mmc_wait_for_cmd(host, &cmd, 0); @@ -766,7 +766,7 @@ static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) cmd.opcode = SD_APP_OP_COND; cmd.arg = ocr; - cmd.flags = MMC_RSP_R3; + cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; for (i = 100; i; i--) { err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); @@ -805,7 +805,7 @@ static void mmc_discover_cards(struct mmc_host *host) cmd.opcode = MMC_ALL_SEND_CID; cmd.arg = 0; - cmd.flags = MMC_RSP_R2; + cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); if (err == MMC_ERR_TIMEOUT) { @@ -835,7 +835,7 @@ static void mmc_discover_cards(struct mmc_host *host) cmd.opcode = SD_SEND_RELATIVE_ADDR; cmd.arg = 0; - cmd.flags = MMC_RSP_R6; + cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); if (err != MMC_ERR_NONE) @@ -856,7 +856,7 @@ static void mmc_discover_cards(struct mmc_host *host) } else { cmd.opcode = MMC_SET_RELATIVE_ADDR; cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); if (err != MMC_ERR_NONE) @@ -878,7 +878,7 @@ static void mmc_read_csds(struct mmc_host *host) cmd.opcode = MMC_SEND_CSD; cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R2; + cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); if (err != MMC_ERR_NONE) { @@ -920,7 +920,7 @@ static void mmc_read_scrs(struct mmc_host *host) cmd.opcode = MMC_APP_CMD; cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(host, &cmd, 0); if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { @@ -932,7 +932,7 @@ static void mmc_read_scrs(struct mmc_host *host) cmd.opcode = SD_APP_SEND_SCR; cmd.arg = 0; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; memset(&data, 0, sizeof(struct mmc_data)); @@ -1003,7 +1003,7 @@ static void mmc_check_cards(struct mmc_host *host) cmd.opcode = MMC_SEND_STATUS; cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); if (err == MMC_ERR_NONE) diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 5b014c370e..8eb2a2ede6 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -171,14 +171,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.mrq.data = &brq.data; brq.cmd.arg = req->sector << 9; - brq.cmd.flags = MMC_RSP_R1; + brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; brq.data.timeout_ns = card->csd.tacc_ns * 10; brq.data.timeout_clks = card->csd.tacc_clks * 10; brq.data.blksz_bits = md->block_bits; brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); brq.stop.opcode = MMC_STOP_TRANSMISSION; brq.stop.arg = 0; - brq.stop.flags = MMC_RSP_R1B; + brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; if (rq_data_dir(req) == READ) { brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; @@ -223,7 +223,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) cmd.opcode = MMC_SEND_STATUS; cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 5); if (err) { printk(KERN_ERR "%s: error %d requesting status\n", @@ -430,7 +430,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) mmc_card_claim_host(card); cmd.opcode = MMC_SET_BLOCKLEN; cmd.arg = 1 << md->block_bits; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 5); mmc_card_release_host(card); diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 634ef53e85..37ee7f8dc8 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -124,15 +124,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) } c |= cmd->opcode | MCI_CPSM_ENABLE; - switch (cmd->flags & MMC_RSP_MASK) { - case MMC_RSP_NONE: - default: - break; - case MMC_RSP_LONG: - c |= MCI_CPSM_LONGRSP; - case MMC_RSP_SHORT: + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) + c |= MCI_CPSM_LONGRSP; c |= MCI_CPSM_RESPONSE; - break; } if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index ee8f8a0420..285d7d0680 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -178,14 +178,15 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, if (cmd->flags & MMC_RSP_BUSY) cmdat |= CMDAT_BUSY; - switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) { - case MMC_RSP_SHORT | MMC_RSP_CRC: +#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) + switch (RSP_TYPE(mmc_resp_type(cmd))) { + case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */ cmdat |= CMDAT_RESP_SHORT; break; - case MMC_RSP_SHORT: + case RSP_TYPE(MMC_RSP_R3): cmdat |= CMDAT_RESP_R3; break; - case MMC_RSP_LONG | MMC_RSP_CRC: + case RSP_TYPE(MMC_RSP_R2): cmdat |= CMDAT_RESP_R2; break; default: diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index f257576253..3be397d436 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -459,7 +459,7 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) /* * Do we expect a reply? */ - if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) { + if (cmd->flags & MMC_RSP_PRESENT) { /* * Read back status. */ @@ -476,10 +476,10 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) cmd->error = MMC_ERR_BADCRC; /* All ok */ else { - if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) - wbsd_get_short_reply(host, cmd); - else + if (cmd->flags & MMC_RSP_136) wbsd_get_long_reply(host, cmd); + else + wbsd_get_short_reply(host, cmd); } } diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index ccd3e13de1..f38872abc1 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -21,24 +21,35 @@ struct mmc_command { u32 arg; u32 resp[4]; unsigned int flags; /* expected response type */ -#define MMC_RSP_NONE (0 << 0) -#define MMC_RSP_SHORT (1 << 0) -#define MMC_RSP_LONG (2 << 0) -#define MMC_RSP_MASK (3 << 0) -#define MMC_RSP_CRC (1 << 3) /* expect valid crc */ -#define MMC_RSP_BUSY (1 << 4) /* card may send busy */ -#define MMC_RSP_OPCODE (1 << 5) /* response contains opcode */ +#define MMC_RSP_PRESENT (1 << 0) +#define MMC_RSP_136 (1 << 1) /* 136 bit response */ +#define MMC_RSP_CRC (1 << 2) /* expect valid crc */ +#define MMC_RSP_BUSY (1 << 3) /* card may send busy */ +#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ +#define MMC_CMD_MASK (3 << 5) /* command type */ +#define MMC_CMD_AC (0 << 5) +#define MMC_CMD_ADTC (1 << 5) +#define MMC_CMD_BC (2 << 5) +#define MMC_CMD_BCR (3 << 5) /* * These are the response types, and correspond to valid bit * patterns of the above flags. One additional valid pattern * is all zeros, which means we don't expect a response. */ -#define MMC_RSP_R1 (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE) -#define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) -#define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC) -#define MMC_RSP_R3 (MMC_RSP_SHORT) -#define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC) +#define MMC_RSP_NONE (0) +#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) +#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) +#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) +#define MMC_RSP_R3 (MMC_RSP_PRESENT) +#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC) + +#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) + +/* + * These are the command types. + */ +#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_TYPE) unsigned int retries; /* max number of retries */ unsigned int error; /* command error */ diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h index a14dc30654..81c3f77f65 100644 --- a/include/linux/mmc/protocol.h +++ b/include/linux/mmc/protocol.h @@ -79,7 +79,7 @@ /* SD commands type argument response */ /* class 8 */ /* This is basically the same command as for MMC with some quirks. */ -#define SD_SEND_RELATIVE_ADDR 3 /* ac R6 */ +#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ /* Application commands */ #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ -- 2.39.5