51
51
NP_ERR_LEN_NOT_ALIGN = -111 ,
52
52
NP_ERR_LEN_EXCEEDED = -112 ,
53
53
NP_ERR_LEN_INVALID = -113 ,
54
+ NP_ERR_BBT_OVERFLOW = -114 ,
54
55
};
55
56
56
57
typedef struct __attribute__((__packed__ ))
@@ -170,6 +171,7 @@ typedef struct
170
171
uint32_t addr ;
171
172
uint32_t len ;
172
173
int addr_is_set ;
174
+ int bb_is_read ;
173
175
np_page_t page ;
174
176
uint32_t bytes_written ;
175
177
uint32_t bytes_ack ;
@@ -251,6 +253,73 @@ static int np_cmd_nand_read_id(np_prog_t *prog)
251
253
return ret ;
252
254
}
253
255
256
+ static int np_read_bad_block_info_from_page (np_prog_t * prog , uint32_t block ,
257
+ uint32_t page , chip_info_t * chip_info , bool * is_bad )
258
+ {
259
+ uint8_t bad_block_data ;
260
+ uint32_t status , addr = block * chip_info -> block_size ;
261
+
262
+ status = nand_read_data (& bad_block_data , page , chip_info -> page_size ,
263
+ sizeof (bad_block_data ));
264
+ switch (status )
265
+ {
266
+ case NAND_READY :
267
+ break ;
268
+ case NAND_ERROR :
269
+ ERROR_PRINT ("NAND read bad block info error at 0x%lx\r\n" , addr );
270
+ return NP_ERR_NAND_RD ;
271
+ case NAND_TIMEOUT_ERROR :
272
+ ERROR_PRINT ("NAND read timeout at 0x%lx\r\n" , addr );
273
+ return NP_ERR_NAND_RD ;
274
+ default :
275
+ ERROR_PRINT ("Unknown NAND status\r\n" );
276
+ return NP_ERR_NAND_RD ;
277
+ }
278
+
279
+ * is_bad = bad_block_data != NP_NAND_GOOD_BLOCK_MARK ;
280
+
281
+ return 0 ;
282
+ }
283
+
284
+ static int _np_cmd_read_bad_blocks (np_prog_t * prog )
285
+ {
286
+ int ret ;
287
+ bool is_bad ;
288
+ uint32_t block , block_num , page_num , page ;
289
+
290
+ block_num = prog -> chip_info -> size / prog -> chip_info -> block_size ;
291
+ page_num = prog -> chip_info -> block_size / prog -> chip_info -> page_size ;
292
+
293
+ /* Bad block - not 0xFF value in the first or second page in the block at
294
+ * zero offset in the page spare area
295
+ */
296
+ for (block = 0 ; block < block_num ; block ++ )
297
+ {
298
+ page = block * page_num ;
299
+ if ((ret = np_read_bad_block_info_from_page (prog , block , page ,
300
+ prog -> chip_info , & is_bad )))
301
+ {
302
+ return ret ;
303
+ }
304
+
305
+ if (!is_bad && (ret = np_read_bad_block_info_from_page (prog , block ,
306
+ page + 1 , prog -> chip_info , & is_bad )))
307
+ {
308
+ return ret ;
309
+ }
310
+
311
+ if (is_bad && nand_bad_block_table_add (block *
312
+ prog -> chip_info -> block_size ))
313
+ {
314
+ return NP_ERR_BBT_OVERFLOW ;
315
+ }
316
+ }
317
+
318
+ prog -> bb_is_read = 1 ;
319
+
320
+ return 0 ;
321
+ }
322
+
254
323
static int np_nand_erase (np_prog_t * prog , uint32_t page )
255
324
{
256
325
uint32_t status ;
@@ -280,6 +349,7 @@ static int np_nand_erase(np_prog_t *prog, uint32_t page)
280
349
281
350
static int _np_cmd_nand_erase (np_prog_t * prog )
282
351
{
352
+ int ret ;
283
353
uint32_t addr , page , pages_in_block , len ;
284
354
np_erase_cmd_t * erase_cmd = (np_erase_cmd_t * )prog -> rx_buf ;
285
355
bool is_bad = false, skip_bb = erase_cmd -> flags .skip_bb ;
@@ -289,6 +359,9 @@ static int _np_cmd_nand_erase(np_prog_t *prog)
289
359
290
360
DEBUG_PRINT ("Erase at 0x%lx %lx bytes command\r\n" , addr , len );
291
361
362
+ if (skip_bb && !prog -> bb_is_read && (ret = _np_cmd_read_bad_blocks (prog )))
363
+ return ret ;
364
+
292
365
if (addr & (prog -> chip_info -> block_size - 1 ))
293
366
{
294
367
ERROR_PRINT ("Address 0x%lx is not aligned to block size 0x%lx\r\n" ,
@@ -372,6 +445,7 @@ static int np_send_write_ack(uint32_t bytes_ack)
372
445
373
446
static int np_cmd_nand_write_start (np_prog_t * prog )
374
447
{
448
+ int ret ;
375
449
uint32_t addr , len ;
376
450
377
451
np_write_start_cmd_t * write_start_cmd =
@@ -408,6 +482,13 @@ static int np_cmd_nand_write_start(np_prog_t *prog)
408
482
return NP_ERR_ADDR_NOT_ALIGN ;
409
483
}
410
484
485
+ prog -> skip_bb = write_start_cmd -> flags .skip_bb ;
486
+ if (prog -> skip_bb && !prog -> bb_is_read &&
487
+ (ret = _np_cmd_read_bad_blocks (prog )))
488
+ {
489
+ return ret ;
490
+ }
491
+
411
492
prog -> addr = addr ;
412
493
prog -> len = len ;
413
494
prog -> addr_is_set = 1 ;
@@ -417,7 +498,6 @@ static int np_cmd_nand_write_start(np_prog_t *prog)
417
498
418
499
prog -> bytes_written = 0 ;
419
500
prog -> bytes_ack = 0 ;
420
- prog -> skip_bb = write_start_cmd -> flags .skip_bb ;
421
501
422
502
return np_send_ok_status ();
423
503
}
@@ -627,6 +707,7 @@ static int np_nand_read(uint32_t addr, np_page_t *page,
627
707
628
708
static int _np_cmd_nand_read (np_prog_t * prog )
629
709
{
710
+ int ret ;
630
711
uint32_t addr , len , send_len ;
631
712
static np_page_t page ;
632
713
uint32_t resp_header_size = offsetof(np_resp_t , data );
@@ -666,6 +747,9 @@ static int _np_cmd_nand_read(np_prog_t *prog)
666
747
return NP_ERR_LEN_NOT_ALIGN ;
667
748
}
668
749
750
+ if (skip_bb && !prog -> bb_is_read && (ret = _np_cmd_read_bad_blocks (prog )))
751
+ return ret ;
752
+
669
753
page .page = addr / prog -> chip_info -> page_size ;
670
754
page .offset = 0 ;
671
755
@@ -752,6 +836,7 @@ static int np_cmd_nand_select(np_prog_t *prog)
752
836
{
753
837
nand_init ();
754
838
nand_bad_block_table_init ();
839
+ prog -> bb_is_read = 0 ;
755
840
prog -> chip_info = chip_info_selected_get ();
756
841
}
757
842
else
@@ -765,73 +850,21 @@ static int np_cmd_nand_select(np_prog_t *prog)
765
850
return np_send_ok_status ();
766
851
}
767
852
768
- static int np_read_bad_block_info_from_page (np_prog_t * prog , uint32_t block ,
769
- uint32_t page , chip_info_t * chip_info , bool * is_bad )
853
+ static int np_send_bad_blocks (np_prog_t * prog )
770
854
{
771
- uint8_t bad_block_data ;
772
- uint32_t status , addr = block * chip_info -> block_size ;
773
-
774
- status = nand_read_data (& bad_block_data , page , chip_info -> page_size ,
775
- sizeof (bad_block_data ));
776
- switch (status )
777
- {
778
- case NAND_READY :
779
- break ;
780
- case NAND_ERROR :
781
- ERROR_PRINT ("NAND read bad block info error at 0x%lx\r\n" , addr );
782
- return NP_ERR_NAND_RD ;
783
- case NAND_TIMEOUT_ERROR :
784
- ERROR_PRINT ("NAND read timeout at 0x%lx\r\n" , addr );
785
- return NP_ERR_NAND_RD ;
786
- default :
787
- ERROR_PRINT ("Unknown NAND status\r\n" );
788
- return NP_ERR_NAND_RD ;
789
- }
855
+ uint32_t addr ;
856
+ void * bb_iter ;
790
857
791
- if (bad_block_data != NP_NAND_GOOD_BLOCK_MARK )
858
+ for (bb_iter = nand_bad_block_table_iter_alloc (& addr ); bb_iter ;
859
+ bb_iter = nand_bad_block_table_iter_next (bb_iter , & addr ))
792
860
{
793
- * is_bad = true;
794
861
if (np_send_bad_block_info (addr , prog -> chip_info -> block_size ))
795
862
return -1 ;
796
- if (nand_bad_block_table_add (addr ))
797
- return -1 ;
798
863
}
799
- else
800
- * is_bad = false;
801
864
802
865
return 0 ;
803
866
}
804
867
805
- static int _np_cmd_read_bad_blocks (np_prog_t * prog )
806
- {
807
- bool is_bad ;
808
- uint32_t block , block_num , page_num , page ;
809
-
810
- block_num = prog -> chip_info -> size / prog -> chip_info -> block_size ;
811
- page_num = prog -> chip_info -> block_size / prog -> chip_info -> page_size ;
812
-
813
- /* Bad block - not 0xFF value in the first or second page in the block at
814
- * zero offset in the page spare area
815
- */
816
- for (block = 0 ; block < block_num ; block ++ )
817
- {
818
- page = block * page_num ;
819
- if (np_read_bad_block_info_from_page (prog , block , page , prog -> chip_info ,
820
- & is_bad ))
821
- {
822
- return -1 ;
823
- }
824
-
825
- if (!is_bad && np_read_bad_block_info_from_page (prog , block , page + 1 ,
826
- prog -> chip_info , & is_bad ))
827
- {
828
- return -1 ;
829
- }
830
- }
831
-
832
- return np_send_ok_status ();
833
- }
834
-
835
868
int np_cmd_read_bad_blocks (np_prog_t * prog )
836
869
{
837
870
int ret ;
@@ -840,7 +873,10 @@ int np_cmd_read_bad_blocks(np_prog_t *prog)
840
873
ret = _np_cmd_read_bad_blocks (prog );
841
874
led_rd_set (false);
842
875
843
- return ret ;
876
+ if (ret || (ret = np_send_bad_blocks (prog )))
877
+ return ret ;
878
+
879
+ return np_send_ok_status ();
844
880
}
845
881
846
882
static np_cmd_handler_t cmd_handler [] =
0 commit comments