📄 lun.c
字号:
/*============================================================================
____________________________________________________________________________
______________________________________________
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 + -