mmc-sec-feature.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Samsung Specific feature
  4. *
  5. * Copyright (C) 2024 Samsung Electronics Co., Ltd.
  6. *
  7. * Authors:
  8. * Storage Driver <[email protected]>
  9. */
  10. #include <linux/of.h>
  11. #include <linux/sched/clock.h>
  12. #include <linux/mmc/mmc.h>
  13. #include <linux/mmc/slot-gpio.h>
  14. #include "mmc-sec-feature.h"
  15. #include "mmc-sec-sysfs.h"
  16. struct mmc_sd_sec_device_info sdi;
  17. static int sd_sec_sdcard_uevent(struct device *dev,
  18. struct kobj_uevent_env *env)
  19. {
  20. struct mmc_host *host = dev_get_drvdata(dev);
  21. int retval;
  22. bool card_exist = false;
  23. struct mmc_sd_sec_status_err_info *status_err = &sdi.status_err;
  24. add_uevent_var(env, "DEVNAME=%s", dev->kobj.name);
  25. if (host->card)
  26. card_exist = true;
  27. retval = add_uevent_var(env, "IOERROR=%s", card_exist ? (
  28. ((status_err->ge_cnt && !(status_err->ge_cnt % 1000)) ||
  29. (status_err->ecc_cnt && !(status_err->ecc_cnt % 1000)) ||
  30. (status_err->wp_cnt && !(status_err->wp_cnt % 100)) ||
  31. (status_err->oor_cnt && !(status_err->oor_cnt % 100)))
  32. ? "YES" : "NO") : "NoCard");
  33. return retval;
  34. }
  35. static void sd_sec_sdcard_noti_work(struct work_struct *work)
  36. {
  37. struct mmc_sd_sec_device_info *cdi;
  38. struct mmc_sd_sec_status_err_info *status_err = &sdi.status_err;
  39. int ret;
  40. cdi = container_of(work, struct mmc_sd_sec_device_info, noti_work);
  41. if (!cdi->mmc->card)
  42. return;
  43. status_err->noti_cnt++;
  44. pr_info("%s: Send notification for SD card IO error. cnt(%d)\n",
  45. mmc_hostname(cdi->mmc), status_err->noti_cnt);
  46. ret = kobject_uevent(&sec_sdcard_cmd_dev->kobj, KOBJ_CHANGE);
  47. if (ret)
  48. pr_err("%s: Failed to send uevent with err %d\n", __func__, ret);
  49. }
  50. static struct device_type sdcard_type = {
  51. .uevent = sd_sec_sdcard_uevent,
  52. };
  53. static void mmc_sd_sec_inc_status_err(struct mmc_card *card, u32 status)
  54. {
  55. struct mmc_sd_sec_status_err_info *status_err = &sdi.status_err;
  56. bool noti = false;
  57. if (status & R1_ERROR) {
  58. status_err->ge_cnt++;
  59. if (!(status_err->ge_cnt % 1000))
  60. noti = true;
  61. }
  62. if (status & R1_CC_ERROR)
  63. status_err->cc_cnt++;
  64. if (status & R1_CARD_ECC_FAILED) {
  65. status_err->ecc_cnt++;
  66. if (!(status_err->ecc_cnt % 1000))
  67. noti = true;
  68. }
  69. if (status & R1_WP_VIOLATION) {
  70. status_err->wp_cnt++;
  71. if (!(status_err->wp_cnt % 100))
  72. noti = true;
  73. }
  74. if (status & R1_OUT_OF_RANGE) {
  75. status_err->oor_cnt++;
  76. if (!(status_err->oor_cnt % 100))
  77. noti = true;
  78. }
  79. /*
  80. * Make notification for SD card errors
  81. *
  82. * Condition :
  83. * GE, ECC : Every 1000 error
  84. * WP, OOR : Every 100 error
  85. */
  86. if (noti && mmc_card_sd(card) && sec_sdcard_cmd_dev)
  87. schedule_work(&sdi.noti_work);
  88. }
  89. static void mmc_sd_sec_inc_err_count(int index, int error, u32 status)
  90. {
  91. int i = 0;
  92. int cpu = raw_smp_processor_id();
  93. struct mmc_sd_sec_err_info *err_log = &sdi.err_info[0];
  94. if (!error)
  95. return;
  96. /*
  97. * Storage error count's policy handles only both EILSEQ and ETIMEDOUT.
  98. * There is possible to detect minor error cases(e.g. ENOMEIDUM, EIO)
  99. * In this case, it should be handled as -ETIMEDOUT error.
  100. */
  101. if (error != -EILSEQ)
  102. error = -ETIMEDOUT;
  103. for (i = 0; i < MAX_ERR_TYPE_INDEX; i++) {
  104. if (err_log[index + i].err_type == error) {
  105. index += i;
  106. break;
  107. }
  108. }
  109. if (i >= MAX_ERR_TYPE_INDEX)
  110. return;
  111. /* log device status and time if this is the first error */
  112. if (!err_log[index].status || !(R1_CURRENT_STATE(status) & R1_STATE_TRAN))
  113. err_log[index].status = status;
  114. if (!err_log[index].first_issue_time)
  115. err_log[index].first_issue_time = cpu_clock(cpu);
  116. err_log[index].last_issue_time = cpu_clock(cpu);
  117. err_log[index].count++;
  118. }
  119. #define MMC_BLK_TIMEOUT_MS (9 * 1000)
  120. static bool mmc_sd_sec_check_busy_stuck(u32 status)
  121. {
  122. if (time_before(jiffies,
  123. sdi.tstamp_last_cmd + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS)))
  124. return false;
  125. if (status && (!(status & R1_READY_FOR_DATA) ||
  126. (R1_CURRENT_STATE(status) == R1_STATE_PRG)))
  127. return true;
  128. return false;
  129. }
  130. static void mmc_sd_sec_log_err_count(struct mmc_card *card,
  131. struct mmc_request *mrq)
  132. {
  133. u32 status = (mrq->sbc ? mrq->sbc->resp[0] : 0) |
  134. (mrq->stop ? mrq->stop->resp[0] : 0) |
  135. (mrq->cmd ? mrq->cmd->resp[0] : 0);
  136. if (status & STATUS_MASK)
  137. mmc_sd_sec_inc_status_err(card, status);
  138. if (mrq->cmd->error)
  139. mmc_sd_sec_inc_err_count(SD_CMD_OFFSET,
  140. mrq->cmd->error, status);
  141. if (mrq->sbc && mrq->sbc->error)
  142. mmc_sd_sec_inc_err_count(SD_SBC_OFFSET,
  143. mrq->sbc->error, status);
  144. if (mrq->data && mrq->data->error)
  145. mmc_sd_sec_inc_err_count(SD_DATA_OFFSET,
  146. mrq->data->error, status);
  147. if (mrq->stop && mrq->stop->error)
  148. mmc_sd_sec_inc_err_count(SD_STOP_OFFSET,
  149. mrq->stop->error, status);
  150. /*
  151. * in block.c
  152. * #define MMC_BLK_TIMEOUT_MS (10 * 1000)
  153. * refer to card_busy_detect()
  154. * so, check CMD13's response(status)
  155. * if there is no other CMD for 9 secs or more.
  156. */
  157. if (mrq->cmd->opcode != MMC_SEND_STATUS)
  158. return;
  159. if (mmc_sd_sec_check_busy_stuck(status)) {
  160. /* card stuck in prg state */
  161. mmc_sd_sec_inc_err_count(SD_BUSY_OFFSET, -ETIMEDOUT, status);
  162. /* not to check card busy again */
  163. sdi.tstamp_last_cmd = jiffies;
  164. }
  165. }
  166. static void mmc_sd_sec_clear_err_count(void)
  167. {
  168. struct mmc_sd_sec_err_info *err_log = &sdi.err_info[0];
  169. struct mmc_sd_sec_status_err_info *status_err = &sdi.status_err;
  170. int i = 0;
  171. for (i = 0; i < MAX_LOG_INDEX; i++) {
  172. err_log[i].status = 0;
  173. err_log[i].first_issue_time = 0;
  174. err_log[i].last_issue_time = 0;
  175. err_log[i].count = 0;
  176. }
  177. memset(status_err, 0, sizeof(struct mmc_sd_sec_status_err_info));
  178. }
  179. static void mmc_sd_sec_init_err_count(void)
  180. {
  181. static const char *const req_types[] = {
  182. "sbc ", "cmd ", "data ", "stop ", "busy "
  183. };
  184. struct mmc_sd_sec_err_info *err_log = &sdi.err_info[0];
  185. int i;
  186. /*
  187. * err_log[0].type = "sbc "
  188. * err_log[0].err_type = -EILSEQ;
  189. * err_log[1].type = "sbc "
  190. * err_log[1].err_type = -ETIMEDOUT;
  191. * ...
  192. */
  193. for (i = 0; i < MAX_LOG_INDEX; i++) {
  194. snprintf(err_log[i].type, sizeof(char) * 5, "%s",
  195. req_types[i / MAX_ERR_TYPE_INDEX]);
  196. err_log[i].err_type =
  197. (i % MAX_ERR_TYPE_INDEX == 0) ? -EILSEQ : -ETIMEDOUT;
  198. }
  199. }
  200. void sd_sec_card_event(struct mmc_host *host)
  201. {
  202. bool status;
  203. if (!host)
  204. return;
  205. status = mmc_gpio_get_cd(host) ? true : false;
  206. if (status ^ sdi.tray_status) {
  207. pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
  208. mmc_hostname(host), sdi.tray_status, status,
  209. (host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
  210. "HIGH" : "LOW");
  211. sdi.tray_status = status;
  212. if (sdi.card_detect_cnt < UINT_MAX)
  213. sdi.card_detect_cnt++;
  214. host->unused = 0;
  215. mmc_sd_sec_clear_err_count();
  216. }
  217. }
  218. static bool mmc_sd_sec_check_cmd_type(struct mmc_request *mrq)
  219. {
  220. /*
  221. * cmd->flags info
  222. * MMC_CMD_AC (0b00 << 5) : Addressed commands
  223. * MMC_CMD_ADTC (0b01 << 5) : Addressed data transfer commands
  224. * MMC_CMD_BC (0b10 << 5) : Broadcast commands
  225. * MMC_CMD_BCR (0b11 << 5) : Broadcast commands with response
  226. *
  227. * Log the errors only for AC or ADTC type
  228. */
  229. if (!(mrq->cmd->flags & MMC_RSP_PRESENT))
  230. return false;
  231. if (mrq->cmd->flags & MMC_CMD_BC)
  232. return false;
  233. /*
  234. * No need to check if MMC_RSP_136 set or cmd MMC_APP_CMD.
  235. * CMD55 is sent with MMC_CMD_AC flag but no need to log.
  236. */
  237. if ((mrq->cmd->flags & MMC_RSP_136) ||
  238. (mrq->cmd->opcode == MMC_APP_CMD))
  239. return false;
  240. return true;
  241. }
  242. void mmc_sd_sec_check_req_err(struct mmc_host *host, struct mmc_request *mrq)
  243. {
  244. if (!host->card || !mrq || !mrq->cmd)
  245. return;
  246. /* return if the cmd is tuning block */
  247. if ((mrq->cmd->opcode == MMC_SEND_TUNING_BLOCK) ||
  248. (mrq->cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200))
  249. return;
  250. /* set CMD(except CMD13) timestamp to check card stuck */
  251. if (mrq->cmd->opcode != MMC_SEND_STATUS)
  252. sdi.tstamp_last_cmd = jiffies;
  253. if (mmc_sd_sec_check_cmd_type(mrq))
  254. mmc_sd_sec_log_err_count(host->card, mrq);
  255. }
  256. void sd_sec_set_features(struct mmc_host *host, struct platform_device *pdev)
  257. {
  258. struct device_node *np = pdev->dev.of_node;
  259. host->caps &= ~MMC_CAP_AGGRESSIVE_PM;
  260. host->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
  261. sdi.tray_status = mmc_gpio_get_cd(host) ? true : false;
  262. /* skip init without SD card detect irq */
  263. host->trigger_card_event = true;
  264. if (of_property_read_u32(np, "sec-sd-slot-type", &sdi.sd_slot_type)) {
  265. if (mmc_gpio_get_cd(host) < 0)
  266. sdi.sd_slot_type = SEC_NO_DET_SD_SLOT;
  267. else
  268. sdi.sd_slot_type = SEC_INVALID_SD_SLOT;
  269. }
  270. sdi.card_detect_cnt = 0;
  271. sd_sec_init_sysfs(host);
  272. mmc_sd_sec_init_err_count();
  273. /* Register sd uevent . */
  274. sdi.mmc = host;
  275. sec_sdcard_cmd_dev->type = &sdcard_type;
  276. INIT_WORK(&sdi.noti_work, sd_sec_sdcard_noti_work);
  277. }