0099-mmc-mmcblk-Add-new-feature-CONFIG_MMC_BLOCK_PARAN.patch 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. From 5ca694dfd981a371e9b18cdd4a89c002ffaccbc5 Mon Sep 17 00:00:00 2001
  2. From: San Mehat <[email protected]>
  3. Date: Wed, 3 Dec 2008 10:22:59 -0800
  4. Subject: [PATCH 099/134] mmc: mmcblk: Add new feature 'CONFIG_MMC_BLOCK_PARANOID_RESUME'
  5. With this feature enabled, mmcblk will check the card-status before issuing
  6. a transaction *only* after being resumed. This protectes us from issuing
  7. transactions before the sdcard is ready (which can occur if the host driver
  8. deferrs mmc_resume_host() to reduce resume latency)
  9. Signed-off-by: San Mehat <[email protected]>
  10. ---
  11. drivers/mmc/card/Kconfig | 7 +++++++
  12. drivers/mmc/card/block.c | 3 +++
  13. drivers/mmc/card/queue.c | 28 ++++++++++++++++++++++++++++
  14. drivers/mmc/card/queue.h | 3 +++
  15. 4 files changed, 41 insertions(+), 0 deletions(-)
  16. --- a/drivers/mmc/card/Kconfig
  17. +++ b/drivers/mmc/card/Kconfig
  18. @@ -32,6 +32,13 @@ config MMC_BLOCK_BOUNCE
  19. If unsure, say Y here.
  20. +config MMC_BLOCK_PARANOID_RESUME
  21. + bool "Check card status on resume"
  22. + depends on MMC_BLOCK
  23. + default y
  24. + help
  25. + Nohelp
  26. +
  27. config SDIO_UART
  28. tristate "SDIO UART/GPS class support"
  29. help
  30. --- a/drivers/mmc/card/block.c
  31. +++ b/drivers/mmc/card/block.c
  32. @@ -643,6 +643,9 @@ static int mmc_blk_resume(struct mmc_car
  33. if (md) {
  34. mmc_blk_set_blksize(md, card);
  35. +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
  36. + md->queue.check_status = 1;
  37. +#endif
  38. mmc_queue_resume(&md->queue);
  39. }
  40. return 0;
  41. --- a/drivers/mmc/card/queue.c
  42. +++ b/drivers/mmc/card/queue.c
  43. @@ -14,7 +14,9 @@
  44. #include <linux/freezer.h>
  45. #include <linux/kthread.h>
  46. #include <linux/scatterlist.h>
  47. +#include <linux/delay.h>
  48. +#include <linux/mmc/mmc.h>
  49. #include <linux/mmc/card.h>
  50. #include <linux/mmc/host.h>
  51. #include "queue.h"
  52. @@ -70,7 +72,33 @@ static int mmc_queue_thread(void *d)
  53. continue;
  54. }
  55. set_current_state(TASK_RUNNING);
  56. +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
  57. + if (mq->check_status) {
  58. + struct mmc_command cmd;
  59. + do {
  60. + int err;
  61. +
  62. + cmd.opcode = MMC_SEND_STATUS;
  63. + cmd.arg = mq->card->rca << 16;
  64. + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  65. +
  66. + mmc_claim_host(mq->card->host);
  67. + err = mmc_wait_for_cmd(mq->card->host, &cmd, 5);
  68. + mmc_release_host(mq->card->host);
  69. +
  70. + if (err) {
  71. + printk(KERN_ERR "%s: failed to get status (%d)\n",
  72. + __func__, err);
  73. + msleep(5);
  74. + continue;
  75. + }
  76. + printk(KERN_DEBUG "%s: status 0x%.8x\n", __func__, cmd.resp[0]);
  77. + } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
  78. + (R1_CURRENT_STATE(cmd.resp[0]) == 7));
  79. + mq->check_status = 0;
  80. + }
  81. +#endif
  82. mq->issue_fn(mq, req);
  83. } while (1);
  84. up(&mq->thread_sem);
  85. --- a/drivers/mmc/card/queue.h
  86. +++ b/drivers/mmc/card/queue.h
  87. @@ -17,6 +17,9 @@ struct mmc_queue {
  88. char *bounce_buf;
  89. struct scatterlist *bounce_sg;
  90. unsigned int bounce_sg_len;
  91. +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
  92. + int check_status;
  93. +#endif
  94. };
  95. extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);