diff options
-rw-r--r-- | drivers/mmc/host/rtsx_pci_sdmmc.c | 234 |
1 files changed, 138 insertions, 96 deletions
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index b96c9ed22f8f..0217db60e115 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | #include <linux/mmc/mmc.h> | 29 | #include <linux/mmc/mmc.h> |
30 | #include <linux/mmc/sd.h> | 30 | #include <linux/mmc/sd.h> |
31 | #include <linux/mmc/sdio.h> | ||
31 | #include <linux/mmc/card.h> | 32 | #include <linux/mmc/card.h> |
32 | #include <linux/mfd/rtsx_pci.h> | 33 | #include <linux/mfd/rtsx_pci.h> |
33 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
@@ -70,6 +71,9 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc *host) | |||
70 | SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); | 71 | SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); |
71 | } | 72 | } |
72 | 73 | ||
74 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | ||
75 | struct mmc_command *cmd); | ||
76 | |||
73 | #ifdef DEBUG | 77 | #ifdef DEBUG |
74 | static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end) | 78 | static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end) |
75 | { | 79 | { |
@@ -214,34 +218,27 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | |||
214 | data->host_cookie = 0; | 218 | data->host_cookie = 0; |
215 | } | 219 | } |
216 | 220 | ||
217 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | 221 | static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command *cmd, |
218 | u8 *buf, int buf_len, int timeout) | 222 | u16 byte_cnt, u8 *buf, int buf_len, int timeout) |
219 | { | 223 | { |
220 | struct rtsx_pcr *pcr = host->pcr; | 224 | struct rtsx_pcr *pcr = host->pcr; |
221 | int err, i; | 225 | int err; |
222 | u8 trans_mode; | 226 | u8 trans_mode; |
223 | 227 | ||
224 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40); | 228 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
229 | __func__, cmd->opcode, cmd->arg); | ||
225 | 230 | ||
226 | if (!buf) | 231 | if (!buf) |
227 | buf_len = 0; | 232 | buf_len = 0; |
228 | 233 | ||
229 | if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK) | 234 | if (cmd->opcode == MMC_SEND_TUNING_BLOCK) |
230 | trans_mode = SD_TM_AUTO_TUNING; | 235 | trans_mode = SD_TM_AUTO_TUNING; |
231 | else | 236 | else |
232 | trans_mode = SD_TM_NORMAL_READ; | 237 | trans_mode = SD_TM_NORMAL_READ; |
233 | 238 | ||
234 | rtsx_pci_init_cmd(pcr); | 239 | rtsx_pci_init_cmd(pcr); |
235 | 240 | sd_cmd_set_sd_cmd(pcr, cmd); | |
236 | for (i = 0; i < 5; i++) | 241 | sd_cmd_set_data_len(pcr, 1, byte_cnt); |
237 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]); | ||
238 | |||
239 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); | ||
240 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, | ||
241 | 0xFF, (u8)(byte_cnt >> 8)); | ||
242 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); | ||
243 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); | ||
244 | |||
245 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | 242 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, |
246 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 243 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | |
247 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | 244 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); |
@@ -274,16 +271,23 @@ static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | |||
274 | return 0; | 271 | return 0; |
275 | } | 272 | } |
276 | 273 | ||
277 | static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | 274 | static int sd_write_data(struct realtek_pci_sdmmc *host, |
278 | u8 *buf, int buf_len, int timeout) | 275 | struct mmc_command *cmd, u16 byte_cnt, u8 *buf, int buf_len, |
276 | int timeout) | ||
279 | { | 277 | { |
280 | struct rtsx_pcr *pcr = host->pcr; | 278 | struct rtsx_pcr *pcr = host->pcr; |
281 | int err, i; | 279 | int err; |
282 | u8 trans_mode; | 280 | |
281 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
282 | __func__, cmd->opcode, cmd->arg); | ||
283 | 283 | ||
284 | if (!buf) | 284 | if (!buf) |
285 | buf_len = 0; | 285 | buf_len = 0; |
286 | 286 | ||
287 | sd_send_cmd_get_rsp(host, cmd); | ||
288 | if (cmd->error) | ||
289 | return cmd->error; | ||
290 | |||
287 | if (buf && buf_len) { | 291 | if (buf && buf_len) { |
288 | err = rtsx_pci_write_ppbuf(pcr, buf, buf_len); | 292 | err = rtsx_pci_write_ppbuf(pcr, buf, buf_len); |
289 | if (err < 0) { | 293 | if (err < 0) { |
@@ -293,30 +297,13 @@ static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | |||
293 | } | 297 | } |
294 | } | 298 | } |
295 | 299 | ||
296 | trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3; | ||
297 | rtsx_pci_init_cmd(pcr); | 300 | rtsx_pci_init_cmd(pcr); |
298 | 301 | sd_cmd_set_data_len(pcr, 1, byte_cnt); | |
299 | if (cmd) { | ||
300 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__, | ||
301 | cmd[0] - 0x40); | ||
302 | |||
303 | for (i = 0; i < 5; i++) | ||
304 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
305 | SD_CMD0 + i, 0xFF, cmd[i]); | ||
306 | } | ||
307 | |||
308 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); | ||
309 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, | ||
310 | 0xFF, (u8)(byte_cnt >> 8)); | ||
311 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); | ||
312 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); | ||
313 | |||
314 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | 302 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, |
315 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 303 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | |
316 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | 304 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0); |
317 | |||
318 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | 305 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, |
319 | trans_mode | SD_TRANSFER_START); | 306 | SD_TRANSFER_START | SD_TM_AUTO_WRITE_3); |
320 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | 307 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, |
321 | SD_TRANSFER_END, SD_TRANSFER_END); | 308 | SD_TRANSFER_END, SD_TRANSFER_END); |
322 | 309 | ||
@@ -449,71 +436,113 @@ out: | |||
449 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); | 436 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); |
450 | } | 437 | } |
451 | 438 | ||
452 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | 439 | static int sd_read_long_data(struct realtek_pci_sdmmc *host, |
440 | struct mmc_request *mrq) | ||
453 | { | 441 | { |
454 | struct rtsx_pcr *pcr = host->pcr; | 442 | struct rtsx_pcr *pcr = host->pcr; |
455 | struct mmc_host *mmc = host->mmc; | 443 | struct mmc_host *mmc = host->mmc; |
456 | struct mmc_card *card = mmc->card; | 444 | struct mmc_card *card = mmc->card; |
445 | struct mmc_command *cmd = mrq->cmd; | ||
457 | struct mmc_data *data = mrq->data; | 446 | struct mmc_data *data = mrq->data; |
458 | int uhs = mmc_card_uhs(card); | 447 | int uhs = mmc_card_uhs(card); |
459 | int read = (data->flags & MMC_DATA_READ) ? 1 : 0; | 448 | u8 cfg2 = 0; |
460 | u8 cfg2, trans_mode; | ||
461 | int err; | 449 | int err; |
450 | int resp_type; | ||
462 | size_t data_len = data->blksz * data->blocks; | 451 | size_t data_len = data->blksz * data->blocks; |
463 | 452 | ||
464 | if (read) { | 453 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
465 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 454 | __func__, cmd->opcode, cmd->arg); |
466 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; | 455 | |
467 | trans_mode = SD_TM_AUTO_READ_3; | 456 | resp_type = sd_response_type(cmd); |
468 | } else { | 457 | if (resp_type < 0) |
469 | cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 458 | return resp_type; |
470 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; | ||
471 | trans_mode = SD_TM_AUTO_WRITE_3; | ||
472 | } | ||
473 | 459 | ||
474 | if (!uhs) | 460 | if (!uhs) |
475 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; | 461 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; |
476 | 462 | ||
477 | rtsx_pci_init_cmd(pcr); | 463 | rtsx_pci_init_cmd(pcr); |
478 | 464 | sd_cmd_set_sd_cmd(pcr, cmd); | |
479 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); | 465 | sd_cmd_set_data_len(pcr, data->blocks, data->blksz); |
480 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); | ||
481 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, | ||
482 | 0xFF, (u8)data->blocks); | ||
483 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, | ||
484 | 0xFF, (u8)(data->blocks >> 8)); | ||
485 | |||
486 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, | 466 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, |
487 | DMA_DONE_INT, DMA_DONE_INT); | 467 | DMA_DONE_INT, DMA_DONE_INT); |
488 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, | 468 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, |
489 | 0xFF, (u8)(data_len >> 24)); | 469 | 0xFF, (u8)(data_len >> 24)); |
490 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, | 470 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, |
491 | 0xFF, (u8)(data_len >> 16)); | 471 | 0xFF, (u8)(data_len >> 16)); |
492 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, | 472 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, |
493 | 0xFF, (u8)(data_len >> 8)); | 473 | 0xFF, (u8)(data_len >> 8)); |
494 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); | 474 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); |
495 | if (read) { | 475 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, |
496 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | 476 | 0x03 | DMA_PACK_SIZE_MASK, |
497 | 0x03 | DMA_PACK_SIZE_MASK, | 477 | DMA_DIR_FROM_CARD | DMA_EN | DMA_512); |
498 | DMA_DIR_FROM_CARD | DMA_EN | DMA_512); | 478 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
499 | } else { | 479 | 0x01, RING_BUFFER); |
500 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | 480 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2 | resp_type); |
501 | 0x03 | DMA_PACK_SIZE_MASK, | 481 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, |
502 | DMA_DIR_TO_CARD | DMA_EN | DMA_512); | 482 | SD_TRANSFER_START | SD_TM_AUTO_READ_2); |
483 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
484 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
485 | rtsx_pci_send_cmd_no_wait(pcr); | ||
486 | |||
487 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, 1, 10000); | ||
488 | if (err < 0) { | ||
489 | sd_print_debug_regs(host); | ||
490 | sd_clear_error(host); | ||
491 | return err; | ||
503 | } | 492 | } |
504 | 493 | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static int sd_write_long_data(struct realtek_pci_sdmmc *host, | ||
498 | struct mmc_request *mrq) | ||
499 | { | ||
500 | struct rtsx_pcr *pcr = host->pcr; | ||
501 | struct mmc_host *mmc = host->mmc; | ||
502 | struct mmc_card *card = mmc->card; | ||
503 | struct mmc_command *cmd = mrq->cmd; | ||
504 | struct mmc_data *data = mrq->data; | ||
505 | int uhs = mmc_card_uhs(card); | ||
506 | u8 cfg2; | ||
507 | int err; | ||
508 | size_t data_len = data->blksz * data->blocks; | ||
509 | |||
510 | sd_send_cmd_get_rsp(host, cmd); | ||
511 | if (cmd->error) | ||
512 | return cmd->error; | ||
513 | |||
514 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
515 | __func__, cmd->opcode, cmd->arg); | ||
516 | |||
517 | cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
518 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; | ||
519 | |||
520 | if (!uhs) | ||
521 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; | ||
522 | |||
523 | rtsx_pci_init_cmd(pcr); | ||
524 | sd_cmd_set_data_len(pcr, data->blocks, data->blksz); | ||
525 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, | ||
526 | DMA_DONE_INT, DMA_DONE_INT); | ||
527 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, | ||
528 | 0xFF, (u8)(data_len >> 24)); | ||
529 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, | ||
530 | 0xFF, (u8)(data_len >> 16)); | ||
531 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, | ||
532 | 0xFF, (u8)(data_len >> 8)); | ||
533 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); | ||
534 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | ||
535 | 0x03 | DMA_PACK_SIZE_MASK, | ||
536 | DMA_DIR_TO_CARD | DMA_EN | DMA_512); | ||
505 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, | 537 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
506 | 0x01, RING_BUFFER); | 538 | 0x01, RING_BUFFER); |
507 | |||
508 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2); | 539 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2); |
509 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | 540 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, |
510 | trans_mode | SD_TRANSFER_START); | 541 | SD_TRANSFER_START | SD_TM_AUTO_WRITE_3); |
511 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | 542 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, |
512 | SD_TRANSFER_END, SD_TRANSFER_END); | 543 | SD_TRANSFER_END, SD_TRANSFER_END); |
513 | |||
514 | rtsx_pci_send_cmd_no_wait(pcr); | 544 | rtsx_pci_send_cmd_no_wait(pcr); |
515 | 545 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, 0, 10000); | |
516 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read, 10000); | ||
517 | if (err < 0) { | 546 | if (err < 0) { |
518 | sd_clear_error(host); | 547 | sd_clear_error(host); |
519 | return err; | 548 | return err; |
@@ -522,6 +551,16 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | |||
522 | return 0; | 551 | return 0; |
523 | } | 552 | } |
524 | 553 | ||
554 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | ||
555 | { | ||
556 | struct mmc_data *data = mrq->data; | ||
557 | |||
558 | if (data->flags & MMC_DATA_READ) | ||
559 | return sd_read_long_data(host, mrq); | ||
560 | |||
561 | return sd_write_long_data(host, mrq); | ||
562 | } | ||
563 | |||
525 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) | 564 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) |
526 | { | 565 | { |
527 | rtsx_pci_write_register(host->pcr, SD_CFG1, | 566 | rtsx_pci_write_register(host->pcr, SD_CFG1, |
@@ -539,10 +578,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
539 | { | 578 | { |
540 | struct mmc_command *cmd = mrq->cmd; | 579 | struct mmc_command *cmd = mrq->cmd; |
541 | struct mmc_data *data = mrq->data; | 580 | struct mmc_data *data = mrq->data; |
542 | u8 _cmd[5], *buf; | 581 | u8 *buf; |
543 | |||
544 | _cmd[0] = 0x40 | (u8)cmd->opcode; | ||
545 | put_unaligned_be32(cmd->arg, (u32 *)(&_cmd[1])); | ||
546 | 582 | ||
547 | buf = kzalloc(data->blksz, GFP_NOIO); | 583 | buf = kzalloc(data->blksz, GFP_NOIO); |
548 | if (!buf) { | 584 | if (!buf) { |
@@ -554,7 +590,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
554 | if (host->initial_mode) | 590 | if (host->initial_mode) |
555 | sd_disable_initial_mode(host); | 591 | sd_disable_initial_mode(host); |
556 | 592 | ||
557 | cmd->error = sd_read_data(host, _cmd, (u16)data->blksz, buf, | 593 | cmd->error = sd_read_data(host, cmd, (u16)data->blksz, buf, |
558 | data->blksz, 200); | 594 | data->blksz, 200); |
559 | 595 | ||
560 | if (host->initial_mode) | 596 | if (host->initial_mode) |
@@ -564,7 +600,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
564 | } else { | 600 | } else { |
565 | sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz); | 601 | sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz); |
566 | 602 | ||
567 | cmd->error = sd_write_data(host, _cmd, (u16)data->blksz, buf, | 603 | cmd->error = sd_write_data(host, cmd, (u16)data->blksz, buf, |
568 | data->blksz, 200); | 604 | data->blksz, 200); |
569 | } | 605 | } |
570 | 606 | ||
@@ -664,14 +700,14 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, | |||
664 | u8 opcode, u8 sample_point) | 700 | u8 opcode, u8 sample_point) |
665 | { | 701 | { |
666 | int err; | 702 | int err; |
667 | u8 cmd[5] = {0}; | 703 | struct mmc_command cmd = {0}; |
668 | 704 | ||
669 | err = sd_change_phase(host, sample_point, true); | 705 | err = sd_change_phase(host, sample_point, true); |
670 | if (err < 0) | 706 | if (err < 0) |
671 | return err; | 707 | return err; |
672 | 708 | ||
673 | cmd[0] = 0x40 | opcode; | 709 | cmd.opcode = opcode; |
674 | err = sd_read_data(host, cmd, 0x40, NULL, 0, 100); | 710 | err = sd_read_data(host, &cmd, 0x40, NULL, 0, 100); |
675 | if (err < 0) { | 711 | if (err < 0) { |
676 | /* Wait till SD DATA IDLE */ | 712 | /* Wait till SD DATA IDLE */ |
677 | sd_wait_data_idle(host); | 713 | sd_wait_data_idle(host); |
@@ -738,6 +774,12 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) | |||
738 | return 0; | 774 | return 0; |
739 | } | 775 | } |
740 | 776 | ||
777 | static inline int sdio_extblock_cmd(struct mmc_command *cmd, | ||
778 | struct mmc_data *data) | ||
779 | { | ||
780 | return (cmd->opcode == SD_IO_RW_EXTENDED) && (data->blksz == 512); | ||
781 | } | ||
782 | |||
741 | static inline int sd_rw_cmd(struct mmc_command *cmd) | 783 | static inline int sd_rw_cmd(struct mmc_command *cmd) |
742 | { | 784 | { |
743 | return mmc_op_multi(cmd->opcode) || | 785 | return mmc_op_multi(cmd->opcode) || |
@@ -787,17 +829,15 @@ static void sd_request(struct work_struct *work) | |||
787 | if (mrq->data) | 829 | if (mrq->data) |
788 | data_size = data->blocks * data->blksz; | 830 | data_size = data->blocks * data->blksz; |
789 | 831 | ||
790 | if (!data_size || sd_rw_cmd(cmd)) { | 832 | if (!data_size) { |
791 | sd_send_cmd_get_rsp(host, cmd); | 833 | sd_send_cmd_get_rsp(host, cmd); |
834 | } else if (sd_rw_cmd(cmd) || sdio_extblock_cmd(cmd, data)) { | ||
835 | cmd->error = sd_rw_multi(host, mrq); | ||
836 | if (!host->using_cookie) | ||
837 | sdmmc_post_req(host->mmc, host->mrq, 0); | ||
792 | 838 | ||
793 | if (!cmd->error && data_size) { | 839 | if (mmc_op_multi(cmd->opcode) && mrq->stop) |
794 | sd_rw_multi(host, mrq); | 840 | sd_send_cmd_get_rsp(host, mrq->stop); |
795 | if (!host->using_cookie) | ||
796 | sdmmc_post_req(host->mmc, host->mrq, 0); | ||
797 | |||
798 | if (mmc_op_multi(cmd->opcode) && mrq->stop) | ||
799 | sd_send_cmd_get_rsp(host, mrq->stop); | ||
800 | } | ||
801 | } else { | 841 | } else { |
802 | sd_normal_rw(host, mrq); | 842 | sd_normal_rw(host, mrq); |
803 | } | 843 | } |
@@ -812,8 +852,10 @@ static void sd_request(struct work_struct *work) | |||
812 | mutex_unlock(&pcr->pcr_mutex); | 852 | mutex_unlock(&pcr->pcr_mutex); |
813 | 853 | ||
814 | finish: | 854 | finish: |
815 | if (cmd->error) | 855 | if (cmd->error) { |
816 | dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); | 856 | dev_dbg(sdmmc_dev(host), "CMD %d 0x%08x error(%d)\n", |
857 | cmd->opcode, cmd->arg, cmd->error); | ||
858 | } | ||
817 | 859 | ||
818 | mutex_lock(&host->host_mutex); | 860 | mutex_lock(&host->host_mutex); |
819 | host->mrq = NULL; | 861 | host->mrq = NULL; |
@@ -831,7 +873,7 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
831 | host->mrq = mrq; | 873 | host->mrq = mrq; |
832 | mutex_unlock(&host->host_mutex); | 874 | mutex_unlock(&host->host_mutex); |
833 | 875 | ||
834 | if (sd_rw_cmd(mrq->cmd)) | 876 | if (sd_rw_cmd(mrq->cmd) || sdio_extblock_cmd(mrq->cmd, data)) |
835 | host->using_cookie = sd_pre_dma_transfer(host, data, false); | 877 | host->using_cookie = sd_pre_dma_transfer(host, data, false); |
836 | 878 | ||
837 | queue_work(host->workq, &host->work); | 879 | queue_work(host->workq, &host->work); |