1*76af099aSliuyi /* 2*76af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 3*76af099aSliuyi * Seth Liu 2017.03.01 4*76af099aSliuyi * 5*76af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 6*76af099aSliuyi */ 7*76af099aSliuyi 8*76af099aSliuyi #include "RKComm.h" 9*76af099aSliuyi #include "RKLog.h" 10*76af099aSliuyi #include "Endian.h" 11*76af099aSliuyi extern unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber); 12*76af099aSliuyi CRKComm::CRKComm(CRKLog *pLog) 13*76af099aSliuyi { 14*76af099aSliuyi memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC)); 15*76af099aSliuyi m_log = pLog; 16*76af099aSliuyi } 17*76af099aSliuyi CRKComm::~CRKComm() 18*76af099aSliuyi { 19*76af099aSliuyi } 20*76af099aSliuyi 21*76af099aSliuyi CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog) 22*76af099aSliuyi { 23*76af099aSliuyi bRet = InitializeUsb(devDesc); 24*76af099aSliuyi } 25*76af099aSliuyi CRKUsbComm::~CRKUsbComm() 26*76af099aSliuyi { 27*76af099aSliuyi UninitializeUsb(); 28*76af099aSliuyi } 29*76af099aSliuyi 30*76af099aSliuyi bool CRKUsbComm::InitializeUsb(STRUCT_RKDEVICE_DESC devDesc) 31*76af099aSliuyi { 32*76af099aSliuyi m_pUsbHandle = NULL; 33*76af099aSliuyi m_pipeBulkIn = m_pipeBulkOut = 0; 34*76af099aSliuyi m_interfaceNum = -1; 35*76af099aSliuyi if (!devDesc.pUsbHandle) { 36*76af099aSliuyi return false; 37*76af099aSliuyi } 38*76af099aSliuyi memcpy(&m_deviceDesc, &devDesc, sizeof(STRUCT_RKDEVICE_DESC)); 39*76af099aSliuyi int iRet; 40*76af099aSliuyi iRet = libusb_open((libusb_device *)devDesc.pUsbHandle, (libusb_device_handle **)&m_pUsbHandle); 41*76af099aSliuyi if (iRet!=0) { 42*76af099aSliuyi if (m_log) { 43*76af099aSliuyi m_log->Record("Error:InitializeUsb-->open device failed,err=%d", iRet); 44*76af099aSliuyi } 45*76af099aSliuyi return false; 46*76af099aSliuyi } 47*76af099aSliuyi struct libusb_config_descriptor *pConfigDesc=NULL; 48*76af099aSliuyi iRet = libusb_get_active_config_descriptor((libusb_device *)devDesc.pUsbHandle, &pConfigDesc); 49*76af099aSliuyi if (iRet!=0) { 50*76af099aSliuyi if (m_log) { 51*76af099aSliuyi m_log->Record("Error:InitializeUsb-->get device config descriptor failed, err=%d", iRet); 52*76af099aSliuyi } 53*76af099aSliuyi return false; 54*76af099aSliuyi } 55*76af099aSliuyi int i, j, k; 56*76af099aSliuyi const struct libusb_interface *pInterface; 57*76af099aSliuyi const struct libusb_endpoint_descriptor *pEndpointDesc; 58*76af099aSliuyi const struct libusb_interface_descriptor *pInterfaceDesc; 59*76af099aSliuyi for(i = 0; i < pConfigDesc->bNumInterfaces; i++) { 60*76af099aSliuyi pInterface = pConfigDesc->interface + i; 61*76af099aSliuyi for(j = 0; j < pInterface->num_altsetting; j++) { 62*76af099aSliuyi pInterfaceDesc = pInterface->altsetting+j; 63*76af099aSliuyi if (m_deviceDesc.emUsbType == RKUSB_MSC) { 64*76af099aSliuyi if( (pInterfaceDesc->bInterfaceClass != 8) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 0x50)) 65*76af099aSliuyi continue; 66*76af099aSliuyi } 67*76af099aSliuyi else 68*76af099aSliuyi { 69*76af099aSliuyi if( (pInterfaceDesc->bInterfaceClass != 0xff) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 5)) 70*76af099aSliuyi continue; 71*76af099aSliuyi } 72*76af099aSliuyi for(k = 0; k < pInterfaceDesc->bNumEndpoints; k++) { 73*76af099aSliuyi pEndpointDesc = pInterfaceDesc->endpoint+k; 74*76af099aSliuyi if ((pEndpointDesc->bEndpointAddress & 0x80) == 0) { 75*76af099aSliuyi if (m_pipeBulkOut == 0) 76*76af099aSliuyi m_pipeBulkOut = pEndpointDesc->bEndpointAddress; 77*76af099aSliuyi } 78*76af099aSliuyi else { 79*76af099aSliuyi if (m_pipeBulkIn == 0) 80*76af099aSliuyi m_pipeBulkIn = pEndpointDesc->bEndpointAddress; 81*76af099aSliuyi } 82*76af099aSliuyi if ((m_pipeBulkIn != 0) && (m_pipeBulkOut != 0)) {//found it 83*76af099aSliuyi m_interfaceNum = i; 84*76af099aSliuyi libusb_free_config_descriptor(pConfigDesc); 85*76af099aSliuyi iRet = libusb_claim_interface((libusb_device_handle *)m_pUsbHandle, m_interfaceNum); 86*76af099aSliuyi if (iRet != 0) { 87*76af099aSliuyi if (m_log) { 88*76af099aSliuyi m_log->Record("Error:libusb_claim_interface failed,err=%d", iRet); 89*76af099aSliuyi } 90*76af099aSliuyi return false; 91*76af099aSliuyi } 92*76af099aSliuyi return true; 93*76af099aSliuyi } 94*76af099aSliuyi } 95*76af099aSliuyi } 96*76af099aSliuyi } 97*76af099aSliuyi libusb_free_config_descriptor(pConfigDesc); 98*76af099aSliuyi return false; 99*76af099aSliuyi } 100*76af099aSliuyi void CRKUsbComm::UninitializeUsb() 101*76af099aSliuyi { 102*76af099aSliuyi if (m_pUsbHandle) { 103*76af099aSliuyi libusb_close((libusb_device_handle *)m_pUsbHandle); 104*76af099aSliuyi m_pUsbHandle = NULL; 105*76af099aSliuyi } 106*76af099aSliuyi memset(&m_deviceDesc, 0, sizeof(STRUCT_RKDEVICE_DESC)); 107*76af099aSliuyi m_pipeBulkIn = m_pipeBulkOut = 0; 108*76af099aSliuyi return ; 109*76af099aSliuyi } 110*76af099aSliuyi bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc) 111*76af099aSliuyi { 112*76af099aSliuyi bool bRet; 113*76af099aSliuyi UninitializeUsb(); 114*76af099aSliuyi bRet = InitializeUsb(devDesc); 115*76af099aSliuyi return bRet; 116*76af099aSliuyi } 117*76af099aSliuyi bool CRKUsbComm::Reset_Usb_Device() 118*76af099aSliuyi { 119*76af099aSliuyi int iRet = -1; 120*76af099aSliuyi if (m_pUsbHandle) { 121*76af099aSliuyi iRet=libusb_reset_device((libusb_device_handle *)m_pUsbHandle); 122*76af099aSliuyi } 123*76af099aSliuyi return (iRet == 0) ? true : false; 124*76af099aSliuyi } 125*76af099aSliuyi 126*76af099aSliuyi bool CRKUsbComm::RKU_Read(BYTE* lpBuffer, DWORD dwSize) 127*76af099aSliuyi { 128*76af099aSliuyi int iRet; 129*76af099aSliuyi int nRead; 130*76af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, CMD_TIMEOUT); 131*76af099aSliuyi if (iRet!=0) { 132*76af099aSliuyi if (m_log) { 133*76af099aSliuyi m_log->Record("Error:RKU_Read failed,err=%d", iRet); 134*76af099aSliuyi } 135*76af099aSliuyi return false; 136*76af099aSliuyi } 137*76af099aSliuyi if (nRead != (int)dwSize) { 138*76af099aSliuyi if (m_log) { 139*76af099aSliuyi m_log->Record("Error:RKU_Read failed, size=%d, read=%d", dwSize, nRead); 140*76af099aSliuyi } 141*76af099aSliuyi return false; 142*76af099aSliuyi } 143*76af099aSliuyi return true; 144*76af099aSliuyi } 145*76af099aSliuyi 146*76af099aSliuyi bool CRKUsbComm::RKU_Write(BYTE* lpBuffer, DWORD dwSize) 147*76af099aSliuyi { 148*76af099aSliuyi int iRet; 149*76af099aSliuyi int nWrite; 150*76af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkOut, lpBuffer, dwSize, &nWrite, CMD_TIMEOUT); 151*76af099aSliuyi if (iRet != 0) { 152*76af099aSliuyi if (m_log) { 153*76af099aSliuyi m_log->Record("Error:RKU_Write failed, err=%d", iRet); 154*76af099aSliuyi } 155*76af099aSliuyi return false; 156*76af099aSliuyi } 157*76af099aSliuyi if (nWrite != (int)dwSize) { 158*76af099aSliuyi if (m_log) { 159*76af099aSliuyi m_log->Record("Error:RKU_Write failed, size=%d, read=%d", dwSize, nWrite); 160*76af099aSliuyi } 161*76af099aSliuyi return false; 162*76af099aSliuyi } 163*76af099aSliuyi return true; 164*76af099aSliuyi } 165*76af099aSliuyi int CRKUsbComm::RandomInteger(int low, int high) 166*76af099aSliuyi { 167*76af099aSliuyi int k; 168*76af099aSliuyi double d; 169*76af099aSliuyi 170*76af099aSliuyi d = (double)rand() / ((double)RAND_MAX + 1); 171*76af099aSliuyi k = (int)(d * (high - low + 1)); 172*76af099aSliuyi return (low + k); 173*76af099aSliuyi } 174*76af099aSliuyi DWORD CRKUsbComm::MakeCBWTag() 175*76af099aSliuyi { 176*76af099aSliuyi DWORD tag = 0; 177*76af099aSliuyi int i = 0; 178*76af099aSliuyi 179*76af099aSliuyi for(i=0; i<4; i++){ 180*76af099aSliuyi tag <<= 8; 181*76af099aSliuyi tag += RandomInteger(0, 0xFF); 182*76af099aSliuyi } 183*76af099aSliuyi return tag; 184*76af099aSliuyi } 185*76af099aSliuyi void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code) 186*76af099aSliuyi { 187*76af099aSliuyi memset(pCBW,0, sizeof(CBW)); 188*76af099aSliuyi 189*76af099aSliuyi pCBW->dwCBWSignature = CBW_SIGN; 190*76af099aSliuyi pCBW->dwCBWTag = MakeCBWTag(); 191*76af099aSliuyi pCBW->cbwcb.ucOperCode = code; 192*76af099aSliuyi 193*76af099aSliuyi switch(code) { 194*76af099aSliuyi case TEST_UNIT_READY: /* Test Unit Ready : 0 */ 195*76af099aSliuyi case READ_FLASH_ID: /* Read Flash ID : 1 */ 196*76af099aSliuyi case READ_FLASH_INFO: 197*76af099aSliuyi case READ_CHIP_INFO: 198*76af099aSliuyi case READ_EFUSE: 199*76af099aSliuyi pCBW->ucCBWFlags= DIRECTION_IN; 200*76af099aSliuyi pCBW->ucCBWCBLength = 0x06; 201*76af099aSliuyi break; 202*76af099aSliuyi case DEVICE_RESET: /* Reset Device : 0xff */ 203*76af099aSliuyi case ERASE_SYSTEMDISK: 204*76af099aSliuyi case SET_RESET_FLAG: 205*76af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT; 206*76af099aSliuyi pCBW->ucCBWCBLength = 0x06; 207*76af099aSliuyi break; 208*76af099aSliuyi case TEST_BAD_BLOCK: /* Test Bad Block : 3 */ 209*76af099aSliuyi case READ_SECTOR: /* Read Pages : 4 */ 210*76af099aSliuyi case READ_LBA: /* Read Pages : 4 */ 211*76af099aSliuyi case READ_SDRAM: /* Write Pages : 15 */ 212*76af099aSliuyi case READ_SPI_FLASH: 213*76af099aSliuyi case READ_NEW_EFUSE: 214*76af099aSliuyi pCBW->ucCBWFlags = DIRECTION_IN; 215*76af099aSliuyi pCBW->ucCBWCBLength = 0x0a; 216*76af099aSliuyi break; 217*76af099aSliuyi case WRITE_SECTOR: /* Write Pages : 5 */ 218*76af099aSliuyi case WRITE_LBA: /* Write Pages : 15 */ 219*76af099aSliuyi case WRITE_SDRAM: /* Write Pages : 15 */ 220*76af099aSliuyi case EXECUTE_SDRAM: 221*76af099aSliuyi case ERASE_NORMAL: /* Erase Blocks : 6 */ 222*76af099aSliuyi case ERASE_FORCE: /* Read Spare : 11 */ 223*76af099aSliuyi case WRITE_EFUSE: 224*76af099aSliuyi case WRITE_SPI_FLASH: 225*76af099aSliuyi case WRITE_NEW_EFUSE: 226*76af099aSliuyi pCBW->ucCBWFlags = DIRECTION_OUT; 227*76af099aSliuyi pCBW->ucCBWCBLength = 0x0a; 228*76af099aSliuyi break; 229*76af099aSliuyi default: 230*76af099aSliuyi break; 231*76af099aSliuyi } 232*76af099aSliuyi } 233*76af099aSliuyi 234*76af099aSliuyi 235*76af099aSliuyi bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw) 236*76af099aSliuyi { 237*76af099aSliuyi DWORD dwReadBytes=0; 238*76af099aSliuyi DWORD dwTotalRead=0; 239*76af099aSliuyi int iTryCount; 240*76af099aSliuyi iTryCount = 3; 241*76af099aSliuyi do { 242*76af099aSliuyi dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) ); 243*76af099aSliuyi 244*76af099aSliuyi if (UFI_CHECK_SIGN(cbw,csw)) 245*76af099aSliuyi { 246*76af099aSliuyi return true; 247*76af099aSliuyi } 248*76af099aSliuyi if (dwReadBytes != sizeof(CSW)) 249*76af099aSliuyi { 250*76af099aSliuyi iTryCount--; 251*76af099aSliuyi sleep(3); 252*76af099aSliuyi } 253*76af099aSliuyi dwTotalRead += dwReadBytes; 254*76af099aSliuyi if (dwTotalRead >= MAX_CLEAR_LEN) 255*76af099aSliuyi { 256*76af099aSliuyi break; 257*76af099aSliuyi } 258*76af099aSliuyi }while ( iTryCount > 0 ); 259*76af099aSliuyi return false; 260*76af099aSliuyi } 261*76af099aSliuyi 262*76af099aSliuyi DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize) 263*76af099aSliuyi { 264*76af099aSliuyi int iRet; 265*76af099aSliuyi int nRead; 266*76af099aSliuyi iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000); 267*76af099aSliuyi if (iRet != 0) { 268*76af099aSliuyi if (m_log) { 269*76af099aSliuyi m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet); 270*76af099aSliuyi } 271*76af099aSliuyi return 0; 272*76af099aSliuyi } 273*76af099aSliuyi return nRead; 274*76af099aSliuyi } 275*76af099aSliuyi 276*76af099aSliuyi int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType) 277*76af099aSliuyi { 278*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 279*76af099aSliuyi if (m_log) { 280*76af099aSliuyi m_log->Record("Error:RKU_EraseBlock failed,device not support"); 281*76af099aSliuyi } 282*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 283*76af099aSliuyi } 284*76af099aSliuyi CBW cbw; 285*76af099aSliuyi CSW csw; 286*76af099aSliuyi USHORT usCount; 287*76af099aSliuyi usCount = dwCount; 288*76af099aSliuyi if(dwCount > MAX_ERASE_BLOCKS) 289*76af099aSliuyi return ERR_CROSS_BORDER; 290*76af099aSliuyi 291*76af099aSliuyi InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType); 292*76af099aSliuyi cbw.ucCBWLUN = ucFlashCS; 293*76af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 294*76af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 295*76af099aSliuyi 296*76af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 297*76af099aSliuyi { 298*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 299*76af099aSliuyi } 300*76af099aSliuyi 301*76af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 302*76af099aSliuyi { 303*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 304*76af099aSliuyi } 305*76af099aSliuyi 306*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 307*76af099aSliuyi return ERR_CMD_NOTMATCH; 308*76af099aSliuyi 309*76af099aSliuyi if(csw.ucCSWStatus == 1) 310*76af099aSliuyi return ERR_FOUND_BAD_BLOCK; 311*76af099aSliuyi 312*76af099aSliuyi return ERR_SUCCESS; 313*76af099aSliuyi } 314*76af099aSliuyi int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer) 315*76af099aSliuyi { 316*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 317*76af099aSliuyi if (m_log) { 318*76af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 319*76af099aSliuyi } 320*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 321*76af099aSliuyi } 322*76af099aSliuyi 323*76af099aSliuyi CBW cbw; 324*76af099aSliuyi CSW csw; 325*76af099aSliuyi 326*76af099aSliuyi InitializeCBW(&cbw, READ_CHIP_INFO); 327*76af099aSliuyi 328*76af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 329*76af099aSliuyi { 330*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 331*76af099aSliuyi } 332*76af099aSliuyi 333*76af099aSliuyi if(!RKU_Read(lpBuffer, 16)) 334*76af099aSliuyi { 335*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 336*76af099aSliuyi } 337*76af099aSliuyi 338*76af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 339*76af099aSliuyi { 340*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 341*76af099aSliuyi } 342*76af099aSliuyi 343*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 344*76af099aSliuyi return ERR_CMD_NOTMATCH; 345*76af099aSliuyi 346*76af099aSliuyi return ERR_SUCCESS; 347*76af099aSliuyi } 348*76af099aSliuyi int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer) 349*76af099aSliuyi { 350*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 351*76af099aSliuyi if (m_log) { 352*76af099aSliuyi m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 353*76af099aSliuyi } 354*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 355*76af099aSliuyi } 356*76af099aSliuyi 357*76af099aSliuyi CBW cbw; 358*76af099aSliuyi CSW csw; 359*76af099aSliuyi 360*76af099aSliuyi InitializeCBW(&cbw, READ_FLASH_ID); 361*76af099aSliuyi 362*76af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 363*76af099aSliuyi { 364*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 365*76af099aSliuyi } 366*76af099aSliuyi 367*76af099aSliuyi if(!RKU_Read(lpBuffer, 5)) 368*76af099aSliuyi { 369*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 370*76af099aSliuyi } 371*76af099aSliuyi 372*76af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 373*76af099aSliuyi { 374*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 375*76af099aSliuyi } 376*76af099aSliuyi 377*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 378*76af099aSliuyi return ERR_CMD_NOTMATCH; 379*76af099aSliuyi 380*76af099aSliuyi return ERR_SUCCESS; 381*76af099aSliuyi } 382*76af099aSliuyi int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead) 383*76af099aSliuyi { 384*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 385*76af099aSliuyi if (m_log) { 386*76af099aSliuyi m_log->Record("Error:RKU_ReadFlashInfo failed,device not support"); 387*76af099aSliuyi } 388*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 389*76af099aSliuyi } 390*76af099aSliuyi CBW cbw; 391*76af099aSliuyi CSW csw; 392*76af099aSliuyi 393*76af099aSliuyi InitializeCBW(&cbw, READ_FLASH_INFO); 394*76af099aSliuyi 395*76af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 396*76af099aSliuyi { 397*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 398*76af099aSliuyi } 399*76af099aSliuyi 400*76af099aSliuyi DWORD dwRead; 401*76af099aSliuyi dwRead = RKU_Read_EX(lpBuffer, 512); 402*76af099aSliuyi if ((dwRead < 11) || (dwRead > 512)) 403*76af099aSliuyi { 404*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 405*76af099aSliuyi } 406*76af099aSliuyi if (puiRead) 407*76af099aSliuyi { 408*76af099aSliuyi *puiRead = dwRead; 409*76af099aSliuyi } 410*76af099aSliuyi /* 411*76af099aSliuyi if(!RKU_Read(hDev, lpBuffer, 11)) 412*76af099aSliuyi { 413*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 414*76af099aSliuyi } 415*76af099aSliuyi */ 416*76af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 417*76af099aSliuyi { 418*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 419*76af099aSliuyi } 420*76af099aSliuyi 421*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 422*76af099aSliuyi return ERR_CMD_NOTMATCH; 423*76af099aSliuyi 424*76af099aSliuyi return ERR_SUCCESS; 425*76af099aSliuyi } 426*76af099aSliuyi int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 427*76af099aSliuyi { 428*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 429*76af099aSliuyi if (m_log) { 430*76af099aSliuyi m_log->Record("Error:RKU_ReadLBA failed,device not support"); 431*76af099aSliuyi } 432*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 433*76af099aSliuyi } 434*76af099aSliuyi CBW cbw; 435*76af099aSliuyi CSW csw; 436*76af099aSliuyi USHORT wSectorSize; 437*76af099aSliuyi USHORT usSectorLen; 438*76af099aSliuyi wSectorSize = 512; 439*76af099aSliuyi usSectorLen=dwCount; 440*76af099aSliuyi 441*76af099aSliuyi InitializeCBW(&cbw, READ_LBA); 442*76af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 443*76af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen); 444*76af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 445*76af099aSliuyi 446*76af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 447*76af099aSliuyi { 448*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 449*76af099aSliuyi } 450*76af099aSliuyi DWORD dwTotal; 451*76af099aSliuyi dwTotal = usSectorLen * wSectorSize; 452*76af099aSliuyi 453*76af099aSliuyi if(!RKU_Read(lpBuffer, dwTotal)) 454*76af099aSliuyi { 455*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 456*76af099aSliuyi } 457*76af099aSliuyi 458*76af099aSliuyi if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) 459*76af099aSliuyi { 460*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 461*76af099aSliuyi } 462*76af099aSliuyi 463*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 464*76af099aSliuyi return ERR_CMD_NOTMATCH; 465*76af099aSliuyi 466*76af099aSliuyi if(csw.ucCSWStatus == 1) 467*76af099aSliuyi return ERR_FAILED; 468*76af099aSliuyi 469*76af099aSliuyi return ERR_SUCCESS; 470*76af099aSliuyi } 471*76af099aSliuyi 472*76af099aSliuyi int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode) 473*76af099aSliuyi { 474*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 475*76af099aSliuyi if (m_log) { 476*76af099aSliuyi m_log->Record("Error:RKU_ResetDevice failed,device not support"); 477*76af099aSliuyi } 478*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 479*76af099aSliuyi } 480*76af099aSliuyi 481*76af099aSliuyi CBW cbw; 482*76af099aSliuyi CSW csw; 483*76af099aSliuyi 484*76af099aSliuyi InitializeCBW(&cbw, DEVICE_RESET); 485*76af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 486*76af099aSliuyi 487*76af099aSliuyi if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 488*76af099aSliuyi { 489*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 490*76af099aSliuyi } 491*76af099aSliuyi 492*76af099aSliuyi if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 493*76af099aSliuyi { 494*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 495*76af099aSliuyi } 496*76af099aSliuyi 497*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) { 498*76af099aSliuyi bool bRet; 499*76af099aSliuyi bRet = RKU_ClearBuffer(cbw, csw); 500*76af099aSliuyi if (!bRet) { 501*76af099aSliuyi return ERR_CMD_NOTMATCH; 502*76af099aSliuyi } 503*76af099aSliuyi } 504*76af099aSliuyi 505*76af099aSliuyi if(csw.ucCSWStatus == 1) 506*76af099aSliuyi return ERR_FAILED; 507*76af099aSliuyi 508*76af099aSliuyi return ERR_SUCCESS; 509*76af099aSliuyi } 510*76af099aSliuyi 511*76af099aSliuyi int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode) 512*76af099aSliuyi { 513*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 514*76af099aSliuyi if (m_log) { 515*76af099aSliuyi m_log->Record("Error:RKU_TestDeviceReady failed,device not support"); 516*76af099aSliuyi } 517*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 518*76af099aSliuyi } 519*76af099aSliuyi CBW cbw; 520*76af099aSliuyi CSW csw; 521*76af099aSliuyi 522*76af099aSliuyi InitializeCBW(&cbw, TEST_UNIT_READY); 523*76af099aSliuyi 524*76af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 525*76af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 526*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 527*76af099aSliuyi } 528*76af099aSliuyi 529*76af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 530*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 531*76af099aSliuyi } 532*76af099aSliuyi 533*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) { 534*76af099aSliuyi bool bRet; 535*76af099aSliuyi bRet = RKU_ClearBuffer(cbw ,csw); 536*76af099aSliuyi if (!bRet) { 537*76af099aSliuyi return ERR_CMD_NOTMATCH; 538*76af099aSliuyi } 539*76af099aSliuyi } 540*76af099aSliuyi 541*76af099aSliuyi if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) { 542*76af099aSliuyi *dwCurrent = (csw.dwCBWDataResidue >>16); 543*76af099aSliuyi *dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF); 544*76af099aSliuyi 545*76af099aSliuyi *dwTotal = EndianU16_BtoL(*dwTotal); 546*76af099aSliuyi *dwCurrent = EndianU16_BtoL(*dwCurrent); 547*76af099aSliuyi } 548*76af099aSliuyi if(csw.ucCSWStatus == 1) { 549*76af099aSliuyi return ERR_DEVICE_UNREADY; 550*76af099aSliuyi } 551*76af099aSliuyi 552*76af099aSliuyi return ERR_DEVICE_READY; 553*76af099aSliuyi } 554*76af099aSliuyi int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 555*76af099aSliuyi { 556*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 557*76af099aSliuyi if (m_log) { 558*76af099aSliuyi m_log->Record("Error:RKU_WriteLBA failed,device not support"); 559*76af099aSliuyi } 560*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 561*76af099aSliuyi } 562*76af099aSliuyi CBW cbw; 563*76af099aSliuyi CSW csw; 564*76af099aSliuyi USHORT wSectorSize; 565*76af099aSliuyi USHORT usCount; 566*76af099aSliuyi wSectorSize = 512; 567*76af099aSliuyi usCount = dwCount; 568*76af099aSliuyi DWORD dwTotal = usCount * wSectorSize; 569*76af099aSliuyi 570*76af099aSliuyi InitializeCBW(&cbw, WRITE_LBA); 571*76af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 572*76af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 573*76af099aSliuyi cbw.cbwcb.ucReserved = bySubCode; 574*76af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 575*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 576*76af099aSliuyi } 577*76af099aSliuyi 578*76af099aSliuyi if(!RKU_Write( lpBuffer, dwTotal)) { 579*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 580*76af099aSliuyi } 581*76af099aSliuyi 582*76af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 583*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 584*76af099aSliuyi } 585*76af099aSliuyi 586*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 587*76af099aSliuyi return ERR_CMD_NOTMATCH; 588*76af099aSliuyi 589*76af099aSliuyi if(csw.ucCSWStatus == 1) 590*76af099aSliuyi return ERR_FAILED; 591*76af099aSliuyi 592*76af099aSliuyi return ERR_SUCCESS; 593*76af099aSliuyi } 594*76af099aSliuyi int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer) 595*76af099aSliuyi { 596*76af099aSliuyi if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 597*76af099aSliuyi if (m_log) { 598*76af099aSliuyi m_log->Record("Error:RKU_WriteSector failed,device not support"); 599*76af099aSliuyi } 600*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 601*76af099aSliuyi } 602*76af099aSliuyi CBW cbw; 603*76af099aSliuyi CSW csw; 604*76af099aSliuyi USHORT wSectorSize; 605*76af099aSliuyi USHORT usCount; 606*76af099aSliuyi usCount=dwCount; 607*76af099aSliuyi if(usCount > 32) 608*76af099aSliuyi return ERR_CROSS_BORDER; 609*76af099aSliuyi 610*76af099aSliuyi wSectorSize = 528; 611*76af099aSliuyi InitializeCBW(&cbw, WRITE_SECTOR); 612*76af099aSliuyi cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 613*76af099aSliuyi cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 614*76af099aSliuyi 615*76af099aSliuyi if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 616*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 617*76af099aSliuyi } 618*76af099aSliuyi 619*76af099aSliuyi if(!RKU_Write( lpBuffer, usCount * wSectorSize)) { 620*76af099aSliuyi return ERR_DEVICE_WRITE_FAILED; 621*76af099aSliuyi } 622*76af099aSliuyi 623*76af099aSliuyi if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 624*76af099aSliuyi return ERR_DEVICE_READ_FAILED; 625*76af099aSliuyi } 626*76af099aSliuyi 627*76af099aSliuyi if( !UFI_CHECK_SIGN(cbw, csw) ) 628*76af099aSliuyi return ERR_CMD_NOTMATCH; 629*76af099aSliuyi 630*76af099aSliuyi if(csw.ucCSWStatus == 1) 631*76af099aSliuyi return ERR_FAILED; 632*76af099aSliuyi 633*76af099aSliuyi return ERR_SUCCESS; 634*76af099aSliuyi } 635*76af099aSliuyi 636*76af099aSliuyi 637*76af099aSliuyi int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize) 638*76af099aSliuyi { 639*76af099aSliuyi if (m_deviceDesc.emUsbType != RKUSB_MASKROM) { 640*76af099aSliuyi if (m_log) { 641*76af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,device not support"); 642*76af099aSliuyi } 643*76af099aSliuyi return ERR_DEVICE_NOT_SUPPORT; 644*76af099aSliuyi } 645*76af099aSliuyi if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) { 646*76af099aSliuyi if (m_log) { 647*76af099aSliuyi m_log->Record("Error:RKU_DeviceRequest failed,request not support"); 648*76af099aSliuyi } 649*76af099aSliuyi return ERR_REQUEST_NOT_SUPPORT; 650*76af099aSliuyi } 651*76af099aSliuyi 652*76af099aSliuyi bool bSendPendPacket = false; 653*76af099aSliuyi USHORT crcValue = 0xffff; 654*76af099aSliuyi BYTE *pData = NULL; 655*76af099aSliuyi pData = new BYTE[dwDataSize + 5]; 656*76af099aSliuyi memset(pData, 0, dwDataSize + 5); 657*76af099aSliuyi memcpy(pData, lpBuffer, dwDataSize); 658*76af099aSliuyi 659*76af099aSliuyi switch(dwDataSize % 4096) { 660*76af099aSliuyi case 4095: 661*76af099aSliuyi ++dwDataSize; 662*76af099aSliuyi break; 663*76af099aSliuyi case 4094: 664*76af099aSliuyi bSendPendPacket = true; 665*76af099aSliuyi break; 666*76af099aSliuyi case 0: 667*76af099aSliuyi default: 668*76af099aSliuyi break; 669*76af099aSliuyi } 670*76af099aSliuyi 671*76af099aSliuyi crcValue = CRC_CCITT(pData, dwDataSize); 672*76af099aSliuyi pData[dwDataSize] = (crcValue & 0xff00) >> 8; 673*76af099aSliuyi pData[dwDataSize+1] = crcValue & 0x00ff; 674*76af099aSliuyi dwDataSize += 2; 675*76af099aSliuyi 676*76af099aSliuyi UINT nSendBytes = 0; 677*76af099aSliuyi DWORD dwTotalSended = 0; 678*76af099aSliuyi int iRet; 679*76af099aSliuyi 680*76af099aSliuyi while(dwTotalSended < dwDataSize) { 681*76af099aSliuyi nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended); 682*76af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT); 683*76af099aSliuyi if (iRet != (int)nSendBytes) { 684*76af099aSliuyi if (m_log) { 685*76af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet); 686*76af099aSliuyi } 687*76af099aSliuyi delete []pData; 688*76af099aSliuyi return ERR_REQUEST_FAIL; 689*76af099aSliuyi } 690*76af099aSliuyi dwTotalSended += nSendBytes; 691*76af099aSliuyi } 692*76af099aSliuyi 693*76af099aSliuyi if(bSendPendPacket) { 694*76af099aSliuyi BYTE ucFillByte = 0; 695*76af099aSliuyi iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT); 696*76af099aSliuyi if (iRet != 0) { 697*76af099aSliuyi if (m_log) { 698*76af099aSliuyi m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet); 699*76af099aSliuyi } 700*76af099aSliuyi delete []pData; 701*76af099aSliuyi return ERR_REQUEST_FAIL; 702*76af099aSliuyi } 703*76af099aSliuyi } 704*76af099aSliuyi 705*76af099aSliuyi delete []pData; 706*76af099aSliuyi 707*76af099aSliuyi return ERR_SUCCESS; 708*76af099aSliuyi } 709*76af099aSliuyi 710*76af099aSliuyi 711