📄 hostrbc.c
字号:
/*****************************Copyright(c)****************************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**------File Info-----------------------------------------------------------------------------------------
** File Name: rbc.c
** Latest modified Date: 2007-11-16
** Latest Version: V1.0
** Description: 实现RBC命令
**
**--------------------------------------------------------------------------------------------------------
** Created By: 吴隆穗 Longsui Wu
** Created date: 2007-11-18
** Version: V1.0
** Descriptions: 初始版本
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
*********************************************************************************************************/
#include "mshostconfig.h"
static USB_INT8U __GucMsCmdCnt = 0; /* 大容量类设备的命令调用次数 */
static USB_BOOL __GbHostMsExitReq = FALSE; /* 是否要求退出操作标志 */
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************************************************
** Function name: __rbcInit
** Descriptions: RBC层软件初始化
** input parameters: None
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void __rbcInit (void)
{
OS_ENTER_CRITICAL();
__GucMsCmdCnt = 0; /* 大容量类设备的命令调用次数 */
__GbHostMsExitReq = FALSE; /* 是否要求退出操作标志 */
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** Function name: __rbcDeInit
** Descriptions: RBC层软件卸载
** input parameters: None
** output parameters: None
** Returned value: TRUE: 成功, FALSE: 失败
*********************************************************************************************************/
USB_BOOL __rbcDeInit (void)
{
USB_INT32U i;
OS_ENTER_CRITICAL();
__GbHostMsExitReq = TRUE; /* 请求退出操作 */
OS_EXIT_CRITICAL();
i = 0;
while (__GucMsCmdCnt) { /* 等待退出操作完成 */
OSTimeDly(1);
if (i++ > OS_TICKS_PER_SEC * 10) { /* 最长等待时限为10s */
return FALSE;
}
}
return TRUE;
}
/*********************************************************************************************************
RBC 命令 (SCSI-2规范)
*********************************************************************************************************/
/*********************************************************************************************************
** Function name: rbcInquiry
** Descriptions: 查询设备信息
** input parameters: ucInterfaceIndex : 接口号
** ucLunIndex : LUN号
** output parameters: pucData : 读取到的设备信息
** Returned value: 错误代码,若返回MS_ERR_SUCESS, 说明执行成功, 否则执行失败
*********************************************************************************************************/
USB_INT8U rbcInquiry (USB_INT16U usInterface, USB_INT8U ucLunIndex, USB_INT8U *pucData)
{
__BULK_ONLY_CBW cbwInq;
USB_INT8U ucErrCode;
if ((pucData == NULL) || (ucLunIndex > MS_MAX_LUN)) {
return MS_ERR_INVALID_PARAM;
}
OS_ENTER_CRITICAL();
if (__GbHostMsExitReq) { /* 判断上层是否已要求退出 */
OS_EXIT_CRITICAL();
return MS_ERR_EXIT_REQ;
}
__GucMsCmdCnt++; /* 进入时执行命令计数器加1 */
OS_EXIT_CRITICAL();
usbMemSet(&cbwInq, 0 , sizeof(__BULK_ONLY_CBW));
/*
* 单批量传输的特征码:0x43425355(小端模式), 即:"USBC"(大端模式)
*/
cbwInq.dCBWSignature0 = 0x55; /* 'U' */
cbwInq.dCBWSignature1 = 0x53; /* 'S' */
cbwInq.dCBWSignature2 = 0x42; /* 'B' */
cbwInq.dCBWSignature3 = 0x43; /* 'C' */
/*
* 传输标志位,应为随机数,
* 但为加快程序执行速度,此处固定为0x01,0x02,0x03,0x04,而不是产生随机数
*/
cbwInq.dCBWTag0 = 0x01;
cbwInq.dCBWTag1 = 0x02;
cbwInq.dCBWTag2 = 0x03;
cbwInq.dCBWTag3 = 0x04;
/*
* CBW 和 CSW 间要传输的数据量
*/
cbwInq.dCBWDataTransferLength0 = 8; /* 将要读取的数据长度 */
cbwInq.dCBWDataTransferLength1 = 0x00;
cbwInq.bmCBWFlags = 0x80; /* 方向: BULK IN */
cbwInq.bCBWLUN = (USB_INT8U)(__msInfo.ucUsedLun[ucLunIndex] & 0x0F);
cbwInq.bCBWCBLength = 6;
cbwInq.CBWCB[0] = 0x12; /* 命令号:0x12 */
cbwInq.CBWCB[1] = (USB_INT8U)((__msInfo.ucUsedLun[ucLunIndex] & 0x07) << 5);
cbwInq.CBWCB[2] = 0;
cbwInq.CBWCB[4] = 8;
ucErrCode = __boSendCommand(&cbwInq, pucData);
if (ucErrCode != MS_ERR_SUCESS) {
ucErrCode = rbcRequestSense(ucLunIndex);
if ((ucErrCode != MS_ERR_SUCESS) && (ucErrCode != 0x06)) {
__boMassStorReset(usInterface);
}
}
OS_ENTER_CRITICAL();
__GucMsCmdCnt--; /* 退出时执行命令计数器减1 */
OS_EXIT_CRITICAL();
return ucErrCode;
}
/*********************************************************************************************************
** Function name: rbcReadCapacity
** Descriptions: 读取设备容量
** input parameters: usInterface : 接口号
** ucLunIndex : LUN号
** output parameters: puiMaxLba : 最大LBA
** puiBytesPerBlock : 每块字节数
** Returned value: 错误代码,若返回MS_ERR_SUCESS, 说明执行成功, 否则执行失败
*********************************************************************************************************/
USB_INT8U rbcReadCapacity (USB_INT16U usInterface,
USB_INT8U ucLunIndex,
USB_INT32U *puiMaxLba,
USB_INT32U *puiBytesPerBlock)
{
USB_INT8U ucBufTmp[8] = {0};
USB_INT8U ucErrCode;
__BULK_ONLY_CBW cbwInq;
if (ucLunIndex > __msInfo.ucMaxLun) {
return MS_ERR_INVALID_PARAM;
}
OS_ENTER_CRITICAL();
if (__GbHostMsExitReq) {
OS_EXIT_CRITICAL();
return MS_ERR_EXIT_REQ;
}
__GucMsCmdCnt++;
OS_EXIT_CRITICAL();
usbMemSet(&cbwInq, 0 , sizeof(__BULK_ONLY_CBW));
/*
* 单批量传输的特征码:0x43425355(小端模式), 即:"USBC"(大端模式)
*/
cbwInq.dCBWSignature0 = 0x55; /* 'U' */
cbwInq.dCBWSignature1 = 0x53; /* 'S' */
cbwInq.dCBWSignature2 = 0x42; /* 'B' */
cbwInq.dCBWSignature3 = 0x43; /* 'C' */
/*
* 传输标志位,应为随机数,
* 但为加快程序执行速度,此处固定为0x01,0x02,0x03,0x04,而不是产生随机数
*/
cbwInq.dCBWTag0 = 0x01;
cbwInq.dCBWTag1 = 0x02;
cbwInq.dCBWTag2 = 0x03;
cbwInq.dCBWTag3 = 0x04;
/*
* CBW 和 CSW 间要传输的数据量
*/
cbwInq.dCBWDataTransferLength0 = 8;
cbwInq.dCBWDataTransferLength1 = 0x00;
cbwInq.bmCBWFlags = 0x80; /* 方向: BULK IN */
cbwInq.bCBWLUN = (USB_INT8U)(__msInfo.ucUsedLun[ucLunIndex] & 0x0F);
cbwInq.bCBWCBLength = 10;
cbwInq.CBWCB[0] = 0x25;
cbwInq.CBWCB[1] = (USB_INT8U)((__msInfo.ucUsedLun[ucLunIndex] & 0x07) << 5);
cbwInq.CBWCB[2] = 0;
cbwInq.CBWCB[4] = 0;
ucErrCode = __boSendCommand(&cbwInq, ucBufTmp);
if (ucErrCode != MS_ERR_SUCESS) {
ucErrCode = rbcRequestSense(ucLunIndex);
if ((ucErrCode != MS_ERR_SUCESS) && (ucErrCode != 0x06)) {
__boMassStorReset(usInterface);
}
}
*puiMaxLba = (ucBufTmp[0] << 24) + (ucBufTmp[1] << 16) /* 该存储介质最后的 LBA */
+ (ucBufTmp[2] << 8) + ucBufTmp[3];
*puiBytesPerBlock = (ucBufTmp[4] << 24) + (ucBufTmp[5] << 16) /* 每块字节数 */
+ (ucBufTmp[6] << 8) + ucBufTmp[7];
OS_ENTER_CRITICAL();
__GucMsCmdCnt--;
OS_EXIT_CRITICAL();
return ucErrCode;
}
/*********************************************************************************************************
** Function name: rbcStartStopUnit
** Descriptions: 启动或停止设备(LUN)
** input parameters: ucInterfaceIndex : 接口号
** ucLunIndex : LUN号
** ucStatus : 状态,启动(RBC_MAKEREADY)或停止(RBC_STOPMEDIUM) LUN
** output parameters: None
** Returned value: 错误代码,若返回MS_ERR_SUCESS, 说明执行成功, 否则执行失败
*********************************************************************************************************/
USB_INT8U rbcStartStopUnit (USB_INT16U ucInterfaceIndex,
USB_INT8U ucLunIndex,
USB_INT8U ucStatus)
{
__BULK_ONLY_CBW cbwInq;
USB_INT8U ucErrCode;
OS_ENTER_CRITICAL();
if (__GbHostMsExitReq) {
OS_EXIT_CRITICAL();
return MS_ERR_EXIT_REQ;
}
__GucMsCmdCnt++;
OS_EXIT_CRITICAL();
usbMemSet(&cbwInq, 0 , sizeof(__BULK_ONLY_CBW));
/*
* 单批量传输的特征码:0x43425355(小端模式), 即:"USBC"(大端模式)
*/
cbwInq.dCBWSignature0 = 0x55; /* 'U' */
cbwInq.dCBWSignature1 = 0x53; /* 'S' */
cbwInq.dCBWSignature2 = 0x42; /* 'B' */
cbwInq.dCBWSignature3 = 0x43; /* 'C' */
/*
* 传输标志位,应为随机数,
* 但为加快程序执行速度,此处固定为0x01,0x02,0x03,0x04,而不是产生随机数
*/
cbwInq.dCBWTag0 = 0x01;
cbwInq.dCBWTag1 = 0x02;
cbwInq.dCBWTag2 = 0x03;
cbwInq.dCBWTag3 = 0x04;
/*
* CBW 和 CSW 间要传输的数据量
*/
cbwInq.dCBWDataTransferLength0 = 0;
cbwInq.dCBWDataTransferLength1 = 0;
cbwInq.dCBWDataTransferLength2 = 0;
cbwInq.dCBWDataTransferLength3 = 0;
cbwInq.bmCBWFlags = 0x80; /* 方向: BULK IN */
cbwInq.bCBWLUN = (USB_INT8U)(ucLunIndex & 0x0F);
cbwInq.bCBWCBLength = 6;
cbwInq.CBWCB[0] = SCSI_START_STOP; /* 操作码 */
cbwInq.CBWCB[4] = (USB_INT8U)(ucStatus & 0x03);
ucErrCode = __boSendCommand (&cbwInq, NULL);
if (ucErrCode == MS_ERR_CSW) {
__boMassStorReset(ucInterfaceIndex);
OS_ENTER_CRITICAL();
__GucMsCmdCnt--;
OS_EXIT_CRITICAL();
return SCSI_ERR_CMDEXE;
}
OS_ENTER_CRITICAL();
__GucMsCmdCnt--;
OS_EXIT_CRITICAL();
return ucErrCode;
}
/*********************************************************************************************************
** Function name: rbcRead10
** Descriptions: 读取数据
** input parameters: usInterface : 接口号
** ucLunIndex : LUN号
** uiLba : 块地址
** uiTranLen : 要读取的块数
** output parameters: pucData : 接收数据缓冲区
** Returned value: 错误代码,若返回MS_ERR_SUCESS, 说明执行成功, 否则执行失败
*********************************************************************************************************/
USB_INT8U rbcRead10 (USB_INT16U usInterface,
USB_INT8U ucLunIndex,
USB_INT32U uiLba, /* LBA,即逻辑块地址 */
USB_INT32U uiTranLen, /* 要读取的数据长度(块数) */
USB_INT8U *pucData) /* 接收数据缓冲区 */
{
__BULK_ONLY_CBW cbwInq;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -