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

📄 ms.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
  trace1(0, ms, 0, "ms_pio_read_page():%d", g_ms_page);
  //_stack_check();
  if (k_success != ms_write_parm_reg(0x80, 0x20))
    return k_error;
  if (k_success != ms_set_cmd(k_ms_block_read))
    return k_error;
  if (k_success != ms_get_int(5))
    return k_error;
  if (_factor & kbm_ms_reg_int_cmdnk)
  {
    trace0(0, err, 110, "error: cmdnk (ms_pio_read_page)");
    return k_error;
  }
  if (!(_factor & kbm_ms_reg_int_ced))
  {
    trace0(0, err, 110, "error: ced not set (ms_pio_read_page)");
    return k_error;
  }
  if (_factor & kbm_ms_reg_int_breq)
  {
    trace0(0, ms, 110, "breq (ms_pio_read_page)");
    if (_factor & kbm_ms_reg_int_err)
    {
      trace0(0, err, 110, "error: err (ms_pio_read_page)");
      if (k_success != ms_read_status())
        return k_error;
//      if ((_status1 & (kbm_ms_reg_status1_ucdt |kbm_ms_reg_status1_ucex |kbm_ms_reg_status1_ucfg)) ==
//          (kbm_ms_reg_status1_ucdt |kbm_ms_reg_status1_ucex |kbm_ms_reg_status1_ucfg))
      if (_status1 & (kbm_ms_reg_status1_ucdt |kbm_ms_reg_status1_ucex |kbm_ms_reg_status1_ucfg))
      {
        trace0(0, err, 110, "error: ucdt&ucex&ucfg - uncorrectable flash read error (ms_pio_read_page)");
        ms_media_set_phyblock_failed();
        return k_error;
      }
    }
    if (k_success != ms_read_extra_data_reg())
      return k_error;
    if (k_success != ms_read_page_data(pnr))
      return k_error;
    return k_success;
  }
  trace0(0, err, 110, "error: unrecognized interrupt factor (ms_pio_read_page)");
  return k_error;
}

//------------------------------------------------------------------------------
// Name:
//   ms_write_all_reg
//
// Declaration:
//   t_result ms_write_all_reg(uint8 sys_parm, uint8 cmd_parm);
//
// Purpose:
//   Write the all of the of the MS card in preparation for issuing a
//   write flash command.  Writes the address, sys_parm, cmd_parm, page,
//   and extra data.
//
// Arguments:
//   sys_parm - specific to the flash command about to be issued.
//   cmd_parm - specific to the flash command about to be issued.
//
//   The following global variables are accessed and delivered to the MS card:
//     g_ms_blk_addr_msb
//     g_ms_blk_addr_mid
//     g_ms_blk_addr_lsb
//     g_ms_page
//     g_ms_extra
//
// Return:
//   A t_result indicating:
//     k_success - parameter registers are written.
//     k_error   - failed write parameter registers.  actual contents unknown.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_write_all_reg(uint8 sys_parm,
                          uint8 cmd_parm) reentrant;
