//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsUnrefEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // static void DtaEventsUnrefEventsObject(DtaDeviceData* pDvcData, DtaEvents* pDtaEvents) { if (DtAtomicDecrementReturn(&pDtaEvents->m_RefCount) == 0) { DT_ASSERT(pDtaEvents->m_pPrev == NULL); DT_ASSERT(pDtaEvents->m_pNext == NULL); DtMemFreePool(pDtaEvents, DTA_TAG); } }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsCleanup -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // // DtStatus DtaEventsCleanup(DtaDeviceData* pDvcData) { DtaEvents* pEvents; DtaEvents* pTmpEvents; pEvents = pDvcData->m_pEvents; while (pEvents != NULL) { pTmpEvents = pEvents; pEvents = pEvents->m_pNext; DtMemFreePool(pTmpEvents, DTA_TAG); } pDvcData->m_pEvents = NULL; return DT_STATUS_OK; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuLoadDemodFirmware -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtuLoadDemodFirmware( DtuDeviceData* pDvcData, const DtuDemodFirmwareStore* pDemodFirmware) { DtStatus Status = DT_STATUS_OK; UInt8 Buffer[2]; Int i, j; UInt DvcAddr = pDemodFirmware->m_DemodI2cAddress; DT_ASSERT(pDemodFirmware != NULL); // First do the PRE-upload register writes if (pDemodFirmware->m_pPreUpload != NULL) { const DtuInitRegisterStruct* pInitRegisterData = pDemodFirmware->m_pPreUpload; for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++) { Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0]; Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C pre-upload data. (Status=0x%08X)", Status); return Status; } } } // Upload demodulator firmware if (pDemodFirmware->m_pFirmware != NULL) { const Int MAX_BYTES_TO_TRY = 60; UInt8 AddrHigh; UInt8 AddrLow; Int DataCount; Int BytesToTry; const DtuHexStruct* pFirmware = pDemodFirmware->m_pFirmware; UInt8* pHexData=NULL; // First allocate memory for temporary helper buffer pHexData = DtMemAllocPool(DtPoolNonPaged, 4096, DTU_TAG); if (pHexData == NULL) return DT_STATUS_OUT_OF_MEMORY; for (i=0; i<pFirmware->m_HexBlockCount; i++) { const DtuHexBlockStruct* pHexBlock = &(pFirmware->m_HexBlock[i]); DataCount = pHexBlock->m_DataCount; BytesToTry = 0; while (DataCount > 0) { AddrHigh = (UInt8)((pHexBlock->m_Address + pHexBlock->m_DataCount-DataCount) >> 8); AddrLow = (UInt8)(pHexBlock->m_Address + pHexBlock->m_DataCount-DataCount); // Write high address Buffer[0] = (UInt8)pDemodFirmware->m_AddrRegH; Buffer[1] = AddrHigh; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C high address. (Status=0x%08X)", Status); DtMemFreePool(pHexData, DTU_TAG); return Status; } // Write low address Buffer[0] = (UInt8)pDemodFirmware->m_AddrRegL; Buffer[1] = AddrLow; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C low address. (Status=0x%08X)", Status); DtMemFreePool(pHexData, DTU_TAG); return Status; } // Write data pHexData[0] = (UInt8)pDemodFirmware->m_DataReg; BytesToTry = (DataCount<=MAX_BYTES_TO_TRY ? DataCount : MAX_BYTES_TO_TRY); for (j=0; j<BytesToTry; j++) pHexData[j + 1] = pHexBlock->m_Data[j + pHexBlock->m_DataCount - DataCount]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, BytesToTry+1, pHexData); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C data. (Status=0x%08X)", Status); DtMemFreePool(pHexData, DTU_TAG); return Status; } DataCount -= BytesToTry; } } DtMemFreePool(pHexData, DTU_TAG); } // Do the STOP-upload register writes if (pDemodFirmware->m_pStopUpload != NULL) { const DtuInitRegisterStruct* pInitRegisterData = pDemodFirmware->m_pStopUpload; for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++) { Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0]; Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C stop-upload data. (Status=0x%08X)", Status); return Status; } } } // Wait until AP is running if (pDemodFirmware->m_pFirmware != NULL) { Int TimeOut; Buffer[0] = (UInt8)pDemodFirmware->m_ApStatReg; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 1, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C apstat data. (Status=0x%08X)", Status); return Status; } // Wait until ready Buffer[0] = 1; TimeOut = 0; while (Buffer[0]==1 && TimeOut<250) // Wait max. 250ms { DtSleep(10); TimeOut += 10; // Read the app status Status = DtuI2cRead(pDvcData, NULL, DvcAddr, 1, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error reading I2C apstat data. (Status=0x%08X)", Status); return Status; } } if (Buffer[0] == 1) { DtDbgOut(ERR, DTU, "TIMEOUT! APSTAT = %x.", (Int)(Buffer[0])); } } //Do the post-upload register writes if (pDemodFirmware->m_pPostUpload != NULL) { const DtuInitRegisterStruct* pInitRegisterData = pDemodFirmware->m_pPostUpload; for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++) { Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0]; Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C post-upload data. (Status=0x%08X)", Status); return Status; } } } return Status; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersSubKeyDelete -.-.-.-.-.-.-.-.-.-.-.-.-.-.- // NTSTATUS DriverParametersSubKeyDelete( WDFDRIVER Driver, DtString* pKeyName) { NTSTATUS NtStatus = STATUS_SUCCESS; DtStringChar* pRegistryPath; DtString RegistryPath; DtString FullKeyName; UInt PathLength; HANDLE hKey; OBJECT_ATTRIBUTES ObjectAttributes; KEY_BASIC_INFORMATION* pKeyInfo; ULONG Size; ULONG ResultSize; Int Index; DT_STRING_DECL(ParamItemName, "\\Parameters\\"); DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL); // Build the full path pRegistryPath = WdfDriverGetRegistryPath(Driver); PathLength = wcslen(pRegistryPath); DT_STRING_INIT_CONST(RegistryPath, pRegistryPath, PathLength); // Allocate struct for key information result Size = sizeof(KEY_BASIC_INFORMATION)+100; pKeyInfo = DtMemAllocPool(DtPoolNonPaged, Size, SAL_TAG); if (pKeyInfo == NULL) return STATUS_NO_MEMORY; // Allocate a new DtString buffer for the complete path inclusive a '\0' character // and extra '\\' if (!DT_SUCCESS(DtStringAlloc(&FullKeyName, PathLength+ DtStringGetStringLength(&ParamItemName)+ DtStringGetStringLength(pKeyName)+ 100+1+1))) { DtMemFreePool(pKeyInfo, SAL_TAG); return STATUS_NO_MEMORY; } DtStringAppendDtString(&FullKeyName, &RegistryPath); DtStringAppendDtString(&FullKeyName, &ParamItemName); DtStringAppendDtString(&FullKeyName, pKeyName); // Initialize key to open InitializeObjectAttributes(&ObjectAttributes, &FullKeyName, OBJ_KERNEL_HANDLE, NULL, NULL); NtStatus = ZwOpenKey(&hKey, KEY_ENUMERATE_SUB_KEYS , &ObjectAttributes); if (NT_SUCCESS(NtStatus)) { Index = 0; NtStatus = STATUS_SUCCESS; // Enumerate all keys while (NtStatus != STATUS_NO_MORE_ENTRIES) { NtStatus = ZwEnumerateKey(hKey, Index, KeyBasicInformation, pKeyInfo, Size, &ResultSize); if (NT_SUCCESS(NtStatus)) { DtString SubKey; // Build key to delete pKeyInfo->Name[pKeyInfo->NameLength/2] = L'\0'; DT_STRING_INIT_CONST(SubKey, pKeyInfo->Name, ((USHORT)pKeyInfo->NameLength/2)); DtStringClear(&FullKeyName); DtStringAppendDtString(&FullKeyName, pKeyName); DtStringAppendChars(&FullKeyName, "\\"); DtStringAppendDtString(&FullKeyName, &SubKey); DtDbgOut(MAX, SAL, "Delete SubKey %S.", FullKeyName.Buffer); NtStatus = DriverParametersKeyDelete(Driver, &FullKeyName); if (!NT_SUCCESS(NtStatus)) DtDbgOut(ERR, SAL, "Error deleting SubKey %S. Error: %x", FullKeyName.Buffer, NtStatus); } // In case deletion failed, skip this entry if (!NT_SUCCESS(NtStatus)) Index++; } NtStatus = ZwDeleteKey(hKey); ZwClose(hKey); } DtMemFreePool(pKeyInfo, SAL_TAG); DtStringFree(&FullKeyName); return NtStatus; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtIoConfigReadFromIniFile -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtIoConfigReadFromIniFile( const char* DriverName, UInt64 Serial, Int TypeNumber, Int PortNumber, DtIoConfigValueDriver* pCfgValues) { char Filename[256]; Int Length; struct file* File = NULL; mm_segment_t OldFs; int Err = 0; char* FileBuf = NULL; loff_t Offset = 0; FileBuf = DtMemAllocPool(DtPoolNonPaged, CONFIG_MAX_FILE_SIZE, DRVCOMMON_TAG); OldFs = get_fs(); set_fs(get_ds()); Length = snprintf(Filename, sizeof(Filename), "/etc/DekTec/%s/%d/Port%d.ini", DriverName, TypeNumber, PortNumber); File = filp_open(Filename, O_RDONLY, 0); if(!IS_ERR(File)) { // Read data and parse it #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) Err = kernel_read(File, FileBuf, CONFIG_MAX_FILE_SIZE-1, &Offset); #else Err = vfs_read(File, FileBuf, CONFIG_MAX_FILE_SIZE-1, &Offset); #endif if (Err >= 0) { DtDbgOut(AVG, IOCONFIG, "Succesfully read file %s. Filesize %d bytes", Filename, Err); FileBuf[Err] = '\0'; DtaIoConfigParseIniFile(pCfgValues, FileBuf, FileBuf+Err); } else { DtDbgOut(ERR, IOCONFIG, "Error reading config file %s. Error: %d", Filename, -Err); } filp_close(File, NULL); } Length = snprintf(Filename, sizeof(Filename), "/etc/DekTec/%s/%llu/Port%d.ini", DriverName, Serial, PortNumber); File = filp_open(Filename, O_RDONLY, 0); if(!IS_ERR(File)) { Int Size = CONFIG_MAX_FILE_SIZE; // Read data and parse it #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) Err = kernel_read(File, FileBuf, Size, &Offset); #else Err = vfs_read(File, FileBuf, Size, &Offset); #endif if (Err >= 0) { DtDbgOut(AVG, IOCONFIG, "Succesfully read file %s. Filesize %d bytes", Filename, Err); FileBuf[Err] = '\0'; DtaIoConfigParseIniFile(pCfgValues, FileBuf, FileBuf+Err); } else { DtDbgOut(ERR, IOCONFIG, "Error reading config file %s. Error: %d", Filename, -Err); } filp_close(File, NULL); } set_fs(OldFs); DtMemFreePool(FileBuf, DRVCOMMON_TAG); return DT_STATUS_OK; }