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

📄 sm_media.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
        trace0(0, sm_media, 0, "cis data failed ecc check.  media unusable") ;
        sm_soft_reset();
        return k_error ;
      }
      _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") ;
    nand_cmd_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") ;
      nand_cmd_reset_device() ;
      return k_error ;
    }
  }
  else
  {
    // read redundant data (256+8 media) -----------------------
    trace0(0, sm, 0, "reading 256+8 media extra data") ;

    // first page
    for (i=0x00;i<0x08;i++)
      x_sm_redt_data[i] =_sm_data_rd();

    // wait-with-timeout (k_sm_read_timeout)
    if (sm_wait_rdy_with_timeout(k_sm_busy_read_timeout))
    {
      nand_cmd_reset_device() ;
      trace0(0, sm_media, 0, "error reading redt data even page") ;
      return k_error;
    }

    // second page
    x_smc_stat = kbm_smc_stat_rdy ;
    _sm_set_rd_cmd(k_sm_read_redt);
    nand_incr_addr() ;
    _media_set_read_addr() ; 
    if (sm_wait_rdy_with_timeout(k_sm_busy_read_timeout))
    {
      nand_cmd_reset_device() ;
      trace0(0, sm_media, 0, "error trying to read redt data odd page") ;
      return k_error ;
    }

    for (i=0x08;i<0x10;i++)
      x_sm_redt_data[i] =_sm_data_rd();

    if (sm_wait_rdy_with_timeout(k_sm_busy_read_timeout))
    {
      nand_cmd_reset_device() ;
      trace0(0, sm_media, 0, "error after reading redt data odd page") ;
      return k_error ;
    }
  }
  _sm_hw_set_rd_standby();
  sm_synch_hw_buff_to_redt_buf() ;
  return k_success;
}


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

  trace4(0, sm_media, 0, "sm_media_write_extra_data() - zone:%d WR_PHY:%d log:%d page:%d", g_addr_zone, g_addr_wr_phy_blk, g_addr_log_blk, g_addr_page) ;

  result=k_success ;

  // issue some custom commands to put card into write redundant data mode
  sm_set_write_mode_extra_data() ;

  // calculate address
  nand_wr_va2pa() ;

  // issue command
  _sm_wr_cmd_begin(k_sm_write_data) ;
  
  // set page address
  _media_set_write_addr() ; 

  // this transmission is coming to you
  for (i=0x00;i<0x10;i++)
  {
    _sm_data_wr(x_sm_redt_data[i]);
  }

  // commit the data
#if 1
  trace0(0, sm, 0, "cmd:  write") ;
  _sm_set_wr_cmd(k_sm_write);
#else
  if(g_addr_page==(_media_data(pages_per_block)-1))
  {
    trace0(0, sm, 0, "cmd:  write") ;
    _sm_set_wr_cmd(k_sm_write);
  }
  else
  {
    trace0(0, sm, 0, "cmd:  write cache");
    _sm_set_wr_cmd(k_nand_cmd_write_cache);
  }
#endif


  // wait for complete
  if (k_success != sm_wait_rdy_with_timeout(k_sm_busy_programming_timeout))
  {
    trace0(0, sm_media, 0, "error programing extra data") ;
    result=k_error;
  }

  // restore the smart media data pointer mode
  sm_set_write_mode_page_data() ;
  _sm_hw_set_wr_standby();
  _sm_hw_set_rd_standby();
  return result ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_clear_redt_buffer()
