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

📄 lun.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 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
  11/27/01  cds  - added lun_enable_mux() stub
                 - converted all methods to reentrant model
  12/06/01  tbh  clean sweep re-organization
  01/15/02  cds  - added base start-stop unit command for all removable
                   media luns.
                 - added read format capacity processing for all luns
                 - added function comment stubs (in off chance we have time
                   to comment functions that we won't have to rip out later)
  02/26/02  tbh  added logical to physical lun mapping, absorbed lun tables etc
                 moved in here from project.h
  04/08/02  tbh  - on start/stop-eject - if card was mmc then map sd back into
                 the logical lun.
  04/17/02  tbh  added k_protocol_mode_sense_6 case to lun_process_cdb to
                 allow MS (and SM) to override the mode_sense dfa so as to
                 report the WP bit to prevent write commands to rom only cards.
  04/18/02  tbh  replaced dfa_lun_mode_sense with minimal version required
                 to report write protect bit based on lun data.
  04/29/02  tbh  based on Sashi's analysis of the sense codes we report
                 i updated them as follows:
                 - illegal_opcode/05/20/00 for unsupported commands
                 - illegal_cmdpkt/05/24/00 for supported command but unsupported option
                 - illegal_rqst/05/26/xx for command parameter error from host
  06/05/02  cds  updated inquiry function to check media flags before setting/clearing
                 removable media bit
  06/10/02  tbh  performance optimizations by adding __thread_return_dfa()
                 to trick dfa_lun_read and dfa_lun_write into running and
                 exiting correctly when called as functions instead of dfa's
  06/21/02  cds  added nand lun to the vtbl table, and removed the _vtbl(nil)
                 class since it is not necessary.  _vtbl(lun) has been replaced
                 by a simple _vtbl(lun) with all methods set to NULL, instead
                 of a vtbl initialized with methods that may not have implementations.
  06/28/02  ds   Added support for Mode_Sense 10 command.
  07/01/02  tbh  handle write protect at the lun layer.
                 (later fixed typo that set MS to wrprot instead of g_active_lun)
  07/09/02  cds  moved definition of g_sector_buffer here for use by all luns
  07/11/02  tbh  altered dfa_lun_inquiry to stuff an ascii version of the vid/pid
                 as extracted from nvstore into the vendorinfo field of the inquiry
                 data to allow the smsc WinXX custom icon application to enumerate
                 the drives and discover our vid/pid (w/out knowing if its a usb
                 drive or not) and match the vid/pid with an inf file.
  07/12/02  tbh  altered dfa_lun_inquiry again to follow then new scheme for
                 stuffing the vendor/product strings for custom icon matching.
  07/23/02  tbh  modified dfa_lun_start_stop_unit to handle eject differently.
                 because of recent requirement for "card present" leds, and SD
                 card insert/eject crippled hardware, the SD card must be periodically
                 probed to see if tis loaded (because W2K etc won;t send periodic TURs
                 to probe the card).  so, on an eject, changed the command handler
                 to no longer clear the sd/mmc present bits in x_crd_ps register.
                 this prevents the SD prober from firing, avoiding the annoying
                 return of the icon under XP and OSX (which do send periodic TUR).
  08/01/02  ds   On a software eject the SD LED was not getting turned off. Fixed that.
  08/01/02  tbh  rollback last change. bug report was incorrect.
  08/13/02  tbh  there was a bug in dfa_lun)inquiry in that nvstore_read() will
                 return garbage if the nvstore hasn't been written yet.
  08/20/02  cds  added some lun trace points to track down sm/nand/ms corruption
  09/05/02  tbh  removed dead broken code
  09/10/02  tbh  inserted non-space default values for vendor and product
                 strings in the inquiry response template.
  09/11/02  tbh  modified so shorter strings in the nvstore will overwrite
                 the longer default strings in dfa_lun_inquiry.
  09/19/02  cds  added second 'default' mode sense function which can be used for
                 sm, nand, or memory stick luns (or any lun using the log2phy mapper)
                 to relay media geometry to host.
  09/21/02  tbh  added lun_process_idle()
  09/22/02  tbh  eliminated unused code on 242 builds
  09/22/02  tbh  pad the vendor name with spaces in inquiry data
  09/23/02  tbh  added an else to the padding code to make it work properly
  09/23/02  cds  moved mode sense dfa for fmt dev page from lun.c to media.c so that
                 luns w/o the mapper will be able to link
  09/25/02  cds  added support for erase_flash and report_media_geometry lun dfas
  09/26/02  cds  updated small data xfers to use a central function to tx a buffer
                 instead of repeated the tx code all over.
  10/01/02  cds  converted _lun_is_media_XXX() macros to functions to conserve
                 code space.  
  10/01/02  ds   Added implementation for dfa_lun_secure_memory_read and dfa_lun_secure_memory_write
                 to support two vendor specific commands to write to a 24byte secure area in the nvstore.
  10/02/02  jwc  Changed descriptors to always report HS to workaround WHQL bug reported by TW. 
                 g_sector_buffer[off++] = (_mcu_register_rd(x_sie_conf) & kbm_sie_conf_hspeed) ? 'H' : 'H';												 
  10/02/02  ds   Added code to trap a timeout error on receiving the data packet in dfa_lun_secure_memory_write               
  10/02/02  ds   Added code to verify after a nvstore-write is done. 
  10/03/02  ds   Fixed Bug ID 359: The functions _lun_is_media_known and _lun_is_media_present are being
                 called from the high priority BOT layer.So, they must be protected by #pragma NOAREGS
  10/07/02  ds   -Modified dfa_lun_inquiry to fetch the Vendor ID (8 bytes) and Product ID Header (5 bytes)
                  from the nvstore, instead of the mfg and prd strings.
                 -Made all lun_media_xxx functions protectes by #pragma NOAREGS                 
  10/10/02  cds  - added new call "lun_is_media_ready()" to allow lun to check whether or not a read/write
                   cb can be issued.
  10/11/02  cds  added vendor commands cf-10, cf-11 to be executed regardless of unhappy sense                 
  10/15/02  cds  updated inquiry to simply copy inq_vid and inq_pid_hdr from xdata buffer instead of building them at run-time 
  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               

