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); 1276af099aSliuyi CRKComm::CRKComm(CRKLog *pLog) 1376af099aSliuyi { 1476af099aSliuyi memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC)); 1576af099aSliuyi m_log = pLog; 1676af099aSliuyi } 1776af099aSliuyi CRKComm::~CRKComm() 1876af099aSliuyi { 1976af099aSliuyi } 2076af099aSliuyi 2176af099aSliuyi CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog) 2276af099aSliuyi { 2376af099aSliuyi bRet = InitializeUsb(devDesc); 2476af099aSliuyi } 2576af099aSliuyi CRKUsbComm::~CRKUsbComm() 2676af099aSliuyi { 2776af099aSliuyi UninitializeUsb(); 2876af099aSliuyi } 2976af099aSliuyi 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 } 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 } 11076af099aSliuyi bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc) 11176af099aSliuyi { 11276af099aSliuyi bool bRet; 11376af099aSliuyi UninitializeUsb(); 11476af099aSliuyi bRet = InitializeUsb(devDesc); 11576af099aSliuyi return bRet; 11676af099aSliuyi } 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 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 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 } 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 } 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 } 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 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 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 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 } 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 } 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 } 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 } 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 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 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 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 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 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 } 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 } 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 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 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