//
// Declaration:
//   void sm_clear_redt_buffer(void) reentrant
//
// Purpose:
//  TBD
//
// Arguments:
//  TBD
//
// Return:
//  k_success always
//
// Notes:
//  TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_clear_extra_data(void) reentrant
{
  memset(x_sm_redt_data, 0xff, k_sm_redt_buffer_sz) ;
  sm_synch_hw_buff_to_redt_buf() ;
  return k_success ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_media_resolve_conflict()
//
// Declaration:
//  t_result sm_media_resolve_conflict(void) reentrant
//
// Purpose:
//  resolve a log2phy binding in a media-specific algorithm
//
// Arguments:
//  - see Notes
//
// Return:
//  k_success always
//
// Notes:
//  when called,
//    g_addr_rd_phy_blk contains one of the bindings,
//    g_addr_wr_phy_blk contains the original mapping
//
//  before returning, ensure:
//    g_addr_rd_phy_blk should contain the correct mapping
//    g_addr_wr_phy_blk should contain the block to be erased (or not used)
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------

t_result sm_media_resolve_conflict() reentrant
{
  uint16 temp ;

  // call mapper-defined conflict resolver
  if (k_success != map_resolve_conflict())
  {
    // by smart media spec, arbitrarily choose smaller phy_blk as correct binding
    temp = _min(g_addr_rd_phy_blk, g_addr_wr_phy_blk) ;

    // set wr_phy_blk to the phy_blk to be ignored/erased
    g_addr_wr_phy_blk = _max(g_addr_rd_phy_blk, g_addr_wr_phy_blk) ;

    // set rd_phy_blk to the correct binding and return
    g_addr_rd_phy_blk = temp ;
  }
  return k_success ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_media_set_read_addr()
//
// Declaration:
//   t_result sm_media_set_read_addr() reentrant
//               
// Purpose:
//   set media-specific address from internal zone/rd_phy_blk/sector addres
//
// Arguments:
//  TBD
//
// Return:
//  k_success always
//
// Notes:
//  TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_set_read_addr() reentrant 
{
  trace3(0, sm_media, 0, "sm_media_set_read_addr() - page:%02x%02x%02x", g_nand_rd_addr_msb, g_nand_rd_addr_mid, g_nand_rd_addr_lsb) ;
  _sm_hw_set_rd_addr();
  _sm_data_wr(0x00);
  _sm_data_wr(g_nand_rd_addr_lsb) ; 
  _sm_data_wr(g_nand_rd_addr_mid) ; 
  if (_lun_data(media)&kbm_sm_media_addr_4cyc)
    _sm_data_wr(g_nand_rd_addr_msb);
  _sm_hw_set_rd_data(0);
  return k_success ;
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_media_set_write_addr()
//
// Declaration:
//   t_result sm_media_set_write_addr() reentrant
//
// Purpose:
//   set media-specific address from internal zone/wr_phy_blk/sector addres
//
// Arguments:
//  TBD
//
// Return:
//  k_success always
//
// Notes:
//  TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_set_write_addr() reentrant 
{
  trace3(0, sm_media, 0, "sm_media_set_write_addr() - page:%02x%02x%02x", g_nand_wr_addr_msb, g_nand_wr_addr_mid, g_nand_wr_addr_lsb) ;
  _sm_hw_set_wr_addr();
  _sm_data_wr(0x00);
  _sm_data_wr(g_nand_wr_addr_lsb) ;
  _sm_data_wr(g_nand_wr_addr_mid) ;
  if (_lun_data(media)&kbm_sm_media_addr_4cyc)
    _sm_data_wr(g_nand_wr_addr_msb);
  _sm_hw_set_wr_data(0);
  return k_success ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_media_set_erase_addr()
//
// Declaration:
//   t_result sm_media_set_erase_addr() reentrant
//
// Purpose:
//   set media-specific address from internal zone/wr_phy_blk
//
// Arguments:
//  TBD
//
// Return:
//  k_success always
//
// Notes:
//  The block to be erased should be in g_addr_wr_phy_blk before this 
//  function is called
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_set_erase_addr() reentrant 
{
  trace3(0, sm_media, 0, "sm_media_set_erase_addr() - page:%02x%02x%02x", g_nand_wr_addr_msb, g_nand_wr_addr_mid, g_nand_wr_addr_lsb) ;
  _sm_hw_set_wr_addr();
  _sm_data_wr(g_nand_wr_addr_lsb) ;
  _sm_data_wr(g_nand_wr_addr_mid) ;
  if (_lun_data(media)&kbm_sm_media_addr_4cyc)
    _sm_data_wr(g_nand_wr_addr_msb);

  // always use 0 for smart media... forces compatible timing mode on 242
  _sm_hw_set_wr_data(0);
  return k_success ;
}

//+-----------------------------------------------------------------------------
// Name:
//   media_block_has_bad_data()
//
// Declaration:
//   t_result media_block_has_bad_data() reentrant
//
// Purpose:
//   scan blocks to find out whether or not a block contains a page that has 
//   a bad data flag.  This is used for smart media controller who must detect
//   data-gone-bad flag which can't do so at run-time
//
// Arguments:
//
// Return:
//  k_true  if a page between 0 and g_addr_rd_page contains extra data with 
//          'failed' status
//
//  k_false if all pages have good data status
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_block_has_bad_data() reentrant 
{
  trace0(0, sm_media, 0, "sm_media_block_has_bad_data()") ;
  return sm_check_data_status(0, _media_data(pages_per_block));
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_media_is_phyblock_reserved()
//
// Declaration:
//   t_result sm_media_is_phyblock_reserved() reentrant
//
// Purpose:
//   scan blocks to find out whether or not a block is reserved (i.e. boot area) or
//   usable by mapper & user.  
//
// Arguments:
//
// Return:
//  k_true  if physical zone/block can be a user-accessible block
//  k_false if physical block should be ignored by the mapper for everything
//
// Notes:
//  a reserved block is NOT a factory or user-marked bad block.  it is a block reserved
//  for storing private data or boot information.  (i.e. boot blocks, boot area, etc.)
//  blocks marked bad by the factory will be detected in a subsequent call
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_media_is_phyblock_reserved(void) reentrant
{
  if ((!g_addr_zone) && (g_addr_rd_phy_blk <= _media_data(boot_block)))
  {
    trace2(0, sm_media, 0, "block %d:%d is part of the boot area.  tell mapper it is reserved", g_addr_zone, g_addr_rd_phy_blk);
    return k_true;
  }
  return k_false;
}

⌨️ 快捷键说明

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