⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand_util.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
  {
    trace1(0, util, 0, "block %d: not in use - marked bad", g_addr_rd_phy_blk) ;
    util_trace_page() ;
    return;
  }

  // call media to retrieve lb of current pb, or return a reason why it can't be done
  if(k_success != _media_phy2log())
  {
    trace1(0, util, 0, "block %d: not in use - invalid log binding", g_addr_rd_phy_blk) ;
    util_trace_page() ;
    return;
  }

  trace2(0, util, 0, "block:%d ==> lb: %d", g_addr_rd_phy_blk, g_addr_log_blk) ;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_trace_map_zone() reentrant
{
  trace1(0, util, 0, "--- Zone %d Map -----------", g_addr_zone) ;
  for(g_addr_rd_phy_blk=0; g_addr_rd_phy_blk<_media_data(physical_blocks_per_zone);g_addr_rd_phy_blk++)
  {
    util_trace_map_block() ;
  }
  trace1(0, util, 0, "--- Zone %d Map End -------", g_addr_zone) ;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_trace_map_media() reentrant
{
  for(g_addr_zone=0;g_addr_zone<_media_data(num_zones);g_addr_zone++)
  {
    if(g_active_media != k_ix_media_sm)
    {
      nand_select_card() ;
    }
    util_trace_map_zone() ;
  }
}
#endif

xdata uint16 _erase_blocks ;
xdata uint16 _erase_blocks_rsvd ; 
xdata uint16 _erase_blocks_bad ;
xdata uint16 _erase_blocks_restored ;

xdata uint16 _total_blocks ;
xdata uint16 _total_blocks_rsvd ;
xdata uint16 _total_blocks_bad ;
xdata uint16 _total_blocks_restored ;

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result util_wr_verify_page_aa() reentrant
{
  return k_false ;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result util_wr_verify_page_55() reentrant
{
  return k_true ;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result util_recover_bad_block() reentrant
{
  uint16 i ;
  t_result result ;

  if(g_active_media == k_ix_media_ms)
  {
    return _media_erase_block() ;
  }
  
#if (k_lun_sm < k_max_log_lun)
  result = k_error ;
  // smart media/nand recovery only
  // test for factor-marked bad... redt data of all 0's is the best test
  for(i=0; i<16;i++)
  {
    if(x_sm_redt_data[i] != 0x00)
      result = k_success ;
  }
#endif

  // an error indicates a factory-marked-bad candidate
  if(k_success != result)
  {
    // check to see if the block is all 00's too... if so, don't touch it
    nand_rd_va2pa() ;
    _media_data(sector_buffer) = g_sector_buffer ;

    result = _media_read_sector() ;
    if(k_success != result)
      return result ;

    result = k_error ;
    for(i=0;i<512;i++)
    {
      if(g_sector_buffer[i] != 0x00)
      {
        result = k_success ;
      }
    }

    if(k_success != result)
    {
      // factory-marked-bad block... bail
      return result ;
    }
  }


  // do the block erase here
  result = _media_erase_block() ;
#if 0 
  if(k_success != result)
    return result ;

  // write first pattern
  for(g_addr_page;g_addr_page < _media_data(pages_per_block);g_addr_page++)
  {
    result=util_wr_verify_page_55() ;
    if(result != k_success)
      return result ;
  }

  g_addr_page=0 ;
  result = _media_erase_block() ;
  for(g_addr_page;g_addr_page < _media_data(pages_per_block);g_addr_page++)
  {
    result=util_wr_verify_page_aa() ;
    if(result != k_success)
      return result ;
  }

  g_addr_page=0;
  result = _media_erase_block() ;
#endif
  // technically, should write the pattern here for save erase
  return result ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_safe_erase_block() reentrant
{
  if ((!g_addr_zone) && (g_addr_rd_phy_blk <= _media_data(boot_block)))
  {
    trace2(0, util, 0, "zone %d block %d - reserved.  not erased", g_addr_zone, g_addr_rd_phy_blk) ;
    _erase_blocks_rsvd++ ;
    return;
  }
  g_addr_page=0 ;

  _media_read_extra_data() ;
  if( _media_is_phyblock_ok() )
  {
    if (_media_is_phyblock_blank() )
    {
      // not bad... not written... don't erase
      return;
    }
    if (k_success == _media_erase_block())
    {
      _erase_blocks++ ;
      return;
    }
  }
  _erase_blocks_bad++ ;
  
  // attempt to recover blocks not marked bad by the factory
  if( k_success == util_recover_bad_block() )
  {
    trace2(0, util, 0, "zone %d block %d - restored", g_addr_zone, g_addr_wr_phy_blk) ;
    _erase_blocks_bad-- ;
    _erase_blocks_restored++ ;
    return;
  }
  
  trace2(0, util, 0, "zone %d block %d - block is bad",g_addr_zone, g_addr_wr_phy_blk) ;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_safe_erase_zone() reentrant
{
  trace1(0, util, 0, "Erasing Zone %d ------", g_addr_zone) ;

  for(g_addr_rd_phy_blk=0; g_addr_rd_phy_blk<_media_data(physical_blocks_per_zone);g_addr_rd_phy_blk++)
  {
    g_addr_wr_phy_blk=g_addr_rd_phy_blk ;
    util_safe_erase_block() ;
  }
  
  
/*
  trace1(0, util, 0, "Zone %d Erase Stats:", g_addr_zone) ;
  trace1(0, util, 0, " blocks erased:  %d", _erase_blocks) ;
  trace1(0, util, 0, " blocks_rsvd:    %d", _erase_blocks_rsvd) ;
  trace1(0, util, 0, " blocks_bad:     %d", _erase_blocks_bad) ;
  trace1(0, util, 0, " blocks_restored:%d", _erase_blocks_restored) ;
*/

}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_safe_erase_media() reentrant
{
  trace0(0, util, 0, "util_safe_erase_media() - erase all blocks not explicitly marked 'bad' by the factory") ;

  _total_blocks=0;
  _total_blocks_rsvd=0;
  _total_blocks_bad=0;
  _total_blocks_restored=0;
  for(g_addr_zone=0;g_addr_zone<_media_data(num_zones);g_addr_zone++)
  {
    if( !((g_active_media==k_ix_media_sm)||(g_active_media==k_ix_media_ms)))
    {
      nand_select_card() ;
    }
    
    _erase_blocks=0;
    _erase_blocks_rsvd=0; 
    _erase_blocks_bad=0;
    _erase_blocks_restored=0;
    util_safe_erase_zone() ;
    _total_blocks += _erase_blocks ;
    _total_blocks_rsvd += _erase_blocks_rsvd ;
    _total_blocks_bad += _erase_blocks_bad ;
    _total_blocks_restored += _erase_blocks_restored ;
  }
/*
  trace0(0, util, 0, "Safe Erase Results:") ;
  trace1(0, util, 0, " total blocks erased:  %d", _total_blocks) ;
  trace1(0, util, 0, " total blocks_rsvd:    %d", _total_blocks_rsvd) ;
  trace1(0, util, 0, " total blocks_bad:     %d", _total_blocks_bad) ;
  trace1(0, util, 0, " total blocks_restored:%d", _total_blocks_restored) ;
*/
}

#if 0
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void fmc_dbg_dump_sector(uint8* sector) reentrant;
void sm_dbg_dump_redt_data() reentrant;
void n2k_test_read_sequential() reentrant
{
  uint16 i ;

  // useful routine for dumping the contents of a block
  g_addr_zone=0;
  map_build_sector_map() ;
  map_lba2addr_rd(0) ;
  nand_select_card() ;
  nand_rd_va2pa() ;

  // read page into page buffer
  nand_page_read_for_datay() ;
  
  // read next page into cache
  n2k_read_cache_next() ;
  for(g_addr_page=0;g_addr_page<_media_data(pages_per_block);g_addr_page++)
  {
    trace1(0, nand, 0, "Read Page %d", g_addr_page) ;
    for(i=0;i<512;i++)
    {
      g_sector_buffer[i] = _sm_data_rd() ;
    }
    fmc_dbg_dump_sector(g_sector_buffer) ;
    for(i=0;i<16;i++)
    {
      x_sm_redt_data[i] = _sm_data_rd() ;
    }
    sm_dbg_dump_redt_data() ;

    if( (g_addr_page&0x03)==3)
    {
      trace0(0, nand, 0, "read cache decision...") ;
      if(g_addr_page==255)
      {
        trace0(0, nand, 0, "last page... don't issue any command") ;
        continue ;
      }
      else if(g_addr_page==251)
      {
        trace0(0, nand, 0, "2nd to last page.  issue read-final-cache command") ;
        n2k_read_cache_final() ;
      }
      else
      {
        trace0(0, nand, 0, "read in next cached page") ;
        n2k_read_cache_next() ;
      }
    }
  }
}

#endif


#if 0 
void util_clear_boot_block() reentrant
{
  
  uint16 i;

  for(i=0;i<256;i++)
  {
    nand_boot_write(i, 0xff) ;
  }
  nand_boot_write_flush() ;
}
#endif








//+-----------------------------------------------------------------------------
// Name:
//   util_verify_sector_map()
//
// Declaration:
//   t_result util_verify_sector_map(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
#if 0

void util_verify_sector_map(void) reentrant
{
  uint8   zone ;
  uint16  max_lb ;
  uint16  lb;
  uint8   check_for_l2p_entry ;

  trace0(0, map, 0, "map_verify_sector_map()") ;

  zone = g_addr_zone?1:0;
  g_addr_page=0;


  trace2(0, map, 0, "verifying sector map of media zone %d to map index %d", g_addr_zone, zone) ;

  _l2p_map = _l2p_map(zone) ;
  _a_map =   _assign_map(zone) ;

  max_lb = zone?_media_data(logical_blocks_per_zone):_media_data(logical_blocks_per_boot_zone);

  // populate the assignment map
  for (g_addr_rd_phy_blk=0;
       g_addr_rd_phy_blk < _media_data(physical_blocks_per_zone);
       g_addr_rd_phy_blk++ )
  {

    g_addr_page = 0 ;
    if ((!g_addr_zone) && (g_addr_rd_phy_blk <= _media_data(boot_block)))
    {
      // first zone, before CIS struct... in sm terms, nothing comes there
      _map_phy_blk_used( _a_map, g_addr_rd_phy_blk ) ;
      continue;
    }

    if(k_error == _media_read_extra_data() )
    {
      trace0(0, map, 0, "phy_block %d: cannot read extra data.  mark block used, but not mapped.") ;
      if( !_map_is_phy_blk_used( _a_map, g_addr_rd_phy_blk ) )
      {
        trace0(0, map, 0, "***  error!  phy_block %d mapping corrupted!") ;
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -