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

📄 sm_media.c

📁 U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有很好的支持.
💻 C
📖 第 1 页 / 共 4 页
字号:
      return k_success;
    }
  }
  trace2(0, sm_media, 0, "inconsistant log_blk binding:  addr1:%04x addr2:%04x", addr1, addr2) ;
  return k_error ;
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_media_bind_log2phy()
//
// Declaration:
//   t_result  sm_media_bind_log2phy(void) reentrant
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result  sm_media_bind_log2phy(void) reentrant
{
  uint16  addr;
  trace1(0, sm_media, 0, "+sm_media_bind_log2phy(log_blk:%d)", g_addr_log_blk) ;
  x_sm_redt_data[k_ix_redt_block_status]=0xFF;
  x_sm_redt_data[k_ix_redt_data_status] =0xFF;
  addr=g_addr_log_blk*2+0x1000;
  if ((bit_count16(addr)%2)) addr++;
  x_sm_redt_data[k_ix_redt_lba1_hi]=x_sm_redt_data[k_ix_redt_lba2_hi]= _h(addr) ;
  x_sm_redt_data[k_ix_redt_lba1_lo]=x_sm_redt_data[k_ix_redt_lba2_lo]= _l(addr) ;

  // bind the smc buffer too... just to keep 'em all the same
  sm_synch_hw_buff_to_redt_buf() ;

  // note.. this binding is not set until the data is written!  it's only in the
  // redundant (extra) data section
  return k_success ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_map_set_phyblock_failed()
//
// Declaration:
//   t_result sm_map_set_phyblock_failed(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_set_phyblock_failed(void) reentrant
{
  uint8 page;
  uint8 i ;

  page=g_addr_page ;
  trace0(0, sm_media, 0, "sm_media_set_phyblock_failed()...") ;

  // mark the block bad in the x_sm_redt_data data buffer
  for (i=0; i<k_sm_redt_buffer_sz; i++)
    x_sm_redt_data[i]=(uint8)((i==k_ix_redt_block_status)?0xF0:0xFF);
  // write the x_sm_redt_data data buffer to all sectors in the block
  for (g_addr_page=0; 
       g_addr_page<_media_data(pages_per_block) ; 
       g_addr_page++)
  {
    sm_media_write_extra_data();
  }
  g_addr_page=page;
  trace2(0, sm_media, 0, "phy block %d:%d marked bad", g_addr_zone, g_addr_wr_phy_blk);
  return k_success ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_media_is_phyblock_ok()
//
// Declaration:
//   t_bool sm_media_is_phyblock_ok(void) reentrant
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   TBD
//
// Since:
//   TBD
//------------------------------------------------------------------------------
t_result  sm_media_is_phyblock_ok(void) reentrant
{
  uint8 blk_status = x_sm_redt_data[k_ix_redt_block_status] ;

  trace0(0, sm_media, 0, "sm_media_is_phyblock_ok()") ;

  if (blk_status==0xFF)
  {
    trace0(0, sm_media, 0, "sm_media_is_phyblock_ok() - Y") ;
    return k_true ;
  }
  // sm_dbg_dump_redt_data();
  if (blk_status==0x00)
  {
    trace1(0, sm_media, 0, "sm_media_is_phyblock_ok() - N.  block status: %02x.  block marked 'bad'", blk_status) ;
    return k_false ;
  }

  if (bit_count8(blk_status)<7)
  {
    trace1(0, sm_media, 0, "sm_media_is_phyblock_ok() - N.  block status: %02x.  too many errors.  bit_count8(blk) < 7)  could try to reclaim?", blk_status) ;
    return k_false ;
  }

  // if the status was not 0xff, but has a bit count of 7, then there is a
  // 1-bit error, off from being 0xff, therefor it's considered to be "good"
  trace1(0, sm_media, 0, "sm_media_is_phyblock_ok() - Y.  block status: %02x, bit count of 7", blk_status) ;
  return k_true ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_media_is_phyblock_blank()
//
// Declaration:
//   t_bool sm_is_data_blank(void) reentrant
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_is_phyblock_blank (void) reentrant
{
  uint8 i;

  for (i=0; i<k_sm_redt_buffer_sz; i++)
    if (x_sm_redt_data[i]!=0xFF)
    {
      trace0(0, sm, 0, "sm_media_is_phyblock_blank(): N") ;
      return k_false ;
    }
    
  trace0(0, sm, 0, "sm_media_is_phyblock_blank(): Y") ;
  return k_true ;

  
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_media_seek_cis()
//
// Declaration:
// t_result sm_media_seek_cis(void) reentrant
//
// Purpose:
//  TBD
//
// Arguments:
//  TBD
//
// Return:
//  TBD
//
// Notes:
//  TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------

t_result sm_media_seek_cis(void) reentrant
{
  g_addr_zone=0;
  g_addr_page=0;

  trace0(0, sm_media, 0, "sm_media_seek_cis()") ;
  for ( g_addr_rd_phy_blk=0;
        g_addr_rd_phy_blk<(_media_data(physical_blocks_per_zone)-_media_data(logical_blocks_per_zone)-1);
        g_addr_rd_phy_blk++)
  {
    if (k_success != sm_media_read_extra_data())
    {
      trace0(0, sm_media, 0, "error - could not read extra data") ;
      sm_soft_reset();
      return( k_error);
    }
    if (sm_media_is_phyblock_ok())
      break;
  }

  if (g_addr_rd_phy_blk==(_media_data(physical_blocks_per_zone)-_media_data(logical_blocks_per_zone)-1))
  {
    trace0(0, sm_media, 0, "error - valid cis block not found.") ;
    sm_soft_reset();
    return k_error ;
  }

  while (g_addr_page<k_sm_max_cis_sect)
  {
    if (g_addr_page)
    {
      if (k_success != sm_media_read_extra_data())
      {
        trace0(0, sm_media, 0, "error - could not read extra data (2)") ;
        sm_soft_reset();
        return k_error ;
      }
    }

    if (sm_redt_is_data_valid())
    {
      // redundant data reports data is good.
      _media_data(sector_buffer) = g_sector_buffer ;
      if ( k_success != sm_media_read_sector())
      {
        trace1(0, sm_media, 0, "page %d read failure.  cis not found.", g_addr_page) ;
        sm_soft_reset();
        return k_error ;
      }

      if(!(g_dev_attr_hl&kbm_attr_hl_sm_ignore_bad_cis))
      {
        // if not ignoring cis, validate (correct) sector data and CIS field

        if ( k_success != sm_media_validate_sector(g_sector_buffer) )
        {
          trace1(0, sm_media, 0, "page %d data invalid", g_addr_page) ;
          sm_soft_reset();
          return k_error ;
        }

        if ( k_success != sm_validate_cis(g_sector_buffer))
        {
          trace0(0, sm_media, 0, "cis data failed ecc check.  media unusable") ;
          sm_soft_reset();
          return k_error ;
        }
      }
      // otherwise, use the first block we could read

      _media_data(boot_block) = g_addr_rd_phy_blk ;
      _media_data(boot_page) = g_addr_page;
      trace2(0, sm_media, 0, "card info struct data found. rd_phy_blk:%04X sector:%02x", g_addr_rd_phy_blk, g_addr_page) ;
      return k_success ;
    }
    g_addr_page++;
  }
  sm_soft_reset();
  return k_error ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_redt_is_data_valid()
//
// Declaration:
//   t_result sm_redt_is_data_valid(void) reentrant
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_redt_is_data_valid(void) reentrant
{
  uint8 data_status = x_sm_redt_data[k_ix_redt_data_status] ;

  if (data_status==0xFF)
    return k_true;

  if (data_status==0x00)
  {
    trace0(0, sm_media, 0, "data status:0x00 -> factory-marked bad-block") ;
    return k_false;
  }

  if (bit_count8(data_status)<5)
  {
    trace0(0, sm_media, 0, "data status:0x02X -> 4 bits +/- 1 bit error:  data either marked bad, or set bad by factory") ;
    return k_false;
  }

  return k_true;
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_media_read_extra_data()
//
// Declaration:
//   TBD
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_read_extra_data(void) reentrant
{
  uint8 i ;

  trace3(0, sm_media, 0, "sm_media_read_extra_data() - zone:%d RD_PHY:%d page:%d", g_addr_zone, g_addr_rd_phy_blk, g_addr_page) ;

  nand_rd_va2pa() ;

  sm_rd_cmd_begin(k_sm_read_redt) ;
//  sm_set_rd_cmd(k_sm_read_redt);
  _media_set_read_addr() ; 

  if (k_success != sm_wait_rdy_with_timeout(k_sm_busy_read_timeout))
  {
    trace0(0, sm_media, 0, "**** sm_media_read_extra_data() - timed out trying to read extra data") ;
    sm_reset_device() ;
    return(k_error);
  }

  if( !(x_media_sts&kbm_media_sts_sm_256_page) )
  {
    trace0(0, sm, 0, "reading 512+16 media extra data") ;
    // read redundant data (512+16 media) ----------------------
    for (i=0x00;i<k_sm_redt_buffer_sz;i++)
      x_sm_redt_data[i] =_sm_data_rd();
    
    // wait-with-timeout (k_sm_read_timeout)
    if (k_success != sm_wait_rdy_with_timeout(k_sm_busy_read_timeout))
    {
      trace0(0, sm_media, 0, "error - timed out waiting for ready bit") ;

⌨️ 快捷键说明

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