PageRenderTime 25ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/mmc/core/mmc_ffu.c

https://gitlab.com/SpasilliumNexus/frankenclark_kernel
C | 496 lines | 346 code | 72 blank | 78 comment | 54 complexity | 1fa5f72a9ffa96f534ef08c4dfddaaf1 MD5 | raw file
  1. /*
  2. * * ffu.c
  3. *
  4. * Copyright 2007-2008 Pierre Ossman
  5. *
  6. * Modified by SanDisk Corp., Copyright © 2013 SanDisk Corp.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * This program includes bug.h, card.h, host.h, mmc.h, scatterlist.h,
  14. * slab.h, ffu.h & swap.h header files
  15. * The original, unmodified version of this program – the mmc_test.c
  16. * file – is obtained under the GPL v2.0 license that is available via
  17. * http://www.gnu.org/licenses/,
  18. * or http://www.opensource.org/licenses/gpl-2.0.php
  19. */
  20. #include <linux/bug.h>
  21. #include <linux/errno.h>
  22. #include <linux/mmc/card.h>
  23. #include <linux/mmc/host.h>
  24. #include <linux/mmc/mmc.h>
  25. #include <linux/scatterlist.h>
  26. #include <linux/slab.h>
  27. #include <linux/swap.h>
  28. #include <linux/firmware.h>
  29. /**
  30. * struct mmc_ffu_pages - pages allocated by 'alloc_pages()'.
  31. * @page: first page in the allocation
  32. * @order: order of the number of pages allocated
  33. */
  34. struct mmc_ffu_pages {
  35. struct page *page;
  36. unsigned int order;
  37. };
  38. /**
  39. * struct mmc_ffu_mem - allocated memory.
  40. * @arr: array of allocations
  41. * @cnt: number of allocations
  42. */
  43. struct mmc_ffu_mem {
  44. struct mmc_ffu_pages *arr;
  45. unsigned int cnt;
  46. };
  47. struct mmc_ffu_area {
  48. unsigned long max_sz;
  49. unsigned int max_tfr;
  50. unsigned int max_segs;
  51. unsigned int max_seg_sz;
  52. unsigned int blocks;
  53. unsigned int sg_len;
  54. struct mmc_ffu_mem mem;
  55. struct sg_table sgtable;
  56. };
  57. /*
  58. * Map memory into a scatterlist.
  59. */
  60. static unsigned int mmc_ffu_map_sg(struct mmc_ffu_mem *mem, int size,
  61. struct scatterlist *sglist)
  62. {
  63. struct scatterlist *sg = sglist;
  64. unsigned int i;
  65. unsigned long sz = size;
  66. unsigned int sctr_len = 0;
  67. unsigned long len;
  68. for (i = 0; i < mem->cnt && sz; i++, sz -= len) {
  69. len = PAGE_SIZE << mem->arr[i].order;
  70. if (len > sz) {
  71. len = sz;
  72. sz = 0;
  73. }
  74. sg_set_page(sg, mem->arr[i].page, len, 0);
  75. sg = sg_next(sg);
  76. sctr_len++;
  77. }
  78. return sctr_len;
  79. }
  80. static void mmc_ffu_free_mem(struct mmc_ffu_mem *mem)
  81. {
  82. if (!mem)
  83. return;
  84. while (mem->cnt--)
  85. __free_pages(mem->arr[mem->cnt].page, mem->arr[mem->cnt].order);
  86. kfree(mem->arr);
  87. }
  88. /*
  89. * Cleanup struct mmc_ffu_area.
  90. */
  91. static int mmc_ffu_area_cleanup(struct mmc_ffu_area *area)
  92. {
  93. sg_free_table(&area->sgtable);
  94. mmc_ffu_free_mem(&area->mem);
  95. return 0;
  96. }
  97. /*
  98. * Allocate a lot of memory, preferably max_sz but at least min_sz. In case
  99. * there isn't much memory do not exceed 1/16th total low mem pages. Also do
  100. * not exceed a maximum number of segments and try not to make segments much
  101. * bigger than maximum segment size.
  102. */
  103. static int mmc_ffu_alloc_mem(struct mmc_ffu_area *area, unsigned long min_sz)
  104. {
  105. unsigned long max_page_cnt = DIV_ROUND_UP(area->max_tfr, PAGE_SIZE);
  106. unsigned long min_page_cnt = DIV_ROUND_UP(min_sz, PAGE_SIZE);
  107. unsigned long max_seg_page_cnt =
  108. DIV_ROUND_UP(area->max_seg_sz, PAGE_SIZE);
  109. unsigned long page_cnt = 0;
  110. /* we divide by 16 to ensure we will not allocate a big amount
  111. * of unnecessary pages */
  112. unsigned long limit = nr_free_buffer_pages() >> 4;
  113. gfp_t flags = GFP_KERNEL | GFP_DMA | __GFP_NOWARN | __GFP_NORETRY;
  114. if (max_page_cnt > limit) {
  115. max_page_cnt = limit;
  116. area->max_tfr = max_page_cnt * PAGE_SIZE;
  117. }
  118. if (min_page_cnt > max_page_cnt)
  119. min_page_cnt = max_page_cnt;
  120. if (area->max_segs * max_seg_page_cnt > max_page_cnt)
  121. area->max_segs = DIV_ROUND_UP(max_page_cnt, max_seg_page_cnt);
  122. area->mem.arr = kzalloc(sizeof(struct mmc_ffu_pages) * area->max_segs,
  123. GFP_KERNEL);
  124. area->mem.cnt = 0;
  125. if (!area->mem.arr)
  126. goto out_free;
  127. while (max_page_cnt) {
  128. struct page *page;
  129. unsigned int order;
  130. order = get_order(max_seg_page_cnt << PAGE_SHIFT);
  131. do {
  132. page = alloc_pages(flags, order);
  133. } while (!page && order--);
  134. if (!page)
  135. goto out_free;
  136. area->mem.arr[area->mem.cnt].page = page;
  137. area->mem.arr[area->mem.cnt].order = order;
  138. area->mem.cnt++;
  139. page_cnt += 1UL << order;
  140. if (max_page_cnt <= (1UL << order))
  141. break;
  142. max_page_cnt -= 1UL << order;
  143. }
  144. if (page_cnt < min_page_cnt)
  145. goto out_free;
  146. return 0;
  147. out_free:
  148. mmc_ffu_free_mem(&area->mem);
  149. return -ENOMEM;
  150. }
  151. /*
  152. * Initialize an area for data transfers.
  153. * Copy the data to the allocated pages.
  154. */
  155. static int mmc_ffu_area_init(struct mmc_ffu_area *area, struct mmc_card *card,
  156. const u8 *data)
  157. {
  158. int ret;
  159. int i;
  160. unsigned int length = 0, page_length;
  161. ret = mmc_ffu_alloc_mem(area, 1);
  162. for (i = 0; i < area->mem.cnt; i++) {
  163. if (length > area->max_tfr) {
  164. ret = -EINVAL;
  165. goto out_free;
  166. }
  167. page_length = PAGE_SIZE << area->mem.arr[i].order;
  168. memcpy(page_address(area->mem.arr[i].page), data + length,
  169. min(area->max_tfr - length, page_length));
  170. length += page_length;
  171. }
  172. ret = sg_alloc_table(&area->sgtable, area->mem.cnt, GFP_KERNEL);
  173. if (ret)
  174. goto out_free;
  175. area->sg_len = mmc_ffu_map_sg(&area->mem, area->max_tfr,
  176. area->sgtable.sgl);
  177. return 0;
  178. out_free:
  179. mmc_ffu_free_mem(&area->mem);
  180. return ret;
  181. }
  182. static int mmc_ffu_write(struct mmc_card *card, const u8 *src, u32 arg,
  183. int size)
  184. {
  185. int rc;
  186. struct mmc_ffu_area area = {0};
  187. int block_size = card->ext_csd.data_sector_size;
  188. area.max_segs = card->host->max_segs;
  189. area.max_seg_sz = card->host->max_seg_size & ~(block_size - 1);
  190. do {
  191. area.max_tfr = size;
  192. if (area.max_tfr >> 9 > card->host->max_blk_count)
  193. area.max_tfr = card->host->max_blk_count << 9;
  194. if (area.max_tfr > card->host->max_req_size)
  195. area.max_tfr = card->host->max_req_size;
  196. if (DIV_ROUND_UP(area.max_tfr, area.max_seg_sz) > area.max_segs)
  197. area.max_tfr = area.max_segs * area.max_seg_sz;
  198. rc = mmc_ffu_area_init(&area, card, src);
  199. if (rc != 0)
  200. goto exit;
  201. rc = mmc_simple_transfer(card, area.sgtable.sgl, area.sg_len,
  202. arg, area.max_tfr / block_size, block_size, 1);
  203. mmc_ffu_area_cleanup(&area);
  204. if (rc != 0) {
  205. pr_err("%s mmc_ffu_simple_transfer %d\n", __func__, rc);
  206. goto exit;
  207. }
  208. src += area.max_tfr;
  209. size -= area.max_tfr;
  210. } while (size > 0);
  211. exit:
  212. return rc;
  213. }
  214. /* Flush all scheduled work from the MMC work queue.
  215. * and initialize the MMC device */
  216. static int mmc_ffu_restart(struct mmc_card *card)
  217. {
  218. struct mmc_host *host = card->host;
  219. int err = 0;
  220. /*
  221. * Power cycle and hope for the best. On platforms that don't have a
  222. * controllable regulator and/or hardware reset line, all we can do is
  223. * hope that CMD0 is enough to apply the firmware.
  224. */
  225. err = mmc_power_save_host(host);
  226. if (err) {
  227. pr_warn("%s: FFU: %s: failed to power down (%d)\n",
  228. mmc_hostname(card->host), __func__ , err);
  229. goto exit;
  230. }
  231. /*
  232. * Some eMMCs apply the new firmware right away, which looks like a card
  233. * change if any of the CID fields change. There doesn't seem to be a
  234. * good way to handle this for a non-removable card, so this hack
  235. * signals the expected CID change to mmc_init_card().
  236. */
  237. memset(card->raw_cid, 0, sizeof(card->raw_cid));
  238. err = mmc_power_restore_host(host);
  239. if (err)
  240. pr_warn("%s: FFU: %s: failed to power up (%d)\n",
  241. mmc_hostname(card->host), __func__ , err);
  242. exit:
  243. return err;
  244. }
  245. static int mmc_ffu_switch_mode(struct mmc_card *card , int mode)
  246. {
  247. int err = 0;
  248. int offset;
  249. switch (mode) {
  250. case MMC_FFU_MODE_SET:
  251. case MMC_FFU_MODE_NORMAL:
  252. offset = EXT_CSD_MODE_CONFIG;
  253. break;
  254. case MMC_FFU_INSTALL_SET:
  255. offset = EXT_CSD_MODE_OPERATION_CODES;
  256. mode = 0x1;
  257. break;
  258. default:
  259. err = -EINVAL;
  260. break;
  261. }
  262. if (err == 0) {
  263. err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  264. offset, mode,
  265. card->ext_csd.generic_cmd6_time);
  266. }
  267. return err;
  268. }
  269. static int mmc_ffu_install(struct mmc_card *card, u8 *ext_csd)
  270. {
  271. int err;
  272. u32 timeout;
  273. /* check mode operation */
  274. timeout = ext_csd[EXT_CSD_OPERATION_CODE_TIMEOUT];
  275. if (timeout == 0 || timeout > 0x17) {
  276. timeout = 0x17;
  277. pr_warn("%s: FFU: operation code timeout is out "
  278. "of range. Using maximum timeout.\n",
  279. mmc_hostname(card->host));
  280. }
  281. /* timeout is at millisecond resolution */
  282. timeout = DIV_ROUND_UP((100 * (1 << timeout)), 1000);
  283. /* set ext_csd to install mode */
  284. err = mmc_ffu_switch_mode(card, MMC_FFU_INSTALL_SET);
  285. if (err) {
  286. pr_err("%s: FFU: error %d setting install mode\n",
  287. mmc_hostname(card->host), err);
  288. return err;
  289. }
  290. /* read ext_csd */
  291. err = mmc_send_ext_csd(card, ext_csd);
  292. if (err) {
  293. pr_err("%s: FFU: error %d sending ext_csd\n",
  294. mmc_hostname(card->host), err);
  295. return err;
  296. }
  297. /* return status */
  298. err = ext_csd[EXT_CSD_FFU_STATUS];
  299. if (err) {
  300. pr_err("%s: FFU: error %d FFU install:\n",
  301. mmc_hostname(card->host), err);
  302. return -EINVAL;
  303. }
  304. return 0;
  305. }
  306. int mmc_ffu_invoke(struct mmc_card *card, const char *name)
  307. {
  308. u8 ext_csd[512];
  309. int err;
  310. u32 arg;
  311. u32 fw_prog_bytes;
  312. const struct firmware *fw;
  313. int block_size = card->ext_csd.data_sector_size;
  314. /* Check if FFU is supported */
  315. if (!card->ext_csd.ffu_capable) {
  316. pr_err("%s: FFU: error FFU is not supported %d rev %d\n",
  317. mmc_hostname(card->host), card->ext_csd.ffu_capable,
  318. card->ext_csd.rev);
  319. return -EOPNOTSUPP;
  320. }
  321. if (strlen(name) > 512) {
  322. pr_err("%s: FFU: %.20s is not a valid argument\n",
  323. mmc_hostname(card->host), name);
  324. return -EINVAL;
  325. }
  326. /* setup FW data buffer */
  327. pr_info("%s: starting FFU using: %s\n", mmc_hostname(card->host), name);
  328. err = request_firmware(&fw, name, &card->dev);
  329. if (err) {
  330. pr_err("%s: FFU: firmware request for %s failed %d\n",
  331. mmc_hostname(card->host), name, err);
  332. return err;
  333. }
  334. if ((fw->size % block_size)) {
  335. pr_warn("%s: FFU: warning %zd firmware data size "
  336. "is not aligned\n", mmc_hostname(card->host), fw->size);
  337. }
  338. mmc_claim_host(card->host);
  339. /* trigger flushing*/
  340. err = mmc_flush_cache(card);
  341. if (err) {
  342. pr_err("%s: FFU: error %d flushing cache\n",
  343. mmc_hostname(card->host), err);
  344. goto exit;
  345. }
  346. /* Read the EXT_CSD */
  347. err = mmc_send_ext_csd(card, ext_csd);
  348. if (err) {
  349. pr_err("%s: FFU: error %d reading EXT_CSD\n",
  350. mmc_hostname(card->host), err);
  351. goto exit;
  352. }
  353. /* set CMD ARG */
  354. arg = ext_csd[EXT_CSD_FFU_ARG] |
  355. ext_csd[EXT_CSD_FFU_ARG + 1] << 8 |
  356. ext_csd[EXT_CSD_FFU_ARG + 2] << 16 |
  357. ext_csd[EXT_CSD_FFU_ARG + 3] << 24;
  358. /* set device to FFU mode */
  359. err = mmc_ffu_switch_mode(card, MMC_FFU_MODE_SET);
  360. if (err) {
  361. pr_err("%s: FFU: error %d FFU is not supported\n",
  362. mmc_hostname(card->host), err);
  363. goto exit;
  364. }
  365. err = mmc_ffu_write(card, fw->data, arg, fw->size);
  366. if (err) {
  367. pr_err("%s: FFU: write error %d\n",
  368. mmc_hostname(card->host), err);
  369. goto exit;
  370. }
  371. /* payload will be checked only in op_mode supported */
  372. if (card->ext_csd.ffu_mode_op) {
  373. /* Read the EXT_CSD */
  374. err = mmc_send_ext_csd(card, ext_csd);
  375. if (err) {
  376. pr_err("%s: FFU: error %d sending ext_csd\n",
  377. mmc_hostname(card->host), err);
  378. goto exit;
  379. }
  380. /* check that the eMMC has received the payload */
  381. fw_prog_bytes = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG] |
  382. ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG + 1] << 8 |
  383. ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG + 2] << 16 |
  384. ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG + 3] << 24;
  385. /* convert sectors to bytes: multiply by -512B or 4KB as
  386. required by the card */
  387. fw_prog_bytes *=
  388. block_size << (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] * 3);
  389. if (fw_prog_bytes != fw->size) {
  390. err = -EINVAL;
  391. pr_err("%s: FFU: error %d number of programmed fw sector "
  392. "incorrect %d %zd\n", __func__, err,
  393. fw_prog_bytes, fw->size);
  394. goto exit;
  395. }
  396. err = mmc_ffu_install(card, ext_csd);
  397. if (err) {
  398. pr_err("%s: FFU: error firmware install %d\n",
  399. mmc_hostname(card->host), err);
  400. mmc_ffu_switch_mode(card, MMC_FFU_MODE_NORMAL);
  401. goto exit;
  402. }
  403. } else {
  404. /* host switch back to work in normal MMC Read/Write commands */
  405. err = mmc_ffu_switch_mode(card, MMC_FFU_MODE_NORMAL);
  406. if (err)
  407. pr_err("%s: FFU: switch to normal mode error %d (ignoring)\n",
  408. mmc_hostname(card->host), err);
  409. }
  410. if (!card->ext_csd.ffu_mode_op) {
  411. /* restart the eMMC */
  412. err = mmc_ffu_restart(card);
  413. if (err) {
  414. pr_err("%s: FFU: failed to restart device %d\n",
  415. mmc_hostname(card->host), err);
  416. goto exit;
  417. }
  418. }
  419. exit:
  420. mmc_release_host(card->host);
  421. release_firmware(fw);
  422. return err;
  423. }
  424. EXPORT_SYMBOL(mmc_ffu_invoke);