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

📄 device.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
  //#elif defined (k_opt_nand)
  //do nothing
  #else
  return;
  #endif

}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void nvstore_write_disable() reentrant
{
  #ifdef k_opt_eeprom
  eeprom_write_disable();
  //#elif defined (k_opt_otprom)
  //otprom_write_flush();  
  #elif defined (k_opt_nand)
  nand_boot_write_flush();
  #else
  return;
  #endif

}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static t_result dev_sink_nvdata_to_eeprom(uint8 pnr, uint8 len) reentrant;
static t_result dev_sink_nvdata_to_eeprom(uint8 pnr, uint8 len) reentrant
{
  #ifdef k_opt_eeprom
  uint8 i;
  uint8 c;
  uint8 v;

  trace0(0, dev, 0, "dev_sink_nvdata_to_eeprom");
  eeprom_write_enable();
  // sink data
  i=0;
  trace1(0, dev, 0, "writing %d bytes...", len);
  while (i<len)
  {
    mmu_rd(pnr, i++, 1, &c);
    eeprom_write(_nvstore_ix++,c);
  }
  eeprom_write_disable();
  // verify data
  i=0;
  _nvstore_ix -= len;
  trace1(0, dev, 0, "verifying %d bytes...", len);
  while (i < len)
  {
    mmu_rd(pnr, i++, 1, &c);
    v=eeprom_read(_nvstore_ix++);
    if (c != v)
    {
      trace3(0, dev, 0, "nvstore(%d) failure.  expected: %02X, got: %02X", (i-1), c, v);
      return(k_error);
    }
  }
  trace0(0, dev, 0, "data written and verified");
  return(k_success);
  #else
  pnr=pnr; len=len;
  return(k_false);
  #endif // k_opt_eeprom
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static t_result dev_sink_nvdata_to_otprom(uint8 pnr, uint8 len) reentrant;
static t_result dev_sink_nvdata_to_otprom(uint8 pnr, uint8 len) reentrant
{
  #ifdef k_opt_otprom
  trace0(0, dev, 0, "dev_sink_nvdata_to_otprom - only supports sst39lf010");
  mmu_rd(pnr, 0, len, (t_xdata_ref)(k_ram_base + (k_nvstore_base - k_otprom_base) + _nvstore_ix));
  _nvstore_ix += len;
  // not verifying the data here.  host can issue eeread to verify.
  return(k_success);
  #else
  pnr=pnr; len=len;
  return(k_false);
  #endif // k_opt_otprom
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static t_result dev_sink_nvdata_to_nand(uint8 pnr, uint8 len) reentrant;
static t_result dev_sink_nvdata_to_nand(uint8 pnr, uint8 len) reentrant
{
  #ifdef k_opt_nand
  uint8 i;
  uint8 c;

  trace0(0, dev, 0, "dev_sink_nvdata_to_nand()");
  // sink data
  i=0;
  trace1(0, dev, 0, "writing %d bytes...", len);
  while (i<len)
  {
    mmu_rd(pnr, i++, 1, &c);
    nand_boot_write(_nvstore_ix++,c);
  }
  return(k_success);
  #else
  pnr=pnr;len=len;
  return(k_false);
  #endif // k_opt_nand
}

//------------------------------------------------------------------------------
// this function converts whatever is in the x_ata_dev_str_ser buffer or, if
// used, the serial eeprom, into a bulk-only compliant serial number of at
// least 12 bytes.
//------------------------------------------------------------------------------
#define _nvdata(__offset) g_sector_buffer[(__offset)]

static void dev_validate_nvstore(void) reentrant;
static void dev_validate_nvstore() reentrant
{
  #ifdef k_opt_nvstore
  uint8 i,b;
  uint8 sz;

  trace0(0, dev, 0, "dev_validate_nvstore()");

  for (i=0; i<255; i++)
  {
    g_sector_buffer[i] = nvstore_read(i);
    //TRACE2(36, dev, 0, "nvdata[%03d]:0x%02X", i, _nvdata(i));
  }
  g_sector_buffer[255] = nvstore_read(255);
  //TRACE1(37, dev, 0, "nvdata[255]:0x%02X", _nvdata(255));

  _nvstore_data_valid = k_false;
  _serial_number_valid = k_false;
  g_dev_attr_lo = k_attr_lo_default;
  g_password_validated = k_yes;
  g_blink_interval = 0x0A;
  _blink_counter = 0x00;
  _seconds_counter = k_counts_per_sec;
  g_nvstore_post_access_blink_secs = 0x00;
  g_post_access_blink_secs = 0x00;
  g_activity_led_idle_bright = k_true;

  // check the configuration descriptor fields
  if (_nvdata(k_ix_maxpwr) > 0x31)
  {
    trace0(0, dev, 0, "error: bMaxPower > 98ma");
  }
  if (_nvdata(k_ix_maxpwr) < 0x01)
  {
    trace0(0, dev, 0, "error: bMaxPower < 2ma");
  }
  if ((_nvdata(k_ix_bmattrib) != 0xC0) && (_nvdata(k_ix_bmattrib) != 0x80))
  {
    trace1(0, dev, 0, "error: bmAttributes is invalid:%02X", _nvdata(k_ix_bmattrib));
    // this is wrong enough that the nvstore data cannot be trusted, regardless of the signature
    return;
  }

  // check the signature
  if ((_nvdata(k_ix_sig_hi) == k_sig_ata1_hi) &&
      (_nvdata(k_ix_sig_lh) == k_sig_ata1_lh) &&
      (_nvdata(k_ix_sig_hl) == k_sig_ata1_hl) &&
      (_nvdata(k_ix_sig_lo) == k_sig_ata1_lo))
  {
    trace0(0, dev, 0, "nvstore contains valid signature.");
    _nvstore_data_valid = k_true;
  }
  else
  {
    trace4(0, dev, 0, "nvstore signature is invalid:%02X%02X%02X%02X",
           _nvdata(k_ix_sig_hi),_nvdata(k_ix_sig_lh),_nvdata(k_ix_sig_hl),_nvdata(k_ix_sig_lo));
    return;
  }

  // could use an attribute bit to enable password
  #ifdef k_opt_password
  // if there is no password then password is considered to be validated
  b = _nvdata(k_ix_password);
  if ((b == 0xFF) || (b == 0x00))  //0xFF and 0x00 are the password termination characters.
  {
    g_password_validated = k_yes;
    trace0(0, dev, 0, "no password exists, so password is considered valid, and media is not removable");
  }
  else
  {
    g_password_validated = k_no;
    trace0(0, dev, 0, "password exists, so password is not valid, and media is removable");
  }
  #endif

  //Determine attributes for blinky light
  //read the blink interval byte
  g_blink_interval = _nvdata(k_ix_blink_interval);
  //do we need to continue blinking?
  g_nvstore_post_access_blink_secs = _nvdata(k_ix_blinks_after_access);
  trace2(0, dev, 0, "blink interval:%d post:%d", g_blink_interval, g_nvstore_post_access_blink_secs);
  //do they want the led kept on all the time and then blink on access?
  g_activity_led_idle_bright = g_blink_interval & 0x80;
  //the last 7 bits is a multiple of 10ms, as the blink interval
  g_blink_interval &= 0x7f;
  //blink counter starts with the blink interval
  _blink_counter = g_blink_interval;
  trace2(0, dev, 0, " g_activity_led_idle_bright: %d   g_blink_interval: %d" , (uint8)g_activity_led_idle_bright,g_blink_interval);

  // process attribute flags
  g_dev_attr_lo = _nvdata(k_ix_attr_lo);
  //g_dev_attr_hl = nvstore_read(k_ix_attr_hl);
  //g_dev_attr_lh = nvstore_read(k_ix_attr_lh);
  // g_dev_attr_hi = _nvdata(k_ix_attr_hi);
  trace1(0, dev, 0, "attribute: force smart media compatible timing:%c", ((g_dev_attr_lo&kbm_attr_lo_sm_timing)?'Y':'N'));
  trace1(0, dev, 0, "attribute: nand flash hard drives to always enumerate as removable media:%c", ((g_dev_attr_lo&kbm_attr_lo_hd_as_rm)?'Y':'N'));
  trace1(0, dev, 0, "attribute: use gpio5 as sd card detect:%c", ((g_dev_attr_lo&kbm_attr_lo_gpio5_as_sd_insert)?'Y':'N'));
  trace1(0, dev, 0, "attribute: Always report iSerial as zero in the device descriptor:%c", ((g_dev_attr_lo&kbm_attr_lo_force_zero_iserial)?'Y':'N'));

  // copy the device id strings for each lun into the _lun_data
  // (only 7 chars worth gets assembled into the inquiry data for icon matching)
  for (i=0;i<k_max_log_lun;i++)
  {
    uint8 offset;
    // this assumes each 7-byte string is sequential in nvstore!  
    // also, this can only handle up to 4 luns
    offset=k_sz_lun_id*i+k_ix_lun0_id;
    if (isprint(_nvdata(offset)))
    {
      lun_set_active(_lun_log2phy(i));
      memcpy(_lun_data(device_id), &(_nvdata(offset)), k_sz_lun_id);  //k_lun_max_devid_sz);
    }
  }
/*
  #if (k_max_log_lun > 0)
  if (isprint(_nvdata(k_ix_lun0_id)))
  {
    lun_set_active(_lun_log2phy(0));
    memcpy(_lun_data(device_id), &(_nvdata(k_ix_lun0_id)), 7);  //k_lun_max_devid_sz);
  }
  #endif
  #if (k_max_log_lun > 1)
  if (isprint(_nvdata(k_ix_lun1_id)))
  {
    lun_set_active(_lun_log2phy(0));
    memcpy(_lun_data(_lun_log2phy(1), device_id), &(_nvdata(k_ix_lun1_id)), 7);
  }
  #endif
  #if (k_max_log_lun > 2)
  if (isprint(_nvdata(k_ix_lun2_id)))
  {
    lun_set_active(_lun_log2phy(0));
    memcpy(_lun_data(_lun_log2phy(2), device_id), &(_nvdata(k_ix_lun2_id)), 7);
  }
  #endif
  #if (k_max_log_lun > 3)
  if (isprint(_nvdata(k_ix_lun3_id)))
  {
    lun_set_active(_lun_log2phy(0));
    memcpy(_lun_data(_lun_log2phy(3), device_id), &(_nvdata(k_ix_lun3_id)), 7);
  }
  #endif
*/

  // validate serial number
  // read length from nvstore config
  sz = _nvdata(k_ix_ser);
  if (sz != k_sz_ser)
  {
    trace1(0, dev, 0, "serial number invalid.  byte0:%d s/b 26", sz);
    return;
  }
  // make sure its a string descriptor
  b = _nvdata(1);
  if (b != 0x03)
  {
    trace1(0, dev, 0, "serial number invalid.  byte1:%d s/b 0x03", b);
    return;
  }
  trace1(0, dev, 0, "Reading %d bytes of serial data", sz);
  for (i=0; i< sz-2; i++)
  {
    b = _nvdata(i+2);
    // even bytes contain ascii values
    if (!(i&1))
    {
      if ('0' <= b && '9' >= b)
        continue;
      else
        if ('a' <= b && b <= 'f')
        continue;
      else
        if ('A' <= b && b <= 'F')
        continue;
      else
      {
        trace2(0, dev, 0, "serial_number[%d]:'%c' - invalid mass storage class digit.  s/b hex character.", i, b);
        return;
      }
    }
    // odd bytes contain zeros (because its unicode...)
    else
    {
      if (b)
      {
        trace2(0, dev, 0, "serial_number[%d]:'%c' - s/b zero (for hi byte of unicode char).", i, b);
        return;
      }
    }
  }
  trace0(0, dev, 0, "serial number is valid");
  _serial_number_valid = k_true;

  // force iSerial to zero by claiming the serial number is not valid
  if (g_dev_attr_lo & kbm_attr_lo_force_zero_iserial)
  {
    trace0(0, dev, 0, "iSerial forced to zero");
    _serial_number_valid = k_false;
  }

  if (g_dev_attr_lo&kbm_attr_lo_use_inq_mfr_prd_ids)
  {
    trace0(0, dev, 0, "using IMIDS & IPIDS fields for Inquiry Data") ;
    for (i=0; i<k_sz_inq_vid; i++)
    {
      b=_nvdata(k_ix_inq_vid+i);
      g_inq_vid[i]=isprint(b)?b:' ';
    }
    // insert the inquiry product id header string (created from nvstore) 
    for (i=0;i<k_sz_inq_pid_hdr; i++)
    {
      b=_nvdata(k_ix_inq_pid_hdr+i);
      g_inq_pid_hdr[i]=isprint(b)?b:' ';
    }
  }
  else
  {
    // extract the vendor id from mfr string descriptor, store in g_inq_vid, converting uni->ascii
    trace0(0, 

⌨️ 快捷键说明

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