t_result ms_write_all_reg(uint8 sys_parm,
                          uint8 cmd_parm) reentrant
{
  trace0(0, ms, 0, "ms_write_all_reg()");
  //_stack_check();
  trace3(0, ms, 10, " addr:0x00%02X%02X%02X", g_ms_blk_addr_msb, g_ms_blk_addr_mid, g_ms_blk_addr_lsb);
  trace3(0, ms, 10, " page:0x%02X sys_parm:0x%02X cmd_parm:0x%02X", g_ms_page, sys_parm, cmd_parm);
  if (k_success != ms_set_write_reg_addrs(k_ms_parm_system, 10))
    return k_error;
  // write the tpc
  if (k_success != ms_set_tpc(k_ms_tpc_wr_reg, 10))
    return k_error;
  // write the parm regs
  _ms_register_wr(ms_tx_db_msb, g_ms_blk_addr_msb);
  _ms_register_wr(ms_tx_db_lsb, sys_parm);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  _ms_register_wr(ms_tx_db_msb, g_ms_blk_addr_lsb);
  _ms_register_wr(ms_tx_db_lsb, g_ms_blk_addr_mid);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  _ms_register_wr(ms_tx_db_msb, g_ms_page);
  _ms_register_wr(ms_tx_db_lsb, cmd_parm);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  // write the extra data
  trace4(0, ms, 10, "wr xtra[0..3]:%02X%02X%02X%02X", g_ms_extra[0], g_ms_extra[1], g_ms_extra[2], g_ms_extra[3]);
  _ms_register_wr(ms_tx_db_msb, g_ms_extra[1]);
  _ms_register_wr(ms_tx_db_lsb, g_ms_extra[0]);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  _ms_register_wr(ms_tx_db_msb, g_ms_extra[3]);
  _ms_register_wr(ms_tx_db_lsb, g_ms_extra[2]);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_write_extra_data
//
// Declaration:
//   t_result ms_write_extra_data(void);
//
// Purpose:
//   Write the extra data registers of the active block of the MS card from
//   the global variable g_ms_extra.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - contents of the global variable g_ms_extra written to card.
//     k_error   - cannot write the extra data.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_write_extra_data(void) reentrant;
t_result ms_write_extra_data() reentrant
{
  trace4(0, ms, 0, "ms_write_extra_data(addr:0x00%02X%02X%02X page:%d)", g_ms_blk_addr_msb, g_ms_blk_addr_mid, g_ms_blk_addr_lsb, g_ms_page);
  //_stack_check();
  if (k_success != ms_write_all_reg(0x80, 0x40))
    return k_error;
  if (k_success != ms_set_cmd(k_ms_block_write))
    return k_error;
  if (k_success != ms_get_int(10))
    return k_error;
  if (_factor & kbm_ms_reg_int_cmdnk)
  {
    trace0(0, err, 110, "error: cmdnk (ms_write_extra_data)");
    return k_error;
  }
  if (!(_factor & kbm_ms_reg_int_ced))
  {
    trace0(0, err, 110, "error: ced not set (ms_write_extra_data)");
    return k_error;
  }
  if (_factor & kbm_ms_reg_int_err)
  {
    trace0(0, err, 110, "error: !ced&err (ms_write_extra_data)");
    return k_error;
  }
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_erase_block
//
// Declaration:
//   t_result ms_erase_block(void);
//
// Purpose:
//   Erase he active block in the MS card.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - block is erased.
//     k_error   - cannot erase block.  contents undefined.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_erase_block() reentrant
{
  //_profile_on(7);
  trace0(0, ms, 80, "ms_erase_block()");
  //_stack_check();
  //_profile_on(6);
  if (k_success != ms_write_parm_reg(0x80, 0x00))
    return k_error;
  //_profile_off(6);
  //_profile_on(5);
  if (k_success != ms_set_cmd(k_ms_block_erase))
    return k_error;
  //_profile_off(5);
  //_profile_on(4);
  if (k_success != ms_get_int(100))
    return k_error;
  //_profile_off(4);
  if (_factor & kbm_ms_reg_int_cmdnk)
  {
    trace0(0, err, 110, "error: cmdnk (ms_erase_block)");
    return k_error;
  }
  if (!(_factor & kbm_ms_reg_int_ced))
  {
    trace0(0, err, 110, "error: ced not set (ms_erase_block)");
    return k_error;
  }
  if (_factor & kbm_ms_reg_int_err)
  {
    trace0(0, err, 110, "error: err (ms_erase_block)");
    return k_error;
  }
  //_profile_off(7);
  return k_success;
}


//------------------------------------------------------------------------------
// steal a buffer from media.c temporarily (its ok, media.c only uses it for copy-sector).
// actually now that copy sector is done via fmc its probably not used for that purpose
// on the other luns anymore either.
//------------------------------------------------------------------------------
extern xdata uint8  g_sector_buffer[];
void xbuf_rd(uint16 offset, uint16 len, t_memory_ref bufp) reentrant
{
  t_xdata_ref srcbufp;
  mcu_begin_critical_section();
  trace0(0, hal, 0, "mmu_rd()");
  srcbufp = g_sector_buffer;  // shouldnt this be _media_data(sector_buffer) ???
  srcbufp += offset;
  for (; len; len--, *bufp++=*srcbufp++);
  mcu_end_critical_section();
}

//+-----------------------------------------------------------------------------
// Name:
//  ms_read_boot_block
//
// Declaration:
//   t_result ms_read_boot_block(void);
//
// Purpose:
//   Determine the parameters (capacity etc) of the card by examining the contents
//   of the boot block.  Configures the _media_data() settings for the media based
//   of the contents of the boot block.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - boot block read, _media_data() configured.
//     k_error   - cannot read boot block.  contents of _media_data() undefined.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
//   Boot Block Format:
//    page 0: header (368 bytes)
//            system entry (48 bytes)
//            boot and attribute info (96 bytes)
//    page 1: disabled block data
//    page 2: card info struct (256 byets)
//            identification info (256 bytes)
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------

t_result ms_read_boot_block(void) reentrant;
t_result ms_read_boot_block() reentrant
{
  uint8 blk;
  //uint8 pnr;
  uint8 boot_count;
  t_result rslt;

  trace0(0, ms, 80, "ms_read_boot_block()");
  _force_one_burst_per_split = k_no;  // br308
  //_stack_check();
  //pnr = mmu_allocate();

  // no media/mapper optimizations at this time
  _media_data(options) = kbm_media_data_opt_none;
  _media_data(sector_buffer) = g_sector_buffer;  // sneakily share media.c's buffer
  boot_count = 0;
  _media_data(boot_block) = 0xFF;
  for (blk=0; blk<11; blk++)
  {
    trace1(0, ms, 80, "checking block %d", blk);
    // read page 0 of the block
    g_ms_blk_addr_msb = 0;
    g_ms_blk_addr_mid = 0;
    g_ms_blk_addr_lsb = blk;
    g_ms_page = 0;
    if (k_success != (rslt = ms_pio_read_page(k_max_pnr)))
    {
      trace0(0, err, 80, "error: cant read page zero of this block");
      continue;
      //goto exit;
    }
    // block status must be set; e.g., 'ok'
    if (!(g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_bkst))
    {
      trace2(0, ms, 80, "blk:%d bkst:%02X", blk, g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_bkst);
      continue;
    }
    // system bit must be clear; e.g., 'boot'
    if (g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_sysflg)
    {
      trace2(0, ms, 80, "blk:%d sysflg:%02X", blk, g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_sysflg);
      continue;
    }
    // top word of page 0 must be 0x0001
    xbuf_rd(0, 2, (uint8*)&g_wtmp);
    if (0x0001 != g_wtmp)
    {
      trace2(0, ms, 80, "blk:%d top word:%04X", blk, g_wtmp);
      //dbg_dumpram(k_pkt_addrlo[pnr], k_pkt_addrhi[pnr], 512);
      continue;
    }
    // found the boot block
    boot_count++;
    trace1(0, ms, 80, "BOOT BLOCK:%d", blk);
    if (_media_data(boot_block) == 0xFF)
    {
      // if more than one boot block is found then choose the lowest numbered
      trace0(0, ms, 80, "INSTALLING BOOT BLOCK INTO TABLE");
      _media_data(boot_block) = blk;
    }
    trace1(0, ms, 80, "BOOT AREA MAX BLK NOW:%d", blk);
    g_ms_user_area_start_blk=blk+1;

    trace0(0, ms, 80, "PAGE 0 (HEADER)");
    // block size?
    xbuf_rd(418, 1, &(_ms_byte_per_block.u8.hi));
    xbuf_rd(419, 1, &(_ms_byte_per_block.u8.lo));
    _ms_byte_per_block.u16 *= 1024;
    trace1(0, ms, 80, "_ms_byte_per_block:%d", _ms_byte_per_block.u16);
    // number of blocks?
    xbuf_rd(420, 1, &(_ms_block_per_card.u8.hi));
    xbuf_rd(421, 1, &(_ms_block_per_card.u8.lo));
    trace1(0, ms, 80, "_ms_block_per_card:%d", _ms_block_per_card.u16);
    _media_data(num_zones) = _ms_block_per_card.u16 / k_phy_block_per_segment;
    trace1(0, ms, 80, "_ms_zone_per_card:%d", _media_data(num_zones));
    _media_data(physical_blocks_per_zone) = k_phy_block_per_segment;
    _media_data(logical_blocks_per_zone) = k_log_block_per_segment;
    _media_data(logical_blocks_per_boot_zone) = k_log_block_per_boot_segment;

⌨️ 快捷键说明

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