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

📄 ata.c

📁 U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有很好的支持.
💻 C
📖 第 1 页 / 共 5 页
字号:
  uint8 i;
  #else
  uint16 i;
  #endif
  uint16 devword;
  uint8   sector_per_interrupt;
  //uint8 mode_sel;
  uint8 yes_no_flag;
  trace0(0, ata, 1, "ata_identify_device()");
  //_stack_check();
  _thread_clr_sync(kbm_sync_all);

  // select master drive
  ata_register_wr(&ata_device_head, kbm_ata_dev_0);
  // select the identify-device / identify-packet_device function
  ata_register_wr(&ata_command, cmd);
  ata_read_status();
  //result = k_error;
  //while (k_success != result)  // WARNING! WARNING! DANGER, WILL ROBINSON!!!
  //{
  trace1(0, ata, 0, "-- imr0:0x%02X", x_imr0);
  //result = ata_wait_irq_with_timeout(5000);
  result = ata_wait_irq_with_timeout(1000);
  if (k_success != result)
  {
    trace0(0, ata, 1, "ata_identify_device() - error: no irq");
    return k_error;
  }
  //}
  trace0(0, ata, 1, "ata_identify_device() - got the ata irq");
  // BSY=0
  status = ata_read_status();
  if (!(status & kbm_ata_status_drq))
  {
    // BSY=0, DRQ=0, therefore command is done
    trace0(0, ata, 1, "ata_identify_device() - warning: drive has no data");
    return k_error;
  }
  // BSY=0, DRQ=1, therefore the drive wants to send more data
  // read the data
  _mcu_begin_critical_section();
  #if 0 // since the bot layer is now a high priority thread at irq level
  // cannot use packet buffers here... switch to using xdata buffer
  _mcu_register_wr(x_sram_addr_lo, k_pkt_addrlo[4]);
  _mcu_register_wr(x_sram_addr_hi, k_pkt_addrhi[4]);
  // there are always 256 words of device data
  for (i=255; i; i--)
  {
    _mcu_register_wr(x_sram_data, ata_register_rd(&ata_data));
    _mcu_register_wr(x_sram_data, _mcu_register_rd(x_msb_ata));
  }
  _mcu_register_wr(x_sram_data, ata_register_rd(&ata_data));
  _mcu_register_wr(x_sram_data, _mcu_register_rd(x_msb_ata));
  #else
  // there are always 256 words of device data
  for (i=0; i<512; i+=2)
  {
    g_sector_buffer[i] = ata_register_rd(&ata_data);
    g_sector_buffer[i+1] = _mcu_register_rd(x_msb_ata);
  }
  #endif
  _mcu_end_critical_section();

  //!!!$$$ check status for error - as per end of this funct
  trace0(0, ata, 1, "ata_identify_device() - entire xfer complete");

  // examine the data
  _mcu_begin_critical_section();
  // grab the product id string for non-210 devices.
  #ifndef k_flash_family
  for (i=0; i<8; i++)
  {
    // grab 2 chars
    devword = iddev_word(i+27);
    // store them in our sram
    _lun_data(device_id)[2*i]   = _h(devword);
    _lun_data(device_id)[2*i+1] = _l(devword);
    trace1(0, dev_id, 0, "%c", _lun_data(device_id)[2*i]);
    trace1(0, dev_id, 0, "%c", _lun_data(device_id)[2*i+1]);
  }
  #endif

  //profile the edata card and drop it back to mode 1
  for (i=0; i<8; i++)
  {
    // grab 2 chars
    devword = iddev_word(i+27);
    // store them in our sram
    g_sector_buffer[2*i]   = _h(devword);
    g_sector_buffer[2*i+1] = _l(devword);
    trace1(0, ata, 0, "%c", _h(devword));
    trace1(0, ata, 0, "%c", _l(devword));
  }

  g_ata_dev_caps_1 = iddev_word(k_ata_iddev_caps_l);
  g_ata_dev_caps_2 = iddev_word(k_ata_iddev_caps_h);
  // device capabilities
  trace2(0, ata, 0, "dev_caps_1:%04X dev_caps_2:%04X", g_ata_dev_caps_1, g_ata_dev_caps_2);
  // do atapi/ata specific interpretation here
  switch (_lun_data(device_type))
  {
    case k_device_type_ata:
      // general config word
      // set removable/present properties
      if (iddev_word(k_ata_iddev_general_config) & kbm_ata_iddev_gc_removable)
      {
        trace0(0, ata, 0, "  GCFG:  Removable Media Device");
        // set removable property for Inquiry data
        _lun_data(media) |= kbm_lun_media_removable;
        // set media present property (because if we got here, the compact flash media is present)
        _lun_data(media) |= kbm_lun_media_present;
      }
      else
      {
        // fixed media.  media is always present
        _lun_data(media) |= kbm_lun_media_present;
      }
      if (iddev_word(k_ata_iddev_general_config) & kbm_ata_iddev_gc_fixed)
      {
        trace0(0, ata, 0, "  GCFG:  Controller/Device NOT removable");
        // not a removable device
        //_lun_data(media) &= ~kbm_lun_media_removable;
        trace0(0, ata, 0, "WARNING:  Controller/Device NOT removable? For CompactFlash?  Forcing the removable bit!");
        _lun_data(media) |= kbm_lun_media_removable;
        _lun_data(media) |= kbm_lun_media_present;
      }
      // dev caps
      if (g_ata_dev_caps_1& kbm_ata_iddev_caps_timer_values_per_spec)
      {
        trace0(0, ata, 0, "Standby timer values as specified in ATA spec are supported");
      }
      else
      {
        trace0(0, ata, 0, "Standby timer values managed by device");
      }
      #if k_dma_mode
      g_use_dma = g_ata_dev_caps_1&kbm_ata_iddev_caps_support_dma?k_true:k_false;
      #else
      trace0(0, ata, 0, "** firmware dma support disabled ** ");
      g_use_dma = k_false;
      #endif
      g_disable_iordy = (g_ata_dev_caps_1 & kbm_ata_iddev_caps_disable_iordy) ? k_true : k_false;
      yes_no_flag=g_use_dma ? 'Y' : 'N';
      trace1(0, ata, 0, "  DMA Support:%c", yes_no_flag);
      yes_no_flag=(devword & kbm_ata_iddev_caps_support_lba) ? 'Y' : 'N';
      trace1(0, ata, 0, "  LBA Support:%c", yes_no_flag);
      yes_no_flag=(g_disable_iordy) ? 'Y' : 'N';
      trace1(0, ata, 0, "  Can Disable IORDY:%c", yes_no_flag);
      yes_no_flag=(devword & kbm_ata_iddev_caps_support_iordy) ? 'Y' : 'N';
      trace1(0, ata, 0, "  IORDY Support:%c", yes_no_flag);
      // ata-only info
      g_ata_dev_num_log_cyl = iddev_word(k_ata_iddev_num_log_cyl);
      g_ata_dev_num_log_hds = iddev_word(k_ata_iddev_num_log_hds);
      g_ata_dev_num_log_sec_per_trk = iddev_word(k_ata_iddev_num_log_sec_per_log_track);
      _lun_data(capacity).lba_max.u32 = (uint32)iddev_word(k_ata_iddev_total_user_addressable_sectors_h) << 16L;
      _lun_data(capacity).lba_max.u32 += (uint32)iddev_word(k_ata_iddev_total_user_addressable_sectors_l);
      _lun_data(capacity).lba_max.u32 -= 1;
      trace2(0, ata, 0, "Total User-addressable Sectors: %04X%04X", _hw(_lun_data(capacity).lba_max.u32), _lw(_lun_data(capacity).lba_max.u32));
      _lun_data(capacity).lba_sz.u32 = 512;

      sector_per_interrupt=(iddev_word(k_ata_iddev_multi_burst_size)&0x00ff);
      trace1(0, ata, 0, "sector/interrupt = %02x",sector_per_interrupt);  
      /* This check is required to ensure compitability with CF card supporting more then one
         sector per interrrupt.
      */

      /* Date 4/15/03 This is a tricky Fix , but is put in place due to the urgency
          The Compact Flashes supporting more then 1 sector per interrupt failed to 
          work with the 210 ( E.g Lexar 512M) hence the fix was required to check the
          number of sectors per interrupt and switch the split/burst size,unfortunately this
          slows down writes to a great extent on the IBM 1G microdrive, the 1G microdrive
          supports 16 sectors/interrupt, but our logic switches it to single split mode hence
          it slowed down a lot, This check below is just to ensure that we are not profiling the
          IBM drive. We need to Find out the reason for this incompitibility to fix this problem.
          */
     if ( ( sector_per_interrupt > 1) && (sector_per_interrupt <5))
      {
        g_cf_multiple_sectors_per_interrupt=0;
        _lun_data(max_lb_per_split) = 256;
        _lun_data(max_lb_per_burst) = 256;
      }
      else
      {
        g_cf_multiple_sectors_per_interrupt=0;
        _lun_data(max_lb_per_split) = 256;
        _lun_data(max_lb_per_burst) = 256;
      }  
      break;
  }
  // $$$ marked obsolete in ATA-6 spec, but, seems like CF cards use it
  devword = iddev_word(k_ata_iddev_pio_mode) ;
  trace1(0, ata, 0, "Device PIO Tranfer Cycle Mode:%d", (_h(devword))) ;
  // RUDIMENTARY PROFILING OF ATA DRIVES
  // throttle the edata card back to mode 1 because it says it runs at mode 2 3 but it
  // fails to run at mode 3 or 2, and works in modes 1 and 0.
  // added "SunDisk SDCFB-20" and "SunDisk SDCFB-4 ". hm - 12/10/02
  // changed "SunDisk SDCFB-20" and "SunDisk SDCFB-4 " to "SunDisk SDCFB" for saving code space. hm - 12/18/02
  // added CFS card "SAMSUNG CF/ATA". hm - 5/12/03 .... removed 5/13/03
  if (memcmp(g_sector_buffer, "HYPERSTONE FLASH", 16) &&
      memcmp(g_sector_buffer, "SunDisk SDCFB", 13)  && memcmp(g_sector_buffer, "CF Card",7 ) /*&& memcmp(g_sector_buffer, "SAMSUNG CF/ATA", 14)*/ )
  {
    //_mcu_register_set_bits(x_cfc_ata_mode_ctl, _h(devword) );
  }
 #if defined(k_mcu_97210)
 #ifdef  k_opt_pio
 trace0(0, ata, 0, "Setting the Default Mode : 0");
