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: 199*081d237aSliuyi case READ_CAPABILITY: 20076af099aSliuyi pCBW->ucCBWFlags= DIRECTION_IN; 20176af099aSliuyi pCBW->ucCBWCBLength = 0x06; 20276af099aSliuyi break; 20376af099aSliuyi case DEVICE_RESET: /* Reset Device : 0xff */ 20476af099aSliuyi case ERASE_SYSTEMDISK: 20576af099aSliuyi case SET_RESET_FLAG: 20676af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT; 20776af099aSliuyi pCBW->ucCBWCBLength = 0x06; 20876af099aSliuyi break; 20976af099aSliuyi case TEST_BAD_BLOCK: /* Test Bad Block : 3 */ 21076af099aSliuyi case READ_SECTOR: /* Read Pages : 4 */ 21176af099aSliuyi case READ_LBA: /* Read Pages : 4 */ 21276af099aSliuyi case READ_SDRAM: /* Write Pages : 15 */ 21376af099aSliuyi case READ_SPI_FLASH: 21476af099aSliuyi case READ_NEW_EFUSE: 21576af099aSliuyi pCBW->ucCBWFlags = DIRECTION_IN; 21676af099aSliuyi pCBW->ucCBWCBLength = 0x0a; 21776af099aSliuyi break; 21876af099aSliuyi case WRITE_SECTOR: /* Write Pages : 5 */ 21976af099aSliuyi case WRITE_LBA: /* Write Pages : 15 */ 22076af099aSliuyi case WRITE_SDRAM: /* Write Pages : 15 */ 22176af099aSliuyi case EXECUTE_SDRAM: 22276af099aSliuyi case ERASE_NORMAL: /* Erase Blocks : 6 */ 22376af099aSliuyi case ERASE_FORCE: /* Read Spare : 11 */ 22476af099aSliuyi case WRITE_EFUSE: 22576af099aSliuyi case WRITE_SPI_FLASH: 22676af099aSliuyi case WRITE_NEW_EFUSE: 227c29e5f0fSliuyi case ERASE_LBA: 22876af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT; 22976af099aSliuyi pCBW->ucCBWCBLength = 0x0a; 23076af099aSliuyi break; 23176af099aSliuyi default: 23276af099aSliuyi break; 23376af099aSliuyi } 23476af099aSliuyi } 23576af099aSliuyi 23676af099aSliuyi 23776af099aSliuyi bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw) 23876af099aSliuyi { 23976af099aSliuyi DWORD dwReadBytes=0; 24076af099aSliuyi DWORD dwTotalRead=0; 24176af099aSliuyi int iTryCount; 24276af099aSliuyi iTryCount = 3; 24376af099aSliuyi do { 24476af099aSliuyi dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) ); 24576af099aSliuyi 24676af099aSliuyi if (UFI_CHECK_SIGN(cbw,csw)) 24776af099aSliuyi { 24876af099aSliuyi return true; 24976af099aSliuyi } 25076af099aSliuyi if (dwReadBytes != sizeof(CSW)) 25176af099aSliuyi { 25276af099aSliuyi iTryCount--; 25376af099aSliuyi sleep(3); 25476af099aSliuyi } 25576af099aSliuyi dwTotalRead += dwReadBytes; 25676af099aSliuyi if (dwTotalRead >= MAX_CLEAR_LEN) 25776af099aSliuyi { 25876af099aSliuyi break; 25976af099aSliuyi } 26076af099aSliuyi }while ( iTryCount > 0 ); 26176af099aSliuyi return false; 26276af099aSliuyi } 26376af099aSliuyi 26476af099aSliuyi DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize) 26576af099aSliuyi { 26676af099aSliuyi int iRet; 26776af099aSliuyi int nRead; 26876af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000); 26976af099aSliuyi if (iRet != 0) { 27076af099aSliuyi if (m_log) { 27176af099aSliuyi m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet); 27276af099aSliuyi } 27376af099aSliuyi return 0; 27476af099aSliuyi } 27576af099aSliuyi return nRead; 27676af099aSliuyi } 27776af099aSliuyi 27876af099aSliuyi int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType) 27976af099aSliuyi { 28076af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 28176af099aSliuyi if (m_log) { 28276af099aSliuyi m_log->Record("Error:RKU_EraseBlock failed,device not support"); 28376af099aSliuyi } 28476af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 28576af099aSliuyi } 28676af099aSliuyi CBW cbw; 28776af099aSliuyi CSW csw; 28876af099aSliuyi USHORT usCount; 28976af099aSliuyi usCount = dwCount; 29076af099aSliuyi if(dwCount > MAX_ERASE_BLOCKS) 29176af099aSliuyi return ERR_CROSS_BORDER; 29276af099aSliuyi 29376af099aSliuyi InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType); 29476af099aSliuyi cbw.ucCBWLUN = ucFlashCS; 29576af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 29676af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 29776af099aSliuyi 29876af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 29976af099aSliuyi { 30076af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 30176af099aSliuyi } 30276af099aSliuyi 30376af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 30476af099aSliuyi { 30576af099aSliuyi return ERR_DEVICE_READ_FAILED; 30676af099aSliuyi } 30776af099aSliuyi 30876af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 30976af099aSliuyi return ERR_CMD_NOTMATCH; 31076af099aSliuyi 31176af099aSliuyi if(csw.ucCSWStatus == 1) 31276af099aSliuyi return ERR_FOUND_BAD_BLOCK; 31376af099aSliuyi 31476af099aSliuyi return ERR_SUCCESS; 31576af099aSliuyi } 31676af099aSliuyi int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer) 31776af099aSliuyi { 31876af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 31976af099aSliuyi if (m_log) { 32076af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 32176af099aSliuyi } 32276af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 32376af099aSliuyi } 32476af099aSliuyi 32576af099aSliuyi CBW cbw; 32676af099aSliuyi CSW csw; 32776af099aSliuyi 32876af099aSliuyi InitializeCBW(&cbw, READ_CHIP_INFO); 329b5200da5Sliuyi cbw.dwCBWTransferLength = 16; 33076af099aSliuyi 33176af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 33276af099aSliuyi { 33376af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 33476af099aSliuyi } 33576af099aSliuyi 33676af099aSliuyi if(!RKU_Read(lpBuffer, 16)) 33776af099aSliuyi { 33876af099aSliuyi return ERR_DEVICE_READ_FAILED; 33976af099aSliuyi } 34076af099aSliuyi 34176af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 34276af099aSliuyi { 34376af099aSliuyi return ERR_DEVICE_READ_FAILED; 34476af099aSliuyi } 34576af099aSliuyi 34676af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 34776af099aSliuyi return ERR_CMD_NOTMATCH; 34876af099aSliuyi 34976af099aSliuyi return ERR_SUCCESS; 35076af099aSliuyi } 35176af099aSliuyi int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer) 35276af099aSliuyi { 35376af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 35476af099aSliuyi if (m_log) { 35576af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 35676af099aSliuyi } 35776af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 35876af099aSliuyi } 35976af099aSliuyi 36076af099aSliuyi CBW cbw; 36176af099aSliuyi CSW csw; 36276af099aSliuyi 36376af099aSliuyi InitializeCBW(&cbw, READ_FLASH_ID); 364b5200da5Sliuyi cbw.dwCBWTransferLength = 5; 36576af099aSliuyi 36676af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 36776af099aSliuyi { 36876af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 36976af099aSliuyi } 37076af099aSliuyi 37176af099aSliuyi if(!RKU_Read(lpBuffer, 5)) 37276af099aSliuyi { 37376af099aSliuyi return ERR_DEVICE_READ_FAILED; 37476af099aSliuyi } 37576af099aSliuyi 37676af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 37776af099aSliuyi { 37876af099aSliuyi return ERR_DEVICE_READ_FAILED; 37976af099aSliuyi } 38076af099aSliuyi 38176af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 38276af099aSliuyi return ERR_CMD_NOTMATCH; 38376af099aSliuyi 38476af099aSliuyi return ERR_SUCCESS; 38576af099aSliuyi } 38676af099aSliuyi int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead) 38776af099aSliuyi { 38876af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 38976af099aSliuyi if (m_log) { 39076af099aSliuyi m_log->Record("Error:RKU_ReadFlashInfo failed,device not support"); 39176af099aSliuyi } 39276af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 39376af099aSliuyi } 39476af099aSliuyi CBW cbw; 39576af099aSliuyi CSW csw; 39676af099aSliuyi 39776af099aSliuyi InitializeCBW(&cbw, READ_FLASH_INFO); 398b5200da5Sliuyi cbw.dwCBWTransferLength = 11; 39976af099aSliuyi 40076af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 40176af099aSliuyi { 40276af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 40376af099aSliuyi } 40476af099aSliuyi 40576af099aSliuyi DWORD dwRead; 40676af099aSliuyi dwRead = RKU_Read_EX(lpBuffer, 512); 40776af099aSliuyi if ((dwRead < 11) || (dwRead > 512)) 40876af099aSliuyi { 40976af099aSliuyi return ERR_DEVICE_READ_FAILED; 41076af099aSliuyi } 41176af099aSliuyi if (puiRead) 41276af099aSliuyi { 41376af099aSliuyi *puiRead = dwRead; 41476af099aSliuyi } 41576af099aSliuyi /* 41676af099aSliuyi if(!RKU_Read(hDev, lpBuffer, 11)) 41776af099aSliuyi { 41876af099aSliuyi return ERR_DEVICE_READ_FAILED; 41976af099aSliuyi } 42076af099aSliuyi */ 42176af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 42276af099aSliuyi { 42376af099aSliuyi return ERR_DEVICE_READ_FAILED; 42476af099aSliuyi } 42576af099aSliuyi 42676af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 42776af099aSliuyi return ERR_CMD_NOTMATCH; 42876af099aSliuyi 42976af099aSliuyi return ERR_SUCCESS; 43076af099aSliuyi } 431*081d237aSliuyi int CRKUsbComm::RKU_ReadCapability(BYTE* lpBuffer) 432*081d237aSliuyi { 433*081d237aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 434*081d237aSliuyi if (m_log) { 435*081d237aSliuyi m_log->Record("Error:RKU_ReadCapability failed,device not support"); 436*081d237aSliuyi } 437*081d237aSliuyi return ERR_DEVICE_NOT_SUPPORT; 438*081d237aSliuyi } 439*081d237aSliuyi 440*081d237aSliuyi CBW cbw; 441*081d237aSliuyi CSW csw; 442*081d237aSliuyi DWORD dwRead; 443*081d237aSliuyi 444*081d237aSliuyi InitializeCBW(&cbw, READ_CAPABILITY); 445*081d237aSliuyi cbw.dwCBWTransferLength = 8; 446*081d237aSliuyi 447*081d237aSliuyi if(!RKU_Write((BYTE*)&cbw, sizeof(CBW))) 448*081d237aSliuyi { 449*081d237aSliuyi return ERR_DEVICE_WRITE_FAILED; 450*081d237aSliuyi } 451*081d237aSliuyi 452*081d237aSliuyi dwRead = RKU_Read_EX((BYTE*)&csw, sizeof(CSW)); 453*081d237aSliuyi 454*081d237aSliuyi if(dwRead != 8) 455*081d237aSliuyi { 456*081d237aSliuyi return ERR_DEVICE_READ_FAILED; 457*081d237aSliuyi } 458*081d237aSliuyi memcpy(lpBuffer, (BYTE*)&csw, 8); 459*081d237aSliuyi 460*081d237aSliuyi if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) 461*081d237aSliuyi { 462*081d237aSliuyi return ERR_DEVICE_READ_FAILED; 463*081d237aSliuyi } 464*081d237aSliuyi 465*081d237aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 466*081d237aSliuyi return ERR_CMD_NOTMATCH; 467*081d237aSliuyi 468*081d237aSliuyi return ERR_SUCCESS; 469*081d237aSliuyi } 470*081d237aSliuyi 47176af099aSliuyi int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 47276af099aSliuyi { 47376af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 47476af099aSliuyi if (m_log) { 47576af099aSliuyi m_log->Record("Error:RKU_ReadLBA failed,device not support"); 47676af099aSliuyi } 47776af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 47876af099aSliuyi } 47976af099aSliuyi CBW cbw; 48076af099aSliuyi CSW csw; 48176af099aSliuyi USHORT wSectorSize; 48276af099aSliuyi USHORT usSectorLen; 48376af099aSliuyi wSectorSize = 512; 48476af099aSliuyi usSectorLen=dwCount; 48576af099aSliuyi 48676af099aSliuyi InitializeCBW(&cbw, READ_LBA); 487b5200da5Sliuyi cbw.dwCBWTransferLength = dwCount * wSectorSize; 48876af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 48976af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen); 49076af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 49176af099aSliuyi 49276af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 49376af099aSliuyi { 49476af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 49576af099aSliuyi } 49676af099aSliuyi DWORD dwTotal; 49776af099aSliuyi dwTotal = usSectorLen * wSectorSize; 49876af099aSliuyi 49976af099aSliuyi if(!RKU_Read(lpBuffer, dwTotal)) 50076af099aSliuyi { 50176af099aSliuyi return ERR_DEVICE_READ_FAILED; 50276af099aSliuyi } 50376af099aSliuyi 50476af099aSliuyi if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) 50576af099aSliuyi { 50676af099aSliuyi return ERR_DEVICE_READ_FAILED; 50776af099aSliuyi } 50876af099aSliuyi 50976af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 51076af099aSliuyi return ERR_CMD_NOTMATCH; 51176af099aSliuyi 51276af099aSliuyi if(csw.ucCSWStatus == 1) 51376af099aSliuyi return ERR_FAILED; 51476af099aSliuyi 51576af099aSliuyi return ERR_SUCCESS; 51676af099aSliuyi } 51776af099aSliuyi 51876af099aSliuyi int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode) 51976af099aSliuyi { 52076af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 52176af099aSliuyi if (m_log) { 52276af099aSliuyi m_log->Record("Error:RKU_ResetDevice failed,device not support"); 52376af099aSliuyi } 52476af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 52576af099aSliuyi } 52676af099aSliuyi 52776af099aSliuyi CBW cbw; 52876af099aSliuyi CSW csw; 52976af099aSliuyi 53076af099aSliuyi InitializeCBW(&cbw, DEVICE_RESET); 53176af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 53276af099aSliuyi 53376af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 53476af099aSliuyi { 53576af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 53676af099aSliuyi } 53776af099aSliuyi 53876af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 53976af099aSliuyi { 54076af099aSliuyi return ERR_DEVICE_READ_FAILED; 54176af099aSliuyi } 54276af099aSliuyi 54376af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) { 54476af099aSliuyi bool bRet; 54576af099aSliuyi bRet = RKU_ClearBuffer(cbw, csw); 54676af099aSliuyi if (!bRet) { 54776af099aSliuyi return ERR_CMD_NOTMATCH; 54876af099aSliuyi } 54976af099aSliuyi } 55076af099aSliuyi 55176af099aSliuyi if(csw.ucCSWStatus == 1) 55276af099aSliuyi return ERR_FAILED; 55376af099aSliuyi 55476af099aSliuyi return ERR_SUCCESS; 55576af099aSliuyi } 55676af099aSliuyi 55776af099aSliuyi int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode) 55876af099aSliuyi { 55976af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 56076af099aSliuyi if (m_log) { 56176af099aSliuyi m_log->Record("Error:RKU_TestDeviceReady failed,device not support"); 56276af099aSliuyi } 56376af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 56476af099aSliuyi } 56576af099aSliuyi CBW cbw; 56676af099aSliuyi CSW csw; 56776af099aSliuyi 56876af099aSliuyi InitializeCBW(&cbw, TEST_UNIT_READY); 56976af099aSliuyi 57076af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 57176af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 57276af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 57376af099aSliuyi } 57476af099aSliuyi 57576af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 57676af099aSliuyi return ERR_DEVICE_READ_FAILED; 57776af099aSliuyi } 57876af099aSliuyi 57976af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) { 58076af099aSliuyi bool bRet; 58176af099aSliuyi bRet = RKU_ClearBuffer(cbw ,csw); 58276af099aSliuyi if (!bRet) { 58376af099aSliuyi return ERR_CMD_NOTMATCH; 58476af099aSliuyi } 58576af099aSliuyi } 58676af099aSliuyi 58776af099aSliuyi if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) { 58876af099aSliuyi *dwCurrent = (csw.dwCBWDataResidue >>16); 58976af099aSliuyi *dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF); 59076af099aSliuyi 59176af099aSliuyi *dwTotal = EndianU16_BtoL(*dwTotal); 59276af099aSliuyi *dwCurrent = EndianU16_BtoL(*dwCurrent); 59376af099aSliuyi } 59476af099aSliuyi if(csw.ucCSWStatus == 1) { 59576af099aSliuyi return ERR_DEVICE_UNREADY; 59676af099aSliuyi } 59776af099aSliuyi 59876af099aSliuyi return ERR_DEVICE_READY; 59976af099aSliuyi } 60076af099aSliuyi int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 60176af099aSliuyi { 60276af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 60376af099aSliuyi if (m_log) { 60476af099aSliuyi m_log->Record("Error:RKU_WriteLBA failed,device not support"); 60576af099aSliuyi } 60676af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 60776af099aSliuyi } 60876af099aSliuyi CBW cbw; 60976af099aSliuyi CSW csw; 61076af099aSliuyi USHORT wSectorSize; 61176af099aSliuyi USHORT usCount; 61276af099aSliuyi wSectorSize = 512; 61376af099aSliuyi usCount = dwCount; 61476af099aSliuyi DWORD dwTotal = usCount * wSectorSize; 61576af099aSliuyi 61676af099aSliuyi InitializeCBW(&cbw, WRITE_LBA); 617b5200da5Sliuyi cbw.dwCBWTransferLength = dwCount * wSectorSize; 61876af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 61976af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 62076af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 62176af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 62276af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 62376af099aSliuyi } 62476af099aSliuyi 62576af099aSliuyi if(!RKU_Write( lpBuffer, dwTotal)) { 62676af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 62776af099aSliuyi } 62876af099aSliuyi 62976af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 63076af099aSliuyi return ERR_DEVICE_READ_FAILED; 63176af099aSliuyi } 63276af099aSliuyi 63376af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 63476af099aSliuyi return ERR_CMD_NOTMATCH; 63576af099aSliuyi 63676af099aSliuyi if(csw.ucCSWStatus == 1) 63776af099aSliuyi return ERR_FAILED; 63876af099aSliuyi 63976af099aSliuyi return ERR_SUCCESS; 64076af099aSliuyi } 641c29e5f0fSliuyi int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount) 642c29e5f0fSliuyi { 643c29e5f0fSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 644c29e5f0fSliuyi if (m_log) { 645c29e5f0fSliuyi m_log->Record("Error:RKU_WriteLBA failed,device not support"); 646c29e5f0fSliuyi } 647c29e5f0fSliuyi return ERR_DEVICE_NOT_SUPPORT; 648c29e5f0fSliuyi } 649c29e5f0fSliuyi CBW cbw; 650c29e5f0fSliuyi CSW csw; 651c29e5f0fSliuyi USHORT usCount; 652c29e5f0fSliuyi usCount = dwCount; 653c29e5f0fSliuyi 654c29e5f0fSliuyi 655c29e5f0fSliuyi InitializeCBW(&cbw, ERASE_LBA); 656c29e5f0fSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 657c29e5f0fSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 658c29e5f0fSliuyi 659c29e5f0fSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 660c29e5f0fSliuyi return ERR_DEVICE_WRITE_FAILED; 661c29e5f0fSliuyi } 662c29e5f0fSliuyi 663c29e5f0fSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 664c29e5f0fSliuyi return ERR_DEVICE_READ_FAILED; 665c29e5f0fSliuyi } 666c29e5f0fSliuyi 667c29e5f0fSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 668c29e5f0fSliuyi return ERR_CMD_NOTMATCH; 669c29e5f0fSliuyi 670c29e5f0fSliuyi if(csw.ucCSWStatus == 1) 671c29e5f0fSliuyi return ERR_FAILED; 672c29e5f0fSliuyi 673c29e5f0fSliuyi return ERR_SUCCESS; 674c29e5f0fSliuyi } 675c29e5f0fSliuyi 67676af099aSliuyi int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer) 67776af099aSliuyi { 67876af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 67976af099aSliuyi if (m_log) { 68076af099aSliuyi m_log->Record("Error:RKU_WriteSector failed,device not support"); 68176af099aSliuyi } 68276af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 68376af099aSliuyi } 68476af099aSliuyi CBW cbw; 68576af099aSliuyi CSW csw; 68676af099aSliuyi USHORT wSectorSize; 68776af099aSliuyi USHORT usCount; 68876af099aSliuyi usCount=dwCount; 68976af099aSliuyi if(usCount > 32) 69076af099aSliuyi return ERR_CROSS_BORDER; 69176af099aSliuyi 69276af099aSliuyi wSectorSize = 528; 69376af099aSliuyi InitializeCBW(&cbw, WRITE_SECTOR); 694b5200da5Sliuyi cbw.dwCBWTransferLength = dwCount * wSectorSize; 69576af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 69676af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 69776af099aSliuyi 69876af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 69976af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 70076af099aSliuyi } 70176af099aSliuyi 70276af099aSliuyi if(!RKU_Write( lpBuffer, usCount * wSectorSize)) { 70376af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 70476af099aSliuyi } 70576af099aSliuyi 70676af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 70776af099aSliuyi return ERR_DEVICE_READ_FAILED; 70876af099aSliuyi } 70976af099aSliuyi 71076af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 71176af099aSliuyi return ERR_CMD_NOTMATCH; 71276af099aSliuyi 71376af099aSliuyi if(csw.ucCSWStatus == 1) 71476af099aSliuyi return ERR_FAILED; 71576af099aSliuyi 71676af099aSliuyi return ERR_SUCCESS; 71776af099aSliuyi } 71876af099aSliuyi 71976af099aSliuyi 72076af099aSliuyi int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize) 72176af099aSliuyi { 72276af099aSliuyi if (m_deviceDesc.emUsbType != RKUSB_MASKROM) { 72376af099aSliuyi if (m_log) { 72476af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,device not support"); 72576af099aSliuyi } 72676af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 72776af099aSliuyi } 72876af099aSliuyi if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) { 72976af099aSliuyi if (m_log) { 73076af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,request not support"); 73176af099aSliuyi } 73276af099aSliuyi return ERR_REQUEST_NOT_SUPPORT; 73376af099aSliuyi } 73476af099aSliuyi 73576af099aSliuyi bool bSendPendPacket = false; 73676af099aSliuyi USHORT crcValue = 0xffff; 73776af099aSliuyi BYTE *pData = NULL; 73876af099aSliuyi pData = new BYTE[dwDataSize + 5]; 73976af099aSliuyi memset(pData, 0, dwDataSize + 5); 74076af099aSliuyi memcpy(pData, lpBuffer, dwDataSize); 74176af099aSliuyi 74276af099aSliuyi switch(dwDataSize % 4096) { 74376af099aSliuyi case 4095: 74476af099aSliuyi ++dwDataSize; 74576af099aSliuyi break; 74676af099aSliuyi case 4094: 74776af099aSliuyi bSendPendPacket = true; 74876af099aSliuyi break; 74976af099aSliuyi case 0: 75076af099aSliuyi default: 75176af099aSliuyi break; 75276af099aSliuyi } 75376af099aSliuyi 75476af099aSliuyi crcValue = CRC_CCITT(pData, dwDataSize); 75576af099aSliuyi pData[dwDataSize] = (crcValue & 0xff00) >> 8; 75676af099aSliuyi pData[dwDataSize+1] = crcValue & 0x00ff; 75776af099aSliuyi dwDataSize += 2; 75876af099aSliuyi 75976af099aSliuyi UINT nSendBytes = 0; 76076af099aSliuyi DWORD dwTotalSended = 0; 76176af099aSliuyi int iRet; 76276af099aSliuyi 76376af099aSliuyi while(dwTotalSended < dwDataSize) { 76476af099aSliuyi nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended); 76576af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT); 76676af099aSliuyi if (iRet != (int)nSendBytes) { 76776af099aSliuyi if (m_log) { 76876af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet); 76976af099aSliuyi } 77076af099aSliuyi delete []pData; 77176af099aSliuyi return ERR_REQUEST_FAIL; 77276af099aSliuyi } 77376af099aSliuyi dwTotalSended += nSendBytes; 77476af099aSliuyi } 77576af099aSliuyi 77676af099aSliuyi if(bSendPendPacket) { 77776af099aSliuyi BYTE ucFillByte = 0; 77876af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT); 77976af099aSliuyi if (iRet != 0) { 78076af099aSliuyi if (m_log) { 78176af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet); 78276af099aSliuyi } 78376af099aSliuyi delete []pData; 78476af099aSliuyi return ERR_REQUEST_FAIL; 78576af099aSliuyi } 78676af099aSliuyi } 78776af099aSliuyi 78876af099aSliuyi delete []pData; 78976af099aSliuyi 79076af099aSliuyi return ERR_SUCCESS; 79176af099aSliuyi } 79276af099aSliuyi 79376af099aSliuyi 794