📄 rbc.c
字号:
/**************** (c) 2000 STMicroelectronics **********************
PROJECT : USB - ST7 FULL SPEED
VERSION : v 0.96
CREATION DATE : 01/12/2000
AUTHOR : MICROCONTROLLER DIVISION / ST Rousset
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
MODIFICATIONS :
******************************************************************************/
#include "CondComp.h"
#include "hidef.h"
#include "lib_bits.h"
#include "define.h"
#include MAP_FILE
#include "MConfig.h"
#include "MSL.h"
#include "MAL.h"
#include "RBC.h"
#include "SenseDat.h"
#include "Descript.h"
// RBC Extention Major version
#define RBC_EXT_MAJ 0x10
// RBC Extention Minor version
#define RBC_EXT_MIN 0x11
#pragma DATA_SEG SHORT CLASS_RAM0
unsigned char Sense_Head;
unsigned char Sense_Tail;
unsigned char MSL_Param_Size;
#pragma DATA_SEG CLASS_RAM
static unsigned char Current_Operation;
static tRBC_CMD sRBC_CMD;
//static unsigned char FormatProgress;
//static unsigned int NextProgress;
static unsigned int Format_Blk_Done;
#define SENSE_LIST_DEEPTH 4
typedef struct _SENSE_ITEM {
char Skey;
union {
struct _ASCs {
char ASC;
char ASCQ;
}b;
unsigned short ASC;
char *pData;
} w;
} SENSE_ITEM;
SENSE_ITEM Sense_List[SENSE_LIST_DEEPTH];
unsigned char MSL_Param_Buffer[SIZ_MSL_PARAM];
// PFD variable
#pragma DATA_SEG DEFAULT_RAM
unsigned char Current_Mode = 0;
unsigned char Flash_State = 0;
unsigned char Windows_2000 = 0;
unsigned long Private_Zone_Size = 0;
unsigned char Slot_Description[34];
unsigned char PassWord[34];
unsigned char Serial_Number[66];
#pragma CODE_SEG CLASS_ROM
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Init
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
void RBC_Init(void)
{
Sense_Tail = 0;
Sense_Head = 0;
Format_Blk_Done = 0;
Current_Operation = RBC_OP_IDLE;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : SenseCode
INPUT/OUTPUT :
DESCRIPTION :
-----------------------------------------------------------------------------*/
void SenseCode(unsigned char Key, unsigned int ASC)
{
Sense_List[Sense_Tail].Skey = Key;
Sense_List[Sense_Tail].w.ASC = ASC;
Sense_Tail++;
if (Sense_Tail == SENSE_LIST_DEEPTH)
Sense_Tail = 0;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_MAL_Error()
INPUT/OUTPUT : None
DESCRIPTION : Take care all the error code and return the Sense data
Return only on RBC_GOOD
-----------------------------------------------------------------------------*/
unsigned char RBC_MAL_Error(unsigned char Errno)
{
if (Errno == MAL_GOOD)
return RBC_STATUS_GOOD;
if (Errno == MAL_NO_CARD)
SenseCode(NOT_READY, MEDIUM_NOT_PRESENT);
else if (Errno == MAL_NEW_CARD)
SenseCode(UNIT_ATTENTION, MEDIUM_HAVE_CHANGED);
else if (Errno == MAL_CARD_UNKNOWN)
SenseCode(MEDIUM_ERROR, READ_UNKNOW_FORMAT);
else if (Errno == MAL_OUT_RANGE)
SenseCode(ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
else if (Errno == MAL_NO_WRITE)
SenseCode(MEDIUM_ERROR, WRITE_PROTECTED);
else
SenseCode(HARDWARE_ERROR, 0); // Unknow error, must be s/w bug in MAL
return RBC_STATUS_FAIL;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_CopyCmd
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
#pragma NO_ENTRY
void RBC_CopyCmd(unsigned char *pRBC)
{
asm {
ld pRBC:1, A
ld pRBC, X
ld X, #15
copy_loop:
ld A, ([pRBC.w], X)
ld (RBC_Cmd, X), A
dec X
jrpl copy_loop
}
// unsigned char index;
// for (index = 16; index; ) {
// index--;
// RBC_Cmd[index] = pRBC[index];
// }
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Test_Ready
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
char RBC_Test_Ready(void)
{
return RBC_MAL_Error( MAL_Test_Ready() );
}
#pragma NO_ENTRY
unsigned short div16x16(unsigned short dividend, unsigned short divisor)
{
unsigned short quotient;
asm {
LD Y, #17
// shift out leading zero's of divisor
TNZ X
JRMI after_shift_divisor
shift_divisor:
INC Y
SLA A
RLC X
JRPL shift_divisor
after_shift_divisor:
LD divisor, X
LD divisor:1, A
// Initialize the quotient
LD A, #0xFF
LD quotient, A
LD quotient:1, A
// shift out leading zero's of dividend
LD X, dividend:1
LD A, dividend
JRMI after_shift_dividend
shift_dividend:
DEC Y
SLA X
RLC A
JRPL shift_dividend
after_shift_dividend:
; LD dividend, A
; LD dividend:1, X
compare_divisor:
CP A, divisor
JRULT shift_quotient
JRUGT subtract_divisor
CP X, divisor:1
JRUGE shift_8_bits
JRT shift_quotient
// JRULT shift_quotient
subtract_divisor:
PUSH A
LD A, X
SUB A, divisor:1
LD X, A
POP A
SBC A, divisor
shift_quotient:
RLC quotient:1
RLC quotient
DEC Y
JREQ return_quotient
// shift left the dividend
SLA X
RLC A
JRNC compare_divisor
PUSH A
LD A, X
SUB A, divisor:1
LD X, A
POP A
SBC A, divisor
RCF
JRT shift_quotient
shift_quotient_only:
LD A, quotient:1
LD X, quotient
RCF
shift_less8_bits:
RLC A
RLC X
DEC Y
JRNE shift_less8_bits
CPL A
CPL X
RET
shift_8_bits:
LD A, X
SUB A, divisor:1
LD X, A
LD A, Y
SUB A, #8
JRULT shift_quotient_only
LD Y, A
LD A, quotient:1
LD quotient, A
LD A, #0x7F
LD quotient:1, A
LD A, X
CLR X
CP Y, #0
JRNE compare_divisor
return_quotient:
}
return ~quotient;
}
static unsigned int _RBC_Percentage_Done()
{
/* Use following version if MAL_Capacity is 2^n
unsigned char Percent_Temp;
asm {
PUSH Y
LD A, MAL_Capacity:2
LD Percent_Temp, A
LD Y, Format_Blk_Done
LD X, Format_Blk_Done:1
CLR A
percent_shift:
SRA Percent_Temp
JRC percent_ret
SRA Y
RRC X
RRC A
JRT percent_shift
percent_ret:
POP Y
}
*/
// if (Format_Blk_Done == 0)
// return 1;
return div16x16(Format_Blk_Done, (unsigned short)MAL_Capacity);
// ((unsigned long)Format_Blk_Done << 16) / MAL_Capacity;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Request_Sense
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
char RBC_Request_Sense(void)
{
char Index;
for (Index = 20; Index > 0; ) {
Index--;
MSL_Param_Buffer[Index] = 0x0; // Clear all to zero
}
MSL_Param_Buffer[0] = 0x70; // Response Code
MSL_Param_Buffer[7] = 12; // Additional sense length
if (Sense_Head != Sense_Tail) {
MSL_Param_Buffer[2] = Sense_List[Sense_Head].Skey; // Sense Key
MSL_Param_Buffer[12]= Sense_List[Sense_Head].w.b.ASC; // Additional sense code
MSL_Param_Buffer[13]= Sense_List[Sense_Head].w.b.ASCQ; // Additional sense code qualifier
Sense_Head++;
if (Sense_Head == SENSE_LIST_DEEPTH)
Sense_Head = 0;
}
else if (MAL_State == MAL_FORMATTING || Format_Blk_Done) { // When formation is on going
#define pSense ((SENSE_DATA*)MSL_Param_Buffer)
Format_Blk_Done = (unsigned short)MAL_Capacity - MAL_Block_Numbers;
// if (Format_Blk_Done >= NextProgress) {
// FormatProgress += (Format_Flags & 0x01) ? 1 : 5;
// if (FormatProgress > 100)
// NextProgress = 0;
// else
// NextProgress = MAL_Capacity * FormatProgress / 100;
// }
pSense->Sense_Key = NOT_READY; // Sense Key
pSense->ASC = 0x04; // Additional sense code
pSense->ASCQ = 0x04; // Additional sense code qualifier
// FORMAT IN PROGRESS
pSense->TBD = 0x80; // Sense Key specific
pSense->Sense_Key_Specific = _RBC_Percentage_Done();
if (MAL_Block_Numbers == 0)
Format_Blk_Done = 0;
}
else // everything is allright, send back 0 !
;
MSL_Param_Size = 20;
return RBC_STATUS_GOOD;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Inquiry
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
char RBC_Inquiry(CMD_INQUIRY *pCmd) // char Page, unsigned long Length)
{
unsigned char Page = pCmd->Page;
unsigned char Length = pCmd->Allocation_Length;
unsigned char *pPage;
if (pCmd->CmdDt == 1) {
SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
return RBC_STATUS_FAIL;
}
if (pCmd->Evpd == 1) {
if (Page == 0x80) {
if (Length > LENGTH_INQUIRY_PAGE80)
Length = LENGTH_INQUIRY_PAGE80;
pPage = Page80_Inquiry_Data;
}
else if (Page == 0x83) {
if (Length > LENGTH_INQUIRY_PAGE83)
Length = LENGTH_INQUIRY_PAGE83;
pPage = Page83_Inquiry_Data;
}
else {
SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
return RBC_STATUS_FAIL;
}
}
else
if (Page == 0x00) {
if (Length > LENGTH_INQUIRY_PAGE00)
Length = LENGTH_INQUIRY_PAGE00;
pPage = Standard_Inquiry_Data;
}
else {
SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
return RBC_STATUS_FAIL;
}
MSL_Param_Size = Length;
while (Length) {
Length--;
MSL_Param_Buffer[Length] = pPage[Length];
}
return RBC_STATUS_GOOD;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Mode_Sense6(CMD_MSense6 *pCmd)
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
char RBC_Mode_Sense6(CMD_MODE_SENSE6 *pCmd)
{
unsigned char index;
if (pCmd->PC_Page != 0x3F && pCmd->PC_Page != 0x00) {
SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
return RBC_STATUS_FAIL;
}
index = MODE_SENSE6_LEN;
while (index) {
index--;
MSL_Param_Buffer[index] = MODE_SENSE6_data[index];
}
MSL_Param_Size = MODE_SENSE6_LEN;
if (isWRITE_PROTECT())
MSL_Param_Buffer[2] = 0x80;
return RBC_STATUS_GOOD;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Mode_Select6(CMD_MSelect6 *pCmd)
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
char RBC_Mode_Select6(CMD_MODE_SELECT6 *pCmd)
{
SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
return RBC_STATUS_FAIL;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Mode_Sense10(CMD_MSense10 *pCmd)
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
char RBC_Mode_Sense10(CMD_MODE_SENSE10 *pCmd)
{
unsigned char index;
if (pCmd->PC_Page != 0x3F) {
SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
return RBC_STATUS_FAIL;
}
index = MODE_SENSE10_LEN;
while (index) {
index--;
MSL_Param_Buffer[index] = MODE_SENSE10_data[index];
}
MSL_Param_Size = MODE_SENSE10_LEN;
if (isWRITE_PROTECT())
MSL_Param_Buffer[3] = 0x80;
return RBC_STATUS_GOOD;
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Read_Capacity
INPUT/OUTPUT : None
DESCRIPTION :
-----------------------------------------------------------------------------*/
char RBC_Read_Capacity(void)
{
unsigned char Errno;
Errno = RBC_MAL_Error( MAL_Read_Capacity() );
if (Errno != RBC_STATUS_GOOD)
return Errno;
MSL_Param_Size = 8;
if(!MAL_Mediano)
{
if((Windows_2000) && (Current_Mode == 2)) // Under Win2000 and Private Mode
{
if(Private_Zone_Size == 0)
*((unsigned long *)MSL_Param_Buffer) = 0;
else
*((unsigned long *)MSL_Param_Buffer) = (MAL_Capacity - Private_Zone_Size) - 1;
}
else{
if(Private_Zone_Size == 0)
*((unsigned long *)MSL_Param_Buffer) = MAL_Capacity - 1;
else{
if(!Current_Mode)
*((unsigned long *)MSL_Param_Buffer) = MAL_Capacity - 1;
else
*((unsigned long *)MSL_Param_Buffer) = Private_Zone_Size - 1;
}
}
}
else{
if(Private_Zone_Size == 0)
*((unsigned long *)MSL_Param_Buffer) = 0;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -