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

📄 bulkonly.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************
********************
* Module History
********************
*2007-6-20 10:10 Created by Oli
*********************************************************************/
/*********************************************************************
* Support the SCSI command
*********************************************************************/
#include "hw_include.h"
#include "usb.h"
#include "hw_memmap.h"
#include "hw_common.h"
#include "BulkOnly.h"
#include "hwapi_cache.h"
#include "usbblock.h"

#include "include.h"

#define USB_WRITE_BUF_EN    1

USB_MSDC_CBW  *pCBW;
UINT8               SCSIDATA_RequestSense[18];
UINT8               *pBulkOutDataBuff;
UINT8 volatile      UsbStatus;

UINT8               G_ucBulkStausPhase;
INT32               dCSWDataResidueVal;
USB_MSDC_CSW      gCSW;
UINT8               *pBulkInDataBuff  ;
UINT16              BulkEndpSize;
UINT8               G_ucBulkPhase;   //BULK命令阶段状态字
extern      UINT8   Bulk_buf[4096];
UINT32  SCSI_BulkOutDataLen;
extern UINT8 volatile SCSI_MediaReady;   //BULK命令阶段状态字
static uint8 MediaChange[4]; //add by lxs @2008.02.22


__align(4) UINT8 SCSIDATA_RequestSense[] =
{
    0x70,               //information filed is invalid=0x70,information filed is valid=0xf0,
    0x00,               //reserve
    0x05,               //Sense Key[3...0]
    0x00, 0x00, 0x00, 0x00, //information
    0x0a,               //Addition Sense Length
    0x00, 0x00, 0x00, 0x00, //reserve
    0x20,               //Additional Sense Code(ASC)
    0x00,               //Additional Sense Code Qualifier(ASCQ)
    0x00,               //reserve
    0x00, 0x00, 0x00,   //reserve
};

__align(4) UINT8 InquirySupportedData[] =
{
    0x00,
    SUPPORTED_PAGES,
    0x00,
    0x03,
    SERIAL_NUMBER_PAGE,
    DEVICE_INDENIFICATION_PAGE
};
__align(4) UINT8 InquirySnData[] =
{
    0x00,
    SERIAL_NUMBER_PAGE,
    0x00,
    20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20,
    0x20
};
__align(4) UINT8 InquiryDeviceData[] =
{
    0x00,
    DEVICE_INDENIFICATION_PAGE,
    0x00,
    26,
    0x02,
    0x01,
    0x00,
    22,
    'R', 'o', 'c', 'k', 'c', 'h', 'i', 'p', ' ',
    'U', 's', 'b', ' ', 'M', 'p', '3', ' ',
    ' ', ' ', ' ', ' '
};

__align(4) UINT8  SCSIDATA_Sense[] =
{
#if (CD_ROM==1)
    0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0a,
    0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

//  0x01, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
//  0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
#else
    0x03, 0x00, 0x00, 0x00, //第3字节为0x80表示写保护
    0x01, 0x0a, 0x00, 0x10,
    0x00, 0x00, 0x00, 0x00
#endif
#if 0
    0x02, 0x00, 0x00, 0x00, //page 1
    0x05, 0x1e, 0x0f, 0xa0, //page 2
    0x04, 0x10, 0x02, 0x00,
    0x00, 0xfa, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
#endif
};


void SCSICMD_Read12(void);
/***************************************************************************
16位数据大小端转换
***************************************************************************/
UINT16 Swap16(UINT16 input)
{
    return ((input >> 8) | (input << 8));
}

/***************************************************************************
32位数据大小端转换
***************************************************************************/
UINT32 Swap32(UINT32 input)
{
    return ((input >> 24) | (input << 24) | (input >> 8&0xff00) | (input << 8&0xff0000));
}
/********************************************************************
Routine  :  UsbBulkInPacket
Input  :  None
Output  :  None
Function :  ...
*********************************************************************/
extern MSC_DEVICE          gUsbMscDevice[4];
void BulkInIoDoneCallback(void);
extern UINT32 uCurrentBulklPacketSize;
void UsbBulkInPacket(void)
{
    UINT32 TX_Status;
    //TX_Status = TX2_STATUS;
    return;
    if (TX_Status & (/*TxVOID|*/TxERR))
    {
        return;
    }
    else
    {
        TX_Status &= 0x7ff;
    }

    if (G_ucBulkStausPhase == K_InDataPhase)
    {
        pBulkInDataBuff = UsbBlkBulkInDataPack(BulkEndpSize);

        if (pBulkInDataBuff)
        {
            UsbWriteDataEP(BulkEndpSize, pBulkInDataBuff);
        }
    }
}

void BulkInIoDoneCallback(void)
{
    SendCSW();
    G_ucBulkStausPhase = K_CommandPhase;
    G_ucBulkPhase = K_CommandPhase;
}
/***************************************************************************
批量数据传输BulkOnly命令解释
***************************************************************************/
void BulkOutIoDoneCallback(void);
void UsbBulkOutPacket(void)  //NOT OK
{
#if (USB_WRITE_BUF_EN==0)
    MSC_DEVICE *pMscDev;
#endif

    UINT32 len;
    len = RX1_STATUS;//2007-8-31 10:47

    if (len & (RxOVF | RxERR | RxVOID))
    {
        len = 0;
        return;
    }
    else
        len &= 0x7ff;

    if (len == 0)        //无数据返回
    {
        return;
    }

    //接收命令
    if (G_ucBulkPhase == K_CommandPhase)
    {
        Cache_FlushDataLine((UINT32)(Bulk_buf), 64);
        (UINT8 *)pCBW = (Bulk_buf);
        pCBW->LBA = Swap32(pCBW->LBA);
        pCBW->Len = Swap16(pCBW->Len);

        if (CBWValidVerify() == OK)
        {
            BulkOnlyCmd();
        }
        else
        {
            CSWHandler(CASECBW, 0);
        }
    }
    //接收数据
    else if (G_ucBulkPhase == K_OutDataPhase)
    {
#if (USB_WRITE_BUF_EN)
        //printf("out while %x %x %x\n",pBulkOutDataBuff,dCSWDataResidueVal,SCSI_BulkOutDataLen);
        pBulkOutDataBuff = UsbBlkBulkOutDataPack(len);
        UsbReadyToReadDataEP(pBulkOutDataBuff);
        //printf("write ep2 \n");
#endif
#if 0//(USB_WRITE_BUF_EN)
        do
        {
            //printf("out \n");

            //printf("out while %x %x %x\n",pBulkOutDataBuff,dCSWDataResidueVal,SCSI_BulkOutDataLen);
            if (dCSWDataResidueVal == SCSI_BulkOutDataLen)
            {
                //printf("break \n");
                break;
            }
            pBulkOutDataBuff = UsbBlkBulkOutDataPack(len);

            UsbReadyToReadDataEP(pBulkOutDataBuff);
            SCSI_BulkOutDataLen = SCSI_BulkOutDataLen + len;
            //printf("write ep2 \n");

        }
        while (ReadReg32(UDC_RX1STAT) & RxFULL);
#endif
        ///////////////

    }
}

void BulkOutIoDoneCallback(void)
{
    SendCSW();
    G_ucBulkPhase = K_CommandPhase;
    UsbStatus = USB_XFER_IDLE;
}

/***************************************************************************
批量数据传输BulkOnly命令解释
***************************************************************************/
void BulkOnlyCmd(void)
{
    switch (pCBW->Code)
    {
            //6-byte command
        case K_SCSICMD_TEST_UNIT_READY:  //0x00
            SCSICMD_TestUnitReady();
            break;
        case K_SCSICMD_REQUEST_SENSE:   //0x03
            SCSICMD_RequestSense();
            break;
        case K_SCSICMD_INQUIRY:    //0x12
            SCSICMD_Inquiry();
            break;
        case K_SCSICMD_MODE_SENSE_06:   //0x1a
            SCSICMD_ModeSense06();
            break;
        case K_SCSICMD_PREVENT_ALLOW_MEDIUM_REMOVAL:  //0x1e
            SCSICMD_PreventAllowMediumRemoval();
            break;
        case K_SCSICMD_START_STOP_UNIT:  //0x1b
            SCSICMD_StartStopUnit();
            break;

            //10-byte command
        case K_SCSICMD_READ_CAPACITY:   //0x25
            SCSICMD_ReadCapacity();
            break;
        case K_SCSICMD_READ_10:    //0x28
            SCSICMD_Read10();
            break;
        case K_SCSICMD_WRITE_10:    //0x2a
            G_ucBulkPhase = K_OutDataPhase;
            SCSICMD_Write10();
            break;
        case K_SCSICMD_VERIFY_10:    //0x2f
            SCSICMD_Verify10();
            break;
        case K_SCSICMD_MODE_SENSE_10:   //0x5a
            SCSICMD_ModeSense10();
            break;

            //12-byte command
        case K_SCSICMD_READ_FORMAT_CAPACITIES:          //0x23
            SCSICMD_ReadFormatCapacities();
            break;

        case K_SCSICMD_READ_12:
            SCSICMD_Read12();
            break;
        default:
            CSWHandler(CASECBW, 0);
            BuildSenseData(SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_ILLEGAL_COMMAND, 0);
            break;
    }
}
/***************************************************************************
功能:命令块有效校验
入口:无
出口:OK=命令块格式正确,ERROR=命令块格式出错
***************************************************************************/
BOOL CBWValidVerify(void)  //ok
{
    if (pCBW->dCBWSignature == 0x43425355  //CBW_SIGNATURE校对
            && pCBW->bCBWLUN < 10/*MAX_LUN*/ && pCBW->bCBWCBLength <= MAX_CDBLEN)     //LUN和命令块长度校对
        return(OK);  //有效返回
    else
        return(ERROR); //无效返回
}



/***************************************************************************
功能:CSW处理
入口:HostDevCase=状态,DeviceTrDataLen=设备要发送的数据长度
出口:无
***************************************************************************/
void CSWHandler(UINT8 HostDevCase, UINT16 DeviceTrDataLen)
{
    gCSW.dCSWSignature = 0x53425355;
    gCSW.dCSWTag = pCBW->dCBWTag;
    gCSW.dCSWDataResidue = (pCBW->dCBWDataTransferLength - DeviceTrDataLen);

    switch (HostDevCase)
    {
        case CASEOK:
        case CASE1:  /* Hn=Dn*/
        case CASE6:  /* Hi=Di*/
        case CASE12: /* Ho=Do*/
            gCSW.bCSWStatus = CSW_GOOD;
            break;

        case CASE4:  /* Hi>Dn*/
        case CASE5:  /* Hi>Di*/
        case CASE9:  /* Ho>Dn*/
        case CASE11: /* Ho>Do*/
            gCSW.bCSWStatus = CSW_GOOD; //CSW_GOOD or CSW_FAIL
            break;

        case CASE2:  /* Hn<Di*/
        case CASE3:  /* Hn<Do*/
        case CASE7:  /* Hi<Di*/
        case CASE8:  /* Hi<>Do */
        case CASECMDFAIL:
            //2007-6-13 23:42MUSBHSFC_SetEndpointStatus(3, 1);  //stall IN endpoint
            //?将out ep置stall
            gCSW.bCSWStatus = CSW_PHASE_ERROR;
            break;

        case CASE13: /* Ho<Do*/
            //2007-6-13 23:42MUSBHSFC_SetEndpointStatus(2, 1);
            //?将in ep置stall
            gCSW.bCSWStatus = CSW_FAIL;
            break;
        case CASE10: /* Ho<>Di */
        case CASECBW: /* invalid CBW */
            WriteReg32(UDC_TX2CON, ReadReg32(UDC_TX2CON) | (1 << 13));
            gCSW.bCSWStatus = CSW_FAIL;
            break;

        default:
            break;
    }
}

/***************************************************************************
功能:拷贝FLASH的后面PAGE
入口:无
出口:无
***************************************************************************/
void CopyFlashReside(void)
{
    //serial_printf(" CopyFlashReside\n");
}

/***************************************************************************
功能:回送CSW
入口:无
出口:无
***************************************************************************/
void SendCSW(void)//ok
{
    UsbWriteDataEP(13, (UINT8*)&gCSW);
    UsbReadyToReadDataEP(Bulk_buf);
    G_ucBulkPhase = K_CommandPhase;
    G_ucBulkStausPhase = K_CommandPhase;
}


/***************************************************************************
功能:建立 sense
入口:
出口:无
***************************************************************************/
void BuildSenseData(UINT8 SenseKey, UINT8 ASC, UINT8 ASCQ)//ok
{
    SCSIDATA_RequestSense[0] = 0x70;  //information filed is invalid=0x70,information filed is valid=0xf0,
    SCSIDATA_RequestSense[1] = 0x00;  //reserve
    SCSIDATA_RequestSense[2] = SenseKey;

    SCSIDATA_RequestSense[3] = 0x00;  //information
    SCSIDATA_RequestSense[4] = 0x00;
    SCSIDATA_RequestSense[5] = 0x00;
    SCSIDATA_RequestSense[6] = 0x00;

    SCSIDATA_RequestSense[7] = 0x0a;  //Addition Sense Length

    SCSIDATA_RequestSense[8] = 0x00;  //reserve
    SCSIDATA_RequestSense[9] = 0x00;
    SCSIDATA_RequestSense[10] = 0x00;
    SCSIDATA_RequestSense[11] = 0x00;

    SCSIDATA_RequestSense[12] = ASC;
    SCSIDATA_RequestSense[13] = ASCQ;

    SCSIDATA_RequestSense[14] = 0x00;  //reserve
    SCSIDATA_RequestSense[15] = 0x00;
    SCSIDATA_RequestSense[16] = 0x00;
    SCSIDATA_RequestSense[17] = 0x00;
}

extern  UINT8   g_pmid[16];
/***************************************************************************
函数描述:修改DRM9 ID值
入口参数:
出口参数:
调用函数:
***************************************************************************/
void Modify_DRM9ID()
{
    UINT32 i;

    InquirySnData[3] = 16;

    for (i = 0;i < 16; i++)
    {
        InquirySnData[i+4] = g_pmid[i];
    }
}

/********************************************************************
  SCSI COMMAND
********************************************************************/
/***************************************************************************
命令:查询0x12
***************************************************************************/
void SCSICMD_Inquiry(void)
{
    UINT8 t;
    MSC_PROPERTIES p;
    MSC_STATUS     MediaStatus;

⌨️ 快捷键说明

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