176af099aSliuyi /*
276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi * Seth Liu 2017.03.01
476af099aSliuyi *
576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+
676af099aSliuyi */
776af099aSliuyi
876af099aSliuyi #include "RKComm.h"
976af099aSliuyi #include "RKLog.h"
1076af099aSliuyi #include "Endian.h"
1176af099aSliuyi extern unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber);
CRKComm(CRKLog * pLog)1276af099aSliuyi CRKComm::CRKComm(CRKLog *pLog)
1376af099aSliuyi {
1476af099aSliuyi memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC));
1576af099aSliuyi m_log = pLog;
1676af099aSliuyi }
~CRKComm()1776af099aSliuyi CRKComm::~CRKComm()
1876af099aSliuyi {
1976af099aSliuyi }
2076af099aSliuyi
CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc,CRKLog * pLog,bool & bRet)2176af099aSliuyi CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog)
2276af099aSliuyi {
2376af099aSliuyi bRet = InitializeUsb(devDesc);
2476af099aSliuyi }
~CRKUsbComm()2576af099aSliuyi CRKUsbComm::~CRKUsbComm()
2676af099aSliuyi {
2776af099aSliuyi UninitializeUsb();
2876af099aSliuyi }
2976af099aSliuyi
InitializeUsb(STRUCT_RKDEVICE_DESC devDesc)3076af099aSliuyi bool CRKUsbComm::InitializeUsb(STRUCT_RKDEVICE_DESC devDesc)
3176af099aSliuyi {
3276af099aSliuyi m_pUsbHandle = NULL;
3376af099aSliuyi m_pipeBulkIn = m_pipeBulkOut = 0;
3476af099aSliuyi m_interfaceNum = -1;
3576af099aSliuyi if (!devDesc.pUsbHandle) {
3676af099aSliuyi return false;
3776af099aSliuyi }
3876af099aSliuyi memcpy(&m_deviceDesc, &devDesc, sizeof(STRUCT_RKDEVICE_DESC));
3976af099aSliuyi int iRet;
4076af099aSliuyi iRet = libusb_open((libusb_device *)devDesc.pUsbHandle, (libusb_device_handle **)&m_pUsbHandle);
4176af099aSliuyi if (iRet!=0) {
4276af099aSliuyi if (m_log) {
4376af099aSliuyi m_log->Record("Error:InitializeUsb-->open device failed,err=%d", iRet);
4476af099aSliuyi }
4576af099aSliuyi return false;
4676af099aSliuyi }
4776af099aSliuyi struct libusb_config_descriptor *pConfigDesc=NULL;
4876af099aSliuyi iRet = libusb_get_active_config_descriptor((libusb_device *)devDesc.pUsbHandle, &pConfigDesc);
4976af099aSliuyi if (iRet!=0) {
5076af099aSliuyi if (m_log) {
5176af099aSliuyi m_log->Record("Error:InitializeUsb-->get device config descriptor failed, err=%d", iRet);
5276af099aSliuyi }
5376af099aSliuyi return false;
5476af099aSliuyi }
5576af099aSliuyi int i, j, k;
5676af099aSliuyi const struct libusb_interface *pInterface;
5776af099aSliuyi const struct libusb_endpoint_descriptor *pEndpointDesc;
5876af099aSliuyi const struct libusb_interface_descriptor *pInterfaceDesc;
5976af099aSliuyi for(i = 0; i < pConfigDesc->bNumInterfaces; i++) {
6076af099aSliuyi pInterface = pConfigDesc->interface + i;
6176af099aSliuyi for(j = 0; j < pInterface->num_altsetting; j++) {
6276af099aSliuyi pInterfaceDesc = pInterface->altsetting+j;
6376af099aSliuyi if (m_deviceDesc.emUsbType == RKUSB_MSC) {
6476af099aSliuyi if( (pInterfaceDesc->bInterfaceClass != 8) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 0x50))
6576af099aSliuyi continue;
6676af099aSliuyi }
6776af099aSliuyi else
6876af099aSliuyi {
6976af099aSliuyi if( (pInterfaceDesc->bInterfaceClass != 0xff) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 5))
7076af099aSliuyi continue;
7176af099aSliuyi }
7276af099aSliuyi for(k = 0; k < pInterfaceDesc->bNumEndpoints; k++) {
7376af099aSliuyi pEndpointDesc = pInterfaceDesc->endpoint+k;
7476af099aSliuyi if ((pEndpointDesc->bEndpointAddress & 0x80) == 0) {
7576af099aSliuyi if (m_pipeBulkOut == 0)
7676af099aSliuyi m_pipeBulkOut = pEndpointDesc->bEndpointAddress;
7776af099aSliuyi }
7876af099aSliuyi else {
7976af099aSliuyi if (m_pipeBulkIn == 0)
8076af099aSliuyi m_pipeBulkIn = pEndpointDesc->bEndpointAddress;
8176af099aSliuyi }
8276af099aSliuyi if ((m_pipeBulkIn != 0) && (m_pipeBulkOut != 0)) {//found it
8376af099aSliuyi m_interfaceNum = i;
8476af099aSliuyi libusb_free_config_descriptor(pConfigDesc);
8576af099aSliuyi iRet = libusb_claim_interface((libusb_device_handle *)m_pUsbHandle, m_interfaceNum);
8676af099aSliuyi if (iRet != 0) {
8776af099aSliuyi if (m_log) {
8876af099aSliuyi m_log->Record("Error:libusb_claim_interface failed,err=%d", iRet);
8976af099aSliuyi }
9076af099aSliuyi return false;
9176af099aSliuyi }
9276af099aSliuyi return true;
9376af099aSliuyi }
9476af099aSliuyi }
9576af099aSliuyi }
9676af099aSliuyi }
9776af099aSliuyi libusb_free_config_descriptor(pConfigDesc);
9876af099aSliuyi return false;
9976af099aSliuyi }
UninitializeUsb()10076af099aSliuyi void CRKUsbComm::UninitializeUsb()
10176af099aSliuyi {
10276af099aSliuyi if (m_pUsbHandle) {
10376af099aSliuyi libusb_close((libusb_device_handle *)m_pUsbHandle);
10476af099aSliuyi m_pUsbHandle = NULL;
10576af099aSliuyi }
10676af099aSliuyi memset(&m_deviceDesc, 0, sizeof(STRUCT_RKDEVICE_DESC));
10776af099aSliuyi m_pipeBulkIn = m_pipeBulkOut = 0;
10876af099aSliuyi return ;
10976af099aSliuyi }
Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc)11076af099aSliuyi bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc)
11176af099aSliuyi {
11276af099aSliuyi bool bRet;
11376af099aSliuyi UninitializeUsb();
11476af099aSliuyi bRet = InitializeUsb(devDesc);
11576af099aSliuyi return bRet;
11676af099aSliuyi }
Reset_Usb_Device()11776af099aSliuyi bool CRKUsbComm::Reset_Usb_Device()
11876af099aSliuyi {
11976af099aSliuyi int iRet = -1;
12076af099aSliuyi if (m_pUsbHandle) {
12176af099aSliuyi iRet=libusb_reset_device((libusb_device_handle *)m_pUsbHandle);
12276af099aSliuyi }
12376af099aSliuyi return (iRet == 0) ? true : false;
12476af099aSliuyi }
12576af099aSliuyi
RKU_Read(BYTE * lpBuffer,DWORD dwSize)12676af099aSliuyi bool CRKUsbComm::RKU_Read(BYTE* lpBuffer, DWORD dwSize)
12776af099aSliuyi {
12876af099aSliuyi int iRet;
12976af099aSliuyi int nRead;
13076af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, CMD_TIMEOUT);
13176af099aSliuyi if (iRet!=0) {
13276af099aSliuyi if (m_log) {
13376af099aSliuyi m_log->Record("Error:RKU_Read failed,err=%d", iRet);
13476af099aSliuyi }
13576af099aSliuyi return false;
13676af099aSliuyi }
13776af099aSliuyi if (nRead != (int)dwSize) {
13876af099aSliuyi if (m_log) {
13976af099aSliuyi m_log->Record("Error:RKU_Read failed, size=%d, read=%d", dwSize, nRead);
14076af099aSliuyi }
14176af099aSliuyi return false;
14276af099aSliuyi }
14376af099aSliuyi return true;
14476af099aSliuyi }
14576af099aSliuyi
RKU_Write(BYTE * lpBuffer,DWORD dwSize)14676af099aSliuyi bool CRKUsbComm::RKU_Write(BYTE* lpBuffer, DWORD dwSize)
14776af099aSliuyi {
14876af099aSliuyi int iRet;
14976af099aSliuyi int nWrite;
15076af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkOut, lpBuffer, dwSize, &nWrite, CMD_TIMEOUT);
15176af099aSliuyi if (iRet != 0) {
15276af099aSliuyi if (m_log) {
15376af099aSliuyi m_log->Record("Error:RKU_Write failed, err=%d", iRet);
15476af099aSliuyi }
15576af099aSliuyi return false;
15676af099aSliuyi }
15776af099aSliuyi if (nWrite != (int)dwSize) {
15876af099aSliuyi if (m_log) {
15976af099aSliuyi m_log->Record("Error:RKU_Write failed, size=%d, read=%d", dwSize, nWrite);
16076af099aSliuyi }
16176af099aSliuyi return false;
16276af099aSliuyi }
16376af099aSliuyi return true;
16476af099aSliuyi }
RandomInteger(int low,int high)16576af099aSliuyi int CRKUsbComm::RandomInteger(int low, int high)
16676af099aSliuyi {
16776af099aSliuyi int k;
16876af099aSliuyi double d;
16976af099aSliuyi
17076af099aSliuyi d = (double)rand() / ((double)RAND_MAX + 1);
17176af099aSliuyi k = (int)(d * (high - low + 1));
17276af099aSliuyi return (low + k);
17376af099aSliuyi }
MakeCBWTag()17476af099aSliuyi DWORD CRKUsbComm::MakeCBWTag()
17576af099aSliuyi {
17676af099aSliuyi DWORD tag = 0;
17776af099aSliuyi int i = 0;
17876af099aSliuyi
17976af099aSliuyi for(i=0; i<4; i++){
18076af099aSliuyi tag <<= 8;
18176af099aSliuyi tag += RandomInteger(0, 0xFF);
18276af099aSliuyi }
18376af099aSliuyi return tag;
18476af099aSliuyi }
InitializeCBW(PCBW pCBW,USB_OPERATION_CODE code)18576af099aSliuyi void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code)
18676af099aSliuyi {
18776af099aSliuyi memset(pCBW,0, sizeof(CBW));
18876af099aSliuyi
18976af099aSliuyi pCBW->dwCBWSignature = CBW_SIGN;
19076af099aSliuyi pCBW->dwCBWTag = MakeCBWTag();
19176af099aSliuyi pCBW->cbwcb.ucOperCode = code;
19276af099aSliuyi
19376af099aSliuyi switch(code) {
19476af099aSliuyi case TEST_UNIT_READY: /* Test Unit Ready : 0 */
19576af099aSliuyi case READ_FLASH_ID: /* Read Flash ID : 1 */
19676af099aSliuyi case READ_FLASH_INFO:
19776af099aSliuyi case READ_CHIP_INFO:
19876af099aSliuyi case READ_EFUSE:
199081d237aSliuyi case READ_CAPABILITY:
200*554066a0SArnaud Mouiche case READ_STORAGE:
20176af099aSliuyi pCBW->ucCBWFlags= DIRECTION_IN;
20276af099aSliuyi pCBW->ucCBWCBLength = 0x06;
20376af099aSliuyi break;
20476af099aSliuyi case DEVICE_RESET: /* Reset Device : 0xff */
20576af099aSliuyi case ERASE_SYSTEMDISK:
20676af099aSliuyi case SET_RESET_FLAG:
207*554066a0SArnaud Mouiche case CHANGE_STORAGE:
20876af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT;
20976af099aSliuyi pCBW->ucCBWCBLength = 0x06;
21076af099aSliuyi break;
21176af099aSliuyi case TEST_BAD_BLOCK: /* Test Bad Block : 3 */
21276af099aSliuyi case READ_SECTOR: /* Read Pages : 4 */
21376af099aSliuyi case READ_LBA: /* Read Pages : 4 */
21476af099aSliuyi case READ_SDRAM: /* Write Pages : 15 */
21576af099aSliuyi case READ_SPI_FLASH:
21676af099aSliuyi case READ_NEW_EFUSE:
21776af099aSliuyi pCBW->ucCBWFlags = DIRECTION_IN;
21876af099aSliuyi pCBW->ucCBWCBLength = 0x0a;
21976af099aSliuyi break;
22076af099aSliuyi case WRITE_SECTOR: /* Write Pages : 5 */
22176af099aSliuyi case WRITE_LBA: /* Write Pages : 15 */
22276af099aSliuyi case WRITE_SDRAM: /* Write Pages : 15 */
22376af099aSliuyi case EXECUTE_SDRAM:
22476af099aSliuyi case ERASE_NORMAL: /* Erase Blocks : 6 */
22576af099aSliuyi case ERASE_FORCE: /* Read Spare : 11 */
22676af099aSliuyi case WRITE_EFUSE:
22776af099aSliuyi case WRITE_SPI_FLASH:
22876af099aSliuyi case WRITE_NEW_EFUSE:
229c29e5f0fSliuyi case ERASE_LBA:
23076af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT;
23176af099aSliuyi pCBW->ucCBWCBLength = 0x0a;
23276af099aSliuyi break;
23376af099aSliuyi default:
23476af099aSliuyi break;
23576af099aSliuyi }
23676af099aSliuyi }
23776af099aSliuyi
23876af099aSliuyi
RKU_ClearBuffer(CBW & cbw,CSW & csw)23976af099aSliuyi bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw)
24076af099aSliuyi {
24176af099aSliuyi DWORD dwReadBytes=0;
24276af099aSliuyi DWORD dwTotalRead=0;
24376af099aSliuyi int iTryCount;
24476af099aSliuyi iTryCount = 3;
24576af099aSliuyi do {
24676af099aSliuyi dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) );
24776af099aSliuyi
24876af099aSliuyi if (UFI_CHECK_SIGN(cbw,csw))
24976af099aSliuyi {
25076af099aSliuyi return true;
25176af099aSliuyi }
25276af099aSliuyi if (dwReadBytes != sizeof(CSW))
25376af099aSliuyi {
25476af099aSliuyi iTryCount--;
25576af099aSliuyi sleep(3);
25676af099aSliuyi }
25776af099aSliuyi dwTotalRead += dwReadBytes;
25876af099aSliuyi if (dwTotalRead >= MAX_CLEAR_LEN)
25976af099aSliuyi {
26076af099aSliuyi break;
26176af099aSliuyi }
26276af099aSliuyi }while ( iTryCount > 0 );
26376af099aSliuyi return false;
26476af099aSliuyi }
26576af099aSliuyi
RKU_Read_EX(BYTE * lpBuffer,DWORD dwSize)26676af099aSliuyi DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize)
26776af099aSliuyi {
26876af099aSliuyi int iRet;
26976af099aSliuyi int nRead;
27076af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000);
27176af099aSliuyi if (iRet != 0) {
27276af099aSliuyi if (m_log) {
27376af099aSliuyi m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet);
27476af099aSliuyi }
27576af099aSliuyi return 0;
27676af099aSliuyi }
27776af099aSliuyi return nRead;
27876af099aSliuyi }
27976af099aSliuyi
RKU_EraseBlock(BYTE ucFlashCS,DWORD dwPos,DWORD dwCount,BYTE ucEraseType)28076af099aSliuyi int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType)
28176af099aSliuyi {
28276af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
28376af099aSliuyi if (m_log) {
28476af099aSliuyi m_log->Record("Error:RKU_EraseBlock failed,device not support");
28576af099aSliuyi }
28676af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
28776af099aSliuyi }
28876af099aSliuyi CBW cbw;
28976af099aSliuyi CSW csw;
29076af099aSliuyi USHORT usCount;
29176af099aSliuyi usCount = dwCount;
29276af099aSliuyi if(dwCount > MAX_ERASE_BLOCKS)
29376af099aSliuyi return ERR_CROSS_BORDER;
29476af099aSliuyi
29576af099aSliuyi InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType);
29676af099aSliuyi cbw.ucCBWLUN = ucFlashCS;
29776af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
29876af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
29976af099aSliuyi
30076af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
30176af099aSliuyi {
30276af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
30376af099aSliuyi }
30476af099aSliuyi
30576af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
30676af099aSliuyi {
30776af099aSliuyi return ERR_DEVICE_READ_FAILED;
30876af099aSliuyi }
30976af099aSliuyi
31076af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
31176af099aSliuyi return ERR_CMD_NOTMATCH;
31276af099aSliuyi
31376af099aSliuyi if(csw.ucCSWStatus == 1)
31476af099aSliuyi return ERR_FOUND_BAD_BLOCK;
31576af099aSliuyi
31676af099aSliuyi return ERR_SUCCESS;
31776af099aSliuyi }
RKU_ReadChipInfo(BYTE * lpBuffer)31876af099aSliuyi int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer)
31976af099aSliuyi {
32076af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
32176af099aSliuyi if (m_log) {
32276af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
32376af099aSliuyi }
32476af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
32576af099aSliuyi }
32676af099aSliuyi
32776af099aSliuyi CBW cbw;
32876af099aSliuyi CSW csw;
32976af099aSliuyi
33076af099aSliuyi InitializeCBW(&cbw, READ_CHIP_INFO);
331b5200da5Sliuyi cbw.dwCBWTransferLength = 16;
33276af099aSliuyi
33376af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
33476af099aSliuyi {
33576af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
33676af099aSliuyi }
33776af099aSliuyi
33876af099aSliuyi if(!RKU_Read(lpBuffer, 16))
33976af099aSliuyi {
34076af099aSliuyi return ERR_DEVICE_READ_FAILED;
34176af099aSliuyi }
34276af099aSliuyi
34376af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
34476af099aSliuyi {
34576af099aSliuyi return ERR_DEVICE_READ_FAILED;
34676af099aSliuyi }
34776af099aSliuyi
34876af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
34976af099aSliuyi return ERR_CMD_NOTMATCH;
35076af099aSliuyi
35176af099aSliuyi return ERR_SUCCESS;
35276af099aSliuyi }
RKU_ReadFlashID(BYTE * lpBuffer)35376af099aSliuyi int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer)
35476af099aSliuyi {
35576af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
35676af099aSliuyi if (m_log) {
35776af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
35876af099aSliuyi }
35976af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
36076af099aSliuyi }
36176af099aSliuyi
36276af099aSliuyi CBW cbw;
36376af099aSliuyi CSW csw;
36476af099aSliuyi
36576af099aSliuyi InitializeCBW(&cbw, READ_FLASH_ID);
366b5200da5Sliuyi cbw.dwCBWTransferLength = 5;
36776af099aSliuyi
36876af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
36976af099aSliuyi {
37076af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
37176af099aSliuyi }
37276af099aSliuyi
37376af099aSliuyi if(!RKU_Read(lpBuffer, 5))
37476af099aSliuyi {
37576af099aSliuyi return ERR_DEVICE_READ_FAILED;
37676af099aSliuyi }
37776af099aSliuyi
37876af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
37976af099aSliuyi {
38076af099aSliuyi return ERR_DEVICE_READ_FAILED;
38176af099aSliuyi }
38276af099aSliuyi
38376af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
38476af099aSliuyi return ERR_CMD_NOTMATCH;
38576af099aSliuyi
38676af099aSliuyi return ERR_SUCCESS;
38776af099aSliuyi }
RKU_ReadFlashInfo(BYTE * lpBuffer,UINT * puiRead)38876af099aSliuyi int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead)
38976af099aSliuyi {
39076af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
39176af099aSliuyi if (m_log) {
39276af099aSliuyi m_log->Record("Error:RKU_ReadFlashInfo failed,device not support");
39376af099aSliuyi }
39476af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
39576af099aSliuyi }
39676af099aSliuyi CBW cbw;
39776af099aSliuyi CSW csw;
39876af099aSliuyi
39976af099aSliuyi InitializeCBW(&cbw, READ_FLASH_INFO);
400b5200da5Sliuyi cbw.dwCBWTransferLength = 11;
40176af099aSliuyi
40276af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
40376af099aSliuyi {
40476af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
40576af099aSliuyi }
40676af099aSliuyi
40776af099aSliuyi DWORD dwRead;
40876af099aSliuyi dwRead = RKU_Read_EX(lpBuffer, 512);
40976af099aSliuyi if ((dwRead < 11) || (dwRead > 512))
41076af099aSliuyi {
41176af099aSliuyi return ERR_DEVICE_READ_FAILED;
41276af099aSliuyi }
41376af099aSliuyi if (puiRead)
41476af099aSliuyi {
41576af099aSliuyi *puiRead = dwRead;
41676af099aSliuyi }
41776af099aSliuyi /*
41876af099aSliuyi if(!RKU_Read(hDev, lpBuffer, 11))
41976af099aSliuyi {
42076af099aSliuyi return ERR_DEVICE_READ_FAILED;
42176af099aSliuyi }
42276af099aSliuyi */
42376af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
42476af099aSliuyi {
42576af099aSliuyi return ERR_DEVICE_READ_FAILED;
42676af099aSliuyi }
42776af099aSliuyi
42876af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
42976af099aSliuyi return ERR_CMD_NOTMATCH;
43076af099aSliuyi
43176af099aSliuyi return ERR_SUCCESS;
43276af099aSliuyi }
RKU_ReadCapability(BYTE * lpBuffer)433081d237aSliuyi int CRKUsbComm::RKU_ReadCapability(BYTE* lpBuffer)
434081d237aSliuyi {
435081d237aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
436081d237aSliuyi if (m_log) {
437081d237aSliuyi m_log->Record("Error:RKU_ReadCapability failed,device not support");
438081d237aSliuyi }
439081d237aSliuyi return ERR_DEVICE_NOT_SUPPORT;
440081d237aSliuyi }
441081d237aSliuyi
442081d237aSliuyi CBW cbw;
443081d237aSliuyi CSW csw;
444081d237aSliuyi DWORD dwRead;
445081d237aSliuyi
446081d237aSliuyi InitializeCBW(&cbw, READ_CAPABILITY);
447081d237aSliuyi cbw.dwCBWTransferLength = 8;
448081d237aSliuyi
449081d237aSliuyi if(!RKU_Write((BYTE*)&cbw, sizeof(CBW)))
450081d237aSliuyi {
451081d237aSliuyi return ERR_DEVICE_WRITE_FAILED;
452081d237aSliuyi }
453081d237aSliuyi
454081d237aSliuyi dwRead = RKU_Read_EX((BYTE*)&csw, sizeof(CSW));
455081d237aSliuyi
456081d237aSliuyi if(dwRead != 8)
457081d237aSliuyi {
458081d237aSliuyi return ERR_DEVICE_READ_FAILED;
459081d237aSliuyi }
460081d237aSliuyi memcpy(lpBuffer, (BYTE*)&csw, 8);
461081d237aSliuyi
462081d237aSliuyi if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
463081d237aSliuyi {
464081d237aSliuyi return ERR_DEVICE_READ_FAILED;
465081d237aSliuyi }
466081d237aSliuyi
467081d237aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
468081d237aSliuyi return ERR_CMD_NOTMATCH;
469081d237aSliuyi
470081d237aSliuyi return ERR_SUCCESS;
471081d237aSliuyi }
472081d237aSliuyi
RKU_ReadLBA(DWORD dwPos,DWORD dwCount,BYTE * lpBuffer,BYTE bySubCode)47376af099aSliuyi int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
47476af099aSliuyi {
47576af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
47676af099aSliuyi if (m_log) {
47776af099aSliuyi m_log->Record("Error:RKU_ReadLBA failed,device not support");
47876af099aSliuyi }
47976af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
48076af099aSliuyi }
48176af099aSliuyi CBW cbw;
48276af099aSliuyi CSW csw;
48376af099aSliuyi USHORT wSectorSize;
48476af099aSliuyi USHORT usSectorLen;
48576af099aSliuyi wSectorSize = 512;
48676af099aSliuyi usSectorLen=dwCount;
48776af099aSliuyi
48876af099aSliuyi InitializeCBW(&cbw, READ_LBA);
489b5200da5Sliuyi cbw.dwCBWTransferLength = dwCount * wSectorSize;
49076af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
49176af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen);
49276af099aSliuyi cbw.cbwcb.ucReserved = bySubCode;
49376af099aSliuyi
49476af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
49576af099aSliuyi {
49676af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
49776af099aSliuyi }
49876af099aSliuyi DWORD dwTotal;
49976af099aSliuyi dwTotal = usSectorLen * wSectorSize;
50076af099aSliuyi
50176af099aSliuyi if(!RKU_Read(lpBuffer, dwTotal))
50276af099aSliuyi {
50376af099aSliuyi return ERR_DEVICE_READ_FAILED;
50476af099aSliuyi }
50576af099aSliuyi
50676af099aSliuyi if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
50776af099aSliuyi {
50876af099aSliuyi return ERR_DEVICE_READ_FAILED;
50976af099aSliuyi }
51076af099aSliuyi
51176af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
51276af099aSliuyi return ERR_CMD_NOTMATCH;
51376af099aSliuyi
51476af099aSliuyi if(csw.ucCSWStatus == 1)
51576af099aSliuyi return ERR_FAILED;
51676af099aSliuyi
51776af099aSliuyi return ERR_SUCCESS;
51876af099aSliuyi }
51976af099aSliuyi
RKU_ResetDevice(BYTE bySubCode)52076af099aSliuyi int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode)
52176af099aSliuyi {
52276af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
52376af099aSliuyi if (m_log) {
52476af099aSliuyi m_log->Record("Error:RKU_ResetDevice failed,device not support");
52576af099aSliuyi }
52676af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
52776af099aSliuyi }
52876af099aSliuyi
52976af099aSliuyi CBW cbw;
53076af099aSliuyi CSW csw;
53176af099aSliuyi
53276af099aSliuyi InitializeCBW(&cbw, DEVICE_RESET);
53376af099aSliuyi cbw.cbwcb.ucReserved = bySubCode;
53476af099aSliuyi
53576af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
53676af099aSliuyi {
53776af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
53876af099aSliuyi }
53976af099aSliuyi
54076af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
54176af099aSliuyi {
54276af099aSliuyi return ERR_DEVICE_READ_FAILED;
54376af099aSliuyi }
54476af099aSliuyi
54576af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) {
54676af099aSliuyi bool bRet;
54776af099aSliuyi bRet = RKU_ClearBuffer(cbw, csw);
54876af099aSliuyi if (!bRet) {
54976af099aSliuyi return ERR_CMD_NOTMATCH;
55076af099aSliuyi }
55176af099aSliuyi }
55276af099aSliuyi
55376af099aSliuyi if(csw.ucCSWStatus == 1)
55476af099aSliuyi return ERR_FAILED;
55576af099aSliuyi
55676af099aSliuyi return ERR_SUCCESS;
55776af099aSliuyi }
55876af099aSliuyi
RKU_ChangeStorage(BYTE storage)559*554066a0SArnaud Mouiche int CRKUsbComm::RKU_ChangeStorage(BYTE storage)
560*554066a0SArnaud Mouiche {
561*554066a0SArnaud Mouiche if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
562*554066a0SArnaud Mouiche if (m_log) {
563*554066a0SArnaud Mouiche m_log->Record("Error:RKU_ChangeStorage failed,device not support");
564*554066a0SArnaud Mouiche }
565*554066a0SArnaud Mouiche return ERR_DEVICE_NOT_SUPPORT;
566*554066a0SArnaud Mouiche }
567*554066a0SArnaud Mouiche
568*554066a0SArnaud Mouiche CBW cbw;
569*554066a0SArnaud Mouiche CSW csw;
570*554066a0SArnaud Mouiche
571*554066a0SArnaud Mouiche InitializeCBW(&cbw, CHANGE_STORAGE);
572*554066a0SArnaud Mouiche cbw.cbwcb.ucReserved = storage;
573*554066a0SArnaud Mouiche
574*554066a0SArnaud Mouiche if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
575*554066a0SArnaud Mouiche {
576*554066a0SArnaud Mouiche printf("AMO: ERR_DEVICE_WRITE_FAILED\n");
577*554066a0SArnaud Mouiche return ERR_DEVICE_WRITE_FAILED;
578*554066a0SArnaud Mouiche }
579*554066a0SArnaud Mouiche
580*554066a0SArnaud Mouiche if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
581*554066a0SArnaud Mouiche {
582*554066a0SArnaud Mouiche return ERR_DEVICE_READ_FAILED;
583*554066a0SArnaud Mouiche }
584*554066a0SArnaud Mouiche
585*554066a0SArnaud Mouiche if( !UFI_CHECK_SIGN(cbw, csw) ) {
586*554066a0SArnaud Mouiche bool bRet;
587*554066a0SArnaud Mouiche bRet = RKU_ClearBuffer(cbw, csw);
588*554066a0SArnaud Mouiche if (!bRet) {
589*554066a0SArnaud Mouiche return ERR_CMD_NOTMATCH;
590*554066a0SArnaud Mouiche }
591*554066a0SArnaud Mouiche }
592*554066a0SArnaud Mouiche
593*554066a0SArnaud Mouiche if(csw.ucCSWStatus == 1)
594*554066a0SArnaud Mouiche return ERR_FAILED;
595*554066a0SArnaud Mouiche
596*554066a0SArnaud Mouiche return ERR_SUCCESS;
597*554066a0SArnaud Mouiche }
598*554066a0SArnaud Mouiche
RKU_ReadStorage(BYTE * storage)599*554066a0SArnaud Mouiche int CRKUsbComm::RKU_ReadStorage(BYTE* storage)
600*554066a0SArnaud Mouiche {
601*554066a0SArnaud Mouiche if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
602*554066a0SArnaud Mouiche if (m_log) {
603*554066a0SArnaud Mouiche m_log->Record("Error:RKU_ReadCapability failed,device not support");
604*554066a0SArnaud Mouiche }
605*554066a0SArnaud Mouiche return ERR_DEVICE_NOT_SUPPORT;
606*554066a0SArnaud Mouiche }
607*554066a0SArnaud Mouiche
608*554066a0SArnaud Mouiche CBW cbw;
609*554066a0SArnaud Mouiche CSW csw;
610*554066a0SArnaud Mouiche DWORD dwRead;
611*554066a0SArnaud Mouiche
612*554066a0SArnaud Mouiche InitializeCBW(&cbw, READ_STORAGE);
613*554066a0SArnaud Mouiche cbw.dwCBWTransferLength = 4;
614*554066a0SArnaud Mouiche
615*554066a0SArnaud Mouiche if(!RKU_Write((BYTE*)&cbw, sizeof(CBW)))
616*554066a0SArnaud Mouiche {
617*554066a0SArnaud Mouiche return ERR_DEVICE_WRITE_FAILED;
618*554066a0SArnaud Mouiche }
619*554066a0SArnaud Mouiche
620*554066a0SArnaud Mouiche DWORD storage_bits;
621*554066a0SArnaud Mouiche dwRead = RKU_Read_EX((BYTE*)&storage_bits, sizeof(storage_bits));
622*554066a0SArnaud Mouiche
623*554066a0SArnaud Mouiche if(dwRead != 4)
624*554066a0SArnaud Mouiche {
625*554066a0SArnaud Mouiche return ERR_DEVICE_READ_FAILED;
626*554066a0SArnaud Mouiche }
627*554066a0SArnaud Mouiche
628*554066a0SArnaud Mouiche if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
629*554066a0SArnaud Mouiche {
630*554066a0SArnaud Mouiche return ERR_DEVICE_READ_FAILED;
631*554066a0SArnaud Mouiche }
632*554066a0SArnaud Mouiche
633*554066a0SArnaud Mouiche if( !UFI_CHECK_SIGN(cbw, csw) )
634*554066a0SArnaud Mouiche return ERR_CMD_NOTMATCH;
635*554066a0SArnaud Mouiche
636*554066a0SArnaud Mouiche /* search the bit index */
637*554066a0SArnaud Mouiche *storage = 255;
638*554066a0SArnaud Mouiche for (unsigned i=0; i < 32; i++) {
639*554066a0SArnaud Mouiche if (storage_bits & (1<<i)) {
640*554066a0SArnaud Mouiche *storage = i;
641*554066a0SArnaud Mouiche break;
642*554066a0SArnaud Mouiche }
643*554066a0SArnaud Mouiche }
644*554066a0SArnaud Mouiche return ERR_SUCCESS;
645*554066a0SArnaud Mouiche }
646*554066a0SArnaud Mouiche
647*554066a0SArnaud Mouiche
RKU_TestDeviceReady(DWORD * dwTotal,DWORD * dwCurrent,BYTE bySubCode)64876af099aSliuyi int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode)
64976af099aSliuyi {
65076af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
65176af099aSliuyi if (m_log) {
65276af099aSliuyi m_log->Record("Error:RKU_TestDeviceReady failed,device not support");
65376af099aSliuyi }
65476af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
65576af099aSliuyi }
65676af099aSliuyi CBW cbw;
65776af099aSliuyi CSW csw;
65876af099aSliuyi
65976af099aSliuyi InitializeCBW(&cbw, TEST_UNIT_READY);
66076af099aSliuyi
66176af099aSliuyi cbw.cbwcb.ucReserved = bySubCode;
66276af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
66376af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
66476af099aSliuyi }
66576af099aSliuyi
66676af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
66776af099aSliuyi return ERR_DEVICE_READ_FAILED;
66876af099aSliuyi }
66976af099aSliuyi
67076af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) {
67176af099aSliuyi bool bRet;
67276af099aSliuyi bRet = RKU_ClearBuffer(cbw ,csw);
67376af099aSliuyi if (!bRet) {
67476af099aSliuyi return ERR_CMD_NOTMATCH;
67576af099aSliuyi }
67676af099aSliuyi }
67776af099aSliuyi
67876af099aSliuyi if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) {
67976af099aSliuyi *dwCurrent = (csw.dwCBWDataResidue >>16);
68076af099aSliuyi *dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF);
68176af099aSliuyi
68276af099aSliuyi *dwTotal = EndianU16_BtoL(*dwTotal);
68376af099aSliuyi *dwCurrent = EndianU16_BtoL(*dwCurrent);
68476af099aSliuyi }
68576af099aSliuyi if(csw.ucCSWStatus == 1) {
68676af099aSliuyi return ERR_DEVICE_UNREADY;
68776af099aSliuyi }
68876af099aSliuyi
68976af099aSliuyi return ERR_DEVICE_READY;
69076af099aSliuyi }
RKU_WriteLBA(DWORD dwPos,DWORD dwCount,BYTE * lpBuffer,BYTE bySubCode)69176af099aSliuyi int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
69276af099aSliuyi {
69376af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
69476af099aSliuyi if (m_log) {
69576af099aSliuyi m_log->Record("Error:RKU_WriteLBA failed,device not support");
69676af099aSliuyi }
69776af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
69876af099aSliuyi }
69976af099aSliuyi CBW cbw;
70076af099aSliuyi CSW csw;
70176af099aSliuyi USHORT wSectorSize;
70276af099aSliuyi USHORT usCount;
70376af099aSliuyi wSectorSize = 512;
70476af099aSliuyi usCount = dwCount;
70576af099aSliuyi DWORD dwTotal = usCount * wSectorSize;
70676af099aSliuyi
70776af099aSliuyi InitializeCBW(&cbw, WRITE_LBA);
708b5200da5Sliuyi cbw.dwCBWTransferLength = dwCount * wSectorSize;
70976af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
71076af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
71176af099aSliuyi cbw.cbwcb.ucReserved = bySubCode;
71276af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
71376af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
71476af099aSliuyi }
71576af099aSliuyi
71676af099aSliuyi if(!RKU_Write( lpBuffer, dwTotal)) {
71776af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
71876af099aSliuyi }
71976af099aSliuyi
72076af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
72176af099aSliuyi return ERR_DEVICE_READ_FAILED;
72276af099aSliuyi }
72376af099aSliuyi
72476af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
72576af099aSliuyi return ERR_CMD_NOTMATCH;
72676af099aSliuyi
72776af099aSliuyi if(csw.ucCSWStatus == 1)
72876af099aSliuyi return ERR_FAILED;
72976af099aSliuyi
73076af099aSliuyi return ERR_SUCCESS;
73176af099aSliuyi }
RKU_EraseLBA(DWORD dwPos,DWORD dwCount)732c29e5f0fSliuyi int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount)
733c29e5f0fSliuyi {
734c29e5f0fSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
735c29e5f0fSliuyi if (m_log) {
736c29e5f0fSliuyi m_log->Record("Error:RKU_WriteLBA failed,device not support");
737c29e5f0fSliuyi }
738c29e5f0fSliuyi return ERR_DEVICE_NOT_SUPPORT;
739c29e5f0fSliuyi }
740c29e5f0fSliuyi CBW cbw;
741c29e5f0fSliuyi CSW csw;
742c29e5f0fSliuyi USHORT usCount;
743c29e5f0fSliuyi usCount = dwCount;
744c29e5f0fSliuyi
745c29e5f0fSliuyi
746c29e5f0fSliuyi InitializeCBW(&cbw, ERASE_LBA);
747c29e5f0fSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
748c29e5f0fSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
749c29e5f0fSliuyi
750c29e5f0fSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
751c29e5f0fSliuyi return ERR_DEVICE_WRITE_FAILED;
752c29e5f0fSliuyi }
753c29e5f0fSliuyi
754c29e5f0fSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
755c29e5f0fSliuyi return ERR_DEVICE_READ_FAILED;
756c29e5f0fSliuyi }
757c29e5f0fSliuyi
758c29e5f0fSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
759c29e5f0fSliuyi return ERR_CMD_NOTMATCH;
760c29e5f0fSliuyi
761c29e5f0fSliuyi if(csw.ucCSWStatus == 1)
762c29e5f0fSliuyi return ERR_FAILED;
763c29e5f0fSliuyi
764c29e5f0fSliuyi return ERR_SUCCESS;
765c29e5f0fSliuyi }
766c29e5f0fSliuyi
RKU_WriteSector(DWORD dwPos,DWORD dwCount,BYTE * lpBuffer)76776af099aSliuyi int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer)
76876af099aSliuyi {
76976af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
77076af099aSliuyi if (m_log) {
77176af099aSliuyi m_log->Record("Error:RKU_WriteSector failed,device not support");
77276af099aSliuyi }
77376af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
77476af099aSliuyi }
77576af099aSliuyi CBW cbw;
77676af099aSliuyi CSW csw;
77776af099aSliuyi USHORT wSectorSize;
77876af099aSliuyi USHORT usCount;
77976af099aSliuyi usCount=dwCount;
78076af099aSliuyi if(usCount > 32)
78176af099aSliuyi return ERR_CROSS_BORDER;
78276af099aSliuyi
78376af099aSliuyi wSectorSize = 528;
78476af099aSliuyi InitializeCBW(&cbw, WRITE_SECTOR);
785b5200da5Sliuyi cbw.dwCBWTransferLength = dwCount * wSectorSize;
78676af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
78776af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
78876af099aSliuyi
78976af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
79076af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
79176af099aSliuyi }
79276af099aSliuyi
79376af099aSliuyi if(!RKU_Write( lpBuffer, usCount * wSectorSize)) {
79476af099aSliuyi return ERR_DEVICE_WRITE_FAILED;
79576af099aSliuyi }
79676af099aSliuyi
79776af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
79876af099aSliuyi return ERR_DEVICE_READ_FAILED;
79976af099aSliuyi }
80076af099aSliuyi
80176af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) )
80276af099aSliuyi return ERR_CMD_NOTMATCH;
80376af099aSliuyi
80476af099aSliuyi if(csw.ucCSWStatus == 1)
80576af099aSliuyi return ERR_FAILED;
80676af099aSliuyi
80776af099aSliuyi return ERR_SUCCESS;
80876af099aSliuyi }
80976af099aSliuyi
81076af099aSliuyi
RKU_DeviceRequest(DWORD dwRequest,BYTE * lpBuffer,DWORD dwDataSize)81176af099aSliuyi int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize)
81276af099aSliuyi {
81376af099aSliuyi if (m_deviceDesc.emUsbType != RKUSB_MASKROM) {
81476af099aSliuyi if (m_log) {
81576af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,device not support");
81676af099aSliuyi }
81776af099aSliuyi return ERR_DEVICE_NOT_SUPPORT;
81876af099aSliuyi }
81976af099aSliuyi if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) {
82076af099aSliuyi if (m_log) {
82176af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,request not support");
82276af099aSliuyi }
82376af099aSliuyi return ERR_REQUEST_NOT_SUPPORT;
82476af099aSliuyi }
82576af099aSliuyi
82676af099aSliuyi bool bSendPendPacket = false;
82776af099aSliuyi USHORT crcValue = 0xffff;
82876af099aSliuyi BYTE *pData = NULL;
82976af099aSliuyi pData = new BYTE[dwDataSize + 5];
83076af099aSliuyi memset(pData, 0, dwDataSize + 5);
83176af099aSliuyi memcpy(pData, lpBuffer, dwDataSize);
83276af099aSliuyi
83376af099aSliuyi switch(dwDataSize % 4096) {
83476af099aSliuyi case 4095:
83576af099aSliuyi ++dwDataSize;
83676af099aSliuyi break;
83776af099aSliuyi case 4094:
83876af099aSliuyi bSendPendPacket = true;
83976af099aSliuyi break;
84076af099aSliuyi case 0:
84176af099aSliuyi default:
84276af099aSliuyi break;
84376af099aSliuyi }
84476af099aSliuyi
84576af099aSliuyi crcValue = CRC_CCITT(pData, dwDataSize);
84676af099aSliuyi pData[dwDataSize] = (crcValue & 0xff00) >> 8;
84776af099aSliuyi pData[dwDataSize+1] = crcValue & 0x00ff;
84876af099aSliuyi dwDataSize += 2;
84976af099aSliuyi
85076af099aSliuyi UINT nSendBytes = 0;
85176af099aSliuyi DWORD dwTotalSended = 0;
85276af099aSliuyi int iRet;
85376af099aSliuyi
85476af099aSliuyi while(dwTotalSended < dwDataSize) {
85576af099aSliuyi nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended);
85676af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT);
85776af099aSliuyi if (iRet != (int)nSendBytes) {
85876af099aSliuyi if (m_log) {
85976af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet);
86076af099aSliuyi }
86176af099aSliuyi delete []pData;
86276af099aSliuyi return ERR_REQUEST_FAIL;
86376af099aSliuyi }
86476af099aSliuyi dwTotalSended += nSendBytes;
86576af099aSliuyi }
86676af099aSliuyi
86776af099aSliuyi if(bSendPendPacket) {
86876af099aSliuyi BYTE ucFillByte = 0;
86976af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT);
87076af099aSliuyi if (iRet != 0) {
87176af099aSliuyi if (m_log) {
87276af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet);
87376af099aSliuyi }
87476af099aSliuyi delete []pData;
87576af099aSliuyi return ERR_REQUEST_FAIL;
87676af099aSliuyi }
87776af099aSliuyi }
87876af099aSliuyi
87976af099aSliuyi delete []pData;
88076af099aSliuyi
88176af099aSliuyi return ERR_SUCCESS;
88276af099aSliuyi }
88376af099aSliuyi
88476af099aSliuyi
885