_mcu_register_clr_bits(x_cfc_ata_mode_ctl, k_cfc_ata_mode_0 );
#endif
#endif
trace1(0, ata, 0, "g_dev_attr_hl - %02x",g_dev_attr_hl);


//--------------------------------------------------- 
 devword = iddev_word(49);
 trace1(0, test, 0, "Byte 49_h = %02x",_h(devword));
 trace1(0, test, 0, "Byte 49_l = %02x",_l(devword));
//--------------------------------------------------
devword = iddev_word(51);
 trace1(0, test, 0, "Byte 51_h = %02x",_h(devword));
 trace1(0, test, 0, "Byte 51_l = %02x",_l(devword));
//-------------------------------------------------- 
 devword = iddev_word(53);
 trace1(0, test, 0, "Byte 53_h = %02x",_h(devword));
 trace1(0, test, 0, "Byte 53_l = %02x",_l(devword));
//-------------------------------------------------- 
 devword = iddev_word(64);
 trace1(0, test, 0, "Byte 64_h = %02x",_h(devword));
 trace1(0, test, 0, "Byte 64_l = %02x",_l(devword));
//-------------------------------------------------------

devword = iddev_word(53);
  if ((_l(devword) & kbm_ata_iddev_valid_fields_pio_mwdma_timing))
  {
    trace0(0, ata, 0, "Advanced PIO MOde is supported");
    devword = iddev_word(k_ata_iddev_pio_mode_support );
    if (( _l(devword) & K_ata_pio_mode_4   ))
    {
      trace0(0, ata, 0, "Advanced PIO MOde is -4");
      _mcu_register_set_bits(x_cfc_ata_mode_ctl, k_cfc_ata_mode_4);
    }
    if (! ( _l(devword) >1))
    {
      trace0(0, ata, 0, "Advanced PIO MOde is -3");
      _mcu_register_set_bits(x_cfc_ata_mode_ctl, k_cfc_ata_mode_3);
    }

  }
  else
  {
    trace0(0, ata, 0, "Advanced PIO MOde is  not supported");
    devword = iddev_word(k_ata_iddev_pio_mode) ;
    if (! ( _h(devword)  > 2))
    {
      trace0(0, ata, 0, "Invalid Mode Defaulting to Mode Zero ");
      _mcu_register_wr(x_cfc_ata_mode_ctl , (  _mcu_register_rd( x_cfc_ata_mode_ctl ) & 0x38 ) );
    }
    else
    {
      trace1(0, ata, 0, "Setting Mode to %02x ",_h(devword));
      _mcu_register_set_bits(x_cfc_ata_mode_ctl, _h(devword) );
    }   

  }   

  /*******************************************************************************/
  /* This section of profiling is still required for cards that do not comply     */
  /* with the CF specification's, one of them sampled is KINGMAX 8MB card ,plase  */
  /* refer to CF Bugs and Resolutions document.                                   */
  /********************************************************************************/

  // $$$ marked obsolete in ATA-6 spec, but, seems like CF cards use it
  devword = iddev_word(k_ata_iddev_pio_mode) ;
  //  TRACE1(41, ata, 0, "Device PIO Tranfer Cycle Mode:%d", (_h(devword))) ;
  // RUDIMENTARY PROFILING OF ATA DRIVES
  // throttle the edata card back to mode 1 because it says it runs at mode 2 3 but it
  // fails to run at mode 3 or 2, and works in modes 1 and 0.
  // added "SunDisk SDCFB-20" and "SunDisk SDCFB-4 ". hm - 12/10/02
  // changed "SunDisk SDCFB-20" and "SunDisk SDCFB-4 " to "SunDisk SDCFB" for saving code space. hm - 12/18/02
  // added CFS card "SAMSUNG CF/ATA". hm - 5/12/03 .... removed 5/13/03
  if (!(memcmp(g_sector_buffer, "HYPERSTONE FLASH", 16) &&
        memcmp(g_sector_buffer, "SunDisk SDCFB", 13)  && memcmp(g_sector_buffer, "CF Card",7 ) ))
  {
    trace0(0, ata, 0, "Setting Default Mode Zero");
    _mcu_register_wr(x_cfc_ata_mode_ctl , (  _mcu_register_rd( x_cfc_ata_mode_ctl ) & 0x38 ) );

  }


