📄 lun.c
字号:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_lun_sync_cache(void)reentrant
{
TRACE0(167, lun, 0, "dfa_lun_sync_cache() - warning: not implemented");
_lun_data(sensep) = &sense_illegal_opcode;
_thread_return_dfa(k_command_failed);
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_lun_erase_media()
//
// Declaration:
// void dfa_lun_erase_media(void) reentrant ;
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
// - This is a dfa.
// - luns that support erasing the media should override this function
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_lun_erase_media(void) reentrant
{
TRACE0(168, lun, 0, "dfa_lun_erase_media() - not implemented on this lun");
_lun_data(sensep) = &sense_illegal_opcode;
_thread_return_dfa(k_command_failed);
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_lun_report_media_geometry()
//
// Declaration:
// void dfa_lun_report_media_geometry(void) reentrant ;
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
// - This is a dfa.
// - luns that support mapped media override this function
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_lun_report_media_geometry(void) reentrant
{
TRACE0(169, lun, 0, "dfa_lun_report_media_geometry() - not implemented on this lun");
_lun_data(sensep) = &sense_illegal_opcode;
_thread_return_dfa(k_command_failed);
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_lun_secure_memory_write()
//
// Declaration:
// void dfa_lun_secure_memory_write(void) reentrant ;
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
// - This is a dfa.
// - should not be overridden. Vendor specific command. independant of what lun it is
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_lun_secure_memory_write(void) reentrant
{
uint8 i, len;
TRACE0(170, lun, 0, "dfa_lun_secure_memory_write()");
_lun_data(sensep) = &sense_none;
len = g_bot_cbw.cdb[8];
// receive the data
if (k_success != mscbot_rx_data_buffer(g_sector_buffer, len))
_thread_return_dfa(k_command_failed);
//get the nvstore ready to write
nvstore_write_enable();
for (i= 0; i < len; i++)
{
//TRACE2(387, lun, 0, "buffer[%d] = %02x",i,g_sector_buffer[i]);
nvstore_write((k_ix_secure_mem + i), g_sector_buffer[i]);
}
//Post write operation
nvstore_write_disable();
//verify the writes
for (i=0; i < len; i++)
{
if (nvstore_read((k_ix_secure_mem + i)) != g_sector_buffer[i])
{
_thread_return_dfa(k_command_failed);
}
}
_mscbot_decr_residue(len); //Decrement the residue
_thread_return_dfa(k_command_passed);
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_lun_secure_memory_read()
//
// Declaration:
// void dfa_lun_secure_memory_read(void) reentrant ;
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
// - This is a dfa.
// - should not be overridden. Vendor specific command. independant of what lun it is
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_lun_secure_memory_read(void) reentrant
{
uint8 i, len;
TRACE0(171, lun, 0, "dfa_lun_secure_memory_read()");
_lun_data(sensep) = &sense_none;
len = g_bot_cbw.cdb[8];
for (i= 0; i < len; i++)
{
g_sector_buffer[i] = nvstore_read((k_ix_secure_mem + i));
}
// send it
mscbot_tx_data_buffer(g_sector_buffer, len);
_thread_return_dfa(k_command_passed);
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_lun_device_diagnostics()
//
// Declaration:
// void dfa_lun_device_diagnostics(void) reentrant ;
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
// - This is a dfa.
// - Should not need to be overridden. This function will automatically use
// lun instance data to respond to the host.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_lun_device_diagnostics(void) reentrant
{
TRACE0(172, lun, 0, "dfa_lun_device_diagnostics() - warning: not implemented");
_lun_data(sensep) = &sense_illegal_opcode;
_thread_return_dfa(k_command_failed);
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_lun_unsupported()
//
// Declaration:
// void dfa_lun_unsupported(void) reentrant ;
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
// - This is a dfa.
// - Should not need to be overridden. This function will automatically use
// lun instance data to respond to the host.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_lun_unsupported(void) reentrant
{
TRACE0(173, lun, 0, "dfa_lun_unsupported() - warning: host delivered unsupported command");
_lun_data(sensep) = &sense_illegal_opcode;
_thread_return_dfa(k_command_failed);
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_lun_inquiry()
//
// Declaration:
// void dfa_lun_inquiry(void) reentrant ;
//
// Purpose:
// Default mass storage class inquiry handling, utilizing
// info that should be present in the _lun_data instances
// during lun initialization.
//
// Arguments:
//
// Return:
//
// Notes:
// - This is a dfa.
// - Should not need to be overridden. This function will automatically use
// lun instance data to respond to the host.
//
// Since:
// atapi.20
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// clearly we need "nvstore.h", but since brian has device.c checked out,
// and as usual i'm in a hurry, i'll do a smidegon of hackmeistering to
// quick-n-dirty this. the enterprising reader should take it upon his/herself
// to fabricate nvstore.h and nvstore.c
//
// offsets into the nvstore - COMBINE THESE WITH THOSE IN DEVICE.C AND PUT INTO DEV.H!!!
#define k_ix_mfr 34
#define k_sz_mfr 60
#define k_ix_prd 94
#define k_sz_prd 60
#define k_ix_vid_lo 26
#define k_ix_vid_hi 27
#define k_ix_pid_lo 28
#define k_ix_pid_hi 29
//------------------------------------------------------------------------------
#define k_sz_lun_inquiry 36
#define kbm_inquiry_rmb 0x80
code uint8 lun_inquiry_template[k_sz_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]
};
//------------------------------------------------------------------------------
void dfa_lun_inquiry(void) reentrant
{
uint8 length;
// uint8 pnr;
uint8 off;
uint8 n;
TRACE0(174, lun, 0, "dfa_lun_inquiry()");
TRACE1(175, lun, 0, "alloc length:%02X", g_bot_cbw.cdb[4]);
// load template into buffer
memcpy((uint8 xdata *)g_sector_buffer, (uint8 code *)lun_inquiry_template, k_sz_lun_inquiry);
// offset 1: overwrite the rmb bit
g_sector_buffer[1] = (_lun_is_media_removable(g_active_lun))
? lun_inquiry_template[1] |kbm_inquiry_rmb
: lun_inquiry_template[1] & ~kbm_inquiry_rmb;
// offset 8..15: overwrite the vendor up to 8 chars from the mfg string dscr
memcpy(g_sector_buffer+8, g_inq_vid, k_sz_inq_vid);
// offset 16..<24>: overwrite the product up to 9 chars from the Inquiry Prd ID header
memcpy(g_sector_buffer+16, g_inq_pid_hdr, k_sz_inq_pid_hdr) ;
off=16+k_sz_inq_pid_hdr;
// offset <16>..<16>+5: _XS-, should always be HS as per jwc
g_sector_buffer[off++] = ' ';
g_sector_buffer[off++] = 'H';
g_sector_buffer[off++] = 'S';
g_sector_buffer[off++] = '-';
// offset <16>+3..31: lun device id
n = k_sz_lun_inquiry - off - 4;
memcpy(g_sector_buffer + off, _lun_data(device_id), _min(n, k_lun_max_devid_sz));
// send it
length = _min(k_sz_lun_inquiry, g_bot_cbw.cdb[4]);
mscbot_tx_data_buffer(g_sector_buffer, length) ;
_thread_return_dfa(k_command_passed);
}
//+-----------------------------------------------------------------------------
// Name:
// lun_process_cb2()
//
// Declaration:
// void lun_process_cb2() reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void lun_process_cb2(void) reentrant;
void lun_process_cb2() reentrant
{
uint8 cmd = g_bot_cbw.cdb[0];
TRACE2(176, lun, 0, "lun_process_cb2(lun:%d, cmd:%02x)", g_active_lun, cmd);
// _stack_check();
// _stack_dump();
// run these regardless of current sense code - they cannot be failed for any reason
if (cmd == k_protocol_inquiry)
{
TRACE0(177, lun, 0, "cb-inquiry");
thread_run_dfa(_dfa_lun_inquiry(), thread_rd_dfa_argp(), thread_end_dfa);
}
if (cmd == k_protocol_request_sense)
{
TRACE0(178, lun, 0, "cb-request-sense");
thread_run_dfa(_dfa_lun_req_sense(), thread_rd_dfa_argp(), thread_end_dfa);
}
if (cmd == k_protocol_vendor_secure_memory_write)
{
TRACE0(179, lun, 0, "cb-protocol-vendor-secure-memory-write");
thread_run_dfa(_dfa_lun_secure_memory_write(), thread_rd_dfa_argp(), thread_end_dfa);
}
if (cmd == k_protocol_vendor_secure_memory_read)
{
TRACE0(180, lun, 0, "cb-protocol-vendor-secure-memory-read");
thread_run_dfa(_dfa_lun_secure_memory_read(), thread_rd_dfa_argp(), thread_end_dfa);
}
if(cmd==k_protocol_vendor)
{
uint8 cmd2=g_bot_cbw.cdb[1];
if(cmd2==k_vendor_erase_media)
{
TRACE0(181, lun, 0, "vendor specific: erase media");
thread_run_dfa(_dfa_lun_erase_media(), thread_rd_dfa_argp(), thread_end_dfa);
}
else if(cmd2==k_vendor_report_media_geometry)
{
TRACE0(182, lun, 0, "vendor specific: report media geometry");
thread_run_dfa(_dfa_lun_report_media_geometry(), thread_rd_dfa_argp(), thread_end_dfa);
}
}
// check if there is an error condition
if (_lun_data(sensep) != &sense_none)
{
TRACE0(183, lun, 99, "unhappy sensep");
_thread_return_dfa(k_command_failed);
}
// dispatch the command to the a virtual handler
switch (cmd)
{
// BBB: the first optimization to this was to call rd/wr directly from dfa_lun_proces
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -