📄 lun.c
字号:
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2005
*
* File name : lun0.c
* Description : USB Mass storage device LUNs
*
* History :
* 1. Data : November 15, 2005
* Author : Stanimir Bonev
* Description : Create
*
* $Revision: 1.2.2.1 $
**************************************************************************/
#define LUN_GOBALS
#include "lun.h"
#define LCD_BACKLIGHT_ON() (IO0SET_bit.P0_21 = 1)
#define LCD_BACKLIGHT_OFF() (IO0CLR_bit.P0_21 = 1)
LunFpnt_t LunFun [SCSI_LUN_NUMB] =
{
// Lun0
{
// Init
NULL,
// Info
NULL,
// Status
NULL,
// Io
NULL,
},
// Lun1
{
// Init
NULL,
// Info
NULL,
// Status
NULL,
// Io
NULL,
},
};
#pragma location="DMA_RAM"
#pragma data_alignment=4
__no_init Int8U Lun0Buffer[2048];
/*************************************************************************
* Function Name: LunInit
* Parameters: Int32U LunInd,
* DiskInitFpnt_t DiskInitFpnt, DiskInfoFpnt_t DiskInfoFpnt,
* DiskStatusFpnt_t DiskStatusFpnt, DiskIoFpnt_t, DiskIoFpnt
*
* Return: none
*
* Description: LUN Init
*
*************************************************************************/
void LunInit (Int32U LunInd,
DiskInitFpnt_t DiskInitFpnt, DiskInfoFpnt_t DiskInfoFpnt,
DiskStatusFpnt_t DiskStatusFpnt, DiskIoFpnt_t DiskIoFpnt)
{
LunFun[LunInd].DiskInitFpnt = DiskInitFpnt;
LunFun[LunInd].DiskInfoFpnt = DiskInfoFpnt;
LunFun[LunInd].DiskStatusFpnt = DiskStatusFpnt;
LunFun[LunInd].DiskIoFpnt = DiskIoFpnt;
}
/*************************************************************************
* Function Name: LunImp
* Parameters: none
*
* Return: none
*
* Description: LUN commands implementation
*
*************************************************************************/
void LunImp (Int32U LunInd)
{
static LunState_t LunState;
static Int32U BlockStart, BlockNum;
pLunFpnt_t Lun = &LunFun[LunInd];
pDiskStatus_t pDiskStatus;
if(pScsiMessage[LunInd] == NULL)
{
return;
}
// Get a message
Int32U Message = *pScsiMessage[LunInd];
pInt32U pMessage = pScsiMessage[LunInd]+1;
// Clear the message pointer
pScsiMessage[LunInd] = NULL;
if (Message == LunInitMsg)
{
Lun->DiskInitFpnt();
LunState = LunCommandDecode;
return;
}
if (Message == LunResetReqMsg)
{
LunState = LunCommandDecode;
return;
}
switch (LunState)
{
case LunCommandDecode:
switch (Message)
{
case LunInquiryReqMsg:
ScsiInquiryData(Lun0Buffer,Lun->DiskInfoFpnt(Lun0Buffer,DiskInquiry));
break;
case LunTestUntilReadyReqMsg:
pDiskStatus = Lun->DiskStatusFpnt();
switch (pDiskStatus->DiskStatus)
{
case DiskCommandPass:
if (pDiskStatus->MediaChanged)
{
ScsiTestUntilReadyData(ScsiMediaChanged);
pDiskStatus->MediaChanged = FALSE;
}
else
{
ScsiTestUntilReadyData(ScsiCommandNoKey);
}
break;
case DiskNotReady:
ScsiTestUntilReadyData(ScsiMediamNotReady);
break;
case DiskNotPresent:
ScsiTestUntilReadyData(ScsiMediaNotPresent);
break;
case DiskChanged:
ScsiTestUntilReadyData(ScsiMediaChanged);
break;
default:
ScsiTestUntilReadyData(ScsiFatalError);
break;
}
break;
case LunModeSense6ReqMsg:
ScsiModeSenseData(Lun->DiskStatusFpnt()->WriteProtect);
break;
case LunReadFormatCapacityReqMsg:
ScsiReadFormatCapcityData(Lun0Buffer,Lun->DiskInfoFpnt(Lun0Buffer,DiskFormatCapacity));
break;
case LunReadCapacity10ReqMsg:
ScsiReadCapacityData(Lun->DiskStatusFpnt()->BlockNumb-1,
Lun->DiskStatusFpnt()->BlockSize);
break;
case LunRead10ReqMsg:
BlockStart = *pMessage;
BlockNum = *++pMessage;
if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
{
ScsiCmdError(ScsiInvalidCbd,ScsiStallIn);
break;
}
switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskRead))
{
case DiskCommandPass:
ScsiReadData(Lun0Buffer,
Lun->DiskStatusFpnt()->BlockSize,
(--BlockNum == 0));
if(BlockNum)
{
LunState = LunRead;
}
break;
case DiskNotReady:
// the Media not ready
ScsiCmdError(ScsiMediamNotReady,ScsiStallIn);
break;
case DiskNotPresent:
// the Media not present
ScsiCmdError(ScsiMediaNotPresent,ScsiStallIn);
break;
default:
ScsiCmdError(ScsiFatalError,ScsiStallIn);
break;
}
break;
case LunWrite10ReqMsg:
BlockStart = *pMessage;
BlockNum = *++pMessage;
if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
{
ScsiCmdError(ScsiInvalidCbd,ScsiStallOut);
break;
}
ScsiWriteData(Lun0Buffer,
Lun->DiskStatusFpnt()->BlockSize,
FALSE);
LunState = LunWrite;
break;
case LunVerify10BytChkReqMsg:
BlockStart = *pMessage;
BlockNum = *++pMessage;
if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
{
ScsiCmdError(ScsiInvalidCbd,ScsiStallOut);
break;
}
ScsiWriteData(Lun0Buffer,
Lun->DiskStatusFpnt()->BlockSize,
FALSE);
LunState = LunVerify;
break;
case LunVerify10ReqMsg:
BlockStart = *pMessage;
BlockNum = *++pMessage;
if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
{
ScsiCmdError(ScsiInvalidCbd,ScsiStallOut);
break;
}
// Always pass
ScsiWriteData(NULL,0,TRUE);
break;
default:
// Unknow command
ScsiCmdError(ScsiUnknowCommand,ScsiStallBoth);
break;
}
break;
case LunRead:
switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskRead))
{
case DiskCommandPass:
ScsiReadData(Lun0Buffer,
Lun->DiskStatusFpnt()->BlockSize,
(--BlockNum == 0));
if(BlockNum == 0)
{
LunState = LunCommandDecode;
}
break;
case DiskNotReady:
// the Media not ready
ScsiCmdError(ScsiMediamNotReady,ScsiStallIn);
LunState = LunCommandDecode;
break;
case DiskNotPresent:
// the Media not present
ScsiCmdError(ScsiMediaNotPresent,ScsiStallIn);
LunState = LunCommandDecode;
break;
default:
ScsiCmdError(ScsiFatalError,ScsiStallIn);
LunState = LunCommandDecode;
break;
}
break;
case LunWrite:
if(Message == LunDataReadyMsg)
{
switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskWrite))
{
case DiskCommandPass:
if(--BlockNum == 0)
{
ScsiWriteData(NULL,0,TRUE);
LunState = LunCommandDecode;
}
else
{
ScsiWriteData(Lun0Buffer,
Lun->DiskStatusFpnt()->BlockSize,
FALSE);
}
break;
case DiskNotReady:
// the Media not ready
ScsiCmdError(ScsiMediamNotReady,ScsiStallOut);
LunState = LunCommandDecode;
break;
case DiskNotPresent:
// the Media not present
ScsiCmdError(ScsiMediaNotPresent,ScsiStallOut);
LunState = LunCommandDecode;
break;
default:
ScsiCmdError(ScsiFatalError,ScsiStallOut);
LunState = LunCommandDecode;
break;
}
}
else
{
LunState = LunCommandDecode;
}
break;
case LunVerify:
if(Message == LunDataReadyMsg)
{
switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskVerify))
{
case DiskCommandPass:
if(--BlockNum == 0)
{
ScsiWriteData(NULL,0,TRUE);
LunState = LunCommandDecode;
}
else
{
ScsiWriteData(Lun0Buffer,
Lun->DiskStatusFpnt()->BlockSize,
FALSE);
}
break;
case DiskMiscompareError:
ScsiCmdError(ScsiMediaNotPresent,ScsiStallOut);
LunState = LunCommandDecode;
break;
case DiskNotReady:
// the Media not ready
ScsiCmdError(ScsiMediamNotReady,ScsiStallOut);
LunState = LunCommandDecode;
break;
case DiskNotPresent:
// the Media not present
ScsiCmdError(ScsiMediaNotPresent,ScsiStallOut);
LunState = LunCommandDecode;
break;
default:
ScsiCmdError(ScsiFatalError,ScsiStallOut);
LunState = LunCommandDecode;
break;
}
}
else
{
LunState = LunCommandDecode;
}
break;
default:
// something is wrong
ScsiCmdError(ScsiFatalError,ScsiStallBoth);
LunState = LunCommandDecode;
break;
}
if(LunState != LunCommandDecode)
{
LCD_BACKLIGHT_ON();
}
else
{
LCD_BACKLIGHT_OFF();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -