cprmdrv_samsung.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /* drivers/mmc/cprmdrv_samsung.c
  2. *
  3. * Copyright 2010 Samsung Electronics Co.Ltd
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <linux/mmc/core.h>
  16. #include <linux/mmc/card.h>
  17. #include <linux/mmc/host.h>
  18. #include <linux/mmc/mmc.h>
  19. #include <linux/mmc/sd.h>
  20. #include <linux/scatterlist.h>
  21. #include <linux/uaccess.h>
  22. #include "cprmdrv_samsung.h"
  23. #include <linux/slab.h>
  24. static int mmc_wait_busy(struct mmc_card *card)
  25. {
  26. int ret, busy;
  27. struct mmc_command cmd;
  28. busy = 0;
  29. do {
  30. memset(&cmd, 0, sizeof(struct mmc_command));
  31. cmd.opcode = MMC_SEND_STATUS;
  32. cmd.arg = card->rca << 16;
  33. cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  34. ret = mmc_wait_for_cmd(card->host, &cmd, 0);
  35. if (ret)
  36. break;
  37. if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
  38. busy = 1;
  39. printk(KERN_INFO "%s: Warning: Host did not "
  40. "wait for busy state to end.\n",
  41. mmc_hostname(card->host));
  42. }
  43. } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
  44. return ret;
  45. }
  46. static int CPRM_CMD_SecureRW(struct mmc_card *card,
  47. unsigned int command,
  48. unsigned int dir,
  49. unsigned long arg,
  50. unsigned char *buff,
  51. unsigned int length) {
  52. int err;
  53. int i = 0;
  54. struct mmc_request mrq;
  55. struct mmc_command cmd;
  56. struct mmc_command stop;
  57. struct mmc_data data;
  58. struct scatterlist sg;
  59. if (command == SD_ACMD25_SECURE_WRITE_MULTI_BLOCK ||
  60. command == SD_ACMD18_SECURE_READ_MULTI_BLOCK) {
  61. return -EINVAL;
  62. }
  63. memset(&cmd, 0, sizeof(struct mmc_command));
  64. cmd.opcode = MMC_APP_CMD;
  65. cmd.arg = card->rca << 16;
  66. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
  67. //kishore
  68. mmc_rpm_hold(card->host, &card->dev);
  69. mmc_claim_host(card->host);
  70. err = mmc_wait_for_cmd(card->host, &cmd, 0);
  71. if (err)
  72. {
  73. printk("CPRM mmc_wait_for_cmd fail = %d ERROR\n", err);
  74. mmc_release_host(card->host);
  75. mmc_rpm_release(card->host, &card->dev);
  76. return (u32)-1;
  77. }
  78. if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
  79. {
  80. printk("CPRM mmc_host_is_spi fail ERROR\n");
  81. mmc_release_host(card->host);
  82. mmc_rpm_release(card->host, &card->dev);
  83. return (u32)-1;
  84. }
  85. printk("CPRM_CMD_SecureRW: 1, command : %d\n", command);
  86. memset(&cmd, 0, sizeof(struct mmc_command));
  87. cmd.opcode = command;
  88. if (command == SD_ACMD43_GET_MKB)
  89. cmd.arg = arg;
  90. else
  91. cmd.arg = 0;
  92. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
  93. memset(&data, 0, sizeof(struct mmc_data));
  94. data.timeout_ns = 100000000;
  95. data.timeout_clks = 0;
  96. data.blksz = length;
  97. data.blocks = 1;
  98. data.flags = dir;
  99. data.sg = &sg;
  100. data.sg_len = 1;
  101. stop.opcode = MMC_STOP_TRANSMISSION;
  102. stop.arg = 0;
  103. stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
  104. memset(&mrq, 0, sizeof(struct mmc_request));
  105. mrq.cmd = &cmd;
  106. mrq.data = &data;
  107. if (data.blocks == 1)
  108. mrq.stop = NULL;
  109. else
  110. mrq.stop = &stop;
  111. printk(KERN_DEBUG"CPRM_CMD_SecureRW: 2\n");
  112. sg_init_one(&sg, buff, length);
  113. printk(KERN_DEBUG"CPRM_CMD_SecureRW: 3\n");
  114. mmc_wait_for_req(card->host, &mrq);
  115. //kishore
  116. mmc_release_host(card->host);
  117. mmc_rpm_release(card->host, &card->dev);
  118. printk(KERN_DEBUG"CPRM_CMD_SecureRW: 4\n");
  119. i = 0;
  120. do {
  121. printk(KERN_DEBUG"%x", buff[i++]);
  122. if (i > 10)
  123. break;
  124. } while (i < length);
  125. printk(KERN_DEBUG"\n");
  126. if (cmd.error) {
  127. printk(KERN_DEBUG "%s]cmd.error=%d\n ", __func__, cmd.error);
  128. return cmd.error;
  129. }
  130. if (data.error) {
  131. printk(KERN_DEBUG "%s]data.error=%d\n ", __func__, data.error);
  132. return data.error;
  133. }
  134. err = mmc_wait_busy(card);
  135. printk(KERN_DEBUG"CPRM_CMD_SecureRW: 5\n");
  136. if (err)
  137. return err;
  138. return 0;
  139. }
  140. static int CPRM_CMD_SecureMultiRW(struct mmc_card *card,
  141. unsigned int command,
  142. unsigned int dir,
  143. unsigned long arg,
  144. unsigned char *buff,
  145. unsigned int length) {
  146. int err;
  147. struct mmc_request mrq;
  148. struct mmc_command cmd;
  149. struct mmc_command stop;
  150. struct mmc_data data;
  151. unsigned long flags;
  152. struct scatterlist sg;
  153. memset(&cmd, 0, sizeof(struct mmc_command));
  154. memset(&stop, 0, sizeof(struct mmc_command));
  155. cmd.opcode = MMC_APP_CMD;
  156. cmd.arg = card->rca << 16;
  157. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
  158. err = mmc_wait_for_cmd(card->host, &cmd, 0);
  159. if (err)
  160. return (u32)-1;
  161. if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
  162. return (u32)-1;
  163. printk(KERN_DEBUG"CPRM_CMD_SecureRW: 1\n");
  164. memset(&cmd, 0, sizeof(struct mmc_command));
  165. cmd.opcode = command;
  166. if (command == SD_ACMD43_GET_MKB)
  167. cmd.arg = arg;
  168. else
  169. cmd.arg = 0;
  170. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
  171. memset(&data, 0, sizeof(struct mmc_data));
  172. data.timeout_ns = 100000000;
  173. data.timeout_clks = 0;
  174. data.blksz = 512;
  175. data.blocks = (length + 511) / 512;
  176. data.flags = dir;
  177. data.sg = &sg;
  178. data.sg_len = 1;
  179. stop.opcode = MMC_STOP_TRANSMISSION;
  180. stop.arg = 0;
  181. stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
  182. memset(&mrq, 0, sizeof(struct mmc_request));
  183. mrq.cmd = &cmd;
  184. mrq.data = &data;
  185. mrq.stop = &stop;
  186. printk(KERN_DEBUG "CPRM_CMD_SecureRW: 2\n");
  187. sg_init_one(&sg, buff, length);
  188. if (dir == MMC_DATA_WRITE) {
  189. local_irq_save(flags);
  190. sg_copy_from_buffer(&sg, data.sg_len, buff, length);
  191. local_irq_restore(flags);
  192. }
  193. printk(KERN_DEBUG "CPRM_CMD_SecureRW: 3\n");
  194. mmc_wait_for_req(card->host, &mrq);
  195. printk(KERN_DEBUG "CPRM_CMD_SecureRW: 4\n");
  196. if (cmd.error) {
  197. printk(KERN_DEBUG "%s]cmd.error=%d\n", __func__, cmd.error);
  198. return cmd.error;
  199. }
  200. if (data.error) {
  201. printk(KERN_DEBUG "%s]data.error=%d\n", __func__, data.error);
  202. return data.error;
  203. }
  204. err = mmc_wait_busy(card);
  205. printk(KERN_DEBUG "CPRM_CMD_SecureRW: 5\n");
  206. if (dir == MMC_DATA_READ) {
  207. local_irq_save(flags);
  208. sg_copy_to_buffer(&sg, data.sg_len, buff, length);
  209. local_irq_restore(flags);
  210. }
  211. if (err)
  212. return err;
  213. return 0;
  214. }
  215. int stub_sendcmd(struct mmc_card *card,
  216. unsigned int cmd,
  217. unsigned long arg,
  218. unsigned int len,
  219. unsigned char *buff) {
  220. int returnVal = -1;
  221. unsigned char *kbuffer = NULL;
  222. int direction = 0;
  223. int result = 0;
  224. if (card == NULL) {
  225. printk(KERN_DEBUG "stub_sendcmd: card is null error\n");
  226. return -ENXIO;
  227. }
  228. kbuffer = kmalloc(len, GFP_KERNEL);
  229. if (kbuffer == NULL) {
  230. printk(KERN_DEBUG "malloc failed\n");
  231. return -ENOMEM;
  232. }
  233. memset(kbuffer, 0x00, len);
  234. printk(KERN_DEBUG "%s]cmd=0x%x,len=%d\n ", __func__, cmd, len);
  235. mmc_claim_host(card->host);
  236. switch (cmd) {
  237. case ACMD43:
  238. direction = MMC_DATA_READ;
  239. returnVal = CPRM_CMD_SecureRW(card,
  240. SD_ACMD43_GET_MKB,
  241. direction,
  242. arg,
  243. kbuffer,
  244. len);
  245. printk(KERN_DEBUG "SD_ACMD43_GET_MKB:0x%x\n", returnVal);
  246. break;
  247. case ACMD44:
  248. direction = MMC_DATA_READ;
  249. returnVal = CPRM_CMD_SecureRW(card,
  250. SD_ACMD44_GET_MID,
  251. direction,
  252. 0,
  253. kbuffer,
  254. len);
  255. printk(KERN_DEBUG "SD_ACMD44_GET_MID:0x%x\n", returnVal);
  256. break;
  257. case ACMD45:
  258. direction = MMC_DATA_WRITE;
  259. result = copy_from_user((void *)kbuffer, (void *)buff, len);
  260. returnVal = CPRM_CMD_SecureRW(card,
  261. SD_ACMD45_SET_CER_RN1,
  262. direction,
  263. 0,
  264. kbuffer,
  265. len);
  266. printk(KERN_INFO"SD_ACMD45_SET_CER_RN1 [0x%x]\n ", returnVal);
  267. break;
  268. case ACMD46:
  269. direction = MMC_DATA_READ;
  270. returnVal = CPRM_CMD_SecureRW(card,
  271. SD_ACMD46_GET_CER_RN2,
  272. direction,
  273. 0,
  274. kbuffer,
  275. len);
  276. printk(KERN_DEBUG "SD_ACMD46_GET_CER_RN2:0x%x\n",
  277. returnVal);
  278. break;
  279. case ACMD47:
  280. direction = MMC_DATA_WRITE;
  281. result = copy_from_user((void *)kbuffer, (void *)buff, len);
  282. returnVal = CPRM_CMD_SecureRW(card,
  283. SD_ACMD47_SET_CER_RES2,
  284. direction,
  285. 0,
  286. kbuffer,
  287. len);
  288. printk(KERN_DEBUG "SD_ACMD47_SET_CER_RES2:0x%x\n",
  289. returnVal);
  290. break;
  291. case ACMD48:
  292. direction = MMC_DATA_READ;
  293. returnVal = CPRM_CMD_SecureRW(card,
  294. SD_ACMD48_GET_CER_RES1,
  295. direction,
  296. 0,
  297. kbuffer,
  298. len);
  299. printk(KERN_DEBUG "SD_ACMD48_GET_CER_RES1:0x%x\n",
  300. returnVal);
  301. break;
  302. case ACMD25:
  303. direction = MMC_DATA_WRITE;
  304. result = copy_from_user((void *)kbuffer, (void *)buff, len);
  305. returnVal = CPRM_CMD_SecureMultiRW(card,
  306. SD_ACMD25_SECURE_WRITE_MULTI_BLOCK,
  307. direction,
  308. 0,
  309. kbuffer,
  310. len);
  311. printk(KERN_DEBUG "SD_ACMD25_SECURE_WRITE_MULTI_BLOCK[%d]=%d\n",
  312. len, returnVal);
  313. break;
  314. case ACMD18:
  315. direction = MMC_DATA_READ;
  316. returnVal = CPRM_CMD_SecureMultiRW(card,
  317. SD_ACMD18_SECURE_READ_MULTI_BLOCK,
  318. direction,
  319. 0,
  320. kbuffer,
  321. len);
  322. printk(KERN_DEBUG "SD_ACMD18_SECURE_READ_MULTI_BLOCK [%d]=%d\n",
  323. len, returnVal);
  324. break;
  325. case ACMD13:
  326. break;
  327. default:
  328. printk(KERN_DEBUG " %s ] : CMD [ %x ] ERROR", __func__, cmd);
  329. break;
  330. }
  331. if (returnVal == 0) {
  332. if (direction == MMC_DATA_READ)
  333. result = copy_to_user((void *)buff,
  334. (void *)kbuffer,
  335. len);
  336. result = returnVal;
  337. printk(KERN_DEBUG "stub_sendcmd SDAS_E_SUCCESS\n");
  338. } else {
  339. printk(KERN_DEBUG "stub_sendcmd SDAS_E_FAIL\n");
  340. result = -EIO;
  341. }
  342. mmc_release_host(card->host);
  343. kfree(kbuffer);
  344. return result;
  345. }