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

📄 hostrbc.c

📁 smartARM2400 USB host例程
💻 C
📖 第 1 页 / 共 2 页
字号:
    USB_INT8U        ucErrCode;
   
    if ((pucData == NULL) || (uiTranLen == 0) || (ucLunIndex >= __msInfo.ucMaxLun) ||
        (uiLba + uiTranLen > __msInfo.msLunInfo[ucLunIndex].uiMaxLba)) {
        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;
    
    cbwInq.bmCBWFlags   = 0x80;                                         /*  方向: BULK IN               */
    cbwInq.bCBWLUN      = (USB_INT8U)(__msInfo.ucUsedLun[ucLunIndex] & 0x0F);
    cbwInq.bCBWCBLength = 10;
    
    cbwInq.CBWCB[0] = 0x28;                                             /*  操作码                      */
    cbwInq.CBWCB[1] = (USB_INT8U)((__msInfo.ucUsedLun[ucLunIndex] & 0x07) << 5);
    
    /*  
     *  CBW 和 CSW 间要传输的数据量
     */
    cbwInq.dCBWDataTransferLength0 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 0);
    cbwInq.dCBWDataTransferLength1 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 1);
    cbwInq.dCBWDataTransferLength2 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 2);
    cbwInq.dCBWDataTransferLength3 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 3);
    
    cbwInq.CBWCB[2] = __MSLSB(uiLba, 3);
    cbwInq.CBWCB[3] = __MSLSB(uiLba, 2);
    cbwInq.CBWCB[4] = __MSLSB(uiLba, 1);
    cbwInq.CBWCB[5] = __MSLSB(uiLba, 0);
    
    cbwInq.CBWCB[7] = __MSLSB(uiTranLen, 1);
    cbwInq.CBWCB[8] = __MSLSB(uiTranLen, 0);
    
    ucErrCode = __boSendCommand(&cbwInq, pucData);
    if (ucErrCode != MS_ERR_SUCESS) {
        if (ucErrCode == MS_ERR_CSW) {
            ucErrCode = rbcRequestSense (ucLunIndex);
            if ((ucErrCode != MS_ERR_SUCESS) && (ucErrCode != 0x06)) {
                __boMassStorReset(usInterface);
            }
        } else {
            __boMassStorReset(usInterface);
        }
    }
    
    OS_ENTER_CRITICAL();
    __GucMsCmdCnt--;
    OS_EXIT_CRITICAL();
    
    return ucErrCode;
}

/*********************************************************************************************************
** Function name:       rbcWrite10
** Descriptions:        读取数据
** input parameters:    usInterface : 接口号
**                      ucLunIndex  : LUN号
**                      uiLba       : 块地址
**                      uiTranLen   : 要写的块数
** output parameters:   pucData     : 写数据缓冲区
** Returned value:      错误代码,若返回MS_ERR_SUCESS, 说明执行成功, 否则执行失败
*********************************************************************************************************/
USB_INT8U rbcWrite10 (USB_INT16U usInterface,
                      USB_INT8U  ucLunIndex,
                      USB_INT32U uiLba,                                 /*  LBA,即逻辑块地址            */
                      USB_INT32U uiTranLen,                             /*  要读取的数据长度            */
                      USB_INT8U *pucData)                               /*  接收数据缓冲区              */
{
    USB_INT8U       ucErrCode;
    __BULK_ONLY_CBW cbwInq;
    
    if ((pucData == NULL) || (uiTranLen == 0) || (ucLunIndex >= __msInfo.ucMaxLun) ||
        (uiLba + uiTranLen > __msInfo.msLunInfo[ucLunIndex].uiMaxLba)) {
        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;
    
    cbwInq.bmCBWFlags   = 0x00;                                         /*  方向: BULK IN               */
    cbwInq.bCBWLUN      = (USB_INT8U)(__msInfo.ucUsedLun[ucLunIndex] & 0x0F);
    cbwInq.bCBWCBLength = 10;
    
    cbwInq.CBWCB[0] = 0x2A;                                             /*  操作码                      */
    cbwInq.CBWCB[1] = (USB_INT8U)((__msInfo.ucUsedLun[ucLunIndex] & 0x07) << 5);
    
    /*  
     *  CBW 和 CSW 间要传输的数据量
     */
    cbwInq.dCBWDataTransferLength0 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 0);
    cbwInq.dCBWDataTransferLength1 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 1);
    cbwInq.dCBWDataTransferLength2 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 2);
    cbwInq.dCBWDataTransferLength3 = __MSLSB(uiTranLen * \
                                             __msInfo.msLunInfo[ucLunIndex].uiBytesPerBlock, 3);
        
    cbwInq.CBWCB[2] = __MSLSB(uiLba, 3);
    cbwInq.CBWCB[3] = __MSLSB(uiLba, 2);
    cbwInq.CBWCB[4] = __MSLSB(uiLba, 1);
    cbwInq.CBWCB[5] = __MSLSB(uiLba, 0);
    
    cbwInq.CBWCB[7] = __MSLSB(uiTranLen, 1);
    cbwInq.CBWCB[8] = __MSLSB(uiTranLen, 0);
    
    ucErrCode = __boSendCommand(&cbwInq, pucData);
    if (ucErrCode != MS_ERR_SUCESS) {
        if (ucErrCode == MS_ERR_CSW) {
            ucErrCode = rbcRequestSense (ucLunIndex);
            if ((ucErrCode != MS_ERR_SUCESS) && (ucErrCode != 0x06)) {
                __boMassStorReset(usInterface);
            }
        } else {
            __boMassStorReset(usInterface);
        } 
    }
    
    OS_ENTER_CRITICAL();
    __GucMsCmdCnt--;
    OS_EXIT_CRITICAL();
    
    return ucErrCode;
}

