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: 19976af099aSliuyi pCBW->ucCBWFlags= DIRECTION_IN; 20076af099aSliuyi pCBW->ucCBWCBLength = 0x06; 20176af099aSliuyi break; 20276af099aSliuyi case DEVICE_RESET: /* Reset Device : 0xff */ 20376af099aSliuyi case ERASE_SYSTEMDISK: 20476af099aSliuyi case SET_RESET_FLAG: 20576af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT; 20676af099aSliuyi pCBW->ucCBWCBLength = 0x06; 20776af099aSliuyi break; 20876af099aSliuyi case TEST_BAD_BLOCK: /* Test Bad Block : 3 */ 20976af099aSliuyi case READ_SECTOR: /* Read Pages : 4 */ 21076af099aSliuyi case READ_LBA: /* Read Pages : 4 */ 21176af099aSliuyi case READ_SDRAM: /* Write Pages : 15 */ 21276af099aSliuyi case READ_SPI_FLASH: 21376af099aSliuyi case READ_NEW_EFUSE: 21476af099aSliuyi pCBW->ucCBWFlags = DIRECTION_IN; 21576af099aSliuyi pCBW->ucCBWCBLength = 0x0a; 21676af099aSliuyi break; 21776af099aSliuyi case WRITE_SECTOR: /* Write Pages : 5 */ 21876af099aSliuyi case WRITE_LBA: /* Write Pages : 15 */ 21976af099aSliuyi case WRITE_SDRAM: /* Write Pages : 15 */ 22076af099aSliuyi case EXECUTE_SDRAM: 22176af099aSliuyi case ERASE_NORMAL: /* Erase Blocks : 6 */ 22276af099aSliuyi case ERASE_FORCE: /* Read Spare : 11 */ 22376af099aSliuyi case WRITE_EFUSE: 22476af099aSliuyi case WRITE_SPI_FLASH: 22576af099aSliuyi case WRITE_NEW_EFUSE: 226*c29e5f0fSliuyi case ERASE_LBA: 22776af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT; 22876af099aSliuyi pCBW->ucCBWCBLength = 0x0a; 22976af099aSliuyi break; 23076af099aSliuyi default: 23176af099aSliuyi break; 23276af099aSliuyi } 23376af099aSliuyi } 23476af099aSliuyi 23576af099aSliuyi 23676af099aSliuyi bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw) 23776af099aSliuyi { 23876af099aSliuyi DWORD dwReadBytes=0; 23976af099aSliuyi DWORD dwTotalRead=0; 24076af099aSliuyi int iTryCount; 24176af099aSliuyi iTryCount = 3; 24276af099aSliuyi do { 24376af099aSliuyi dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) ); 24476af099aSliuyi 24576af099aSliuyi if (UFI_CHECK_SIGN(cbw,csw)) 24676af099aSliuyi { 24776af099aSliuyi return true; 24876af099aSliuyi } 24976af099aSliuyi if (dwReadBytes != sizeof(CSW)) 25076af099aSliuyi { 25176af099aSliuyi iTryCount--; 25276af099aSliuyi sleep(3); 25376af099aSliuyi } 25476af099aSliuyi dwTotalRead += dwReadBytes; 25576af099aSliuyi if (dwTotalRead >= MAX_CLEAR_LEN) 25676af099aSliuyi { 25776af099aSliuyi break; 25876af099aSliuyi } 25976af099aSliuyi }while ( iTryCount > 0 ); 26076af099aSliuyi return false; 26176af099aSliuyi } 26276af099aSliuyi 26376af099aSliuyi DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize) 26476af099aSliuyi { 26576af099aSliuyi int iRet; 26676af099aSliuyi int nRead; 26776af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000); 26876af099aSliuyi if (iRet != 0) { 26976af099aSliuyi if (m_log) { 27076af099aSliuyi m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet); 27176af099aSliuyi } 27276af099aSliuyi return 0; 27376af099aSliuyi } 27476af099aSliuyi return nRead; 27576af099aSliuyi } 27676af099aSliuyi 27776af099aSliuyi int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType) 27876af099aSliuyi { 27976af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 28076af099aSliuyi if (m_log) { 28176af099aSliuyi m_log->Record("Error:RKU_EraseBlock failed,device not support"); 28276af099aSliuyi } 28376af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 28476af099aSliuyi } 28576af099aSliuyi CBW cbw; 28676af099aSliuyi CSW csw; 28776af099aSliuyi USHORT usCount; 28876af099aSliuyi usCount = dwCount; 28976af099aSliuyi if(dwCount > MAX_ERASE_BLOCKS) 29076af099aSliuyi return ERR_CROSS_BORDER; 29176af099aSliuyi 29276af099aSliuyi InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType); 29376af099aSliuyi cbw.ucCBWLUN = ucFlashCS; 29476af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 29576af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 29676af099aSliuyi 29776af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 29876af099aSliuyi { 29976af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 30076af099aSliuyi } 30176af099aSliuyi 30276af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 30376af099aSliuyi { 30476af099aSliuyi return ERR_DEVICE_READ_FAILED; 30576af099aSliuyi } 30676af099aSliuyi 30776af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 30876af099aSliuyi return ERR_CMD_NOTMATCH; 30976af099aSliuyi 31076af099aSliuyi if(csw.ucCSWStatus == 1) 31176af099aSliuyi return ERR_FOUND_BAD_BLOCK; 31276af099aSliuyi 31376af099aSliuyi return ERR_SUCCESS; 31476af099aSliuyi } 31576af099aSliuyi int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer) 31676af099aSliuyi { 31776af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 31876af099aSliuyi if (m_log) { 31976af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 32076af099aSliuyi } 32176af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 32276af099aSliuyi } 32376af099aSliuyi 32476af099aSliuyi CBW cbw; 32576af099aSliuyi CSW csw; 32676af099aSliuyi 32776af099aSliuyi InitializeCBW(&cbw, READ_CHIP_INFO); 32876af099aSliuyi 32976af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 33076af099aSliuyi { 33176af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 33276af099aSliuyi } 33376af099aSliuyi 33476af099aSliuyi if(!RKU_Read(lpBuffer, 16)) 33576af099aSliuyi { 33676af099aSliuyi return ERR_DEVICE_READ_FAILED; 33776af099aSliuyi } 33876af099aSliuyi 33976af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 34076af099aSliuyi { 34176af099aSliuyi return ERR_DEVICE_READ_FAILED; 34276af099aSliuyi } 34376af099aSliuyi 34476af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 34576af099aSliuyi return ERR_CMD_NOTMATCH; 34676af099aSliuyi 34776af099aSliuyi return ERR_SUCCESS; 34876af099aSliuyi } 34976af099aSliuyi int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer) 35076af099aSliuyi { 35176af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 35276af099aSliuyi if (m_log) { 35376af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 35476af099aSliuyi } 35576af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 35676af099aSliuyi } 35776af099aSliuyi 35876af099aSliuyi CBW cbw; 35976af099aSliuyi CSW csw; 36076af099aSliuyi 36176af099aSliuyi InitializeCBW(&cbw, READ_FLASH_ID); 36276af099aSliuyi 36376af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 36476af099aSliuyi { 36576af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 36676af099aSliuyi } 36776af099aSliuyi 36876af099aSliuyi if(!RKU_Read(lpBuffer, 5)) 36976af099aSliuyi { 37076af099aSliuyi return ERR_DEVICE_READ_FAILED; 37176af099aSliuyi } 37276af099aSliuyi 37376af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 37476af099aSliuyi { 37576af099aSliuyi return ERR_DEVICE_READ_FAILED; 37676af099aSliuyi } 37776af099aSliuyi 37876af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 37976af099aSliuyi return ERR_CMD_NOTMATCH; 38076af099aSliuyi 38176af099aSliuyi return ERR_SUCCESS; 38276af099aSliuyi } 38376af099aSliuyi int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead) 38476af099aSliuyi { 38576af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 38676af099aSliuyi if (m_log) { 38776af099aSliuyi m_log->Record("Error:RKU_ReadFlashInfo failed,device not support"); 38876af099aSliuyi } 38976af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 39076af099aSliuyi } 39176af099aSliuyi CBW cbw; 39276af099aSliuyi CSW csw; 39376af099aSliuyi 39476af099aSliuyi InitializeCBW(&cbw, READ_FLASH_INFO); 39576af099aSliuyi 39676af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 39776af099aSliuyi { 39876af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 39976af099aSliuyi } 40076af099aSliuyi 40176af099aSliuyi DWORD dwRead; 40276af099aSliuyi dwRead = RKU_Read_EX(lpBuffer, 512); 40376af099aSliuyi if ((dwRead < 11) || (dwRead > 512)) 40476af099aSliuyi { 40576af099aSliuyi return ERR_DEVICE_READ_FAILED; 40676af099aSliuyi } 40776af099aSliuyi if (puiRead) 40876af099aSliuyi { 40976af099aSliuyi *puiRead = dwRead; 41076af099aSliuyi } 41176af099aSliuyi /* 41276af099aSliuyi if(!RKU_Read(hDev, lpBuffer, 11)) 41376af099aSliuyi { 41476af099aSliuyi return ERR_DEVICE_READ_FAILED; 41576af099aSliuyi } 41676af099aSliuyi */ 41776af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 41876af099aSliuyi { 41976af099aSliuyi return ERR_DEVICE_READ_FAILED; 42076af099aSliuyi } 42176af099aSliuyi 42276af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 42376af099aSliuyi return ERR_CMD_NOTMATCH; 42476af099aSliuyi 42576af099aSliuyi return ERR_SUCCESS; 42676af099aSliuyi } 42776af099aSliuyi int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 42876af099aSliuyi { 42976af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 43076af099aSliuyi if (m_log) { 43176af099aSliuyi m_log->Record("Error:RKU_ReadLBA failed,device not support"); 43276af099aSliuyi } 43376af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 43476af099aSliuyi } 43576af099aSliuyi CBW cbw; 43676af099aSliuyi CSW csw; 43776af099aSliuyi USHORT wSectorSize; 43876af099aSliuyi USHORT usSectorLen; 43976af099aSliuyi wSectorSize = 512; 44076af099aSliuyi usSectorLen=dwCount; 44176af099aSliuyi 44276af099aSliuyi InitializeCBW(&cbw, READ_LBA); 44376af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 44476af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen); 44576af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 44676af099aSliuyi 44776af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 44876af099aSliuyi { 44976af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 45076af099aSliuyi } 45176af099aSliuyi DWORD dwTotal; 45276af099aSliuyi dwTotal = usSectorLen * wSectorSize; 45376af099aSliuyi 45476af099aSliuyi if(!RKU_Read(lpBuffer, dwTotal)) 45576af099aSliuyi { 45676af099aSliuyi return ERR_DEVICE_READ_FAILED; 45776af099aSliuyi } 45876af099aSliuyi 45976af099aSliuyi if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) 46076af099aSliuyi { 46176af099aSliuyi return ERR_DEVICE_READ_FAILED; 46276af099aSliuyi } 46376af099aSliuyi 46476af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 46576af099aSliuyi return ERR_CMD_NOTMATCH; 46676af099aSliuyi 46776af099aSliuyi if(csw.ucCSWStatus == 1) 46876af099aSliuyi return ERR_FAILED; 46976af099aSliuyi 47076af099aSliuyi return ERR_SUCCESS; 47176af099aSliuyi } 47276af099aSliuyi 47376af099aSliuyi int CRKUsbComm::RKU_ResetDevice(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_ResetDevice failed,device not support"); 47876af099aSliuyi } 47976af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 48076af099aSliuyi } 48176af099aSliuyi 48276af099aSliuyi CBW cbw; 48376af099aSliuyi CSW csw; 48476af099aSliuyi 48576af099aSliuyi InitializeCBW(&cbw, DEVICE_RESET); 48676af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 48776af099aSliuyi 48876af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 48976af099aSliuyi { 49076af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 49176af099aSliuyi } 49276af099aSliuyi 49376af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 49476af099aSliuyi { 49576af099aSliuyi return ERR_DEVICE_READ_FAILED; 49676af099aSliuyi } 49776af099aSliuyi 49876af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) { 49976af099aSliuyi bool bRet; 50076af099aSliuyi bRet = RKU_ClearBuffer(cbw, csw); 50176af099aSliuyi if (!bRet) { 50276af099aSliuyi return ERR_CMD_NOTMATCH; 50376af099aSliuyi } 50476af099aSliuyi } 50576af099aSliuyi 50676af099aSliuyi if(csw.ucCSWStatus == 1) 50776af099aSliuyi return ERR_FAILED; 50876af099aSliuyi 50976af099aSliuyi return ERR_SUCCESS; 51076af099aSliuyi } 51176af099aSliuyi 51276af099aSliuyi int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode) 51376af099aSliuyi { 51476af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 51576af099aSliuyi if (m_log) { 51676af099aSliuyi m_log->Record("Error:RKU_TestDeviceReady failed,device not support"); 51776af099aSliuyi } 51876af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 51976af099aSliuyi } 52076af099aSliuyi CBW cbw; 52176af099aSliuyi CSW csw; 52276af099aSliuyi 52376af099aSliuyi InitializeCBW(&cbw, TEST_UNIT_READY); 52476af099aSliuyi 52576af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 52676af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 52776af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 52876af099aSliuyi } 52976af099aSliuyi 53076af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 53176af099aSliuyi return ERR_DEVICE_READ_FAILED; 53276af099aSliuyi } 53376af099aSliuyi 53476af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) { 53576af099aSliuyi bool bRet; 53676af099aSliuyi bRet = RKU_ClearBuffer(cbw ,csw); 53776af099aSliuyi if (!bRet) { 53876af099aSliuyi return ERR_CMD_NOTMATCH; 53976af099aSliuyi } 54076af099aSliuyi } 54176af099aSliuyi 54276af099aSliuyi if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) { 54376af099aSliuyi *dwCurrent = (csw.dwCBWDataResidue >>16); 54476af099aSliuyi *dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF); 54576af099aSliuyi 54676af099aSliuyi *dwTotal = EndianU16_BtoL(*dwTotal); 54776af099aSliuyi *dwCurrent = EndianU16_BtoL(*dwCurrent); 54876af099aSliuyi } 54976af099aSliuyi if(csw.ucCSWStatus == 1) { 55076af099aSliuyi return ERR_DEVICE_UNREADY; 55176af099aSliuyi } 55276af099aSliuyi 55376af099aSliuyi return ERR_DEVICE_READY; 55476af099aSliuyi } 55576af099aSliuyi int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 55676af099aSliuyi { 55776af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 55876af099aSliuyi if (m_log) { 55976af099aSliuyi m_log->Record("Error:RKU_WriteLBA failed,device not support"); 56076af099aSliuyi } 56176af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 56276af099aSliuyi } 56376af099aSliuyi CBW cbw; 56476af099aSliuyi CSW csw; 56576af099aSliuyi USHORT wSectorSize; 56676af099aSliuyi USHORT usCount; 56776af099aSliuyi wSectorSize = 512; 56876af099aSliuyi usCount = dwCount; 56976af099aSliuyi DWORD dwTotal = usCount * wSectorSize; 57076af099aSliuyi 57176af099aSliuyi InitializeCBW(&cbw, WRITE_LBA); 57276af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 57376af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 57476af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 57576af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 57676af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 57776af099aSliuyi } 57876af099aSliuyi 57976af099aSliuyi if(!RKU_Write( lpBuffer, dwTotal)) { 58076af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 58176af099aSliuyi } 58276af099aSliuyi 58376af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 58476af099aSliuyi return ERR_DEVICE_READ_FAILED; 58576af099aSliuyi } 58676af099aSliuyi 58776af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 58876af099aSliuyi return ERR_CMD_NOTMATCH; 58976af099aSliuyi 59076af099aSliuyi if(csw.ucCSWStatus == 1) 59176af099aSliuyi return ERR_FAILED; 59276af099aSliuyi 59376af099aSliuyi return ERR_SUCCESS; 59476af099aSliuyi } 595*c29e5f0fSliuyi int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount) 596*c29e5f0fSliuyi { 597*c29e5f0fSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 598*c29e5f0fSliuyi if (m_log) { 599*c29e5f0fSliuyi m_log->Record("Error:RKU_WriteLBA failed,device not support"); 600*c29e5f0fSliuyi } 601*c29e5f0fSliuyi return ERR_DEVICE_NOT_SUPPORT; 602*c29e5f0fSliuyi } 603*c29e5f0fSliuyi CBW cbw; 604*c29e5f0fSliuyi CSW csw; 605*c29e5f0fSliuyi USHORT usCount; 606*c29e5f0fSliuyi usCount = dwCount; 607*c29e5f0fSliuyi 608*c29e5f0fSliuyi 609*c29e5f0fSliuyi InitializeCBW(&cbw, ERASE_LBA); 610*c29e5f0fSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 611*c29e5f0fSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 612*c29e5f0fSliuyi 613*c29e5f0fSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 614*c29e5f0fSliuyi return ERR_DEVICE_WRITE_FAILED; 615*c29e5f0fSliuyi } 616*c29e5f0fSliuyi 617*c29e5f0fSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 618*c29e5f0fSliuyi return ERR_DEVICE_READ_FAILED; 619*c29e5f0fSliuyi } 620*c29e5f0fSliuyi 621*c29e5f0fSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 622*c29e5f0fSliuyi return ERR_CMD_NOTMATCH; 623*c29e5f0fSliuyi 624*c29e5f0fSliuyi if(csw.ucCSWStatus == 1) 625*c29e5f0fSliuyi return ERR_FAILED; 626*c29e5f0fSliuyi 627*c29e5f0fSliuyi return ERR_SUCCESS; 628*c29e5f0fSliuyi } 629*c29e5f0fSliuyi 63076af099aSliuyi int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer) 63176af099aSliuyi { 63276af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 63376af099aSliuyi if (m_log) { 63476af099aSliuyi m_log->Record("Error:RKU_WriteSector failed,device not support"); 63576af099aSliuyi } 63676af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 63776af099aSliuyi } 63876af099aSliuyi CBW cbw; 63976af099aSliuyi CSW csw; 64076af099aSliuyi USHORT wSectorSize; 64176af099aSliuyi USHORT usCount; 64276af099aSliuyi usCount=dwCount; 64376af099aSliuyi if(usCount > 32) 64476af099aSliuyi return ERR_CROSS_BORDER; 64576af099aSliuyi 64676af099aSliuyi wSectorSize = 528; 64776af099aSliuyi InitializeCBW(&cbw, WRITE_SECTOR); 64876af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 64976af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 65076af099aSliuyi 65176af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 65276af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 65376af099aSliuyi } 65476af099aSliuyi 65576af099aSliuyi if(!RKU_Write( lpBuffer, usCount * wSectorSize)) { 65676af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 65776af099aSliuyi } 65876af099aSliuyi 65976af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 66076af099aSliuyi return ERR_DEVICE_READ_FAILED; 66176af099aSliuyi } 66276af099aSliuyi 66376af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 66476af099aSliuyi return ERR_CMD_NOTMATCH; 66576af099aSliuyi 66676af099aSliuyi if(csw.ucCSWStatus == 1) 66776af099aSliuyi return ERR_FAILED; 66876af099aSliuyi 66976af099aSliuyi return ERR_SUCCESS; 67076af099aSliuyi } 67176af099aSliuyi 67276af099aSliuyi 67376af099aSliuyi int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize) 67476af099aSliuyi { 67576af099aSliuyi if (m_deviceDesc.emUsbType != RKUSB_MASKROM) { 67676af099aSliuyi if (m_log) { 67776af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,device not support"); 67876af099aSliuyi } 67976af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 68076af099aSliuyi } 68176af099aSliuyi if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) { 68276af099aSliuyi if (m_log) { 68376af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,request not support"); 68476af099aSliuyi } 68576af099aSliuyi return ERR_REQUEST_NOT_SUPPORT; 68676af099aSliuyi } 68776af099aSliuyi 68876af099aSliuyi bool bSendPendPacket = false; 68976af099aSliuyi USHORT crcValue = 0xffff; 69076af099aSliuyi BYTE *pData = NULL; 69176af099aSliuyi pData = new BYTE[dwDataSize + 5]; 69276af099aSliuyi memset(pData, 0, dwDataSize + 5); 69376af099aSliuyi memcpy(pData, lpBuffer, dwDataSize); 69476af099aSliuyi 69576af099aSliuyi switch(dwDataSize % 4096) { 69676af099aSliuyi case 4095: 69776af099aSliuyi ++dwDataSize; 69876af099aSliuyi break; 69976af099aSliuyi case 4094: 70076af099aSliuyi bSendPendPacket = true; 70176af099aSliuyi break; 70276af099aSliuyi case 0: 70376af099aSliuyi default: 70476af099aSliuyi break; 70576af099aSliuyi } 70676af099aSliuyi 70776af099aSliuyi crcValue = CRC_CCITT(pData, dwDataSize); 70876af099aSliuyi pData[dwDataSize] = (crcValue & 0xff00) >> 8; 70976af099aSliuyi pData[dwDataSize+1] = crcValue & 0x00ff; 71076af099aSliuyi dwDataSize += 2; 71176af099aSliuyi 71276af099aSliuyi UINT nSendBytes = 0; 71376af099aSliuyi DWORD dwTotalSended = 0; 71476af099aSliuyi int iRet; 71576af099aSliuyi 71676af099aSliuyi while(dwTotalSended < dwDataSize) { 71776af099aSliuyi nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended); 71876af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT); 71976af099aSliuyi if (iRet != (int)nSendBytes) { 72076af099aSliuyi if (m_log) { 72176af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet); 72276af099aSliuyi } 72376af099aSliuyi delete []pData; 72476af099aSliuyi return ERR_REQUEST_FAIL; 72576af099aSliuyi } 72676af099aSliuyi dwTotalSended += nSendBytes; 72776af099aSliuyi } 72876af099aSliuyi 72976af099aSliuyi if(bSendPendPacket) { 73076af099aSliuyi BYTE ucFillByte = 0; 73176af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT); 73276af099aSliuyi if (iRet != 0) { 73376af099aSliuyi if (m_log) { 73476af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet); 73576af099aSliuyi } 73676af099aSliuyi delete []pData; 73776af099aSliuyi return ERR_REQUEST_FAIL; 73876af099aSliuyi } 73976af099aSliuyi } 74076af099aSliuyi 74176af099aSliuyi delete []pData; 74276af099aSliuyi 74376af099aSliuyi return ERR_SUCCESS; 74476af099aSliuyi } 74576af099aSliuyi 74676af099aSliuyi 747