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

📄 ms_media.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (_factor & kbm_ms_reg_int_err)
  {
    trace0(0, ms, 10, "error: ced&err unrecoverable flash write error");
    ms_media_set_phyblock_failed();
    return k_error;
  }
  // write complete
  return k_success;
}
#endif

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//t_result ms_media_write_sector() reentrant
//{
//  trace0(0, ms_media, 0, "ms_media_write_sector()");
//  set_wr_phyblk();
//  return ms_pio_write_page(k_max_pnr);
//}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_phy2log() reentrant
{
  uint16 absolute;
  uint16 relative;

  trace0(0, ms_media, 10, "ms_media_phy2log()");
  absolute = g_ms_extra[k_log_addr_msb_flg_offset] * 256 + g_ms_extra[k_log_addr_lsb_flg_offset];
  switch (g_addr_zone)
  {
    case 0:
      relative = absolute;
      break;
    case 1:
      relative = absolute - _media_data(logical_blocks_per_boot_zone);
      break;
    default:
      relative = absolute - _media_data(logical_blocks_per_boot_zone);
      relative %= _media_data(logical_blocks_per_zone);
      break;
  }
  g_addr_log_blk = relative;
  trace3(0, ms, 110, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
  return k_success;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_bind_log2phy() reentrant
{
  uint16 absolute;

  trace1(0, ms_media, 10, "ms_media_bind_log2phy() log:%04X", g_addr_log_blk);
  switch (g_addr_zone)
  {
    case 0:
      absolute = g_addr_log_blk;
      break;
    case 1:
      absolute  = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
      break;
    default:
      absolute = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
      absolute += (g_addr_zone - 1) * _media_data(logical_blocks_per_zone);
      break;
  }
  trace3(0, ms, 10, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
  g_ms_extra[k_log_addr_msb_flg_offset] = _h(absolute);
  g_ms_extra[k_log_addr_lsb_flg_offset] = _l(absolute);
  return k_success;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_set_phyblock_failed() reentrant
{
  trace0(0, ms_media, 0, "ms_media_set_phyblock_failed()");
  g_ms_extra[k_ovwr_flg_offset] &= ~ kbm_ms_ext_ovwr_bkst;
  return k_error;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#define k_reference_bad_block_table
t_bool ms_media_is_phyblock_ok() reentrant
{
  t_bool rslt;

  trace0(0, ms_media, 110, "ms_media_is_phyblock_ok()");
  // start out hopeful
  rslt = k_yes;

  // is this a user area block?
  if(!g_addr_zone && g_addr_rd_phy_blk < g_ms_user_area_start_blk)
  {
    trace0(0, ms_media, 110, "alert:  ms_media_is_phyblock_ok() - block is not in user area");
    rslt = k_no;
  }

  // block status of 0 is bad
  if (!(g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_bkst))
  {
    trace0(0, ms_media, 110, "alert: ms_media_is_phyblock_ok() - bad page by bkst");
    rslt = k_no;
  }
  // page status of 1 is bad
  if (g_ms_extra[k_ovwr_flg_offset] & (kbm_ms_ext_ovwr_pgst0 | kbm_ms_ext_ovwr_pgst1) == 1)
  {
    trace0(0, ms_media, 110, "alert: ms_media_is_phyblock_ok() - bad page by pgst01");
    rslt = k_no;
  }

  // is it the log2phy map table block?  if yes it should get whacked.
  if (!g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_atflg)
  {
    trace0(0, ms_media, 110, "alert: ms_media_is_phyblock_ok() - table block found");
    trace1(0, ms, 80, "atflg:%02X", g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_atflg);
  }

  #ifdef k_reference_bad_block_table
  // read the bad block list
  if (rslt == k_yes)
  {
    t_uw16 blk_to_check;
    trace0(0, ms_media, 110, "reference the bad block table");
    // look to see if this phy block is in it
    trace2(0, ms_media, 110, "g_addr_zone:%d g_addr_rd_phy_blk:%d", g_addr_zone, g_addr_rd_phy_blk);
    blk_to_check.u16 = g_addr_zone * _media_data(physical_blocks_per_zone) + g_addr_rd_phy_blk;
    trace1(0, ms_media, 110, "blk_to_check:%d", blk_to_check.u16);
    if (ms_is_this_blk_in_bad_blk_tbl(blk_to_check.u16))
    {
      // this physical block appears in the bad block list
      rslt = k_no;
      trace1(0, ms_media, 110, "alert: block:%d is in the bad block table!", blk_to_check.u16);
    }
  }
  //exit:
  #endif  //k_reference_bad_block_table
  trace1(0, ms_media, 110, "ms_media_is_phyblock_ok(): %c", rslt ? 'Y' : 'N');
  return rslt;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_is_phyblock_blank() reentrant
{
  t_bool is_blank;
  is_blank = (0xFF == g_ms_extra[k_log_addr_msb_flg_offset]) && (0xFF == g_ms_extra[k_log_addr_lsb_flg_offset]);
  trace1(0, ms_media, 0, "ms_media_is_phyblock_blank(): %c", is_blank ? 'Y' : 'N');
  return is_blank;
}

#if 0
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_is_phyblock_wp() reentrant
{
  t_bool is_wp;
  uint16 blk_to_check;

  blk_to_check = g_addr_zone * _media_data(physical_blocks_per_zone) + g_addr_rd_phy_blk;
  trace1(0, ms_media, 110, "blk_to_check:%d", blk_to_check);
  is_wp = ms_is_this_blk_the_information_block(blk_to_check);
  trace1(0, ms_media, 0, "ms_media_is_phyblock_wp(): %c", is_wp ? 'Y' : 'N');
  return is_wp;
}
#endif

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_read_extra_data() reentrant
{
  trace0(0, ms_media, 0, "ms_media_read_extra_data()------------------------------------");
  set_rd_phyblk();
  return ms_read_extra_data();
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_write_extra_data() reentrant
{
  trace0(0, ms_media, 0, "ms_media_write_extra_data()");
  set_wr_phyblk();
  return ms_write_extra_data();
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_clear_extra_data(void) reentrant
{
  trace0(0, ms_media, 0, "ms_media_clear_extra_data()");
  memset(g_ms_extra, 0xFF, 4);
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_media_resolve_conflict()
//
// Declaration:
//  t_result ms_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 ms_media_resolve_conflict() reentrant
{
  uint16 tmp;
  uint8 udst0;
  uint8 udst1;

  trace0(0, ms_media, 110, "ms_media_resolve_conflict()");
  trace2(0, ms_media, 110, "->g_addr_rd_phy_blk:0x%04X, g_addr_wr_phy_blk:0x%04X", g_addr_rd_phy_blk, g_addr_wr_phy_blk);
  // determine the update status of the block at g_addr_rd_phy_blk
  set_rd_phyblk();
  ms_read_extra_data();
  udst0 = g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_udst;
  // determine the update status of the block at g_addr_wr_phy_blk
  set_wr_phyblk();
  ms_read_extra_data();
  udst1 = g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_udst;
  // udst0 udst1 choose
  // ----- ----- ------
  //   0     0   largest phy addr
  //   0     1   g_addr_rd_phy_blk
  //   1     0   g_addr_wr_phy_blk
  //   1     1   largest phy addr
  if (udst0 == udst1)
  {
    // cannot tell by update status; choose the larger physical block number
    tmp = _max(g_addr_rd_phy_blk, g_addr_wr_phy_blk);
    g_addr_wr_phy_blk = _min(g_addr_rd_phy_blk, g_addr_wr_phy_blk);
    g_addr_rd_phy_blk = tmp;
    trace1(0, ms_media, 110, "-->chose larger:0x%04X", g_addr_rd_phy_blk);
  }
  else
  if (!udst1)
  {
    // ye olde triangle swap
    tmp = g_addr_wr_phy_blk;
    g_addr_wr_phy_blk = g_addr_rd_phy_blk;
    g_addr_rd_phy_blk = tmp;
    trace1(0, ms_media, 110, "-->chose: wr by update status 0x%04X", g_addr_rd_phy_blk);
  }
  else
  {
    trace1(0, ms_media, 110, "-->chose: rd by update status 0x%04X", g_addr_rd_phy_blk);
  }

  // and reverse the order because this works, and doing it the way the spec says doesnt.
  //tmp = g_addr_wr_phy_blk;
  //g_addr_wr_phy_blk = g_addr_rd_phy_blk;
  //g_addr_rd_phy_blk = tmp;

  // otherwise udst0 must be zero, so no variable swapping needs to occur
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   media_erase_card()
//
// Declaration:
//   t_result media_erase_card() reentrant
//
// Purpose:
//  TBD
//
// Arguments:
//  TBD
//
// Return:
//  k_success always
//
// Notes:
//  TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
#if 0
t_result ms_media_erase_card() reentrant
{
  uint16 max_lb ;

  trace0(0, sm, 0, "ms_media_erase_card() - Erasing Memory Stick Card.") ;
  for(g_addr_zone=0 ; g_addr_zone < _media_data(num_zones) ; g_addr_zone++)
  {
    max_lb = g_addr_zone? (_media_data(logical_blocks_per_zone)) : (_media_data(logical_blocks_per_boot_zone)) ;
    g_addr_log_blk = 0 ;
    for(g_addr_wr_phy_blk = g_addr_zone?0:_media_data(cis_phy_block)+1;
        g_addr_wr_phy_blk < _media_data(physical_blocks_per_zone) ;
        g_addr_wr_phy_blk++)
    {
      _media_erase_block() ;
      if( g_addr_log_blk < max_lb )
      {
        // bind the log2phy addrs... memory stick gets upset if all blocks are bound to log_blk 0xffff
        _media_clear_extra_data() ;
        _media_bind_log2phy() ;
        _media_write_extra_data() ;
        g_addr_log_blk++ ;
      }
    }
  }
  return k_success ;
}
#endif

//+-----------------------------------------------------------------------------
// Name:
//   ms_media_is_phyblock_reserved()
//
// Declaration:
//   t_result ms_media_is_phyblock_reserved() reentrant
//
// Purpose:
//   tells mapper 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 ms_media_is_phyblock_reserved(void) reentrant
{
  trace0(0, ms_media, 110, "ms_media_is_phyblock_reserved()");
  if ((!g_addr_zone) && (g_addr_rd_phy_blk < g_ms_user_area_start_blk))
  {
    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;
}



//---eof------------------------------------------------------------------------

⌨️ 快捷键说明

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