⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hostrbc.c

📁 smartARM2400 USB host例程
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************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 + -