xd_sm.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019
  1. #include "xd_port.h"
  2. //#include "sm_port.h"
  3. #include "xd_misc.h"
  4. #include "xd_sm.h"
  5. //Global struct variable, to hold all card information need to operate card
  6. static XD_SM_Card_Info_t _xd_sm_info = {CARD_TYPE_NONE, //card_type
  7. 0, //blk_len
  8. 0, //blk_nums
  9. 0, //read_only_flag
  10. 0, //xd_inited_flag
  11. 0, //xd_removed_flag
  12. 0, //xd_init_retry
  13. 0, //sm_inited_flag
  14. 0, //sm_removed_flag
  15. 0, //sm_init_retry
  16. {0}, //raw_cid
  17. NULL, //xd_power
  18. NULL, //xd_get_ins
  19. NULL, //xd_io_release
  20. NULL, //sm_power
  21. NULL, //sm_get_ins
  22. NULL, //sm_get_wp
  23. NULL //sm_io_release
  24. };
  25. #ifndef XD_SM_ALLOC_MEMORY
  26. static XD_SM_Card_Buffer_t _xd_sm_buf;
  27. #endif
  28. XD_SM_Card_Info_t *xd_sm_info = &_xd_sm_info;
  29. //XD_SM_Card_Buffer_t *xd_sm_buf = &_xd_sm_buf;
  30. #ifdef XD_SM_ALLOC_MEMORY
  31. XD_SM_Card_Buffer_t *xd_sm_buf = NULL;
  32. #else
  33. XD_SM_Card_Buffer_t *xd_sm_buf = &_xd_sm_buf;
  34. #endif
  35. extern unsigned char xd_reset_flag_read, xd_reset_flag_write;
  36. static char * xd_sm_error_string[] = {
  37. "XD_SM_NO_ERROR",
  38. "ERROR_DRIVER_FAILURE",
  39. "ERROR_BUSY",
  40. "ERROR_TIMEOUT",
  41. "ERROR_PARAMETER",
  42. "ERROR_ECC",
  43. "ERROR_BLOCK_ADDRESS",
  44. "ERROR_PHYSICAL_FORMAT",
  45. "ERROR_CONVERTSION_TABLE",
  46. "ERROR_UNSUPPORTED_CAPACITY",
  47. "ERROR_DEVICE_ID",
  48. "ERROR_CARD_ID",
  49. "ERROR_LOGICAL_FORMAT",
  50. "ERROR_NO_FREE_BLOCK",
  51. "ERROR_BLOCK_ERASE",
  52. "ERROR_COPY_PAGE",
  53. "ERROR_PAGE_PROGRAM",
  54. "ERROR_DATA",
  55. "ERROR_CARD_TYPE",
  56. "ERROR_NO_MEMORY"
  57. };
  58. unsigned char CIS_DATA_0_9[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20};
  59. char xd_sm_capacity_1MB[] = {"1MB"};
  60. char xd_sm_capacity_2MB[] = {"2MB"};
  61. char xd_sm_capacity_4MB[] = {"4MB"};
  62. char xd_sm_capacity_8MB[] = {"8MB"};
  63. char xd_sm_capacity_16MB[] = {"16MB"};
  64. char xd_sm_capacity_32MB[] = {"32MB"};
  65. char xd_sm_capacity_64MB[] = {"64MB"};
  66. char xd_sm_capacity_128MB[] = {"128MB"};
  67. char xd_sm_capacity_256MB[] = {"256MB"};
  68. char xd_sm_capacity_512MB[] = {"512MB"};
  69. char xd_sm_capacity_1GB[] = {"1GB"};
  70. char xd_sm_capacity_2GB[] = {"2GB"};
  71. static xd_sm_io_config_t xd_sm_io_config = NULL;
  72. static xd_sm_cmd_input_cycle_t xd_sm_cmd_input_cycle = NULL;
  73. static xd_sm_addr_input_cycle_t xd_sm_addr_input_cycle = NULL;
  74. static xd_sm_data_input_cycle_t xd_sm_data_input_cycle = NULL;
  75. static xd_sm_serial_read_cycle_t xd_sm_serial_read_cycle = NULL;
  76. static xd_sm_test_ready_t xd_sm_test_ready = NULL;
  77. unsigned long xd_sm_total_zones = 0;
  78. unsigned long xd_sm_totoal_physical_blks = 0;
  79. unsigned long xd_sm_totoal_logical_blks = 0;
  80. unsigned short xd_sm_physical_blks_perzone = 0;
  81. unsigned short xd_sm_logical_blks_perzone = 0;
  82. unsigned short xd_sm_pages_per_blk = 0;
  83. unsigned short xd_sm_page_size = 0;
  84. unsigned short xd_sm_redundant_size = 0;
  85. unsigned short xd_sm_actually_zones = MAX_SUPPORTED_ZONES;
  86. //All local function definitions, only used in this .C file
  87. char * xd_sm_error_to_string(int errcode);
  88. void xd_sm_function_init(void);
  89. int xd_sm_wait_ready(unsigned long timeout);
  90. int xd_sm_wait_ready_ms(unsigned long timeout);
  91. int xd_sm_status_read(unsigned char cmd, unsigned char *status);
  92. int xd_sm_read_cycle1(unsigned char column_addr, unsigned long page_addr, unsigned char *data_buf, unsigned long data_cnt, unsigned char *redundant_buf);
  93. int xd_sm_read_cycle2(unsigned char column_addr, unsigned long page_addr, unsigned char *data_buf, unsigned long data_cnt, unsigned char *redundant_buf);
  94. int xd_sm_read_cycle3(unsigned char column_addr, unsigned long page_addr, unsigned char *redundant_buf, unsigned long redundant_cnt);
  95. int xd_sm_auto_page_program(unsigned long page_addr, unsigned char *data_buf, unsigned char *redundant_buf);
  96. int xd_sm_auto_block_erase(unsigned long page_addr);
  97. int xd_sm_reset(void);
  98. int xd_sm_id_read(unsigned char cmd, unsigned char *data_buf);
  99. int xd_sm_check_byte_bits(unsigned char value);
  100. int xd_sm_check_page_ecc(unsigned char *page_buf, unsigned char *redundant_buf);
  101. int xd_sm_check_unit_ecc(unsigned char *data_buf, unsigned char *data_ecc);
  102. int xd_sm_format_redundant_area(unsigned char *page_buf, unsigned char *redundant_buf, unsigned short block_addr);
  103. int xd_sm_copy_page(unsigned short zone_no, unsigned short block_src, unsigned short page_src, unsigned short block_dst, unsigned short page_dst);
  104. void xd_sm_set_block_free(unsigned short zone, unsigned short block);
  105. void xd_sm_clear_block_free(unsigned short zone, unsigned short block);
  106. unsigned short xd_sm_find_free_block(unsigned short zone);
  107. void xd_sm_convertion_table_init(void);
  108. int xd_sm_set_defective_block(unsigned short zone, unsigned short block);
  109. int xd_sm_check_back_block(unsigned short zone, unsigned short block);
  110. int xd_sm_search_free_block(void);
  111. int xd_sm_check_block_address_parity(unsigned short block_addr);
  112. int xd_sm_check_block_address_range(unsigned short block_addr);
  113. unsigned short xd_sm_parse_logical_address(unsigned short block_addr);
  114. unsigned short xd_sm_trans_logical_address(unsigned short logical_addr);
  115. int xd_sm_check_erased_block(unsigned char *redundant_buf);
  116. int xd_sm_check_defective_block(unsigned char *redundant_buf);
  117. int xd_sm_block_address_search(unsigned char *redundant_buf, unsigned short *block_addr);
  118. int xd_sm_card_capacity_determin(void);
  119. int xd_sm_card_indentification(void);
  120. int xd_sm_create_logical_physical_table(void);
  121. int xd_sm_logical_format_determin(void);
  122. int xd_sm_physical_format_determin(void);
  123. int xd_sm_reconstruct_logical_physical_table(void);
  124. int xd_sm_erase_all_blocks(void);
  125. int xd_sm_check_data_consistency(void);
  126. void xd_sm_staff_init(void);
  127. int xd_sm_cmd_test(void);
  128. //Return the string buf address of specific errcode
  129. char * xd_sm_error_to_string(int errcode)
  130. {
  131. return xd_sm_error_string[errcode];
  132. }
  133. void xd_sm_function_init(void)
  134. {
  135. #ifdef XD_CARD_SUPPORTED
  136. if(xd_sm_info->card_type == CARD_TYPE_XD)
  137. {
  138. xd_sm_io_config = xd_io_config;
  139. xd_sm_cmd_input_cycle = xd_cmd_input_cycle;
  140. xd_sm_addr_input_cycle = xd_addr_input_cycle;
  141. xd_sm_data_input_cycle = xd_data_input_cycle;
  142. xd_sm_serial_read_cycle = xd_serial_read_cycle;
  143. xd_sm_test_ready = xd_test_ready;
  144. xd_gpio_enable();
  145. }
  146. #endif
  147. #ifdef SM_CARD_SUPPORTED
  148. if(xd_sm_info->card_type == CARD_TYPE_SM)
  149. {
  150. xd_sm_io_config = sm_io_config;
  151. xd_sm_cmd_input_cycle = sm_cmd_input_cycle;
  152. xd_sm_addr_input_cycle = sm_addr_input_cycle;
  153. xd_sm_data_input_cycle = sm_data_input_cycle;
  154. xd_sm_serial_read_cycle = sm_serial_read_cycle;
  155. xd_sm_test_ready = sm_test_ready;
  156. sm_gpio_enable();
  157. }
  158. #endif
  159. }
  160. int xd_sm_wait_ready(unsigned long timeout)
  161. {
  162. xd_sm_start_timer(timeout);
  163. do
  164. {
  165. if(xd_sm_test_ready() == XD_SM_STATUS_READY)
  166. return XD_SM_NO_ERROR;
  167. xd_sm_check_timer();
  168. } while(!xd_sm_check_timeout());
  169. return XD_SM_ERROR_TIMEOUT;
  170. }
  171. int xd_sm_wait_ready_ms(unsigned long timeout)
  172. {
  173. unsigned long i, timecnt;
  174. timecnt = timeout / TIMER_1MS;
  175. for(i=0; i<timecnt; i++)
  176. {
  177. if(xd_sm_test_ready() == XD_SM_STATUS_READY)
  178. return XD_SM_NO_ERROR;
  179. xd_sm_delay_ms(1);
  180. }
  181. return XD_SM_ERROR_TIMEOUT;
  182. }
  183. int xd_sm_status_read(unsigned char cmd, unsigned char *status)
  184. {
  185. if((cmd != XD_SM_STATUS_READ1) && (cmd != XD_STATUS_READ2))
  186. return XD_SM_ERROR_PARAMETER;
  187. xd_sm_cmd_input_cycle(cmd, XD_SM_WRITE_DISABLED);
  188. #ifdef XD_CARD_SUPPORTED
  189. if(xd_sm_info->card_type == CARD_TYPE_XD)
  190. {
  191. xd_set_ce_enable();
  192. xd_set_dat0_7_input();
  193. }
  194. #endif
  195. #ifdef SM_CARD_SUPPORTED
  196. if(xd_sm_info->card_type == CARD_TYPE_SM)
  197. {
  198. sm_set_ce_enable();
  199. sm_set_dat0_7_input();
  200. }
  201. #endif
  202. xd_sm_delay_20ns(); // Tcls = 20ns
  203. xd_sm_serial_read_cycle(status, 1, NULL, 0);
  204. #ifdef XD_CARD_SUPPORTED
  205. if(xd_sm_info->card_type == CARD_TYPE_XD)
  206. xd_set_ce_disable();
  207. #endif
  208. #ifdef SM_CARD_SUPPORTED
  209. if(xd_sm_info->card_type == CARD_TYPE_SM)
  210. sm_set_ce_disable();
  211. #endif
  212. return XD_SM_NO_ERROR;
  213. }
  214. int xd_sm_read_cycle1(unsigned char column_addr, unsigned long page_addr, unsigned char *data_buf, unsigned long data_cnt, unsigned char *redundant_buf)
  215. {
  216. int err;
  217. unsigned long data_nums = 0, data_offset = 0, read_cnt;
  218. xd_sm_cmd_input_cycle(XD_SM_READ1, XD_SM_WRITE_DISABLED);
  219. xd_sm_addr_input_cycle((page_addr << 8)|column_addr, xd_sm_buf->addr_cycles);
  220. #ifdef XD_CARD_SUPPORTED
  221. if(xd_sm_info->card_type == CARD_TYPE_XD)
  222. {
  223. xd_set_dat0_7_input();
  224. xd_sm_delay_60ns(); // Tar2 = 50ns
  225. }
  226. #endif
  227. #ifdef SM_CARD_SUPPORTED
  228. if(xd_sm_info->card_type == CARD_TYPE_SM)
  229. {
  230. sm_set_dat0_7_input();
  231. xd_sm_delay_100ns(2); // Tar2 = 150ns
  232. }
  233. #endif
  234. read_cnt = xd_sm_page_size - column_addr;
  235. while(data_nums < data_cnt)
  236. {
  237. err = xd_sm_wait_ready(BUSY_TIME_R);
  238. if(err)
  239. {
  240. #ifdef XD_CARD_SUPPORTED
  241. if(xd_sm_info->card_type == CARD_TYPE_XD)
  242. xd_set_ce_disable();
  243. #endif
  244. #ifdef SM_CARD_SUPPORTED
  245. if(xd_sm_info->card_type == CARD_TYPE_SM)
  246. sm_set_ce_disable();
  247. #endif
  248. return err;
  249. }
  250. xd_sm_delay_20ns(); // Trr = 20ns
  251. #ifdef XD_SM_ECC_CHECK
  252. xd_sm_serial_read_cycle(xd_sm_buf->page_buf, read_cnt, redundant_buf, xd_sm_redundant_size);
  253. err = xd_sm_check_page_ecc(xd_sm_buf->page_buf, redundant_buf);
  254. if(err)
  255. {
  256. if(err == ECC_ERROR_CORRECTED)
  257. {
  258. #ifdef XD_SM_DEBUG
  259. Debug_Printf("Data ECC error occured, but corrected!\n");
  260. #endif
  261. }
  262. else
  263. {
  264. #ifdef XD_SM_DEBUG
  265. err = XD_SM_ERROR_ECC;
  266. Debug_Printf("#%s error occured in xd_sm_read_data()\n", xd_sm_error_to_string(err));
  267. #endif
  268. }
  269. }
  270. #ifdef AMLOGIC_CHIP_SUPPORT
  271. if((unsigned long)data_buf == 0x3400000)
  272. {
  273. for(int i=0; i<read_cnt; i++)
  274. {
  275. WRITE_BYTE_TO_FIFO(xd_sm_buf->page_buf[i]);
  276. xd_sm_delay_100ns(1);
  277. }
  278. }
  279. else
  280. #endif
  281. {
  282. memcpy(data_buf+data_offset, xd_sm_buf->page_buf, read_cnt);
  283. }
  284. #else
  285. xd_sm_serial_read_cycle(data_buf+data_offset, read_cnt, redundant_buf, xd_sm_redundant_size);
  286. #endif
  287. //Improve stability for Fujufilm 512MB and above
  288. xd_sm_delay_us(5);
  289. #ifdef AMLOGIC_CHIP_SUPPORT
  290. data_offset += ((unsigned long)data_buf == 0x3400000 ? 0 : read_cnt);
  291. #else
  292. data_offset += read_cnt;
  293. #endif
  294. redundant_buf += xd_sm_redundant_size;
  295. data_nums += read_cnt;
  296. read_cnt = xd_sm_page_size;
  297. }
  298. #ifdef XD_CARD_SUPPORTED
  299. if(xd_sm_info->card_type == CARD_TYPE_XD)
  300. {
  301. xd_set_ce_disable();
  302. xd_sm_delay_100ns(1); // Tceh = 100ns
  303. }
  304. #endif
  305. #ifdef SM_CARD_SUPPORTED
  306. if(xd_sm_info->card_type == CARD_TYPE_SM)
  307. {
  308. sm_set_ce_disable();
  309. xd_sm_delay_100ns(3); // Tceh = 250ns
  310. }
  311. #endif
  312. err = xd_sm_wait_ready(BUSY_TIME_TCRY);
  313. return err;
  314. }
  315. int xd_sm_read_cycle2(unsigned char column_addr, unsigned long page_addr, unsigned char *data_buf, unsigned long data_cnt, unsigned char *redundant_buf)
  316. {
  317. int err;
  318. unsigned long data_nums = 0, data_offset = 0, read_cnt;
  319. if(xd_sm_page_size != XD_SM_SECTOR_SIZE)
  320. return XD_SM_ERROR_PARAMETER;
  321. xd_sm_cmd_input_cycle(XD_SM_READ2, XD_SM_WRITE_DISABLED);
  322. xd_sm_addr_input_cycle((page_addr << 8)|column_addr, xd_sm_buf->addr_cycles);
  323. #ifdef XD_CARD_SUPPORTED
  324. if(xd_sm_info->card_type == CARD_TYPE_XD)
  325. {
  326. xd_set_dat0_7_input();
  327. xd_sm_delay_60ns(); // Tar2 = 50ns
  328. }
  329. #endif
  330. #ifdef SM_CARD_SUPPORTED
  331. if(xd_sm_info->card_type == CARD_TYPE_SM)
  332. {
  333. sm_set_dat0_7_input();
  334. xd_sm_delay_100ns(2); // Tar2 = 150ns
  335. }
  336. #endif
  337. read_cnt = xd_sm_page_size - (XD_SM_SECTOR_SIZE/2 + column_addr);
  338. while(data_nums < data_cnt)
  339. {
  340. err = xd_sm_wait_ready(XD_BUSY_TIME_R);
  341. if(err)
  342. {
  343. #ifdef XD_CARD_SUPPORTED
  344. if(xd_sm_info->card_type == CARD_TYPE_XD)
  345. xd_set_ce_disable();
  346. #endif
  347. #ifdef SM_CARD_SUPPORTED
  348. if(xd_sm_info->card_type == CARD_TYPE_SM)
  349. sm_set_ce_disable();
  350. #endif
  351. return err;
  352. }
  353. xd_sm_delay_20ns(); // Trr = 20ns
  354. #ifdef XD_SM_ECC_CHECK
  355. xd_sm_serial_read_cycle(xd_sm_buf->page_buf, read_cnt, redundant_buf, xd_sm_redundant_size);
  356. err = xd_sm_check_page_ecc(xd_sm_buf->page_buf, redundant_buf);
  357. if(err)
  358. {
  359. if(err == ECC_ERROR_CORRECTED)
  360. {
  361. #ifdef XD_SM_DEBUG
  362. Debug_Printf("Data ECC error occured, but corrected!\n");
  363. #endif
  364. }
  365. else
  366. {
  367. #ifdef XD_SM_DEBUG
  368. err = XD_SM_ERROR_ECC;
  369. Debug_Printf("#%s error occured in xd_sm_read_data()\n", xd_sm_error_to_string(err));
  370. #endif
  371. }
  372. }
  373. #ifdef AMLOGIC_CHIP_SUPPORT
  374. if((unsigned long)data_buf == 0x3400000)
  375. {
  376. for(int i=0; i<read_cnt; i++)
  377. {
  378. WRITE_BYTE_TO_FIFO(xd_sm_buf->page_buf[i]);
  379. xd_sm_delay_100ns(1);
  380. }
  381. }
  382. else
  383. #endif
  384. {
  385. memcpy(data_buf+data_offset, xd_sm_buf->page_buf, read_cnt);
  386. }
  387. #else
  388. xd_sm_serial_read_cycle(data_buf+data_offset, read_cnt, redundant_buf, xd_sm_redundant_size);
  389. #endif
  390. #ifdef AMLOGIC_CHIP_SUPPORT
  391. data_offset += ((unsigned long)data_buf == 0x3400000 ? 0 : read_cnt);
  392. #else
  393. data_offset += read_cnt;
  394. #endif
  395. redundant_buf += xd_sm_redundant_size;
  396. data_nums += read_cnt;
  397. read_cnt = xd_sm_page_size;
  398. }
  399. #ifdef XD_CARD_SUPPORTED
  400. if(xd_sm_info->card_type == CARD_TYPE_XD)
  401. {
  402. xd_set_ce_disable();
  403. xd_sm_delay_100ns(1); // Tceh = 100ns
  404. }
  405. #endif
  406. #ifdef SM_CARD_SUPPORTED
  407. if(xd_sm_info->card_type == CARD_TYPE_SM)
  408. {
  409. sm_set_ce_disable();
  410. xd_sm_delay_100ns(3); // Tceh = 250ns
  411. }
  412. #endif
  413. err = xd_sm_wait_ready(BUSY_TIME_TCRY);
  414. return err;
  415. }
  416. int xd_sm_read_cycle3(unsigned char column_addr, unsigned long page_addr, unsigned char *redundant_buf, unsigned long redundant_cnt)
  417. {
  418. int err;
  419. unsigned long redundant_offset = column_addr;
  420. unsigned long redundant_nums = 0;
  421. xd_sm_cmd_input_cycle(XD_SM_READ3, XD_SM_WRITE_DISABLED);
  422. xd_sm_addr_input_cycle((page_addr << 8)|column_addr, xd_sm_buf->addr_cycles);
  423. #ifdef XD_CARD_SUPPORTED
  424. if(xd_sm_info->card_type == CARD_TYPE_XD)
  425. {
  426. xd_set_dat0_7_input();
  427. xd_sm_delay_60ns(); // Tar2 = 50ns
  428. }
  429. #endif
  430. #ifdef SM_CARD_SUPPORTED
  431. if(xd_sm_info->card_type == CARD_TYPE_SM)
  432. {
  433. sm_set_dat0_7_input();
  434. xd_sm_delay_100ns(2); // Tar2 = 150ns
  435. }
  436. #endif
  437. while(redundant_nums < redundant_cnt)
  438. {
  439. err = xd_sm_wait_ready(BUSY_TIME_R);
  440. if(err)
  441. {
  442. #ifdef XD_CARD_SUPPORTED
  443. if(xd_sm_info->card_type == CARD_TYPE_XD)
  444. xd_set_ce_disable();
  445. #endif
  446. #ifdef SM_CARD_SUPPORTED
  447. if(xd_sm_info->card_type == CARD_TYPE_SM)
  448. sm_set_ce_disable();
  449. #endif
  450. return err;
  451. }
  452. xd_sm_delay_20ns(); // Trr = 20ns
  453. xd_sm_serial_read_cycle(NULL, 0, redundant_buf, xd_sm_redundant_size-redundant_offset);
  454. redundant_buf += (xd_sm_redundant_size - redundant_offset);
  455. redundant_nums += (xd_sm_redundant_size - redundant_offset);
  456. redundant_offset = 0;
  457. }
  458. #ifdef XD_CARD_SUPPORTED
  459. if(xd_sm_info->card_type == CARD_TYPE_XD)
  460. {
  461. xd_set_ce_disable();
  462. xd_sm_delay_100ns(1); // Tceh = 100ns
  463. }
  464. #endif
  465. #ifdef SM_CARD_SUPPORTED
  466. if(xd_sm_info->card_type == CARD_TYPE_SM)
  467. {
  468. sm_set_ce_disable();
  469. xd_sm_delay_100ns(3); // Tceh = 250ns
  470. }
  471. #endif
  472. err = xd_sm_wait_ready(BUSY_TIME_TCRY);
  473. return err;
  474. }
  475. int xd_sm_auto_page_program(unsigned long page_addr, unsigned char *data_buf, unsigned char *redundant_buf)
  476. {
  477. int err;
  478. unsigned char column_addr = 0;
  479. XD_SM_Status1_t status1;
  480. xd_sm_cmd_input_cycle(XD_SM_SERIAL_DATA_INPUT, XD_SM_WRITE_ENABLED);
  481. xd_sm_addr_input_cycle((page_addr << 8)|column_addr, xd_sm_buf->addr_cycles);
  482. xd_sm_delay_20ns(); // Tals = 20ns
  483. xd_sm_data_input_cycle(data_buf, xd_sm_page_size, redundant_buf, xd_sm_redundant_size);
  484. xd_sm_cmd_input_cycle(XD_SM_TRUE_PAGE_PROGRAM, XD_SM_WRITE_DISABLED);
  485. err = xd_sm_wait_ready_ms(BUSY_TIME_PROG);
  486. if(err)
  487. {
  488. #ifdef XD_CARD_SUPPORTED
  489. if(xd_sm_info->card_type == CARD_TYPE_XD)
  490. xd_set_wp_enable();
  491. #endif
  492. #ifdef SM_CARD_SUPPORTED
  493. if(xd_sm_info->card_type == CARD_TYPE_SM)
  494. sm_set_wp_enable();
  495. #endif
  496. return XD_SM_ERROR_TIMEOUT;
  497. }
  498. xd_sm_delay_100ns(1); // Tww = 100ns
  499. #ifdef XD_CARD_SUPPORTED
  500. if(xd_sm_info->card_type == CARD_TYPE_XD)
  501. xd_set_wp_enable();
  502. #endif
  503. #ifdef SM_CARD_SUPPORTED
  504. if(xd_sm_info->card_type == CARD_TYPE_SM)
  505. sm_set_wp_enable();
  506. #endif
  507. xd_sm_delay_100ns(1); // Tww = 100ns
  508. err = xd_sm_status_read(XD_SM_STATUS_READ1, (unsigned char *)&status1);
  509. if(err)
  510. return err;
  511. if((status1.Ready_Busy == XD_SM_STATUS_READY) && (status1.Pass_Fail == XD_SM_STATUS_PASS))
  512. return XD_SM_NO_ERROR;
  513. return XD_SM_ERROR_PAGE_PROGRAM;
  514. }
  515. int xd_sm_auto_block_erase(unsigned long page_addr)
  516. {
  517. int err;
  518. XD_SM_Status1_t status1;
  519. xd_sm_cmd_input_cycle(XD_SM_BLOCK_ERASE_SETUP, XD_SM_WRITE_ENABLED);
  520. xd_sm_addr_input_cycle(page_addr, xd_sm_buf->addr_cycles-1);
  521. xd_sm_cmd_input_cycle(XD_SM_BLOCK_ERASE_EXECUTE, XD_SM_WRITE_DISABLED);
  522. err = xd_sm_wait_ready_ms(BUSY_TIME_BERASE);
  523. if(err)
  524. {
  525. #ifdef XD_CARD_SUPPORTED
  526. if(xd_sm_info->card_type == CARD_TYPE_XD)
  527. xd_set_wp_enable();
  528. #endif
  529. #ifdef SM_CARD_SUPPORTED
  530. if(xd_sm_info->card_type == CARD_TYPE_SM)
  531. sm_set_wp_enable();
  532. #endif
  533. return XD_SM_ERROR_TIMEOUT;
  534. }
  535. xd_sm_delay_100ns(1); // Tww = 100ns
  536. #ifdef XD_CARD_SUPPORTED
  537. if(xd_sm_info->card_type == CARD_TYPE_XD)
  538. xd_set_wp_enable();
  539. #endif
  540. #ifdef SM_CARD_SUPPORTED
  541. if(xd_sm_info->card_type == CARD_TYPE_SM)
  542. sm_set_wp_enable();
  543. #endif
  544. err = xd_sm_status_read(XD_SM_STATUS_READ1, (unsigned char *)&status1);
  545. if(err)
  546. return err;
  547. if((status1.Ready_Busy == XD_SM_STATUS_READY) && (status1.Pass_Fail == XD_SM_STATUS_PASS))
  548. return XD_SM_NO_ERROR;
  549. return XD_SM_ERROR_BLOCK_ERASE;
  550. }
  551. int xd_sm_reset(void)
  552. {
  553. xd_sm_cmd_input_cycle(XD_SM_RESET, XD_SM_WRITE_DISABLED);
  554. return xd_sm_wait_ready(BUSY_TIME_RST);
  555. }
  556. int xd_sm_id_read(unsigned char cmd, unsigned char *data_buf)
  557. {
  558. int data_cnt = 4;
  559. if((cmd != XD_SM_ID_READ90) && (cmd != XD_SM_ID_READ91) && (cmd != XD_ID_READ9A))
  560. return XD_SM_ERROR_PARAMETER;
  561. if(cmd == XD_SM_ID_READ91)
  562. data_cnt = 5;
  563. if(xd_sm_test_ready() == XD_SM_STATUS_BUSY)
  564. return XD_SM_ERROR_BUSY;
  565. xd_sm_cmd_input_cycle(cmd, XD_SM_WRITE_DISABLED);
  566. xd_sm_addr_input_cycle(0x00, 1);
  567. #ifdef XD_CARD_SUPPORTED
  568. if(xd_sm_info->card_type == CARD_TYPE_XD)
  569. {
  570. xd_set_dat0_7_input();
  571. xd_sm_delay_100ns(1); // Tar1 = Tcr = 100ns
  572. }
  573. #endif
  574. #ifdef SM_CARD_SUPPORTED
  575. if(xd_sm_info->card_type == CARD_TYPE_SM)
  576. {
  577. sm_set_dat0_7_input();
  578. xd_sm_delay_100ns(2); // Tar1 = Tcr = 200ns
  579. }
  580. #endif
  581. xd_sm_serial_read_cycle(data_buf, data_cnt, NULL, 0);
  582. #ifdef XD_CARD_SUPPORTED
  583. if(xd_sm_info->card_type == CARD_TYPE_XD)
  584. xd_set_ce_disable();
  585. #endif
  586. #ifdef SM_CARD_SUPPORTED
  587. if(xd_sm_info->card_type == CARD_TYPE_SM)
  588. sm_set_ce_disable();
  589. #endif
  590. return XD_SM_NO_ERROR;
  591. }
  592. int xd_sm_check_byte_bits(unsigned char value)
  593. {
  594. unsigned char mask = 0x01;
  595. int cnt,i;
  596. cnt = 0;
  597. for(i=0; i<8; i++)
  598. {
  599. mask <<= i;
  600. if(value & mask)
  601. cnt++;
  602. }
  603. return cnt;
  604. }
  605. int xd_sm_check_page_ecc(unsigned char *page_buf, unsigned char *redundant_buf)
  606. {
  607. int err;
  608. unsigned char cal_ecc1, cal_ecc2, cal_ecc3;
  609. XD_SM_Redundant_Area_t *redundant = (void *)redundant_buf;
  610. ecc_calculate_ecc(ecc_table, page_buf+STORING_AREA1_OFFSET, &cal_ecc1, &cal_ecc2, &cal_ecc3);
  611. err = ecc_correct_data(page_buf+STORING_AREA1_OFFSET, redundant->ECC1, cal_ecc1, cal_ecc2, cal_ecc3);
  612. if((err != ECC_NO_ERROR) && (err != ECC_ERROR_CORRECTED))
  613. return err;
  614. ecc_calculate_ecc(ecc_table, page_buf+STORING_AREA2_OFFSET, &cal_ecc1, &cal_ecc2, &cal_ecc3);
  615. err = ecc_correct_data(page_buf+STORING_AREA2_OFFSET, redundant->ECC2, cal_ecc1, cal_ecc2, cal_ecc3);
  616. return err;
  617. }
  618. int xd_sm_check_unit_ecc(unsigned char *data_buf, unsigned char *data_ecc)
  619. {
  620. unsigned char cal_ecc1, cal_ecc2, cal_ecc3;
  621. ecc_calculate_ecc(ecc_table, data_buf, &cal_ecc1, &cal_ecc2, &cal_ecc3);
  622. return ecc_correct_data(data_buf, data_ecc, cal_ecc1, cal_ecc2, cal_ecc3);
  623. }
  624. int xd_sm_format_redundant_area(unsigned char *page_buf, unsigned char *redundant_buf, unsigned short block_addr)
  625. {
  626. int i;
  627. unsigned char cal_ecc1, cal_ecc2, cal_ecc3;
  628. XD_SM_Redundant_Area_t *redundant = (void *)redundant_buf;
  629. for(i=0; i<xd_sm_redundant_size; i++)
  630. redundant_buf[i] = 0xFF;
  631. ecc_calculate_ecc(ecc_table, page_buf+STORING_AREA1_OFFSET, &cal_ecc1, &cal_ecc2, &cal_ecc3);
  632. redundant->ECC1[0] = cal_ecc2;
  633. redundant->ECC1[1] = cal_ecc1;
  634. redundant->ECC1[2] = cal_ecc3;
  635. redundant->Block_Address1[0] = (block_addr >> 8) & 0xFF;
  636. redundant->Block_Address1[1] = block_addr & 0xFF;
  637. ecc_calculate_ecc(ecc_table, page_buf+STORING_AREA2_OFFSET, &cal_ecc1, &cal_ecc2, &cal_ecc3);
  638. redundant->ECC2[0] = cal_ecc2;
  639. redundant->ECC2[1] = cal_ecc1;
  640. redundant->ECC2[2] = cal_ecc3;
  641. redundant->Block_Address2[0] = (block_addr >> 8) & 0xFF;
  642. redundant->Block_Address2[1] = block_addr & 0xFF;
  643. return ECC_NO_ERROR;
  644. }
  645. int xd_sm_copy_page(unsigned short zone_no, unsigned short block_src, unsigned short page_src, unsigned short block_dst, unsigned short page_dst)
  646. {
  647. int err;
  648. unsigned long page_addr;
  649. page_addr = (zone_no * xd_sm_physical_blks_perzone + block_src) * xd_sm_pages_per_blk + page_src;
  650. err = xd_sm_read_cycle1(0, page_addr, xd_sm_buf->page_buf, xd_sm_page_size, xd_sm_buf->redundant_buf);
  651. if(err)
  652. return err;
  653. page_addr = (zone_no * xd_sm_physical_blks_perzone + block_dst) * xd_sm_pages_per_blk + page_dst;
  654. err = xd_sm_auto_page_program(page_addr, xd_sm_buf->page_buf, xd_sm_buf->redundant_buf);
  655. if(err)
  656. return err;
  657. return XD_SM_NO_ERROR;
  658. }
  659. void xd_sm_set_block_free(unsigned short zone, unsigned short block)
  660. {
  661. unsigned short byte_offset, bit_offset, mask;
  662. byte_offset = block >> 3;
  663. bit_offset = block % 8;
  664. mask = 0x80 >> bit_offset;
  665. xd_sm_buf->free_block_table[zone][byte_offset] |= mask;
  666. }
  667. void xd_sm_clear_block_free(unsigned short zone, unsigned short block)
  668. {
  669. unsigned short byte_offset, bit_offset, mask;
  670. byte_offset = block >> 3;
  671. bit_offset = block % 8;
  672. mask = 0x80 >> bit_offset;
  673. xd_sm_buf->free_block_table[zone][byte_offset] &= ~mask;
  674. }
  675. unsigned short xd_sm_find_free_block(unsigned short zone)
  676. {
  677. unsigned short byte_offset, bit_offset, mask, block;
  678. for(block=0; block<xd_sm_physical_blks_perzone; block++)
  679. {
  680. byte_offset = block >> 3;
  681. bit_offset = block % 8;
  682. mask = 0x80 >> bit_offset;
  683. if(xd_sm_buf->free_block_table[zone][byte_offset] & mask)
  684. return block;
  685. }
  686. return INVALID_BLOCK_ADDRESS;
  687. }
  688. void xd_sm_convertion_table_init(void)
  689. {
  690. unsigned short i,j;
  691. //Mark all logical address as not assigned
  692. for(i=0; i<xd_sm_actually_zones; i++)
  693. for(j=0; j<xd_sm_logical_blks_perzone; j++)
  694. xd_sm_buf->logical_physical_table[i][j] = INVALID_BLOCK_ADDRESS;
  695. //Mark all physical blocks as assigned
  696. for(i=0; i<xd_sm_actually_zones; i++)
  697. for(j=0; j<(xd_sm_physical_blks_perzone/8); j++)
  698. xd_sm_buf->free_block_table[i][j] = 0;
  699. }
  700. int xd_sm_set_defective_block(unsigned short zone, unsigned short block)
  701. {
  702. unsigned long page_addr;
  703. XD_SM_Redundant_Area_t *redundant = (void *)xd_sm_buf->redundant_buf;
  704. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk;
  705. memset(xd_sm_buf->page_buf, 0, xd_sm_page_size);
  706. redundant->Data_Status_Flag = DATA_STATUS_INVALID;
  707. redundant->Block_Status_Flag = BLOCK_STATUS_MARKED_DEFECTIVE;
  708. return xd_sm_auto_page_program(page_addr, xd_sm_buf->page_buf, xd_sm_buf->redundant_buf);
  709. }
  710. int xd_sm_check_back_block(unsigned short zone, unsigned short block)
  711. {
  712. int err;
  713. unsigned long page_addr;
  714. unsigned short logical_addr, block_addr;
  715. memset(xd_sm_buf->page_buf, 0, xd_sm_page_size);
  716. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk;
  717. err = xd_sm_auto_block_erase(page_addr);
  718. if(err)
  719. return err;
  720. xd_sm_buf->page_buf[0] = 0xAA;
  721. xd_sm_buf->page_buf[1] = 0x55;
  722. logical_addr = xd_sm_physical_blks_perzone-1;
  723. block_addr = xd_sm_trans_logical_address(logical_addr);
  724. err = xd_sm_format_redundant_area(xd_sm_buf->page_buf, xd_sm_buf->redundant_buf, block_addr);
  725. if(err)
  726. return err;
  727. xd_sm_buf->page_buf[0] = 0x00;
  728. xd_sm_buf->page_buf[1] = 0x00;
  729. err = xd_sm_read_cycle1(0, page_addr, xd_sm_buf->page_buf, xd_sm_page_size, xd_sm_buf->redundant_buf);
  730. if(err)
  731. return err;
  732. if((xd_sm_buf->page_buf[0] != 0xAA) || (xd_sm_buf->page_buf[1] != 0x55))
  733. return XD_SM_ERROR_DATA;
  734. xd_sm_buf->page_buf[0] = 0x55;
  735. xd_sm_buf->page_buf[1] = 0xAA;
  736. logical_addr = xd_sm_physical_blks_perzone-1;
  737. block_addr = xd_sm_trans_logical_address(logical_addr);
  738. err = xd_sm_format_redundant_area(xd_sm_buf->page_buf, xd_sm_buf->redundant_buf, block_addr);
  739. if(err)
  740. return err;
  741. xd_sm_buf->page_buf[0] = 0x00;
  742. xd_sm_buf->page_buf[1] = 0x00;
  743. err = xd_sm_read_cycle1(0, page_addr, xd_sm_buf->page_buf, xd_sm_page_size, xd_sm_buf->redundant_buf);
  744. if(err)
  745. return err;
  746. if((xd_sm_buf->page_buf[0] != 0x55) || (xd_sm_buf->page_buf[1] != 0xAA))
  747. return XD_SM_ERROR_DATA;
  748. err = xd_sm_auto_block_erase(page_addr);
  749. if(err)
  750. return err;
  751. return XD_SM_NO_ERROR;
  752. }
  753. int xd_sm_check_block_address_parity(unsigned short block_addr)
  754. {
  755. int bit,i;
  756. unsigned short mask;
  757. mask = 0x001;
  758. bit = 0;
  759. for(i=0; i<16; i++)
  760. {
  761. if((mask << i) & block_addr)
  762. bit ^= 1;
  763. }
  764. if(bit)
  765. return 0;
  766. else
  767. return 1;
  768. }
  769. int xd_sm_check_block_address_range(unsigned short block_addr)
  770. {
  771. if((block_addr & 0xF800) != 0x1000)
  772. return 0;
  773. block_addr &= 0x07FF;
  774. block_addr >>= 1;
  775. if(block_addr < xd_sm_logical_blks_perzone)
  776. return 1;
  777. else
  778. return 0;
  779. }
  780. unsigned short xd_sm_parse_logical_address(unsigned short block_addr)
  781. {
  782. unsigned long logical_addr = block_addr;
  783. logical_addr &= 0x07FF;
  784. logical_addr >>= 1;
  785. return logical_addr;
  786. }
  787. unsigned short xd_sm_trans_logical_address(unsigned short logical_addr)
  788. {
  789. unsigned long block_addr = logical_addr;
  790. int bit = 0;
  791. unsigned short mask = 0x0001;
  792. int i;
  793. block_addr <<= 1;
  794. block_addr &= 0x07FE;
  795. block_addr |= 0x1000;
  796. for(i=1; i<16; i++)
  797. {
  798. if((mask << i) & block_addr)
  799. bit ^= 1;
  800. }
  801. if(bit)
  802. block_addr |= 0x0001;
  803. return block_addr;
  804. }
  805. int xd_sm_check_erased_block(unsigned char *redundant_buf)
  806. {
  807. int err = 0;
  808. int i;
  809. for(i=0; i<xd_sm_redundant_size; i++)
  810. {
  811. if(redundant_buf[i] != 0xFF)
  812. {
  813. err = 1;
  814. break;
  815. }
  816. }
  817. if(err)
  818. return 0;
  819. else
  820. return 1;
  821. }
  822. int xd_sm_check_defective_block(unsigned char *redundant_buf)
  823. {
  824. XD_SM_Redundant_Area_t *redundant = (void *)redundant_buf;
  825. if((redundant->Block_Status_Flag != BLOCK_STATUS_NORMAL)
  826. && (xd_sm_check_byte_bits(redundant->Block_Status_Flag) < 2))
  827. {
  828. return 1;
  829. }
  830. if((redundant->Data_Status_Flag != DATA_STATUS_VALID)
  831. && (xd_sm_check_byte_bits(redundant->Data_Status_Flag) < 4))
  832. {
  833. return 1;
  834. }
  835. return 0;
  836. }
  837. int xd_sm_block_address_search(unsigned char *redundant_buf, unsigned short *block_addr)
  838. {
  839. XD_SM_Redundant_Area_t *redundant = (void *)redundant_buf;
  840. unsigned short block_addr1 = (redundant->Block_Address1[0] << 8) | redundant->Block_Address1[1];
  841. unsigned short block_addr2 = (redundant->Block_Address2[0] << 8) | redundant->Block_Address2[1];
  842. if(block_addr1 != block_addr2)
  843. {
  844. if(xd_sm_check_block_address_parity(block_addr2) && xd_sm_check_block_address_range(block_addr2))
  845. {
  846. if(!xd_sm_check_block_address_parity(block_addr1) || !xd_sm_check_block_address_range(block_addr1))
  847. {
  848. *block_addr = xd_sm_parse_logical_address(block_addr2);
  849. return XD_SM_NO_ERROR;
  850. }
  851. //Erase block or skip
  852. return XD_SM_ERROR_BLOCK_ADDRESS;
  853. }
  854. }
  855. if(!xd_sm_check_block_address_parity(block_addr1) || !xd_sm_check_block_address_range(block_addr1))
  856. {
  857. //Erase block or skip
  858. return XD_SM_ERROR_BLOCK_ADDRESS;
  859. }
  860. *block_addr = xd_sm_parse_logical_address(block_addr1);
  861. return XD_SM_NO_ERROR;
  862. }
  863. int xd_sm_card_capacity_determin(void)
  864. {
  865. int err;
  866. unsigned long temp;
  867. XD_SM_ID_90_t id_90;
  868. err = xd_sm_id_read(XD_SM_ID_READ90, (unsigned char *)&id_90);
  869. if(err)
  870. return err;
  871. #ifdef XD_CARD_SUPPORTED
  872. if(xd_sm_info->card_type == CARD_TYPE_XD)
  873. {
  874. err = xd_card_capacity_determin(id_90.Device_Code);
  875. if(err)
  876. return err;
  877. }
  878. #endif
  879. #ifdef SM_CARD_SUPPORTED
  880. if(xd_sm_info->card_type == CARD_TYPE_SM)
  881. {
  882. err = sm_card_capacity_determin(id_90.Device_Code);
  883. if(err)
  884. return err;
  885. }
  886. #endif
  887. if(xd_sm_info->card_type == CARD_TYPE_NONE)
  888. return XD_SM_ERROR_CARD_TYPE;
  889. if(xd_sm_total_zones > xd_sm_actually_zones)
  890. return XD_SM_ERROR_UNSUPPORTED_CAPACITY;
  891. xd_sm_info->blk_len = XD_SM_SECTOR_SIZE;
  892. temp = xd_sm_totoal_logical_blks;
  893. temp *= xd_sm_pages_per_blk;
  894. xd_sm_info->blk_nums = temp;
  895. return XD_SM_NO_ERROR;
  896. }
  897. int xd_sm_card_indentification(void)
  898. {
  899. int err;
  900. XD_ID_9A_t id_9a;
  901. if(xd_sm_info->card_type == CARD_TYPE_SM)
  902. return XD_SM_NO_ERROR;
  903. err = xd_sm_id_read(XD_ID_READ9A, (unsigned char *)&id_9a);
  904. if(err)
  905. return err;
  906. if(id_9a.XD_CARD_ID != 0xB5)
  907. {
  908. #ifdef XD_SM_DEBUG
  909. Debug_Printf("#XD_CARD_ID error\n");
  910. #endif
  911. //return XD_SM_ERROR_CARD_ID;
  912. }
  913. xd_sm_info->raw_cid = id_9a;
  914. return XD_SM_NO_ERROR;
  915. }
  916. int xd_sm_create_logical_physical_table(void)
  917. {
  918. int err, err_count = 0;
  919. unsigned short zone, block, block_temp;
  920. unsigned short logical_addr, logical_temp;
  921. unsigned long page_addr;
  922. xd_sm_convertion_table_init();
  923. for(zone=0; zone<xd_sm_total_zones; zone++)
  924. {
  925. for(block=0; block<xd_sm_physical_blks_perzone; block++)
  926. {
  927. //Is it CIS area in case of Zone 0?
  928. if((zone == 0) && (block == xd_sm_buf->cis_block_no))
  929. continue;
  930. //Read the data in the redundant area in the first sector
  931. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk;
  932. err = xd_sm_read_cycle3(0, page_addr, xd_sm_buf->redundant_buf, xd_sm_redundant_size);
  933. if(err)
  934. {
  935. err_count++;
  936. if(err_count > 10)
  937. return err;
  938. else
  939. continue;
  940. }
  941. //Is it unused block?
  942. if(xd_sm_check_erased_block(xd_sm_buf->redundant_buf))
  943. {
  944. xd_sm_set_block_free(zone, block);
  945. continue;
  946. }
  947. //Is is defective block?
  948. if(xd_sm_check_defective_block(xd_sm_buf->redundant_buf))
  949. continue;
  950. //Check the logical block address
  951. err = xd_sm_block_address_search(xd_sm_buf->redundant_buf, &logical_addr);
  952. if(err)
  953. {
  954. //xd_sm_set_block_free(zone, block);
  955. continue;
  956. }
  957. //Already entried on the convertsion table?
  958. if(xd_sm_buf->logical_physical_table[zone][logical_addr] == INVALID_BLOCK_ADDRESS)
  959. {
  960. xd_sm_buf->logical_physical_table[zone][logical_addr] = block;
  961. continue;
  962. }
  963. //Read the data in the redundant area in the last sector
  964. page_addr += (xd_sm_pages_per_blk - 1);
  965. err = xd_sm_read_cycle3(0, page_addr, xd_sm_buf->redundant_buf, xd_sm_redundant_size);
  966. if(err)
  967. {
  968. err_count++;
  969. if(err_count > 10)
  970. return err;
  971. else
  972. continue;
  973. }
  974. //Check the logical block address
  975. err = xd_sm_block_address_search(xd_sm_buf->redundant_buf, &logical_temp);
  976. if(err)
  977. continue;
  978. //Erase or skip current physical block
  979. if(logical_addr != logical_temp)
  980. {
  981. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk;
  982. err = 1;//xd_sm_auto_block_erase(page_addr);
  983. if(!err)
  984. {
  985. xd_sm_set_block_free(zone, block);
  986. }
  987. continue;
  988. }
  989. block_temp = xd_sm_buf->logical_physical_table[zone][logical_addr];
  990. //Read the redundant area in the last sector of physical block entried on current convertsion table
  991. page_addr = (zone * xd_sm_physical_blks_perzone + block_temp) * xd_sm_pages_per_blk;
  992. page_addr += (xd_sm_pages_per_blk - 1);
  993. err = xd_sm_read_cycle3(0, page_addr, xd_sm_buf->redundant_buf, xd_sm_redundant_size);
  994. if(err)
  995. continue;
  996. //Check the logical block address
  997. err = xd_sm_block_address_search(xd_sm_buf->redundant_buf, &logical_temp);
  998. if(err)
  999. continue;
  1000. //Erase or skip entried block as having same logical address on the conversion table
  1001. if((logical_addr != logical_temp)
  1002. || ((logical_addr == logical_temp) && (block_temp > block)))
  1003. {
  1004. page_addr = (zone * xd_sm_physical_blks_perzone + block_temp) * xd_sm_pages_per_blk;
  1005. err = 1;//xd_sm_auto_block_erase(page_addr);
  1006. if(!err)
  1007. {
  1008. xd_sm_set_block_free(zone, block_temp);
  1009. }
  1010. xd_sm_buf->logical_physical_table[zone][logical_addr] = block;
  1011. }
  1012. else
  1013. {
  1014. //Erase or skip current physical block
  1015. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk;
  1016. err = 1;//xd_sm_auto_block_erase(page_addr);
  1017. if(!err)
  1018. {
  1019. xd_sm_set_block_free(zone, block);
  1020. }
  1021. }
  1022. }
  1023. }
  1024. return XD_SM_NO_ERROR;
  1025. }
  1026. int xd_sm_logical_format_determin(void)
  1027. {
  1028. int err;
  1029. unsigned char *mbr_buf, *pbr_buf;
  1030. unsigned long pbr_sector;
  1031. unsigned short bytes_per_sector, total_sectors;
  1032. unsigned char cluster_factor;
  1033. unsigned long cluster_number, extended_sectors, sectors_per_cluster;
  1034. mbr_buf = xd_sm_buf->page_buf;
  1035. pbr_buf = xd_sm_buf->page_buf;
  1036. memset(mbr_buf, 0, xd_sm_info->blk_len);
  1037. err = xd_sm_read_data(0, xd_sm_info->blk_len, mbr_buf);
  1038. if(err)
  1039. return err;
  1040. if((mbr_buf[0x1FE] != 0x55) || (mbr_buf[0x1FF] != 0xAA))
  1041. return XD_SM_ERROR_LOGICAL_FORMAT;
  1042. pbr_sector = (((((mbr_buf[0x1C9] << 8) | mbr_buf[0x1C8]) << 8) | mbr_buf[0x1C7]) << 8) | mbr_buf[0x1C6];
  1043. if(pbr_sector > xd_sm_totoal_logical_blks)
  1044. return XD_SM_ERROR_LOGICAL_FORMAT;
  1045. err = xd_sm_read_data(pbr_sector, xd_sm_info->blk_len, pbr_buf);
  1046. if(err)
  1047. return err;
  1048. if((pbr_buf[0x1FE] != 0x55) || (pbr_buf[0x1FF] != 0xAA))
  1049. return XD_SM_ERROR_LOGICAL_FORMAT;
  1050. bytes_per_sector = (pbr_buf[0x0C] << 8) | pbr_buf[0x0B];
  1051. if(bytes_per_sector != 0x0200)
  1052. return XD_SM_ERROR_LOGICAL_FORMAT;
  1053. cluster_factor = pbr_buf[0x0D];
  1054. sectors_per_cluster = cluster_factor;
  1055. if(sectors_per_cluster != xd_sm_pages_per_blk)
  1056. return XD_SM_ERROR_LOGICAL_FORMAT;
  1057. total_sectors = (pbr_buf[0x14] << 8) | pbr_buf[0x13];
  1058. extended_sectors = (((((pbr_buf[0x23] << 8) | pbr_buf[0x22]) << 8) | pbr_buf[0x21]) << 8) | pbr_buf[0x20];
  1059. if(total_sectors)
  1060. cluster_number = total_sectors / sectors_per_cluster;
  1061. else
  1062. cluster_number = extended_sectors / sectors_per_cluster;
  1063. if(cluster_number > 65525)
  1064. return XD_SM_ERROR_LOGICAL_FORMAT;
  1065. return XD_SM_NO_ERROR;
  1066. }
  1067. int xd_sm_reconstruct_logical_physical_table(void)
  1068. {
  1069. int err;
  1070. unsigned short zone, block, i;
  1071. unsigned short block_addr, logical_addr;
  1072. unsigned long page_addr;
  1073. xd_sm_erase_all_blocks();
  1074. for(zone=0; zone<xd_sm_total_zones; zone++)
  1075. {
  1076. logical_addr = 0;
  1077. for(block=0; block<xd_sm_physical_blks_perzone; block++)
  1078. {
  1079. //Is it CIS area in case of Zone 0?
  1080. if((zone == 0) && (block == xd_sm_buf->cis_block_no))
  1081. continue;
  1082. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk;
  1083. //Read the data in the redundant area in the first sector
  1084. err = xd_sm_read_cycle3(0, page_addr, xd_sm_buf->redundant_buf, xd_sm_redundant_size);
  1085. if(err)
  1086. continue;
  1087. //Is is defective block?
  1088. if(xd_sm_check_defective_block(xd_sm_buf->redundant_buf))
  1089. continue;
  1090. //Erase this block
  1091. //err = xd_sm_auto_block_erase(page_addr);
  1092. //Set logical address
  1093. if(logical_addr < xd_sm_logical_blks_perzone)
  1094. {
  1095. memset(xd_sm_buf->page_buf, 0xFF, xd_sm_page_size);
  1096. block_addr = xd_sm_trans_logical_address(logical_addr);
  1097. xd_sm_format_redundant_area(xd_sm_buf->page_buf, xd_sm_buf->redundant_buf, block_addr);
  1098. for(i=0; i<xd_sm_pages_per_blk; i++)
  1099. {
  1100. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk + i;
  1101. xd_sm_auto_page_program(page_addr, xd_sm_buf->page_buf, xd_sm_buf->redundant_buf);
  1102. }
  1103. page_addr = (zone * xd_sm_physical_blks_perzone + block) * xd_sm_pages_per_blk;
  1104. //Read the data in the redundant area in the first sector
  1105. err = xd_sm_read_cycle3(0, page_addr, xd_sm_buf->redundant_buf, xd_sm_redundant_size);
  1106. if(err)
  1107. continue;
  1108. if(xd_sm_check_defective_block(xd_sm_buf->redundant_buf))
  1109. continue;
  1110. logical_addr++;
  1111. }
  1112. }
  1113. }
  1114. return xd_sm_create_logical_physical_table();
  1115. }
  1116. int xd_sm_erase_all_blocks(void)
  1117. {
  1118. unsigned short zone, block;
  1119. for(zone=0; zone<xd_sm_total_zones; zone++)
  1120. {
  1121. for(block=0; block<xd_sm_physical_blks_perzone; block++)
  1122. {
  1123. //Is it CIS area in case of Zone 0?
  1124. if((zone == 0) && (block == xd_sm_buf->cis_block_no))
  1125. continue;
  1126. xd_sm_check_back_block(zone, block);
  1127. }
  1128. }
  1129. return XD_SM_NO_ERROR;
  1130. }
  1131. int xd_sm_physical_format_determin(void)
  1132. {
  1133. int err,i;
  1134. unsigned short block, sector;
  1135. XD_SM_Redundant_Area_t *redundant = (void *)xd_sm_buf->redundant_buf;
  1136. int cis_offset;
  1137. unsigned long page_addr;
  1138. for(block=0; block<xd_sm_buf->cis_search_max; block++)
  1139. {
  1140. sector = 0;
  1141. while(sector < 8)
  1142. {
  1143. page_addr = block * xd_sm_pages_per_blk + sector;
  1144. err = xd_sm_read_cycle3(0, page_addr, xd_sm_buf->redundant_buf, xd_sm_redundant_size);
  1145. if(err)
  1146. {
  1147. sector++;
  1148. continue;
  1149. }
  1150. if(xd_sm_check_defective_block(xd_sm_buf->redundant_buf))
  1151. {
  1152. sector++;
  1153. continue;
  1154. }
  1155. else
  1156. {
  1157. break;
  1158. }
  1159. }
  1160. if(sector >= 8)
  1161. continue;
  1162. page_addr = block * xd_sm_pages_per_blk + sector;
  1163. err = xd_sm_read_cycle1(0, page_addr, xd_sm_buf->page_buf, xd_sm_page_size, xd_sm_buf->redundant_buf);
  1164. if(err)
  1165. continue;
  1166. cis_offset = CIS_FIELD1_OFFSET;
  1167. err = xd_sm_check_unit_ecc(xd_sm_buf->page_buf+cis_offset, redundant->ECC1);
  1168. if((err != ECC_NO_ERROR) && (err != ECC_ERROR_CORRECTED))
  1169. {
  1170. cis_offset = CIS_FIELD2_OFFSET;
  1171. err = xd_sm_check_unit_ecc(xd_sm_buf->page_buf+cis_offset, redundant->ECC2);
  1172. if((err != ECC_NO_ERROR) && (err != ECC_ERROR_CORRECTED))
  1173. {
  1174. continue;
  1175. }
  1176. }
  1177. err = 0;
  1178. for(i=0; i<sizeof(CIS_DATA_0_9); i++)
  1179. {
  1180. if(*(xd_sm_buf->page_buf+cis_offset+i) != CIS_DATA_0_9[i])
  1181. {
  1182. err = 1;
  1183. break;
  1184. }
  1185. }
  1186. if(!err)
  1187. {
  1188. xd_sm_buf->cis_block_no = block;
  1189. return XD_SM_NO_ERROR;
  1190. }
  1191. }
  1192. xd_sm_buf->cis_block_no = INVALID_BLOCK_ADDRESS;
  1193. return XD_SM_ERROR_PHYSICAL_FORMAT;
  1194. }
  1195. void xd_sm_staff_init(void)
  1196. {
  1197. xd_sm_power_on();
  1198. xd_sm_io_config();
  1199. xd_sm_info->blk_len = 0;
  1200. xd_sm_info->blk_nums = 0;
  1201. xd_sm_info->xd_inited_flag = 0;
  1202. xd_sm_info->xd_removed_flag = 0;
  1203. xd_sm_info->sm_inited_flag = 0;
  1204. xd_sm_info->sm_removed_flag = 0;
  1205. xd_sm_info->read_only_flag = 0;
  1206. }
  1207. int xd_sm_cmd_test(void)
  1208. {
  1209. int err;
  1210. XD_SM_Status1_t status1;
  1211. xd_sm_io_config();
  1212. err = xd_sm_status_read(XD_SM_STATUS_READ1, (unsigned char *)&status1);
  1213. if(err)
  1214. return err;
  1215. return XD_SM_NO_ERROR;
  1216. }
  1217. //check data lines consistency
  1218. int xd_sm_check_data_consistency(void)
  1219. {
  1220. int error;
  1221. unsigned char *mbr_buf = xd_sm_buf->page_buf;
  1222. memset(mbr_buf, 0, xd_sm_info->blk_len);
  1223. //read MBR information
  1224. error = xd_sm_read_data(0, xd_sm_info->blk_len, mbr_buf);
  1225. if(error)
  1226. {
  1227. //error! retry again!
  1228. error = xd_sm_read_data(0, xd_sm_info->blk_len, mbr_buf);
  1229. if(error)
  1230. return error;
  1231. }
  1232. //check MBR data consistency
  1233. if((mbr_buf[510] != 0x55) || (mbr_buf[511] != 0xAA))
  1234. {
  1235. //data consistency error! retry again!
  1236. error = xd_sm_read_data(0, xd_sm_info->blk_len, mbr_buf);
  1237. if(error)
  1238. return error;
  1239. //check MBR data consistency
  1240. if((mbr_buf[510] != 0x55) || (mbr_buf[511] != 0xAA))
  1241. {
  1242. return XD_SM_ERROR_LOGICAL_FORMAT;
  1243. }
  1244. }
  1245. return XD_SM_NO_ERROR;
  1246. }
  1247. //XD Initialization...
  1248. int xd_sm_init(XD_SM_Card_Info_t * card_info)
  1249. {
  1250. int error;
  1251. xd_sm_function_init();
  1252. #ifdef XD_CARD_SUPPORTED
  1253. if(xd_sm_info->card_type == CARD_TYPE_XD)
  1254. {
  1255. if(xd_sm_info->xd_inited_flag && !xd_sm_info->xd_removed_flag)
  1256. {
  1257. error = xd_sm_cmd_test();
  1258. if(!error)
  1259. return error;
  1260. }
  1261. if(++xd_sm_info->xd_init_retry > XD_SM_INIT_RETRY)
  1262. return XD_SM_ERROR_DRIVER_FAILURE;
  1263. }
  1264. #endif
  1265. #ifdef SM_CARD_SUPPORTED
  1266. if(xd_sm_info->card_type == CARD_TYPE_SM)
  1267. {
  1268. if(xd_sm_info->sm_inited_flag && !xd_sm_info->sm_removed_flag)
  1269. {
  1270. error = xd_sm_cmd_test();
  1271. if(!error)
  1272. return error;
  1273. }
  1274. if(++xd_sm_info->sm_init_retry > XD_SM_INIT_RETRY)
  1275. return XD_SM_ERROR_DRIVER_FAILURE;
  1276. }
  1277. #endif
  1278. #ifdef XD_SM_DEBUG
  1279. Debug_Printf("\nXD/SM initialization started......\n");
  1280. #endif
  1281. xd_sm_staff_init();
  1282. error = xd_sm_reset();
  1283. if(error)
  1284. {
  1285. #ifdef XD_SM_DEBUG
  1286. Debug_Printf("#%s error occured in xd_sm_reset()\n", xd_sm_error_to_string(error));
  1287. #endif
  1288. return error;
  1289. }
  1290. error = xd_sm_card_capacity_determin();
  1291. if(error)
  1292. {
  1293. #ifdef XD_SM_DEBUG
  1294. Debug_Printf("#%s error occured in xd_sm_card_capacity_determin()\n", xd_sm_error_to_string(error));
  1295. #endif
  1296. return error;
  1297. }
  1298. #ifdef XD_SM_DEBUG
  1299. #ifdef XD_CARD_SUPPORTED
  1300. if(xd_sm_info->card_type == CARD_TYPE_XD)
  1301. Debug_Printf("The capacitty of this XD card is %s!\n", xd_sm_buf->capacity_str);
  1302. #endif
  1303. #ifdef SM_CARD_SUPPORTED
  1304. if(xd_sm_info->card_type == CARD_TYPE_SM)
  1305. Debug_Printf("The capacitty of this SM card is %s!\n", xd_sm_buf->capacity_str);
  1306. #endif
  1307. #endif
  1308. error = xd_sm_card_indentification();
  1309. if(error)
  1310. {
  1311. #ifdef XD_SM_DEBUG
  1312. Debug_Printf("#%s error occured in xd_sm_card_indentification()\n", xd_sm_error_to_string(error));
  1313. #endif
  1314. return error;
  1315. }
  1316. error = xd_sm_physical_format_determin();
  1317. if(error)
  1318. {
  1319. #ifdef XD_SM_DEBUG
  1320. Debug_Printf("#%s error occured in xd_sm_physical_format_determin()\n", xd_sm_error_to_string(error));
  1321. #endif
  1322. //return error;
  1323. }
  1324. error = xd_sm_create_logical_physical_table();
  1325. if(error)
  1326. {
  1327. #ifdef XD_SM_DEBUG
  1328. Debug_Printf("#%s error occured in xd_sm_create_logical_physical_table()\n", xd_sm_error_to_string(error));
  1329. #endif
  1330. #if 0
  1331. #ifdef XD_SM_DEBUG
  1332. Debug_Printf("Try to reconstruct logical-physical convertsion table...\n");
  1333. #endif
  1334. error = xd_sm_reconstruct_logical_physical_table();
  1335. if(error)
  1336. {
  1337. #ifdef XD_SM_DEBUG
  1338. Debug_Printf("Reconstruct logical-physical convertsion table faild!\n");
  1339. #endif
  1340. return error;
  1341. }
  1342. #else
  1343. return error;
  1344. #endif
  1345. }
  1346. error = xd_sm_check_data_consistency();
  1347. if(error)
  1348. {
  1349. #ifdef XD_SM_DEBUG
  1350. Debug_Printf("#%s error occured in xd_sm_check_data_consistency()\n", xd_sm_error_to_string(error));
  1351. #endif
  1352. return error;
  1353. }
  1354. error = xd_sm_logical_format_determin();
  1355. if(error)
  1356. {
  1357. #ifdef XD_SM_DEBUG
  1358. Debug_Printf("#%s error occured in xd_sm_logical_format_determin()\n", xd_sm_error_to_string(error));
  1359. #endif
  1360. //return error;
  1361. }
  1362. #ifdef XD_SM_DEBUG
  1363. Debug_Printf("xd_sm_init() is completed successfully!\n\n");
  1364. #endif
  1365. #ifdef XD_CARD_SUPPORTED
  1366. if(xd_sm_info->card_type == CARD_TYPE_XD)
  1367. {
  1368. xd_sm_info->xd_inited_flag = 1;
  1369. xd_sm_info->xd_init_retry = 0;
  1370. }
  1371. #endif
  1372. #ifdef SM_CARD_SUPPORTED
  1373. if(xd_sm_info->card_type == CARD_TYPE_SM)
  1374. {
  1375. xd_sm_info->sm_inited_flag = 1;
  1376. xd_sm_info->sm_init_retry = 0;
  1377. }
  1378. #endif
  1379. memcpy(card_info, xd_sm_info, sizeof(XD_SM_Card_Info_t));
  1380. return XD_SM_NO_ERROR;
  1381. }
  1382. //Read data from XD card
  1383. int xd_sm_read_data(unsigned long lba, unsigned long byte_cnt, unsigned char * data_buf)
  1384. {
  1385. int error;
  1386. unsigned long data_offset,page_addr;
  1387. unsigned short logical_no,physical_no,page_no,page_nums,zone_no,page_cnt;
  1388. if(byte_cnt == 0)
  1389. {
  1390. error = XD_SM_ERROR_PARAMETER;
  1391. #ifdef XD_SM_DEBUG
  1392. Debug_Printf("#%s error occured in xd_sm_read_data()\n", xd_sm_error_to_string(error));
  1393. #endif
  1394. return error;
  1395. }
  1396. if(xd_reset_flag_read)
  1397. {
  1398. xd_power_on();
  1399. }
  1400. xd_sm_io_config();
  1401. if(xd_reset_flag_read)
  1402. {
  1403. error = xd_sm_reset();
  1404. if (error)
  1405. return error;
  1406. }
  1407. data_offset = 0;
  1408. page_nums = (byte_cnt + xd_sm_page_size - 1) / xd_sm_page_size;
  1409. while(page_nums)
  1410. {
  1411. logical_no = lba / xd_sm_pages_per_blk;
  1412. zone_no = logical_no / xd_sm_logical_blks_perzone;
  1413. logical_no %= xd_sm_logical_blks_perzone;
  1414. if((logical_no >= xd_sm_logical_blks_perzone) || (zone_no >= xd_sm_actually_zones))
  1415. {
  1416. error = XD_SM_ERROR_PARAMETER;
  1417. #ifdef XD_SM_DEBUG
  1418. Debug_Printf("#%s error occured in xd_sm_read_data()\n", xd_sm_error_to_string(error));
  1419. #endif
  1420. return error;
  1421. }
  1422. physical_no = xd_sm_buf->logical_physical_table[zone_no][logical_no];
  1423. page_no = lba % xd_sm_pages_per_blk;
  1424. page_cnt = page_nums > (xd_sm_pages_per_blk - page_no) ? (xd_sm_pages_per_blk - page_no) : page_nums;
  1425. page_addr = (zone_no * xd_sm_physical_blks_perzone + physical_no) * xd_sm_pages_per_blk + page_no;
  1426. //In a flash memory device, there might be a logic block that is not allocate to a physcial
  1427. //block due to the block not being used. all data shoude be set to FFH when access this logical block
  1428. if(physical_no == INVALID_BLOCK_ADDRESS && xd_sm_search_free_block())
  1429. {
  1430. memset(data_buf+data_offset, 0xFF, page_cnt*xd_sm_page_size);
  1431. data_offset += page_cnt*xd_sm_page_size;
  1432. lba += page_cnt;
  1433. page_nums -= page_cnt;
  1434. continue;
  1435. }
  1436. if(physical_no >= xd_sm_physical_blks_perzone)
  1437. {
  1438. error = XD_SM_ERROR_PARAMETER;
  1439. #ifdef XD_SM_DEBUG
  1440. Debug_Printf("#%s error occured in xd_sm_read_data()\n", xd_sm_error_to_string(error));
  1441. #endif
  1442. return error;
  1443. }
  1444. error = xd_sm_read_cycle1(0, page_addr, data_buf+data_offset, page_cnt*xd_sm_page_size, xd_sm_buf->redundant_buf);
  1445. if(error)
  1446. {
  1447. #ifdef XD_SM_DEBUG
  1448. Debug_Printf("#%s error occured in xd_sm_read_data()\n", xd_sm_error_to_string(error));
  1449. #endif
  1450. return error;
  1451. }
  1452. #ifdef AMLOGIC_CHIP_SUPPORT
  1453. data_offset += ((unsigned long)data_buf == 0x3400000) ? 0 : page_cnt*xd_sm_page_size;
  1454. #else
  1455. data_offset += page_cnt*xd_sm_page_size;
  1456. #endif
  1457. lba += page_cnt;
  1458. page_nums -= page_cnt;
  1459. }
  1460. return XD_SM_NO_ERROR;
  1461. }
  1462. //Write data to XD card
  1463. int xd_sm_write_data(unsigned long lba, unsigned long byte_cnt, unsigned char * data_buf)
  1464. {
  1465. int error,i,j,k;
  1466. unsigned long data_offset,page_addr,offset;
  1467. unsigned short logical_no,physical_no,page_no,page_nums,zone_no,page_max,page_cnt;
  1468. unsigned short free_blk_no,block_addr;
  1469. unsigned char *page_buf;
  1470. if(byte_cnt == 0)
  1471. {
  1472. error = XD_SM_ERROR_PARAMETER;
  1473. #ifdef XD_SM_DEBUG
  1474. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1475. #endif
  1476. return error;
  1477. }
  1478. if(xd_sm_info->read_only_flag)
  1479. {
  1480. error = XD_SM_ERROR_DRIVER_FAILURE;
  1481. #ifdef XD_SM_DEBUG
  1482. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1483. #endif
  1484. return error;
  1485. }
  1486. if(xd_reset_flag_write)
  1487. {
  1488. xd_power_on();
  1489. }
  1490. xd_sm_io_config();
  1491. if(xd_reset_flag_write)
  1492. {
  1493. error = xd_sm_reset();
  1494. if (error)
  1495. return error;
  1496. }
  1497. data_offset = 0;
  1498. page_nums = (byte_cnt + xd_sm_page_size - 1) / xd_sm_page_size;
  1499. while(page_nums)
  1500. {
  1501. logical_no = lba / xd_sm_pages_per_blk;
  1502. zone_no = logical_no / xd_sm_logical_blks_perzone;
  1503. logical_no %= xd_sm_logical_blks_perzone;
  1504. page_no = lba % xd_sm_pages_per_blk;
  1505. block_addr = xd_sm_trans_logical_address(logical_no);
  1506. if((logical_no >= xd_sm_logical_blks_perzone) || (zone_no >= xd_sm_actually_zones))
  1507. {
  1508. error = XD_SM_ERROR_PARAMETER;
  1509. #ifdef XD_SM_DEBUG
  1510. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1511. #endif
  1512. return error;
  1513. }
  1514. free_blk_no = xd_sm_find_free_block(zone_no);
  1515. if(free_blk_no == INVALID_BLOCK_ADDRESS)
  1516. {
  1517. error = XD_SM_ERROR_NO_FREE_BLOCK;
  1518. #ifdef XD_SM_DEBUG
  1519. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1520. #endif
  1521. return error;
  1522. }
  1523. page_addr = (zone_no * xd_sm_physical_blks_perzone + free_blk_no) * xd_sm_pages_per_blk;
  1524. error = xd_sm_auto_block_erase(page_addr);
  1525. if(error)
  1526. {
  1527. xd_sm_clear_block_free(zone_no, free_blk_no);
  1528. //continue;
  1529. return error;
  1530. }
  1531. physical_no = xd_sm_buf->logical_physical_table[zone_no][logical_no];
  1532. if(physical_no == INVALID_BLOCK_ADDRESS)
  1533. {
  1534. memset(xd_sm_buf->page_buf, 0xFF, xd_sm_page_size);
  1535. page_max = (page_no+page_nums) < xd_sm_pages_per_blk ? (page_no+page_nums) : xd_sm_pages_per_blk;
  1536. page_cnt = 0;
  1537. offset = data_offset;
  1538. for(i=0; i<xd_sm_pages_per_blk; i++)
  1539. {
  1540. page_addr = (zone_no * xd_sm_physical_blks_perzone + free_blk_no) * xd_sm_pages_per_blk + i;
  1541. if((i >= page_no) && (i < page_max))
  1542. {
  1543. page_buf = data_buf+offset;
  1544. offset += xd_sm_page_size;
  1545. page_cnt++;
  1546. }
  1547. else
  1548. {
  1549. page_buf = xd_sm_buf->page_buf;
  1550. }
  1551. xd_sm_format_redundant_area(page_buf, xd_sm_buf->redundant_buf, block_addr);
  1552. error = xd_sm_auto_page_program(page_addr, page_buf, xd_sm_buf->redundant_buf);
  1553. if(error)
  1554. {
  1555. #ifdef XD_SM_DEBUG
  1556. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1557. #endif
  1558. //return error;
  1559. break;
  1560. }
  1561. }
  1562. if(error)
  1563. continue;
  1564. data_offset = offset;
  1565. lba += page_cnt;
  1566. page_nums -= page_cnt;
  1567. xd_sm_clear_block_free(zone_no, free_blk_no);
  1568. xd_sm_buf->logical_physical_table[zone_no][logical_no] = free_blk_no;
  1569. }
  1570. else
  1571. {
  1572. page_max = (page_no+page_nums) < xd_sm_pages_per_blk ? (page_no+page_nums) : xd_sm_pages_per_blk;
  1573. page_cnt = 0;
  1574. offset = data_offset;
  1575. for(i=0; i<page_no; i++)
  1576. {
  1577. error = xd_sm_copy_page(zone_no, physical_no, i, free_blk_no, i);
  1578. if(error)
  1579. {
  1580. error = XD_SM_ERROR_COPY_PAGE;
  1581. #ifdef XD_SM_DEBUG
  1582. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1583. #endif
  1584. //return error;
  1585. break;
  1586. }
  1587. }
  1588. for(j=page_no; j<page_max; j++)
  1589. {
  1590. xd_sm_format_redundant_area(data_buf+offset, xd_sm_buf->redundant_buf, block_addr);
  1591. page_addr = (zone_no * xd_sm_physical_blks_perzone + free_blk_no) * xd_sm_pages_per_blk + j;
  1592. error = xd_sm_auto_page_program(page_addr, data_buf+offset, xd_sm_buf->redundant_buf);
  1593. if(error)
  1594. {
  1595. #ifdef XD_SM_DEBUG
  1596. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1597. #endif
  1598. //return error;
  1599. break;
  1600. }
  1601. offset += xd_sm_page_size;
  1602. page_cnt++;
  1603. }
  1604. if(error)
  1605. continue;
  1606. for(k=page_max; k<xd_sm_pages_per_blk; k++)
  1607. {
  1608. error = xd_sm_copy_page(zone_no, physical_no, k, free_blk_no, k);
  1609. if(error)
  1610. {
  1611. error = XD_SM_ERROR_COPY_PAGE;
  1612. #ifdef XD_SM_DEBUG
  1613. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1614. #endif
  1615. //return error;
  1616. break;
  1617. }
  1618. }
  1619. if(error)
  1620. continue;
  1621. data_offset = offset;
  1622. lba += page_cnt;
  1623. page_nums -= page_cnt;
  1624. page_addr = (zone_no * xd_sm_physical_blks_perzone + physical_no) * xd_sm_pages_per_blk;
  1625. error = xd_sm_auto_block_erase(page_addr);
  1626. if(error)
  1627. {
  1628. error = XD_SM_ERROR_BLOCK_ERASE;
  1629. #ifdef XD_SM_DEBUG
  1630. Debug_Printf("#%s error occured in xd_sm_write_data()\n", xd_sm_error_to_string(error));
  1631. #endif
  1632. //return error;
  1633. }
  1634. xd_sm_set_block_free(zone_no, physical_no);
  1635. xd_sm_clear_block_free(zone_no, free_blk_no);
  1636. xd_sm_buf->logical_physical_table[zone_no][logical_no] = free_blk_no;
  1637. }
  1638. }
  1639. return XD_SM_NO_ERROR;
  1640. }
  1641. //XD Power on/off
  1642. void xd_sm_power_on(void)
  1643. {
  1644. #ifdef XD_CARD_SUPPORTED
  1645. if(xd_sm_info->card_type == CARD_TYPE_XD)
  1646. xd_power_on();
  1647. #endif
  1648. #ifdef SM_CARD_SUPPORTED
  1649. if(xd_sm_info->card_type == CARD_TYPE_SM)
  1650. sm_power_on();
  1651. #endif
  1652. }
  1653. void xd_sm_power_off()
  1654. {
  1655. #ifdef XD_CARD_SUPPORTED
  1656. if(xd_sm_info->card_type == CARD_TYPE_XD)
  1657. xd_power_off();
  1658. #endif
  1659. #ifdef SM_CARD_SUPPORTED
  1660. if(xd_sm_info->card_type == CARD_TYPE_SM)
  1661. sm_power_off();
  1662. #endif
  1663. }
  1664. int xd_sm_search_free_block(void)
  1665. {
  1666. unsigned zone, block;
  1667. for(zone=0; zone<xd_sm_total_zones; zone++)
  1668. {
  1669. for(block=0; block<xd_sm_physical_blks_perzone/8; block++)
  1670. {
  1671. if(xd_sm_buf->free_block_table[zone][block])
  1672. return 1;
  1673. }
  1674. }
  1675. return 0;
  1676. }