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

📄 ata.c

📁 U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有很好的支持.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*============================================================================
  ____________________________________________________________________________
                                ______________________________________________
   SSSS  M   M          CCCC          Standard Microsystems Corporation
  S      MM MM   SSSS  C                    Austin Design Center
   SSS   M M M  S      C                 11000 N. Mopac Expressway
      S  M   M   SSS   C                Stonelake Bldg. 6, Suite 500
  SSSS   M   M      S   CCCC                Austin, Texas 78759
                SSSS            ______________________________________________
  ____________________________________________________________________________
  Copyright(C) 1999, Standard Microsystems Corporation
  All Rights Reserved.
  This program code listing is proprietary to SMSC and may not be copied,
  distributed, or used without a license to do so.  Such license may have
  Limited or Restricted Rights. Please refer to the license for further
  clarification.
  ____________________________________________________________________________
  Notice: The program contained in this listing is a proprietary trade
  secret of SMSC, Hauppauge, New York, and is copyrighted
  under the United States Copyright Act of 1976 as an unpublished work,
  pursuant to Section 104 and Section 408 of Title XVII of the United
  States code. Unauthorized copying, adaption, distribution, use, or
  display is prohibited by this law.
  ____________________________________________________________________________
  Use, duplication, or disclosure by the Government is subject to
  restrictions as set forth in subparagraph(c)(1)(ii) of the Rights
  in Technical Data and Computer Software clause at DFARS 52.227-7013.
  Contractor/Manufacturer is Standard Microsystems Corporation,
  80 Arkay Drive, Hauppauge, New York, 1178-8847.
  ____________________________________________________________________________
  ____________________________________________________________________________
  <module name> - <module description>
  ____________________________________________________________________________
  comments tbd
  ____________________________________________________________________________
  Revision History
  Date      Who  Comment
  ________  ___  _____________________________________________________________
  04/20/01  cds  initial version
  09/##/01  tbh  optimized for speed
  11/16/01  cds  - updated code to use lun instance data instead of globals.
                 - tried global search & replace of thread_clr_sync to
                   _thread_clr_sync but it turns out the bug is more devious
                   and is attached to bits_got, not the thread_clr_sync.
  11/26/01  cds  modified ata_pio_rd to include blk-xfer for 210 instead of
                 calling pio_wr_pkt.  Tests whether high-speed or full-speed
                 and only sets 512-byte-pkts for blk-xfer in hs connections.
  11/28/01  rcc  modified ata_pio_rd Tests whether high-speed or full-speed
                 and only sets 512-byte-pkts for blk-xfer in hs connections also
                 CLEARS this bit if FS and does this before the blk-xfer bit it set.
  12/04/01  tbh  tweaked identify_device for newish fmc style _lun_data access.
  12/13/01  tbh  tweaked data xfers to use fmc_transfer()
  02/26/02  tbh  added NULL placeholder in _fmc_set_callback() invocations
  03/12/02  tbh  minor renaming to fit the fmc project's idiom
  04/15/02  tbh  ensure fmc_options set to 0 before read/write
  05/20/02  tbh  turn off multiple emulation in ata_read_end_xfer.
                 added ata_write_end_xfer to ensure multiple emulation turned off
                 in case of aborted transfer.
  06/05/02  cds  added trace statement to dump the # of sectors per irq (burst)
                 of the read/write multiple command from identify device data
  06/10/02  tbh  performance enhancements using _ata_register_wr() macro to replace
                 ata_register_wr() function.  other minor enhancements.
  06/20/02  tbh  in ata_initialize_media2 set the CF into pio mode 4 (from default 0)
  06/25/02  tbh  subtract 1 from lba_max to get correct capacity reported to host
                 to fix the problem with quick format.
  07/09/02  cds  replaced _work_buf with common g_sector_buffer, as used in
                 sm, ms, and nand luns.
  07/23/02  cds  added obsolete PIO Transfer Cycle Mode field (word 51) to
                 identify device data.  Moved the setting of the cfc_ata_mode_ctl
                 register into the identify device function so that as soon as
                 the mode is determined, the register is set, but before then,
                 PIO mode 0 is used (to obtain the ID data).
  08/29/02  tbh  added rudimentary profiling of ata drives (to identify the
                 edata 32mb cf card and drop it to mode 0)
  09/10/02  tbh  forced reporting as removable media always because some CF
                 cards seem to say they are fixed disks.
  10/17/02  cds  - project-wide lun data & vtbl paging to reduce code space.
                 - removed g_active_media from _lun_data, _lun_() virtual functions
                - added _lun_data_rd() and _lun_data_wr() macros to bypass lun paging
                 - added lun_set_active(log_lun) function to switch luns
 1/11/03         Changed the Xdata strobe width to  16. This required to ensure proper compitability 
                 with all 4 PIO modes.
 03/20/03  sbs  -Added a new CF card "KINGMAX" in PIO mode 0. 
 03/26/03  sbs  - Modified the split size and burst size to one if the Max blocks per read/
                  write emulation is more then one,this is required cause the CF controller
                  hardware does not more then one sector per interrupt.
                                   
 03/26/03  sbs   - Changes the code to support High speed reads on a card that reports
                  more then 1 sector per interrupt.
 03/27/03 ds/sbs Changed ata_intialize_media2, to clear media-changed bit on an error condition too. 
                 For further explanation please refer the function comments. 
 03/27/03 ds     Relocated the above change to fit into code space.     
 04/1/03  sbs    Added a compile time flag to seclect the PIO mode.
 04/2/03  sbs    Added a Attribute bit kbm_attr_hl_cf_piomode_zero. This bit controls
                 the PIO Xfer mode for the CF device.If this bit is set the Xfer mode
                 is always Mode0. If reset the mode is set to the value reported by the
                 media.
 04/8/03  sbs    Removed  the stack_checks to release the code space,stack check is
                 useful for debug but not required in release firmware as it consumes
                 valuable code space,will probably protect it with a debug flag in 
                 future. 
 04/15/03 sbs    Fix for IBM  1G micro drive write speeds. 
 05/5/03  sbs    The function Identify_ATA set mode zero option using the compile
                 flag & the attribute bit does not work properly caue the
                 _mcu_register_set_bits(x_cfc_ata_mode_ctl, k_cfc_ata_mode_0 )does
                 not set the mode zero bit pattern but retains the last pattern,changed
                 the funtion to  _mcu_register_clr_bits.
 05/12/03 hm     added CFS card "SAMSUNG CF/ATA" in PIO mode 0
 05/13/03 hm     removed the above "SAMSUNG CF/ATA" to restore it
 07/03/03 sbs    Changes made to Compact_Flash (Identify_Device) these changes are required
                 to ensure compiatability with CF Spec.
                 Added code to Fix Bug-XXX.
                 Changed the read status function to check for RRDDY bit to ensure sync with 
                 hardware.