/*********************************************************************************************************
** Function name:       rbcRequestSense
** Descriptions:        读取判别数据
** input parameters:    ucLunIndex : LUN号
** output parameters:   None
** Returned value:      错误代码,若返回MS_ERR_SUCESS, 说明执行成功, 否则执行失败
*********************************************************************************************************/
USB_INT8U rbcRequestSense (USB_INT8U ucLunIndex)
{
    __BULK_ONLY_CBW cbwInq;
    USB_INT8U       ucErrCode;
    USB_INT8U       ucBufTmp[18] = {0};
    USB_INT8U       ucTryCount;
    
    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 = 18;
    cbwInq.dCBWDataTransferLength1 = 0;
    cbwInq.dCBWDataTransferLength2 = 0;
    cbwInq.dCBWDataTransferLength3 = 0;
    
    cbwInq.bmCBWFlags   = 0x80;                                         /*  方向: BULK IN               */
    cbwInq.bCBWLUN      = (USB_INT8U)(__msInfo.ucUsedLun[ucLunIndex] & 0x0F);
    cbwInq.bCBWCBLength = 6;
    
    cbwInq.CBWCB[0] = 0x03;                                             /*  操作码                      */
    cbwInq.CBWCB[4] = 18;
    
    ucTryCount = 0;
    do {
        ucErrCode = __boSendCommand(&cbwInq, ucBufTmp);
        if ((ucErrCode == MS_ERR_CSW) || (ucErrCode == USB_ERR_DEVICE_NOT_READY)) {
            OS_ENTER_CRITICAL();
            __GucMsCmdCnt--;
            OS_EXIT_CRITICAL();
            return SCSI_ERR_CMDEXE;
        }
        
        ucErrCode = (USB_INT8U)(ucBufTmp[2] & 0x0F);
    } while ((ucErrCode == 0x0B) && (++ucTryCount <= 2));
    
    
    OS_ENTER_CRITICAL();
    __GucMsCmdCnt--;
    OS_EXIT_CRITICAL();
    
    return ucErrCode;
}

/*********************************************************************************************************
** Function name:       rbcTestUintReady
** Descriptions:        测试设备是否准备好
** input parameters:    usInterface : 接口号
**                      ucLunIndex  : LUN号
** output parameters:   None
** Returned value:      错误代码,若返回MS_ERR_SUCESS, 说明执行成功, 否则执行失败
*********************************************************************************************************/
USB_INT8U rbcTestUintReady (USB_INT16U usInterface, USB_INT8U ucLunIndex)
{
    __BULK_ONLY_CBW cbwInq;
    USB_INT8U       ucErrCode;
    
    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 = 0;
    cbwInq.dCBWDataTransferLength1 = 0;
    cbwInq.dCBWDataTransferLength2 = 0;
    cbwInq.dCBWDataTransferLength3 = 0;
    
    cbwInq.bmCBWFlags   = 0x80;                                         /*  方向: BULK IN               */
    cbwInq.bCBWLUN      = (USB_INT8U)(ucLunIndex & 0x0F);               /*  LUN号                       */
    cbwInq.bCBWCBLength = 6;                                            /*  命令块有效长度:6            */
    
    cbwInq.CBWCB[0] = SCSI_TEST_UNIT_READY;                             /*  操作码:测试设备是否准备好   */
    
    ucErrCode = __boSendCommand (&cbwInq, NULL);                        /*  发送命令                    */
    if ((ucErrCode == MS_ERR_CSW) || (ucErrCode == USB_ERR_DEVICE_NOT_READY)) {
        __boMassStorReset(usInterface);
        OS_ENTER_CRITICAL();
        __GucMsCmdCnt--;
        OS_EXIT_CRITICAL();
        return SCSI_ERR_CMDEXE;
    } else if (ucErrCode == 0x01) {
        rbcRequestSense (ucLunIndex);
    }
    
    if (ucErrCode == SCSI_CHECK_CONDITION) {
        ;
    }
    
    OS_ENTER_CRITICAL();
    __GucMsCmdCnt--;                                                    /*  退出时执行命令计数器减1     */
    OS_EXIT_CRITICAL();
    
    return ucErrCode;
}

#ifdef __cplusplus
 }
#endif

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -