ms.c

来自「U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有」· C语言 代码 · 共 1,709 行 · 第 1/5 页

C
1,709
字号
/*============================================================================
  ____________________________________________________________________________
                                ______________________________________________
   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.
  ____________________________________________________________________________
  ____________________________________________________________________________
  sm.c - memory stick mass storage class implementation file
  ____________________________________________________________________________
  comments tbd
  ____________________________________________________________________________
  Revision History
  Date      Who  Comment
  ________  ___  _____________________________________________________________
  11/##/01  tbh  initial version
  02/26/02  tbh  changed strcpy to strncpy for safety
  04/01/02  tbh  read_boot now finds 2 boot blocks on cards that have them
  04/02/02  tbh  added ms_copy_page
  04/17/02  tbh  override dfa_lun_mode_sense
  04/18/02  tbh  removed that override.  superclass method handles it now.
  05/07/02  cds  added a rw_intra_burst callback to actually perform the blk_xfer inner loop
                 to get around xdata-access bug in the chip
  05/09/02  cds  added call to _dev_soft_reset() when a usbreset occurs during rw_intra_bursts
  06/03/02  cds  updated ms_write_end_xfer() to turn off auto-xfer so that
                 the sector copy can use the fmdu.
  06/19/02  tbh  converted to read boot into xdata buf instead of packet buf
                 since bot layer is can now run concurrently with discovery
  06/20/02  tbh  tweaked the intra-burst callback to stop clearing the isr bit
                 to be compatible with the perf opto done in fmc_transfer
  06/26/02  tbh  added nops in ms_wait_msc_stat_sif_with_timeout.
                 two back to back reads of the alt_stat register causes failure.
                 there is some latency issue causing intermittant failure...
                 inserting nops fixes it.
  07/01/02  tbh  write-protect check is now performed in the lun layer
  07/09/02  cds  renamed WorkBuf to g_sector_buffer
  07/12/02  tbh  lun string name change caused by mandate from on high
  07/17/02  tbh  ms_write_end_xfer sets g_fmc_rslt if map_write_flush returns an error
                 because fmc_transfer doesn't check the return code of the callback.
                 I feared breaking all of the other luns by changing fmc...
  07/18/02  tbh  fixed long standing (but until recently dormant) bug in
                 ms_rw_intra_burst_callback where && was erroneously used
                 in place of &.
  07/23/02  tbh  the ms_wait_msc_stat_sif_with_timeout nop injection was insufficient,
                 it seems.  i increased the number of ops and moved them into the do
                 loop to delay betwean -every- read of the ms_alt_stat register.
                 this appears to resolve the issue of the cards formatted by DoTop
                 becoming unreadable in the 210.
  07/31/02  cds  called media_set_active(...) instead of setting g_active_media
                 to select a new media object.
  08/06/02  tbh  added _force_one_burst_per_split to solve the SanDisk 64MB cards
                 w/ date codes < J [bug report br308]
  08/13/02  tbh  added status check after read error in read-begin-burst to
                 distinguish uncorrectabel error from correctable error on last block.
  08/28/02  tbh  added extra get-int after block-end command for read and write
                 to ensure that no error happened issuing that command (shawn's suggestions).
                 also changed interpretation of uncorrectable error bits from
                 "all relevant bits set -> uncorrectable error" to
                 "any relevant bit set -> uncorrectable error" to resolve the
                 data corruption issue on sony cards (sorry, no bug reporter number
                 was entered yet)
  09/04/02  cds  address name & usage change-over
                  g_addr_sector => g_addr_page,
                  g_addr_page   => g_addr_segment,
                  _media_data(sectors_per_block)  => _media_data(pages_per_block)
                  _media_data(cis_phy_block)      => _media_data(boot_block)
                  _media_data(cis_sector)         => _media_data(boot_sector)
                                                  => _media_data(segments_per_page)
  09/12/02  tbh  replaced strncpy() with memcpy() to save data space.
  09/18/02  cds  initialized _media_data(options) field to kbm_media_data_opts_none
  10/17/02  cds  updated for new lun vtbl and lun_data macros
  11/01/02  tbh  made xbuf_rd() visible so ms_media.c can call it.
                 ms_read_boot_block was using the wrong boot block when more than one
                 exists.  changed to use the lowest-numbered one, per the spec.
                 move write-protection test to occur before map_build_sector_map
                 to avoid erroneous block erase on write protected disks.
  11/02/02  tbh  added ms_is_this_blk_in_bad_blk_tbl().
                 added ms_find_map_block() to see if any exists, and compare contents.
  11/03/02  cds  - updated ms_is_this_blk_in_bad_blk_tbl() to include info block
                 - added new global g_ms_user_area_start_blk to help mapper know which blocks
                   are to be used for mapping
                 - updated bad-block table code to read data in big endian format
  11/06/02  cds  - initialized media data variables to 0 to fix bug in doing log2phy mapping when paging in zones for the first time.                 
  11/15/02  sbs  -  Added Code of 223(New Registers) & Multi R/W emulation Function.
                 -Modification have been comented.
  12/10/02  cds  - converted g_addr_page back to 8-bits, since pages are now divisible into 8-bit "segments", there 
                   is plenty of address space to handle the various media.                                          
                 - eliminated dual split calculations (to handle page=0, page!=0 cases).  code space it occupied
                   is more valuable than the efficiency gained by doing it that way  
  12/13/02  cds  - replaced k_pfm_fpga compile-time flag with _dev_is_fpga() macro to check attribute bit.
  12/16/02  cds  - added ms_pwr_up_init() function to configure ms registers after ms block has been powered up 
  01/10/03  ds   - added a new fn ms_set_clk() to set the ms clk to 20Mhz on the relevant dfas
  01/13/03  ds   Protected ms_set_clk() and the calls made to it , to be compiled only for 223, as 210
                 with dfu and otprom options set will not build with this code in. It reports a code space overflow. 
  01/31/03  sbs   -  Added MSPRO Functionality , modified some of the legacy MS functions,also fixed the MS CLK set 
                 by masking the FMC_CLK_CTL (for SD and MS) before setting the new clock values
                 
  02/05/03  sbs  - Did some Code space optimization to fit in the 210 code (MSPRO is not supported in this version of 210).
  02/18/03  sbs  - MOdified the ms_set_clk fuction to set the clock based on the Memory Stick Type.        
  02/24/03  sbs  - Added  MSPRO support for 210 device, also optimized the code to fit the 210 related modifications. 
  02/26/03  sbs  - Changed the MS_CLK for 210 on a MS_PRO media (30mhz).
  
  03/3/03   sbs  - Revised the media_identification procedure as per the MSPRO SPEC ver.1.00-01.
                   Also cahnged the Interface switch code to support serial MSPRO media. 
  03/5/03   sbs - Revised the clock settings to proper values after the Code Review
  03/5/03   sbs - Added a hard reset fot MSPRO media .MSPRO media does not support soft reset.
  03/6/03   sbs - Retained the  Auto Xfer off in write end Xfer ,Due to MAC write problem.
  03/7/03   sbs - Removed the FIFO clears from the end R/W Xfers.
  03/9/03   sbs - Modified the MSPRO identify by adding a wait for MSPRO ready on a DFA_MEDIA_RESET.
  03/10/03 sbs - Addded the MSPRO reset for 210.
  03/18/03 sbs - Added the MSPRO Media Format fuctionality, this is supported by Vendor Specific SCSCI commands.
                 also modified the Flag variable defined in ms.c for the this functionality. 
  03/18/03 sbs   changed g_mspro_flag the FLAG to type bit from UINT8 .
  03/26/03 sbs  - Reverted the MSPRO serial clock to 20Mhz cause the MSPRO spec says it supports Max 20mhz serial
                  clock.Also fixed the bug with media size reporting.
  04/01/03 sbs  - Indenting and comments.  
  06/09/03 sbs  - Added the Functionality to handle Single Bit Ecc error abort reported by the Multiple Emulation Hardware.
  06/10/03 sbs  - Format MSPRO bug realted to formating write protected media fixed.
  07/10/03 sbs  - Added code for MS_Classic high speed media support.
  07/25/03 sbs  - Fixed the MS surprise removal Bug for read & write operations.Also added time_outs and checks in
                  while loops to avoid lockup. 
 08/04/03 sbs  - Added Code to support Sony vendor specific formatter application. 
 08/05/03 sbs  - Fixed Bug 786 
 08/06/03 sbs  - Fixed Bug 787,Fixed the MS 2 bit error reporting.      
 08/07/03 sbs  - Fixed the pointer type-casting issue with memcpy.
 08/12/03 sbs  - The sony formatter application response was found to be very slow on 1.1 speeds. Fixed spliting the
                 mode sense response in two packets at 1.1 speeds.
 08/19/03 sbs  - Fixed bug 799.                  
 08/26/03 sbs  - Fixed  Bug ID: 802.The MS 2 bit error reporting.                   
 ========================================================================================================================*/