08/07/03 sbs Added more checks in the CF begin_burst ,to avoid lockup during writes.                  
 ============================================================================*/
#define __ata_dot_c__
#include "project.h"
#include "dev.h"
code _vtbl_defn(ata);
#ifdef k_flash_family
#define k_lun_ata k_lun_cf
#else
#define k_lun_ata 0
#endif
// to use this optimization you want fmc_select_cf() to set CKCON = 0x00 also...
#define _ata_clock_slow() CKCON=0x04
#define _ata_clock_fast() CKCON=0x04
bit g_cf_multiple_sectors_per_interrupt;
//------------------------------------------------------------------------------
// exported globals
xdata uint8   g_dev_max_dma_mode;  // represents max DMA mode supported by the device
// ata device characteristics
bit           g_use_dma;
bit           g_disable_iordy;
xdata uint8   g_dma_mode_current;
// ata device capabilities & properties
// these are all relevant properties from ata identify device data.
xdata uint16  g_ata_dev_cmdset_support_1;
xdata uint16  g_ata_dev_cmdset_support_2;
xdata uint16  g_ata_dev_cmdset_support_3;
xdata uint16  g_ata_dev_cmdset_enabled_1;
xdata uint16  g_ata_dev_cmdset_enabled_2;
xdata uint16  g_ata_dev_cmdset_enabled_3;
xdata uint16  g_ata_dev_num_log_cyl;
xdata uint16  g_ata_dev_num_log_hds;
xdata uint16  g_ata_dev_num_log_sec_per_trk;
xdata uint16  g_ata_dev_caps_1;
xdata uint16  g_ata_dev_caps_2;
extern xdata t_udw32 n_bytes_this_burst;
//+-----------------------------------------------------------------------------
// Name:
//   ata_dump_build_options
//
// Declaration:
//   void ata_dump_build_options(void);
//
// Purpose:
//   Debugging.  Dumps the build options.
//
// Arguments:
//   None.
//
// Return:
//   None.
//
// Notes:
//   None.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void ata_dump_build_options(void) reentrant;
void ata_dump_build_options() reentrant
{
  trace0(0, ata, 0, "ata_dump_build_options()");
  trace1(0, ata, 0, "dma mode: %02x", k_dma_mode);
  trace0(0, ata, 0, "Shadow PIO_COMPLETE: Y");
  trace0(0, ata, 0, "ATA Device Support:Y");
}

//+-----------------------------------------------------------------------------
// Name:
//   ata_register_wr
//
// Declaration:
//   void ata_register_wr(t_ata_register_ref r, uint8 d);
//
// Purpose:
//   Write a value to an ata register.
//
// Arguments:
//   r - the t_ata_register_ref identifying the register to be written.
//   d - the uint8 to be written there.
//
// Return:
//   None.
//
// Notes:
//   None.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void ata_register_wr(t_ata_register_ref r, uint8 d) reentrant
{
  _ata_clock_slow();
  trace2(0, ata, 0, "ata_register_wr(%04x=%02x)", (uint16)r, d);
  while (!(x_cfc_stat & kbm_cfc_stat_xrdy));  // <-- WARNING! WARNING! DANGER, WILL ROBINSON!
  *r = d;
  _ata_clock_fast();
}

//------------------------------------------------------------------------------
// performance enhancement is to use a macro in ata_read/write_begin_burst
// while issuing the command
//------------------------------------------------------------------------------
#define _ata_register_wr(__r, __d)            \
{                                             \
  _ata_clock_slow();                          \
  while( !(x_cfc_stat & kbm_cfc_stat_xrdy));  \
  *(__r) = (__d);                             \
  _ata_clock_fast();                          \
}

//+-----------------------------------------------------------------------------
// Name:
//   ata_register_rd
//
// Declaration:
//   uint8 ata_register_rd(t_ata_register_ref r);
//
// Purpose:
//   Read a value from an ata register.
//
// Arguments:
//   r - the t_register_ref identifying the register to be read.
//
// Return:
//   The uint8 to read from the ata register.
//
// Notes:
//   None.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
uint8 ata_register_rd(t_ata_register_ref r) reentrant
{
   uint8 val;
  _mcu_begin_critical_section();
  _ata_clock_slow();
  // start read cycle, then get data from lsb_ata
  val = *r;
  while( !(x_cfc_stat & kbm_cfc_stat_rrdy));
  val = x_lsb_ata;
  _ata_clock_fast();
  _mcu_end_critical_section();
  return val;
}

//+-----------------------------------------------------------------------------
// Name:
//   ata_read_status
//
// Declaration:
//   uint8 ata_read_status(void);
//
// Purpose:
//   Read the ata status register.
//
// Arguments:
//   None.
//
// Return:
//   The uint8 read from the ata status register.
//
// Notes:
//   Reading the ata status register clears the ata interrupt (in the drive).
//   This function also clears and unmasks the interrupts k_irq_ata and k_irq_fmc_cfc_intrq.
//
// Since:
//   fmc-1.0
//
// History:
//   06/18/02 tbh - modified to leave the ata interrupt masked.
//                - modified this wait_irq_with_timeout to break out if ata irq
//                  bit seen via polling.
//                - this cut about 270usec off the begin burst, decreasing cbw time.
//------------------------------------------------------------------------------
uint8 ata_read_status(void) reentrant;
uint8 ata_read_status() reentrant
{
 uint8 val;
  _mcu_begin_critical_section();
  _ata_clock_slow();
 val = ata_status;
  while( !(x_cfc_stat & kbm_cfc_stat_rrdy));
 val = x_lsb_ata;
  _ata_clock_fast();
  // clear compact flash status as well
  // could do this... but its slower...
  //irq_control(k_irq_fmc_cfc_intrq, kbm_irqctl_clear |kbm_irqctl_unmask);
  x_cfc_stat = kbm_cfc_stat_intrq;
  x_cfc_stat_msk &= ~kbm_cfc_stat_intrq;
  // could do this... but its slower...
  //irq_control(k_irq_ata, kbm_irqctl_clear |kbm_irqctl_unmask);
  x_isr0  = kbm_isr0_ata_irq;
  // 06/18/02 tbh - ata_wait_irq_with_timeout() now polls this bit to avoid
  // the overhead of having the kernel interrupt handler process all of the
  // nested interrupts beneath the fmc/ata irq.  (it takes so long in the isr0
  // handler to check every possible nested source for the ata/fmc irq that
  // it is dramatically faster to just poll the register.
  //x_imr0 &= ~kbm_isr0_ata_irq;
  trace1(0, ata, 99, "status:%02x", val);
  _mcu_end_critical_section();
  return val;
  return val;

⌨️ 快捷键说明

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