============================================================================*/
#define __lun_dot_c__
#include "project.h"
#include "dev.h"

//------------------------------------------------------------------------------
// _vtbl_defn(lun) is not a valid class... it is akin to a "pure virtual" or interface class,
// and as such should not have a stand-alone vtble defined under our
// implementation.
//
// Since we need a "placeholder" vtbl for log-to-phy lun mapping (dynamic
// sub-classing), but cannot have a non-subclassed 'lun', we can eliminated
// either _vtbl_defn(lun) or _vtbl_defn(nil).  I opted to axe the _vtbl(nil)

// provide vtable definition '_vtbl_lun'
code  _vtbl_decl(lun) = { (t_thd_entry) NULL} ;

//------------------------------------------------------------------------------
// tables indexed by physical lun number. they are fixed, and do not change orded with build
xdata t_lun_data  g_lun_data[k_max_phy_lun];
code t_thd_entry* g_lun_tbl[k_max_phy_lun] =
{
#if (k_log_lun_cf < k_max_log_lun)
  _vtbl(cf),
#else
  _vtbl(lun),
#endif

#if (k_log_lun_ms < k_max_log_lun)
  _vtbl(ms),
#else
  _vtbl(lun),
#endif

#if (k_log_lun_sm < k_max_log_lun)
  _vtbl(sm),
#else
  _vtbl(lun),
#endif

#if (k_log_lun_sd < k_max_log_lun)
  _vtbl(sd),
#else
  _vtbl(lun),
#endif

#if (k_log_lun_mmc < k_max_log_lun)
  _vtbl(mmc),
#else
  _vtbl(lun),
#endif

#if (k_log_lun_nand < k_max_log_lun)
  _vtbl(nand)
#else
  _vtbl(lun)
#endif
    
};

//------------------------------------------------------------------------------
// this is a physical lun
xdata uint8 g_active_lun;
// indexed by logical lun
xdata uint8 g_lun_log2phy_map[k_max_log_lun];
// sector buffer used by luns to store temporary sector data
xdata uint8 g_sector_buffer[k_sector_sz]  ;

// prototypes
uint8 nvstore_read(uint8 addr) reentrant;
void nvstore_write(uint8 addr, uint8 value) reentrant;
void nvstore_write_enable(void) reentrant;
void nvstore_write_disable(void) reentrant;

// _lun_is_media_XXX() style functions acting as macros
//DS WARNING!!! THESE FUNCTIONS SHOULD BE PROTECTED BY #PRAGMA NOAREGS, IF THEY ARE CALLED FROM 
//INTERRUPT LEVEL CODE (HIGH PRIORITY)
#pragma NOAREGS
//+-----------------------------------------------------------------------------
t_bool _lun_is_media_present(uint8 lun) reentrant
{
  return(__lun_is_media_present(lun));
}

//+-----------------------------------------------------------------------------
t_bool _lun_is_media_known(uint8 lun) reentrant
{
  return(__lun_is_media_known(lun));
}
//+-----------------------------------------------------------------------------
t_bool _lun_is_media_changed(uint8 lun) reentrant
{
  return(__lun_is_media_changed(lun));
}

//+-----------------------------------------------------------------------------
t_bool _lun_is_media_lockable(uint8 lun) reentrant
{
  return(__lun_is_media_lockable(lun));
}

//+-----------------------------------------------------------------------------
t_bool _lun_is_media_removable(uint8 lun) reentrant
{
  return(__lun_is_media_removable(lun));
}
//+-----------------------------------------------------------------------------
t_bool _lun_requests_idle_processing(uint8 lun) reentrant
{
  return(__lun_requests_idle_processing(lun));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_bool lun_is_media_ready() reentrant
{
  uint8 media;
  media = _lun_data(media);

#ifdef k_opt_password
 if (!(_lun_is_media_present(g_active_lun)))
 {
  trace0(0, dev, 0, "Moving on to process cb"); 
  return k_false;
 }
#else
  if (!(media & kbm_lun_media_present))
    return k_false;
#endif
  if (media & kbm_lun_media_changed)
    return k_false; 
  if (media & kbm_lun_media_unknown)
    return k_false;

  return k_true;
}
#pragma AREGS



//------------------------------------------------------------------------------
// active lun 'page'
xdata t_sense code *g_lun_data_sensep ;          // the sense code to report on next request sense
xdata t_sense code *g_lun_data_statusp ;         // the current, volatile status of the device
xdata uint8         g_lun_data_sense_data[3];    // additional sense data
xdata uint8         g_lun_data_device_id[k_lun_max_devid_sz];  // inquiry and device identification data
xdata uint8         g_lun_data_media ;
xdata t_capacity    g_lun_data_capacity ;        // capacity (and fmt capacity) of current media
xdata uint32        g_lun_data_max_lb_per_split;
xdata uint32        g_lun_data_max_lb_per_burst;
xdata uint8         g_lun_data_device_type;      // set in dfa_initialize

//------------------------------------------------------------------------------
// active lun 'vtbl'
xdata t_thd_entry v_lun_process_idle;              
xdata t_thd_entry v_lun_enable_mux;                
xdata t_thd_entry v_lun_reset_controller;          
xdata t_thd_entry v_lun_initialize_controller;     
xdata t_thd_entry v_dfa_lun_reset_media;           
xdata t_thd_entry v_dfa_lun_initialize_media;      
xdata t_thd_entry v_dfa_lun_identify_media;        
xdata t_thd_entry v_dfa_lun_inquiry;               
xdata t_thd_entry v_dfa_lun_test_unit_ready;       
xdata t_thd_entry v_dfa_lun_req_sense;             
xdata t_thd_entry v_dfa_lun_read_capacity;         
xdata t_thd_entry v_dfa_lun_read;                  
xdata t_thd_entry v_dfa_lun_write;                 
xdata t_thd_entry v_dfa_lun_verify;                
xdata t_thd_entry v_dfa_lun_mode_sense;            
xdata t_thd_entry v_dfa_lun_mode_select;           
xdata t_thd_entry v_dfa_lun_read_format_capacity;  
xdata t_thd_entry v_dfa_lun_format_unit;           
xdata t_thd_entry v_dfa_lun_start_stop_unit;       
xdata t_thd_entry v_dfa_lun_prevent_allow_access;  
xdata t_thd_entry v_dfa_lun_sync_cache;            
xdata t_thd_entry v_dfa_lun_device_diagnostics;    
xdata t_thd_entry v_dfa_lun_erase_media;           
xdata t_thd_entry v_dfa_lun_report_media_geometry; 
xdata t_thd_entry v_dfa_lun_secure_memory_read;    
xdata t_thd_entry v_dfa_lun_secure_memory_write;   
xdata t_thd_entry v_dfa_lun_process_cb;            

#pragma NOAREGS

#if 0 
void lun_trace_vtbl() reentrant
{
  TRACE1(47, lun, 0, "v_lun_process_idle: %04x", (uint16)v_lun_process_idle);
  TRACE1(48, lun, 0, "v_lun_enable_mux: %04x", (uint16) v_lun_enable_mux);
  TRACE1(49, lun, 0, "v_lun_reset_controller: %04x", (uint16) v_lun_reset_controller);
  TRACE1(50, lun, 0, "v_lun_initialize_controller: %04x", (uint16) v_lun_initialize_controller);
  TRACE1(51, lun, 0, "v_dfa_lun_reset_media: %04x", (uint16) v_dfa_lun_reset_media);
  TRACE1(52, lun, 0, "v_dfa_lun_initialize_media: %04x", (uint16) v_dfa_lun_initialize_media);
  TRACE1(53, lun, 0, "v_dfa_lun_identify_media: %04x", (uint16) v_dfa_lun_identify_media);
  TRACE1(54, lun, 0, "v_dfa_lun_inquiry: %04x", (uint16) v_dfa_lun_inquiry);
  TRACE1(55, lun, 0, "v_dfa_lun_test_unit_ready: %04x", (uint16) v_dfa_lun_test_unit_ready);
  TRACE1(56, lun, 0, "v_dfa_lun_req_sense: %04x", (uint16) v_dfa_lun_req_sense);
  TRACE1(57, lun, 0, "v_dfa_lun_read_capacity: %04x", (uint16) v_dfa_lun_read_capacity);
  TRACE1(58, lun, 0, "v_dfa_lun_read: %04x", (uint16) v_dfa_lun_read);
  TRACE1(59, lun, 0, "v_dfa_lun_write: %04x", (uint16) v_dfa_lun_write);
  TRACE1(60, lun, 0, "v_dfa_lun_verify: %04x", (uint16) v_dfa_lun_verify);
  TRACE1(61, lun, 0, "v_dfa_lun_mode_sense: %04x", (uint16) v_dfa_lun_mode_sense);
  TRACE1(62, lun, 0, "v_dfa_lun_mode_select: %04x", (uint16) v_dfa_lun_mode_select);
  TRACE1(63, lun, 0, "v_dfa_lun_read_format_capacity: %04x", (uint16) v_dfa_lun_read_format_capacity);
  TRACE1(64, lun, 0, "v_dfa_lun_format_unit: %04x", (uint16) v_dfa_lun_secure_memory_read);
  TRACE1(65, lun, 0, "v_dfa_lun_start_stop_unit: %04x", (uint16) v_dfa_lun_start_stop_unit);
  TRACE1(66, lun, 0, "v_dfa_lun_prevent_allow_access: %04x", (uint16) v_dfa_lun_prevent_allow_access);
  TRACE1(67, lun, 0, "v_dfa_lun_sync_cache: %04x", (uint16) v_dfa_lun_sync_cache);
  TRACE1(68, lun, 0, "v_dfa_lun_device_diagnostics: %04x", (uint16) v_dfa_lun_device_diagnostics);
  TRACE1(69, lun, 0, "v_dfa_lun_erase_media: %04x", (uint16) v_dfa_lun_erase_media);
  TRACE1(70, lun, 0, "v_dfa_lun_report_media_geometry: %04x", (uint16) v_dfa_lun_report_media_geometry);
  TRACE1(71, lun, 0, "v_dfa_lun_secure_memory_read: %04x", (uint16) v_dfa_lun_secure_memory_read);
  TRACE1(72, lun, 0, "v_dfa_lun_secure_memory_write: %04x", (uint16) v_dfa_lun_secure_memory_write);
  TRACE1(73, lun, 0, "v_dfa_lun_process_cb: %04x", (uint16) v_dfa_lun_process_cb);
}
#endif

//+-----------------------------------------------------------------------------
// Name:
//   media_set_active()
//
// Declaration:
//   void media_set_active(uint8 media) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void lun_set_active(uint8 lun) reentrant
{
  mcu_begin_critical_section() ;
  if(g_active_lun != lun)
  {
    if (g_active_lun<k_max_phy_lun)
    {
      TRACE1(74, lun, 0, "paging data out: lun %d", g_active_lun);
      memcpy(&(g_lun_data[g_active_lun]), (uint8 *) &g_lun_data_sensep, k_lun_data_sz);
    }
    TRACE1(75, lun, 0, "paging data in: lun %d", lun) ;
    memcpy((uint8 *) &g_lun_data_sensep, &(g_lun_data[lun]), k_lun_data_sz) ;
    if( g_lun_tbl[lun] )

⌨️ 快捷键说明

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