@@ -95,6 +95,7 @@ typedef struct __attribute__((__packed__))
9595 np_cmd_t cmd ;
9696 uint32_t addr ;
9797 uint32_t len ;
98+ np_cmd_flags_t flags ;
9899} np_read_cmd_t ;
99100
100101typedef struct __attribute__((__packed__ ))
@@ -134,6 +135,7 @@ typedef struct __attribute__((__packed__))
134135{
135136 np_resp_t header ;
136137 uint32_t addr ;
138+ uint32_t size ;
137139} np_resp_bad_block_t ;
138140
139141typedef struct __attribute__((__packed__ ))
@@ -208,10 +210,10 @@ static int np_send_error(uint8_t err_code)
208210 return 0 ;
209211}
210212
211- static int np_send_bad_block_info (uint32_t addr )
213+ static int np_send_bad_block_info (uint32_t addr , uint32_t size )
212214{
213215 np_resp_t resp_header = { NP_RESP_STATUS , NP_STATUS_BAD_BLOCK };
214- np_resp_bad_block_t bad_block = { resp_header , addr };
216+ np_resp_bad_block_t bad_block = { resp_header , addr , size };
215217
216218 if (np_comm_cb -> send ((uint8_t * )& bad_block , sizeof (bad_block )))
217219 return -1 ;
@@ -260,7 +262,7 @@ static int np_nand_erase(np_prog_t *prog, uint32_t page)
260262 case NAND_READY :
261263 break ;
262264 case NAND_ERROR :
263- if (np_send_bad_block_info (addr ))
265+ if (np_send_bad_block_info (addr , prog -> chip_info -> block_size ))
264266 return -1 ;
265267 break ;
266268 case NAND_TIMEOUT_ERROR :
@@ -327,7 +329,7 @@ static int _np_cmd_nand_erase(np_prog_t *prog)
327329 if (skip_bb && (is_bad = nand_bad_block_table_lookup (addr )))
328330 {
329331 DEBUG_PRINT ("Skipped bad block at 0x%lx\r\n" , addr );
330- if (np_send_bad_block_info (addr ))
332+ if (np_send_bad_block_info (addr , prog -> chip_info -> block_size ))
331333 return -1 ;
332334 }
333335
@@ -422,7 +424,7 @@ static int np_nand_handle_status(np_prog_t *prog)
422424 switch (nand_read_status ())
423425 {
424426 case NAND_ERROR :
425- if (np_send_bad_block_info (prog -> addr ))
427+ if (np_send_bad_block_info (prog -> addr , prog -> chip_info -> block_size ))
426428 return -1 ;
427429 case NAND_READY :
428430 prog -> nand_wr_in_progress = 0 ;
@@ -592,7 +594,7 @@ static int np_nand_read(uint32_t addr, np_page_t *page,
592594 case NAND_READY :
593595 break ;
594596 case NAND_ERROR :
595- if (np_send_bad_block_info (addr ))
597+ if (np_send_bad_block_info (addr , chip_info -> block_size ))
596598 return -1 ;
597599 break ;
598600 case NAND_TIMEOUT_ERROR :
@@ -608,15 +610,16 @@ static int np_nand_read(uint32_t addr, np_page_t *page,
608610
609611static int _np_cmd_nand_read (np_prog_t * prog )
610612{
611- uint32_t addr , len , write_len ;
613+ uint32_t addr , len , send_len ;
612614 static np_page_t page ;
613615 uint32_t resp_header_size = offsetof(np_resp_t , data );
614616 uint32_t tx_data_len = sizeof (np_packet_send_buf ) - resp_header_size ;
615617 np_read_cmd_t * read_cmd = (np_read_cmd_t * )prog -> rx_buf ;
618+ bool skip_bb = read_cmd -> flags .skip_bb ;
616619 np_resp_t * resp = (np_resp_t * )np_packet_send_buf ;
617620
618621 addr = read_cmd -> addr ;
619- len = read_cmd -> len ;
622+ len = read_cmd -> len ;
620623 DEBUG_PRINT ("Read at 0x%lx 0x%lx bytes command\r\n" , addr , len );
621624
622625 if (addr + len > prog -> chip_info -> size )
@@ -653,46 +656,59 @@ static int _np_cmd_nand_read(np_prog_t *prog)
653656
654657 while (len )
655658 {
659+ if (addr >= prog -> chip_info -> size )
660+ {
661+ ERROR_PRINT ("Read address 0x%lx is more then chip size 0x%lx" ,
662+ addr , prog -> chip_info -> page_size );
663+ return NP_ERR_ADDR_EXCEEDED ;
664+ }
665+
666+ if (skip_bb && nand_bad_block_table_lookup (addr ))
667+ {
668+ DEBUG_PRINT ("Skipped bad block at 0x%lx\r\n" , addr );
669+ if (np_send_bad_block_info (addr , prog -> chip_info -> block_size ))
670+ return -1 ;
671+
672+ /* On partial read do not count bad blocks */
673+ if (read_cmd -> len == prog -> chip_info -> size )
674+ len -= prog -> chip_info -> block_size ;
675+ addr += prog -> chip_info -> block_size ;
676+ page .page += prog -> chip_info -> block_size /
677+ prog -> chip_info -> page_size ;
678+ continue ;
679+ }
680+
656681 if (np_nand_read (addr , & page , prog -> chip_info ))
657682 return NP_ERR_NAND_RD ;
658683
659684 while (page .offset < prog -> chip_info -> page_size && len )
660685 {
661686 if (prog -> chip_info -> page_size - page .offset >= tx_data_len )
662- write_len = tx_data_len ;
687+ send_len = tx_data_len ;
663688 else
664- write_len = prog -> chip_info -> page_size - page .offset ;
689+ send_len = prog -> chip_info -> page_size - page .offset ;
690+
691+ if (send_len > len )
692+ send_len = len ;
665693
666- if (write_len > len )
667- write_len = len ;
668-
669- memcpy (resp -> data , page .buf + page .offset , write_len );
694+ memcpy (resp -> data , page .buf + page .offset , send_len );
670695
671696 while (!np_comm_cb -> send_ready ());
672697
673- resp -> info = write_len ;
698+ resp -> info = send_len ;
674699 if (np_comm_cb -> send (np_packet_send_buf ,
675- resp_header_size + write_len ))
700+ resp_header_size + send_len ))
676701 {
677702 return -1 ;
678703 }
679704
680- page .offset += write_len ;
681- len -= write_len ;
705+ page .offset += send_len ;
706+ len -= send_len ;
682707 }
683708
684- if (len )
685- {
686- addr += prog -> chip_info -> page_size ;
687- if (addr >= prog -> chip_info -> size )
688- {
689- ERROR_PRINT ("Read address 0x%lx is more then chip size 0x%lx" ,
690- addr , prog -> chip_info -> page_size );
691- return NP_ERR_ADDR_EXCEEDED ;
692- }
693- page .page ++ ;
694- page .offset = 0 ;
695- }
709+ addr += prog -> chip_info -> page_size ;
710+ page .offset = 0 ;
711+ page .page ++ ;
696712 }
697713
698714 return 0 ;
@@ -758,7 +774,7 @@ static int np_read_bad_block_info_from_page(np_prog_t *prog, uint32_t block,
758774 if (bad_block_data != NP_NAND_GOOD_BLOCK_MARK )
759775 {
760776 * is_bad = true;
761- if (np_send_bad_block_info (addr ))
777+ if (np_send_bad_block_info (addr , prog -> chip_info -> block_size ))
762778 return -1 ;
763779 if (nand_bad_block_table_add (addr ))
764780 return -1 ;
0 commit comments