📄 drv_usb_scsi.c
字号:
/*************************************************
Copyright (C), 2008, DTK Computer.
File name: Scsi.c
Author: lihai
Version: 1.0
Date: 2008.04.28
Description: 实现USB驱动所需的SCSI命令相关函数功能
Others: 无
Function List:
RBC_Hander(void): 设备处理批量传输命令
SPC_InQuiry(): 主机获取设备信息
SPC_ModeSelect(): 主机设置设备参数
SPC_ModeSense(): 主机获取设备参数
RBC_Read10(): 设备读数据
RBC_ReadCapacity(): 主机获取设备介质容量
RBC_StartStop(): 主机启动/停止设备
SPC_RequestSense(): 主机获取设备执行结果及状态数据
SPC_FormatCapacity():主机获取设备格式化后的容量
SPC_TestUnit(): 主机查询设备是否处于ready状态
RBC_Verify(): 验证设备数据
RBC_Write10(): 设备写数据
SPC_LockMedia(): 设备设置写保护
SPC_Reserve(): 错误的命令处理
RBC_BuildSenseData():构造SenseData
History: 初稿
*************************************************/
#include "drv_usb_scsi.h"
extern D_INT32 drv_sd_read(D_INT32 LogicalBlockAddress,
D_INT32 * buff, D_UINT8 BlockNum);
extern D_INT32 drv_sd_write(D_INT32 LogicalBlockAddress,
D_INT32 *buff, D_UINT8 BlockNum);
extern D_INT32 Erase_Cluster(D_INT32 LogicalBlockAddress, D_INT32 BlockNum);
extern BULK_STRUCT Bulk_Block;
extern CONTROL_XFER ControlData;
extern EPPFLAGS bEPPflags;
BULK_CONTROL Bulk_Control_r;
BULK_CONTROL Bulk_Control_w;
D_UINT8 DataBuf[PAGESIZE*BLOCKSIZE];
D_UINT8 NoMedia = 0;
extern D_UINT8 CSWStatus;
#define CBW_bCBWCBLength Bulk_Block.cbw.dCBWDataTransferLength
/*设备信息*/
STD_INQUIRY_DATA inquiryData =
{
{
0x00, 0x80, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00
},
{
0x57, 0x45, 0x49, 0x4d, /*VendorInformation:WEIMING */
0x49, 0x4e, 0x47, 0x20
},
{
0x57, 0x4f, 0x52, 0x4b, /*ProductInformation:WORKING */
0x49, 0x4e, 0x47, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20
},
{
0x30, 0x00, 0x30, 0x31 /*ProductReisionLevel:0.01*/
}
};
/*设备参数*/
MODE_DATA ModeData =
{
3,/*D_UINT8 OperationCode; */
0,/*D_UINT8 Reserved0; */
0,/*D_UINT8 Reserved1 :7; */
0,/*D_UINT8 WP :1; */
0 /*D_UINT8 Reserved2; */
};
/*设备容量*/
READ_CAPACITY_DATA ReadCapacityData =
{
{
0,01,0xe4,0xbf/*D_UINT8 LogicalBlockAddress[4];*/
},
{
0,0,0x08,0/*D_UINT8 LogicalLength[4];*/
}
};
/*命令处理错误信息*/
REQUEST_SENSE_DATA RequestSenseData =
{
{
0xf0, 0x00 /*D_UINT8 Reserved0[2];*/
},
0x00,/* D_UINT8 SenseKey;*/
{
0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00/*D_UINT8 Reserved1[9];*/
},
0,/* D_UINT8 ASC;*/
0,/* D_UINT8 ASCQ;*/
{
0x00, 0x00, 0x00, 0x00/* D_UINT8 Reserved2[4];*/
}
};
/*************************************************
函数名称: D_BOOL RBC_Handler(void)
函数功能: 处理批量传输命令
被本函数调用的函数:
SPC_InQuiry(): 主机获取设备信息
SPC_ModeSelect6():主机设置设备参数
SPC_ModeSense6():主机获取设备参数
RBC_Read10():设备读数据
RBC_ReadCapacity():主机获取设备介质容量
RBC_StartStop():主机启动/停止设备
SPC_RequestSense():主机获取设备执行错误信息
SPC_FormatCapacity():主机获取设备格式化后的容量
SPC_TestUnit():主机查询设备是否处于ready状态
RBC_Verify10():主机验证设备中存储的数据是否正确
RBC_Write10():写数据
SPC_LockMedia():主机对设备设置写保护命令
SPC_Reserve6():错误的主机命令处理
调用本函数的函数:
访问到的全局变量: 无
被修改的全局变量: 无
输入参数: 无
输出参数: 无
函数返回值: 无
其它: 无
*************************************************/
D_BOOL RBC_Hander(void)
{
#define cdbGeneric Bulk_Block.cbw.CBWCB.RbcCdb_Generic
D_BOOL result = FALSE;
ControlData.wLength = 0;
switch (cdbGeneric.OperationCode)
{
/*主机获取设备信息*/
case SPC_CMD_INQUIRY:
result = SPC_InQuiry();
break;
/* 主机设置设备参数*/
case SPC_CMD_MODESELECT6:
result = SPC_ModeSelect6();
break;
/*主机获取设备参数*/
case SPC_CMD_MODESENSE6:
result = SPC_ModeSense6();
break;
/*设备读数据*/
case RBC_CMD_READ10:
result = RBC_Read10();
break;
/*主机获取设备介质容量*/
case RBC_CMD_READCAPACITY:
result = RBC_ReadCapacity();
break;
/*主机启动/停止设备*/
case RBC_CMD_STARTSTOPUNIT:
result = RBC_StartStop();
break;
/*主机获取设备执行结果及状态数据*/
case SPC_CMD_REQUESTSENSE:
result = SPC_RequestSense();
break;
/*主机获取设备格式化后的容量*/
case SPC_CMD_FORMAT_CAPACITY:
result = SPC_FormatCapacity();
break;
/*主机查询设备是否处于ready状态*/
case SPC_CMD_TESTUNITREADY:
result = SPC_TestUnit();
break;
/*验证设备数据*/
case RBC_CMD_VERIFY10:
result = RBC_Verify10();
break;
/*设备写数据*/
case RBC_CMD_WRITE10:
result = RBC_Write10();
break;
/*设备设置写保护*/
case SPC_CMD_PRVENTALLOWMEDIUMREMOVAL:
result = SPC_LockMedia();
break;
/*错误的命令处理*/
case SPC_CMD_RESERVE6:
default:
result = SPC_Reserve6();
break;
}
return result;
#undef cdbGeneric
}
/*************************************************
函数名称: D_BOOL SPC_InQuiry(void)
函数功能: 主机获取设备信息
被本函数调用的函数: Bulk_code_transmit:批量发送函数
调用本函数的函数: RBC_Handler():处理批量传输命令
访问到的全局变量: inquiryData:设备信息
被修改的全局变量: 无
输入参数: 无
输出参数: 无
函数返回值: 无
其它: 无
*************************************************/
D_BOOL SPC_InQuiry(void)
{
/*发送设备信息数据inquiryData*/
Bulk_code_transmit((D_UINT8*)&inquiryData,
sizeof(STD_INQUIRY_DATA));
return TRUE;
}
/*************************************************
函数名称: D_BOOL SPC_ModeSelect(void)
函数功能: 主机设置设备参数
被本函数调用的函数:
Bulk_ErrorHandler (): 处理状态控制
Bulk_CSWHandler (): 发送执行状态CSW
RBC_BuildSenseData():构造SenseData
调用本函数的函数: RBC_Handler():处理批量传输命令
访问到的全局变量: Bulk_Block:CBW数据
被修改的全局变量: 无
输入参数: 无
输出参数: 无
函数返回值: 无
其它: 无
*************************************************/
D_BOOL SPC_ModeSelect6(void)
{
/**********************************************
如果sp位被置1, 这个命令没有数据要返回。
直接写CSW, 置CSWStatus 为1. 并且保持,
当接收到下一个REQUEST_SENSE命令后置0。
( 也就是说, 这中间所有的CSW中的status为都为1。
**********************************************/
if (Bulk_Block.cbw.CBWCB.SpcCdb_ModeSelect.Sp == 1)
{
/*设置处理结果状态数据RequestSenseData*/
RBC_BuildSenseData(ILLEGAL_REQUEST, SCSI_ADSENSE_INVALID_CDB, 0);
/*构造应答CSW,处理状态CSW_FAIL*/
Bulk_ErrorHandler(CSW_FAIL, 0);
}
/*收到合法数据*/
else
{
Bulk_ErrorHandler(CSW_GOOD, 0);
}
Bulk_CSWHandler();
return TRUE;
}
/*************************************************
函数名称: D_BOOL SPC_ModeSense(void)
函数功能: 主机获取设备参数
被本函数调用的函数:
Bulk_code_transmit (): 批量发送函数
调用本函数的函数: RBC_Handler():处理批量传输命令
访问到的全局变量: ModeData:设备参数
被修改的全局变量: 无
输入参数: 无
输出参数: 无
函数返回值: 无
其它: 无
*************************************************/
D_BOOL SPC_ModeSense6(void)
{
/*发送设备参数ModeData*/
Bulk_code_transmit((D_UINT8*)&ModeData,
sizeof(MODE_DATA));
return TRUE;
}
/*************************************************
函数名称: D_BOOL RBC_Read10( )
函数功能: 设备读数据
被本函数调用的函数:
ReadPage():按照页,块读取U盘中的数据
Bulk_ErrorHandler():处理状态控制
USB_WriteEndpoint():向USB端点写入数据
调用本函数的函数: RBC_Handler():处理批量传输命令
访问到的全局变量: Bulk_Control_r:设备读数据的相关控制数据
被修改的全局变量: 无
输入参数: 无
输出参数: 无
函数返回值: 无
其它: 无
*************************************************/
D_BOOL RBC_Read10(void)
{
#define cdbRead10 Bulk_Block.cbw.CBWCB.RbcCdb_Read10
/*获取要读取的数据的地址、长度、起始块和页*/
D_INT32 i;
Bulk_Control_r.LogicalBlockAddress = 0;
Bulk_Control_r.Transfer_Length = 0;
for(i=0; i<4; i++)
{
Bulk_Control_r.LogicalBlockAddress =
Bulk_Control_r.LogicalBlockAddress * 0x100
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -