lld_emu.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. /*
  2. * NAND Flash Controller Device Driver
  3. * Copyright (c) 2009, Intel Corporation and its suppliers.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  17. *
  18. */
  19. #include <linux/fs.h>
  20. #include <linux/slab.h>
  21. #include "flash.h"
  22. #include "ffsdefs.h"
  23. #include "lld_emu.h"
  24. #include "lld.h"
  25. #if CMD_DMA
  26. #include "lld_cdma.h"
  27. #endif
  28. #define GLOB_LLD_PAGES 64
  29. #define GLOB_LLD_PAGE_SIZE (512+16)
  30. #define GLOB_LLD_PAGE_DATA_SIZE 512
  31. #define GLOB_LLD_BLOCKS 2048
  32. #if (CMD_DMA && FLASH_EMU)
  33. #include "lld_cdma.h"
  34. u32 totalUsedBanks;
  35. u32 valid_banks[MAX_CHANS];
  36. #endif
  37. #if FLASH_EMU /* This is for entire module */
  38. static u8 *flash_memory[GLOB_LLD_BLOCKS * GLOB_LLD_PAGES];
  39. /* Read nand emu file and then fill it's content to flash_memory */
  40. int emu_load_file_to_mem(void)
  41. {
  42. mm_segment_t fs;
  43. struct file *nef_filp = NULL;
  44. struct inode *inode = NULL;
  45. loff_t nef_size = 0;
  46. loff_t tmp_file_offset, file_offset;
  47. ssize_t nread;
  48. int i, rc = -EINVAL;
  49. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  50. __FILE__, __LINE__, __func__);
  51. fs = get_fs();
  52. set_fs(get_ds());
  53. nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
  54. if (IS_ERR(nef_filp)) {
  55. printk(KERN_ERR "filp_open error: "
  56. "Unable to open nand emu file!\n");
  57. return PTR_ERR(nef_filp);
  58. }
  59. if (nef_filp->f_path.dentry) {
  60. inode = nef_filp->f_path.dentry->d_inode;
  61. } else {
  62. printk(KERN_ERR "Can not get valid inode!\n");
  63. goto out;
  64. }
  65. nef_size = i_size_read(inode->i_mapping->host);
  66. if (nef_size <= 0) {
  67. printk(KERN_ERR "Invalid nand emu file size: "
  68. "0x%llx\n", nef_size);
  69. goto out;
  70. } else {
  71. nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: %lld\n",
  72. nef_size);
  73. }
  74. file_offset = 0;
  75. for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
  76. tmp_file_offset = file_offset;
  77. nread = vfs_read(nef_filp,
  78. (char __user *)flash_memory[i],
  79. GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
  80. if (nread < GLOB_LLD_PAGE_SIZE) {
  81. printk(KERN_ERR "%s, Line %d - "
  82. "nand emu file partial read: "
  83. "%d bytes\n", __FILE__, __LINE__, (int)nread);
  84. goto out;
  85. }
  86. file_offset += GLOB_LLD_PAGE_SIZE;
  87. }
  88. rc = 0;
  89. out:
  90. filp_close(nef_filp, current->files);
  91. set_fs(fs);
  92. return rc;
  93. }
  94. /* Write contents of flash_memory to nand emu file */
  95. int emu_write_mem_to_file(void)
  96. {
  97. mm_segment_t fs;
  98. struct file *nef_filp = NULL;
  99. struct inode *inode = NULL;
  100. loff_t nef_size = 0;
  101. loff_t tmp_file_offset, file_offset;
  102. ssize_t nwritten;
  103. int i, rc = -EINVAL;
  104. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  105. __FILE__, __LINE__, __func__);
  106. fs = get_fs();
  107. set_fs(get_ds());
  108. nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
  109. if (IS_ERR(nef_filp)) {
  110. printk(KERN_ERR "filp_open error: "
  111. "Unable to open nand emu file!\n");
  112. return PTR_ERR(nef_filp);
  113. }
  114. if (nef_filp->f_path.dentry) {
  115. inode = nef_filp->f_path.dentry->d_inode;
  116. } else {
  117. printk(KERN_ERR "Invalid " "nef_filp->f_path.dentry value!\n");
  118. goto out;
  119. }
  120. nef_size = i_size_read(inode->i_mapping->host);
  121. if (nef_size <= 0) {
  122. printk(KERN_ERR "Invalid "
  123. "nand emu file size: 0x%llx\n", nef_size);
  124. goto out;
  125. } else {
  126. nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: "
  127. "%lld\n", nef_size);
  128. }
  129. file_offset = 0;
  130. for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
  131. tmp_file_offset = file_offset;
  132. nwritten = vfs_write(nef_filp,
  133. (char __user *)flash_memory[i],
  134. GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
  135. if (nwritten < GLOB_LLD_PAGE_SIZE) {
  136. printk(KERN_ERR "%s, Line %d - "
  137. "nand emu file partial write: "
  138. "%d bytes\n", __FILE__, __LINE__, (int)nwritten);
  139. goto out;
  140. }
  141. file_offset += GLOB_LLD_PAGE_SIZE;
  142. }
  143. rc = 0;
  144. out:
  145. filp_close(nef_filp, current->files);
  146. set_fs(fs);
  147. return rc;
  148. }
  149. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  150. * Function: emu_Flash_Init
  151. * Inputs: none
  152. * Outputs: PASS=0 (notice 0=ok here)
  153. * Description: Creates & initializes the flash RAM array.
  154. *
  155. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  156. u16 emu_Flash_Init(void)
  157. {
  158. int i;
  159. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  160. __FILE__, __LINE__, __func__);
  161. flash_memory[0] = (u8 *)vmalloc(GLOB_LLD_PAGE_SIZE *
  162. GLOB_LLD_BLOCKS *
  163. GLOB_LLD_PAGES *
  164. sizeof(u8));
  165. if (!flash_memory[0]) {
  166. printk(KERN_ERR "Fail to allocate memory "
  167. "for nand emulator!\n");
  168. return ERR;
  169. }
  170. memset((char *)(flash_memory[0]), 0xFF,
  171. GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS * GLOB_LLD_PAGES *
  172. sizeof(u8));
  173. for (i = 1; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++)
  174. flash_memory[i] = flash_memory[i - 1] + GLOB_LLD_PAGE_SIZE;
  175. emu_load_file_to_mem(); /* Load nand emu file to mem */
  176. return PASS;
  177. }
  178. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  179. * Function: emu_Flash_Release
  180. * Inputs: none
  181. * Outputs: PASS=0 (notice 0=ok here)
  182. * Description: Releases the flash.
  183. *
  184. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  185. int emu_Flash_Release(void)
  186. {
  187. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  188. __FILE__, __LINE__, __func__);
  189. emu_write_mem_to_file(); /* Write back mem to nand emu file */
  190. vfree(flash_memory[0]);
  191. return PASS;
  192. }
  193. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  194. * Function: emu_Read_Device_ID
  195. * Inputs: none
  196. * Outputs: PASS=1 FAIL=0
  197. * Description: Reads the info from the controller registers.
  198. * Sets up DeviceInfo structure with device parameters
  199. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  200. u16 emu_Read_Device_ID(void)
  201. {
  202. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  203. __FILE__, __LINE__, __func__);
  204. DeviceInfo.wDeviceMaker = 0;
  205. DeviceInfo.wDeviceType = 8;
  206. DeviceInfo.wSpectraStartBlock = 36;
  207. DeviceInfo.wSpectraEndBlock = GLOB_LLD_BLOCKS - 1;
  208. DeviceInfo.wTotalBlocks = GLOB_LLD_BLOCKS;
  209. DeviceInfo.wPagesPerBlock = GLOB_LLD_PAGES;
  210. DeviceInfo.wPageSize = GLOB_LLD_PAGE_SIZE;
  211. DeviceInfo.wPageDataSize = GLOB_LLD_PAGE_DATA_SIZE;
  212. DeviceInfo.wPageSpareSize = GLOB_LLD_PAGE_SIZE -
  213. GLOB_LLD_PAGE_DATA_SIZE;
  214. DeviceInfo.wBlockSize = DeviceInfo.wPageSize * GLOB_LLD_PAGES;
  215. DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * GLOB_LLD_PAGES;
  216. DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
  217. DeviceInfo.wSpectraStartBlock
  218. + 1);
  219. DeviceInfo.MLCDevice = 1; /* Emulate MLC device */
  220. DeviceInfo.nBitsInPageNumber =
  221. (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
  222. DeviceInfo.nBitsInPageDataSize =
  223. (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
  224. DeviceInfo.nBitsInBlockDataSize =
  225. (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
  226. #if CMD_DMA
  227. totalUsedBanks = 4;
  228. valid_banks[0] = 1;
  229. valid_banks[1] = 1;
  230. valid_banks[2] = 1;
  231. valid_banks[3] = 1;
  232. #endif
  233. return PASS;
  234. }
  235. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  236. * Function: emu_Flash_Reset
  237. * Inputs: none
  238. * Outputs: PASS=0 (notice 0=ok here)
  239. * Description: Reset the flash
  240. *
  241. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  242. u16 emu_Flash_Reset(void)
  243. {
  244. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  245. __FILE__, __LINE__, __func__);
  246. return PASS;
  247. }
  248. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  249. * Function: emu_Erase_Block
  250. * Inputs: Address
  251. * Outputs: PASS=0 (notice 0=ok here)
  252. * Description: Erase a block
  253. *
  254. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  255. u16 emu_Erase_Block(u32 block_add)
  256. {
  257. int i;
  258. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  259. __FILE__, __LINE__, __func__);
  260. if (block_add >= DeviceInfo.wTotalBlocks) {
  261. printk(KERN_ERR "emu_Erase_Block error! "
  262. "Too big block address: %d\n", block_add);
  263. return FAIL;
  264. }
  265. nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
  266. (int)block_add);
  267. for (i = block_add * GLOB_LLD_PAGES;
  268. i < ((block_add + 1) * GLOB_LLD_PAGES); i++) {
  269. if (flash_memory[i]) {
  270. memset((u8 *)(flash_memory[i]), 0xFF,
  271. DeviceInfo.wPageSize * sizeof(u8));
  272. }
  273. }
  274. return PASS;
  275. }
  276. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  277. * Function: emu_Write_Page_Main
  278. * Inputs: Write buffer address pointer
  279. * Block number
  280. * Page number
  281. * Number of pages to process
  282. * Outputs: PASS=0 (notice 0=ok here)
  283. * Description: Write the data in the buffer to main area of flash
  284. *
  285. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  286. u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
  287. u16 Page, u16 PageCount)
  288. {
  289. int i;
  290. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  291. __FILE__, __LINE__, __func__);
  292. if (Block >= DeviceInfo.wTotalBlocks)
  293. return FAIL;
  294. if (Page + PageCount > DeviceInfo.wPagesPerBlock)
  295. return FAIL;
  296. nand_dbg_print(NAND_DBG_DEBUG, "emu_Write_Page_Main: "
  297. "lba %u Page %u PageCount %u\n",
  298. (unsigned int)Block,
  299. (unsigned int)Page, (unsigned int)PageCount);
  300. for (i = 0; i < PageCount; i++) {
  301. if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
  302. printk(KERN_ERR "Run out of memory\n");
  303. return FAIL;
  304. }
  305. memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
  306. write_data, DeviceInfo.wPageDataSize);
  307. write_data += DeviceInfo.wPageDataSize;
  308. Page++;
  309. }
  310. return PASS;
  311. }
  312. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  313. * Function: emu_Read_Page_Main
  314. * Inputs: Read buffer address pointer
  315. * Block number
  316. * Page number
  317. * Number of pages to process
  318. * Outputs: PASS=0 (notice 0=ok here)
  319. * Description: Read the data from the flash main area to the buffer
  320. *
  321. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  322. u16 emu_Read_Page_Main(u8 *read_data, u32 Block,
  323. u16 Page, u16 PageCount)
  324. {
  325. int i;
  326. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  327. __FILE__, __LINE__, __func__);
  328. if (Block >= DeviceInfo.wTotalBlocks)
  329. return FAIL;
  330. if (Page + PageCount > DeviceInfo.wPagesPerBlock)
  331. return FAIL;
  332. nand_dbg_print(NAND_DBG_DEBUG, "emu_Read_Page_Main: "
  333. "lba %u Page %u PageCount %u\n",
  334. (unsigned int)Block,
  335. (unsigned int)Page, (unsigned int)PageCount);
  336. for (i = 0; i < PageCount; i++) {
  337. if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
  338. memset(read_data, 0xFF, DeviceInfo.wPageDataSize);
  339. } else {
  340. memcpy(read_data,
  341. (u8 *) (flash_memory[Block * GLOB_LLD_PAGES
  342. + Page]),
  343. DeviceInfo.wPageDataSize);
  344. }
  345. read_data += DeviceInfo.wPageDataSize;
  346. Page++;
  347. }
  348. return PASS;
  349. }
  350. #ifndef ELDORA
  351. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  352. * Function: emu_Read_Page_Main_Spare
  353. * Inputs: Write Buffer
  354. * Address
  355. * Buffer size
  356. * Outputs: PASS=0 (notice 0=ok here)
  357. * Description: Read from flash main+spare area
  358. *
  359. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  360. u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
  361. u16 Page, u16 PageCount)
  362. {
  363. int i;
  364. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  365. __FILE__, __LINE__, __func__);
  366. if (Block >= DeviceInfo.wTotalBlocks) {
  367. printk(KERN_ERR "Read Page Main+Spare "
  368. "Error: Block Address too big\n");
  369. return FAIL;
  370. }
  371. if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
  372. printk(KERN_ERR "Read Page Main+Spare "
  373. "Error: Page number too big\n");
  374. return FAIL;
  375. }
  376. nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
  377. "No. of pages %u block %u start page %u\n",
  378. (unsigned int)PageCount,
  379. (unsigned int)Block, (unsigned int)Page);
  380. for (i = 0; i < PageCount; i++) {
  381. if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
  382. memset(read_data, 0xFF, DeviceInfo.wPageSize);
  383. } else {
  384. memcpy(read_data, (u8 *) (flash_memory[Block *
  385. GLOB_LLD_PAGES
  386. + Page]),
  387. DeviceInfo.wPageSize);
  388. }
  389. read_data += DeviceInfo.wPageSize;
  390. Page++;
  391. }
  392. return PASS;
  393. }
  394. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  395. * Function: emu_Write_Page_Main_Spare
  396. * Inputs: Write buffer
  397. * address
  398. * buffer length
  399. * Outputs: PASS=0 (notice 0=ok here)
  400. * Description: Write the buffer to main+spare area of flash
  401. *
  402. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  403. u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
  404. u16 Page, u16 page_count)
  405. {
  406. u16 i;
  407. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  408. __FILE__, __LINE__, __func__);
  409. if (Block >= DeviceInfo.wTotalBlocks) {
  410. printk(KERN_ERR "Write Page Main + Spare "
  411. "Error: Block Address too big\n");
  412. return FAIL;
  413. }
  414. if (Page + page_count > DeviceInfo.wPagesPerBlock) {
  415. printk(KERN_ERR "Write Page Main + Spare "
  416. "Error: Page number too big\n");
  417. return FAIL;
  418. }
  419. nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
  420. "No. of pages %u block %u start page %u\n",
  421. (unsigned int)page_count,
  422. (unsigned int)Block, (unsigned int)Page);
  423. for (i = 0; i < page_count; i++) {
  424. if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
  425. printk(KERN_ERR "Run out of memory!\n");
  426. return FAIL;
  427. }
  428. memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
  429. write_data, DeviceInfo.wPageSize);
  430. write_data += DeviceInfo.wPageSize;
  431. Page++;
  432. }
  433. return PASS;
  434. }
  435. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  436. * Function: emu_Write_Page_Spare
  437. * Inputs: Write buffer
  438. * Address
  439. * buffer size
  440. * Outputs: PASS=0 (notice 0=ok here)
  441. * Description: Write the buffer in the spare area
  442. *
  443. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  444. u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
  445. u16 Page, u16 PageCount)
  446. {
  447. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  448. __FILE__, __LINE__, __func__);
  449. if (Block >= DeviceInfo.wTotalBlocks) {
  450. printk(KERN_ERR "Read Page Spare Error: "
  451. "Block Address too big\n");
  452. return FAIL;
  453. }
  454. if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
  455. printk(KERN_ERR "Read Page Spare Error: "
  456. "Page number too big\n");
  457. return FAIL;
  458. }
  459. nand_dbg_print(NAND_DBG_DEBUG, "Write Page Spare- "
  460. "block %u page %u\n",
  461. (unsigned int)Block, (unsigned int)Page);
  462. if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
  463. printk(KERN_ERR "Run out of memory!\n");
  464. return FAIL;
  465. }
  466. memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page] +
  467. DeviceInfo.wPageDataSize), write_data,
  468. (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
  469. return PASS;
  470. }
  471. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  472. * Function: emu_Read_Page_Spare
  473. * Inputs: Write Buffer
  474. * Address
  475. * Buffer size
  476. * Outputs: PASS=0 (notice 0=ok here)
  477. * Description: Read data from the spare area
  478. *
  479. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  480. u16 emu_Read_Page_Spare(u8 *write_data, u32 Block,
  481. u16 Page, u16 PageCount)
  482. {
  483. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  484. __FILE__, __LINE__, __func__);
  485. if (Block >= DeviceInfo.wTotalBlocks) {
  486. printk(KERN_ERR "Read Page Spare "
  487. "Error: Block Address too big\n");
  488. return FAIL;
  489. }
  490. if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
  491. printk(KERN_ERR "Read Page Spare "
  492. "Error: Page number too big\n");
  493. return FAIL;
  494. }
  495. nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
  496. "block %u page %u\n",
  497. (unsigned int)Block, (unsigned int)Page);
  498. if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
  499. memset(write_data, 0xFF,
  500. (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
  501. } else {
  502. memcpy(write_data,
  503. (u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]
  504. + DeviceInfo.wPageDataSize),
  505. (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
  506. }
  507. return PASS;
  508. }
  509. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  510. * Function: emu_Enable_Disable_Interrupts
  511. * Inputs: enable or disable
  512. * Outputs: none
  513. * Description: NOP
  514. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  515. void emu_Enable_Disable_Interrupts(u16 INT_ENABLE)
  516. {
  517. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  518. __FILE__, __LINE__, __func__);
  519. }
  520. u16 emu_Get_Bad_Block(u32 block)
  521. {
  522. return 0;
  523. }
  524. #if CMD_DMA
  525. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  526. * Support for CDMA functions
  527. ************************************
  528. * emu_CDMA_Flash_Init
  529. * CDMA_process_data command (use LLD_CDMA)
  530. * CDMA_MemCopy_CMD (use LLD_CDMA)
  531. * emu_CDMA_execute all commands
  532. * emu_CDMA_Event_Status
  533. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  534. u16 emu_CDMA_Flash_Init(void)
  535. {
  536. u16 i;
  537. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  538. __FILE__, __LINE__, __func__);
  539. for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
  540. PendingCMD[i].CMD = 0;
  541. PendingCMD[i].Tag = 0;
  542. PendingCMD[i].DataAddr = 0;
  543. PendingCMD[i].Block = 0;
  544. PendingCMD[i].Page = 0;
  545. PendingCMD[i].PageCount = 0;
  546. PendingCMD[i].DataDestAddr = 0;
  547. PendingCMD[i].DataSrcAddr = 0;
  548. PendingCMD[i].MemCopyByteCnt = 0;
  549. PendingCMD[i].ChanSync[0] = 0;
  550. PendingCMD[i].ChanSync[1] = 0;
  551. PendingCMD[i].ChanSync[2] = 0;
  552. PendingCMD[i].ChanSync[3] = 0;
  553. PendingCMD[i].ChanSync[4] = 0;
  554. PendingCMD[i].Status = 3;
  555. }
  556. return PASS;
  557. }
  558. static void emu_isr(int irq, void *dev_id)
  559. {
  560. /* TODO: ... */
  561. }
  562. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  563. * Function: CDMA_Execute_CMDs
  564. * Inputs: tag_count: the number of pending cmds to do
  565. * Outputs: PASS/FAIL
  566. * Description: execute each command in the pending CMD array
  567. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  568. u16 emu_CDMA_Execute_CMDs(u16 tag_count)
  569. {
  570. u16 i, j;
  571. u8 CMD; /* cmd parameter */
  572. u8 *data;
  573. u32 block;
  574. u16 page;
  575. u16 count;
  576. u16 status = PASS;
  577. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  578. __FILE__, __LINE__, __func__);
  579. nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
  580. "Tag Count %u\n", tag_count);
  581. for (i = 0; i < totalUsedBanks; i++) {
  582. PendingCMD[i].CMD = DUMMY_CMD;
  583. PendingCMD[i].Tag = 0xFF;
  584. PendingCMD[i].Block =
  585. (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
  586. for (j = 0; j <= MAX_CHANS; j++)
  587. PendingCMD[i].ChanSync[j] = 0;
  588. }
  589. CDMA_Execute_CMDs(tag_count);
  590. print_pending_cmds(tag_count);
  591. #if DEBUG_SYNC
  592. }
  593. debug_sync_cnt++;
  594. #endif
  595. for (i = MAX_CHANS;
  596. i < tag_count + MAX_CHANS; i++) {
  597. CMD = PendingCMD[i].CMD;
  598. data = PendingCMD[i].DataAddr;
  599. block = PendingCMD[i].Block;
  600. page = PendingCMD[i].Page;
  601. count = PendingCMD[i].PageCount;
  602. switch (CMD) {
  603. case ERASE_CMD:
  604. emu_Erase_Block(block);
  605. PendingCMD[i].Status = PASS;
  606. break;
  607. case WRITE_MAIN_CMD:
  608. emu_Write_Page_Main(data, block, page, count);
  609. PendingCMD[i].Status = PASS;
  610. break;
  611. case WRITE_MAIN_SPARE_CMD:
  612. emu_Write_Page_Main_Spare(data, block, page, count);
  613. PendingCMD[i].Status = PASS;
  614. break;
  615. case READ_MAIN_CMD:
  616. emu_Read_Page_Main(data, block, page, count);
  617. PendingCMD[i].Status = PASS;
  618. break;
  619. case MEMCOPY_CMD:
  620. memcpy(PendingCMD[i].DataDestAddr,
  621. PendingCMD[i].DataSrcAddr,
  622. PendingCMD[i].MemCopyByteCnt);
  623. case DUMMY_CMD:
  624. PendingCMD[i].Status = PASS;
  625. break;
  626. default:
  627. PendingCMD[i].Status = FAIL;
  628. break;
  629. }
  630. }
  631. /*
  632. * Temperory adding code to reset PendingCMD array for basic testing.
  633. * It should be done at the end of event status function.
  634. */
  635. for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
  636. PendingCMD[i].CMD = 0;
  637. PendingCMD[i].Tag = 0;
  638. PendingCMD[i].DataAddr = 0;
  639. PendingCMD[i].Block = 0;
  640. PendingCMD[i].Page = 0;
  641. PendingCMD[i].PageCount = 0;
  642. PendingCMD[i].DataDestAddr = 0;
  643. PendingCMD[i].DataSrcAddr = 0;
  644. PendingCMD[i].MemCopyByteCnt = 0;
  645. PendingCMD[i].ChanSync[0] = 0;
  646. PendingCMD[i].ChanSync[1] = 0;
  647. PendingCMD[i].ChanSync[2] = 0;
  648. PendingCMD[i].ChanSync[3] = 0;
  649. PendingCMD[i].ChanSync[4] = 0;
  650. PendingCMD[i].Status = CMD_NOT_DONE;
  651. }
  652. nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
  653. emu_isr(0, 0); /* This is a null isr now. Need fill it in future */
  654. return status;
  655. }
  656. /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  657. * Function: emu_Event_Status
  658. * Inputs: none
  659. * Outputs: Event_Status code
  660. * Description: This function can also be used to force errors
  661. *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
  662. u16 emu_CDMA_Event_Status(void)
  663. {
  664. nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
  665. __FILE__, __LINE__, __func__);
  666. return EVENT_PASS;
  667. }
  668. #endif /* CMD_DMA */
  669. #endif /* !ELDORA */
  670. #endif /* FLASH_EMU */