diff options
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r-- | drivers/mmc/card/block.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 93fe2e5dd616..e38d5a3b2a89 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -151,17 +151,19 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | |||
151 | 151 | ||
152 | cmd.opcode = MMC_APP_CMD; | 152 | cmd.opcode = MMC_APP_CMD; |
153 | cmd.arg = card->rca << 16; | 153 | cmd.arg = card->rca << 16; |
154 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 154 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
155 | 155 | ||
156 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | 156 | err = mmc_wait_for_cmd(card->host, &cmd, 0); |
157 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) | 157 | if (err) |
158 | return (u32)-1; | ||
159 | if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) | ||
158 | return (u32)-1; | 160 | return (u32)-1; |
159 | 161 | ||
160 | memset(&cmd, 0, sizeof(struct mmc_command)); | 162 | memset(&cmd, 0, sizeof(struct mmc_command)); |
161 | 163 | ||
162 | cmd.opcode = SD_APP_SEND_NUM_WR_BLKS; | 164 | cmd.opcode = SD_APP_SEND_NUM_WR_BLKS; |
163 | cmd.arg = 0; | 165 | cmd.arg = 0; |
164 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 166 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; |
165 | 167 | ||
166 | memset(&data, 0, sizeof(struct mmc_data)); | 168 | memset(&data, 0, sizeof(struct mmc_data)); |
167 | 169 | ||
@@ -192,7 +194,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | |||
192 | 194 | ||
193 | mmc_wait_for_req(card->host, &mrq); | 195 | mmc_wait_for_req(card->host, &mrq); |
194 | 196 | ||
195 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) | 197 | if (cmd.error || data.error) |
196 | return (u32)-1; | 198 | return (u32)-1; |
197 | 199 | ||
198 | blocks = ntohl(blocks); | 200 | blocks = ntohl(blocks); |
@@ -220,17 +222,15 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
220 | brq.cmd.arg = req->sector; | 222 | brq.cmd.arg = req->sector; |
221 | if (!mmc_card_blockaddr(card)) | 223 | if (!mmc_card_blockaddr(card)) |
222 | brq.cmd.arg <<= 9; | 224 | brq.cmd.arg <<= 9; |
223 | brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 225 | brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; |
224 | brq.data.blksz = 1 << md->block_bits; | 226 | brq.data.blksz = 1 << md->block_bits; |
225 | brq.stop.opcode = MMC_STOP_TRANSMISSION; | 227 | brq.stop.opcode = MMC_STOP_TRANSMISSION; |
226 | brq.stop.arg = 0; | 228 | brq.stop.arg = 0; |
227 | brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; | 229 | brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; |
228 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); | 230 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); |
229 | if (brq.data.blocks > card->host->max_blk_count) | 231 | if (brq.data.blocks > card->host->max_blk_count) |
230 | brq.data.blocks = card->host->max_blk_count; | 232 | brq.data.blocks = card->host->max_blk_count; |
231 | 233 | ||
232 | mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ); | ||
233 | |||
234 | /* | 234 | /* |
235 | * If the host doesn't support multiple block writes, force | 235 | * If the host doesn't support multiple block writes, force |
236 | * block writes to single block. SD cards are excepted from | 236 | * block writes to single block. SD cards are excepted from |
@@ -243,8 +243,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
243 | brq.data.blocks = 1; | 243 | brq.data.blocks = 1; |
244 | 244 | ||
245 | if (brq.data.blocks > 1) { | 245 | if (brq.data.blocks > 1) { |
246 | brq.data.flags |= MMC_DATA_MULTI; | 246 | /* SPI multiblock writes terminate using a special |
247 | brq.mrq.stop = &brq.stop; | 247 | * token, not a STOP_TRANSMISSION request. |
248 | */ | ||
249 | if (!mmc_host_is_spi(card->host) | ||
250 | || rq_data_dir(req) == READ) | ||
251 | brq.mrq.stop = &brq.stop; | ||
248 | readcmd = MMC_READ_MULTIPLE_BLOCK; | 252 | readcmd = MMC_READ_MULTIPLE_BLOCK; |
249 | writecmd = MMC_WRITE_MULTIPLE_BLOCK; | 253 | writecmd = MMC_WRITE_MULTIPLE_BLOCK; |
250 | } else { | 254 | } else { |
@@ -261,6 +265,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
261 | brq.data.flags |= MMC_DATA_WRITE; | 265 | brq.data.flags |= MMC_DATA_WRITE; |
262 | } | 266 | } |
263 | 267 | ||
268 | mmc_set_data_timeout(&brq.data, card); | ||
269 | |||
264 | brq.data.sg = mq->sg; | 270 | brq.data.sg = mq->sg; |
265 | brq.data.sg_len = mmc_queue_map_sg(mq); | 271 | brq.data.sg_len = mmc_queue_map_sg(mq); |
266 | 272 | ||
@@ -302,7 +308,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
302 | goto cmd_err; | 308 | goto cmd_err; |
303 | } | 309 | } |
304 | 310 | ||
305 | if (rq_data_dir(req) != READ) { | 311 | if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { |
306 | do { | 312 | do { |
307 | int err; | 313 | int err; |
308 | 314 | ||
@@ -510,7 +516,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
510 | mmc_claim_host(card->host); | 516 | mmc_claim_host(card->host); |
511 | cmd.opcode = MMC_SET_BLOCKLEN; | 517 | cmd.opcode = MMC_SET_BLOCKLEN; |
512 | cmd.arg = 1 << md->block_bits; | 518 | cmd.arg = 1 << md->block_bits; |
513 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 519 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
514 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 520 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
515 | mmc_release_host(card->host); | 521 | mmc_release_host(card->host); |
516 | 522 | ||