#define __ms_dot_c__
#include "project.h"
#include "dev.h"

code _vtbl_defn(ms);
void fmc_dbg_dump_sector(uint8* sector) reentrant;
//#define k_memory_stick_eraser
//------------------------------------------------------------------------------
// module globals
// status
xdata uint8 _factor;
xdata uint8 _status0;
xdata uint8 _status1;
xdata uint8 _typereg;
xdata uint8 _rsvd;
xdata uint8 _catreg;
xdata uint8 _classreg;
// extra data registers buffer
xdata uint8 g_ms_extra[4];
// shadow registers
xdata uint8 g_ms_blk_addr_msb;
xdata uint8 g_ms_blk_addr_mid;
xdata uint8 g_ms_blk_addr_lsb;
xdata uint8 g_ms_page;

//------------------------------------------------------------------------------
// 
//Sony Format Specific Data Structures
xdata  t_sense dummy_sense =
{
  0x70,                           // ErrorCode
  0x00,                           // Reserved
  0x00,                           // SenseKey
  0x00, 0x00, 0x00, 0x00,         // VendorSpecificA[4]
  sizeof(t_sense) - 8,            // AdditionalLength
  0x00, 0x00, 0x00, 0x00,         // VendorSpecificB[4]
  0x00,                           // AdditionalSenseCode
  0x00,                           // AscQualifier
  0x00,                           // FieldReplacableUnitCode
  0x00, 0x00, 0x00                // SenseKeySpecific[3]
};
xdata t_sense *dummy_sense_ptr;
xdata t_uw16 _report;
xdata t_udw32  x,y;
//------------------------------------------------------------------------
#define k_sz_ms_lun_inquiry 56
#define kbm_ms_inquiry_rmb         0x80
code uint8 lun_ms_inquiry_template[k_sz_ms_lun_inquiry] =
{
  0x00,                 // PeripheralDeviceType = DASD
  0x00,                 // Removable bit set in process_inquiry
  0x00,                 // IsoEcmaAnsiVersion
  0x02,                 // ResponseDataFormat
  0x20,                 // AdditionalLength
  0x00, 0x00, 0x00,     // Reserved[3]
  // VendorInfo[8]
  'S', 'M', 'S', 'C', 0, 0, 0, 0,
  // ProductInfo[16]
  'U', 'S', 'B', ' ', '2', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  '0' + kbcd_dev_version_major,  // ProductVersion[0]
  '.',                  // ProductVersion[1]
  '0' + (kbcd_dev_version_minor >> 4),  // ProductVersion[2]
  '0' + (kbcd_dev_version_minor & 0x0F),  // ProductVersion[3]
  'M','E','M','O','R','Y','S','T','I','C','K',' ',' ',' ',
  0x01,
  0x20,
  0x20,
  0x20,
  0x20,
  0x20
};
//-------------------------------------------------------------------------
uint8 code _ms_msense[4]    = { 0x03, 0x00, 0x00, 0x00};
uint8 code _ms_msense_wp[4] = { 0x03, 0x00, 0x80, 0x00}; 
uint8 code _ms_msense10[8] =  { 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8 code _ms_msense10_wp[8] = { 0x00, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00};
//--------------------------------------------------------------------------
xdata unsigned char volatile g_ms_sense_buffer[108];
bit  g_sony_mspro_format_flag=0;
//----------------------------
extern bit  g_mspro_format_flag;
//xdata uint8 g_ms_data_count_msb;
//xdata uint8 g_ms_data_count_lsb;
//---------------------------
//xdata uint8 g_ms_data_address_0;
//xdata uint8 g_ms_data_address_1;
//xdata uint8 g_ms_data_address_2;
//xdata uint8 g_ms_data_address_3;
// logical to physical sector mapping table
//xdata uint16 _ms_map_table[512];
#define k_map_boot_blk    0x8000
#define k_map_initial_err 0xfffd
#define k_map_fatal_err   0xfffe
extern xdata t_udw32 g_start_lb_this_xfer;
extern xdata t_udw32 g_n_lb_this_xfer;
xdata t_udw32 g_ms_data_count;
xdata t_udw32 g_ms_data_address;
xdata t_udw32 g_temp_xfer_count; 
extern t_result ms_media_erase_card() reentrant;
extern void util_safe_erase_media() reentrant;
// total number of blocks on the card
xdata t_uw16 _ms_block_per_card;
// block size - 8k or 16k bytes
xdata t_uw16 _ms_byte_per_block;
xdata t_uw16 _ms_uint_size;
// segment size - number of card blocks in a card segment
#define k_phy_block_per_segment      512L
#define k_log_block_per_segment      496L
#define k_log_block_per_boot_segment 494L
// Declare a media type flag
bit  _mspro;
bit _msparallel;
// pages per block - a page is analogous to a mass storage class logical block, or disk sector
xdata uint16 _ms_page_per_block;
// tables used by the mapper/pager
#define k_ms_max_zones_per_table 2
xdata uint16 _ms_log2phy[k_ms_max_zones_per_table][k_phy_block_per_segment];
xdata uint8  _ms_assign_map[k_ms_max_zones_per_table][k_phy_block_per_segment/8];
xdata uint16 _ms_bad_blk_tbl[256];
xdata uint16 g_ms_user_area_start_blk;
#ifdef k_mcu_97223
//+-----------------------------------------------------------------------------
// Name:
//   ms_set_clk:
//
// Declaration:
//   void ms_set_clk(void);
//
// Purpose:
//   This function is used to set the MS clock bits to appropriate CLK value .This is required cause
//   the clk control bits in the 223 FPGA are shared by MS/SD,hence evry thime MS is selected for a read/write
//   the clock setting is changed to proper value.This code is protected by the is_fpga flag.
//
// Arguments:
//   None
//
// Return: None
// Notes:
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void ms_set_clk() reentrant
{
  if (_dev_is_fpga())
  {
    if (_mspro)
    {
      if ((_mcu_register_rd(x_fmc_clk_ctl)&kbm_msk_fmc_clk_sd)!=k_fmc_clk_ctl_sd_40mhz)
      {
        // Set the MS Clock by setting the SD bits. This is only true for FPGA 
        trace0(0, ms, 0, "fpga alert - shared ms/sd clk being changed for ms");
        _mcu_register_clr_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_sd_disable );
        _mcu_register_set_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_sd_40mhz );

        //Enough time to let the clk freq change... should be changed to more accurate time.
        thread_set_timer(1);
        while (!(thread_got_sync(kbm_sync_timer)));
        thread_clr_sync(kbm_sync_timer);
      }

    }
    else
    {
      if ((_mcu_register_rd(x_fmc_clk_ctl)&kbm_msk_fmc_clk_sd)!=k_fmc_clk_ctl_sd_20mhz)
      {
        // Set the MS Clock by setting the SD bits. This is only true for FPGA 
        trace0(0, ms, 0, "fpga alert - shared ms/sd clk being changed for ms");
        _mcu_register_clr_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_sd_disable );
        _mcu_register_set_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_sd_20mhz );
        //Enough time to let the clk freq change... should be changed to more accurate time.
        thread_set_timer(1);
        while (!(thread_got_sync(kbm_sync_timer)));
        thread_clr_sync(kbm_sync_timer);
      }
    }  
  }
  return;
}
#endif
// br308
// set to false when the boot blocks are read.
// set to true if a block write fails with breq after block-end (i.e., exibits the bug).
// provides the solution for the SanDisk 64MB cards w/ date codes < J
static bit _force_one_burst_per_split;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_bool ms_is_this_blk_in_bad_blk_tbl(uint16 blk) reentrant
{
  uint8 i;

⌨️ 快捷键说明

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