if(g_dev_attr_hl & kbm_attr_hl_cf_piomode_zero)
    {
      trace0(0, ata, 0, "Attribute Set to PIO Mode Zero // Switching PIO MOde to Zero");
      _mcu_register_clr_bits(x_cfc_ata_mode_ctl, k_cfc_ata_mode_0 );
    }


  trace1(0, ata, 0, "x_cfc_ata_mode_ctl now: %02x", x_cfc_ata_mode_ctl) ;
  if (iddev_word(k_ata_iddev_valid_fields) & kbm_ata_iddev_valid_fields_pio_mwdma_timing)
  {
    trace1(0, ata, 1, "PIO Modes Supported:%04X", iddev_word(k_ata_iddev_pio_mode_support));
    trace1(0, ata, 1, "Min MWDMA xfer cycle time: %d ns", iddev_word(k_ata_iddev_min_mwdma_cycles));
    trace1(0, ata, 1, "Manufacturer's recommended Multiword DMA transfer cycle time: %d ns", iddev_word(k_ata_iddev_mfr_recommened_mwdma_cycles));
    trace1(0, ata, 1, "Minimum PIO transfer cycle time without flow control: %d ns",  iddev_word(k_ata_iddev_min_pio_xfer_cycle_no_flow));
    trace1(0, ata, 1, "Minimum PIO transfer cycle time with IORDY flow control: %d ns", iddev_word(k_ata_iddev_min_pio_xfer_cycle_flow));
  }
  if (iddev_word(k_ata_iddev_valid_fields) & kbm_ata_iddev_valid_fields_cur_log_chs_cap)
  {
    trace1(0, ata, 0, "Number of current logical cylinders: %d", iddev_word(k_ata_iddev_cur_log_cyl));
    trace1(0, ata, 0, "Number of current logical heads: %d", iddev_word(k_ata_iddev_cur_log_hds));
    trace1(0, ata, 0, "Number of current logical sectors per track: %d", iddev_word(k_ata_iddev_cur_log_sec_per_trk));
    trace2(0, ata, 0, "Current sector capacity: %04X%04X", iddev_word(k_ata_iddev_cur_sector_cap_h), iddev_word(k_ata_iddev_cur_sector_cap_l));
    //_lun_data(capacity).lba_max.u32 = (uint32)iddev_word(k_ata_iddev_cur_sector_cap_h) << 16L;
    //_lun_data(capacity).lba_max.u32 += (uint32)iddev_word(k_ata_iddev_cur_sector_cap_l);
    //TRACE2(389, ata, 0, "Total User-addressable Sectors: %04X%04X", _hw(_lun_data(capacity).lba_max.u32), _lw(_lun_data(capacity).lba_max.u32));
  }

  trace1(0, ata, 0, "Number of sectors xferred per irq on READ/WRITE Multiple: %d", (iddev_word(k_ata_iddev_multi_burst_size)&0x00ff)) ;

  #if 0
  // dma info - already detected above if we support it

⌨️ 快捷键说明

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