#include "precomp.h" // Precompiled header /**************************************************************************************** * * * Module: SPD_W2K.C * * * * Creation: 14th April 1999 * * * * Author: Paul Smith * * * * Version: 1.0.0 * * * * Description: Functions specific to SPEED and Windows 2000 * * * ****************************************************************************************/ // Paging... #ifdef ALLOC_PRAGMA #pragma alloc_text (PAGE, SpxGetNtCardType) #endif #define FILE_ID SPD_W2K_C // File ID for Event Logging see SPD_DEFS.H for values. /***************************************************************************** **************************** **************************** **************************** SpxGetNtCardType **************************** **************************** **************************** ****************************************************************************** prototype: ULONG SpxGetNtCardType(IN PDEVICE_OBJECT pDevObject) description: Return the NT defined card type for the specified card device object. parameters: pDevObject points to the NT device object for the card returns: NT defined card type, or -1 if not identified */ ULONG SpxGetNtCardType(IN PDEVICE_OBJECT pDevObject) { PCARD_DEVICE_EXTENSION pCard = pDevObject->DeviceExtension; ULONG NtCardType = -1; PVOID pPropertyBuffer = NULL; ULONG ResultLength = 0; NTSTATUS status = STATUS_SUCCESS; ULONG BufferLength = 1; // Initial size. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL pPropertyBuffer = SpxAllocateMem(PagedPool, BufferLength); // Allocate the buffer if(pPropertyBuffer == NULL) // SpxAllocateMem failed. return -1; // Try to get HardwareID status = IoGetDeviceProperty(pCard->PDO, DevicePropertyHardwareID , BufferLength, pPropertyBuffer, &ResultLength); if(!SPX_SUCCESS(status)) // IoGetDeviceProperty failed. { if(status == STATUS_BUFFER_TOO_SMALL) // Buffer was too small. { ExFreePool(pPropertyBuffer); // Free old buffer that was not big enough. BufferLength = ResultLength + 1; // Set BufferLength to size required. pPropertyBuffer = SpxAllocateMem(PagedPool, BufferLength); // Allocate a bigger buffer. if(pPropertyBuffer == NULL) // SpxAllocateMem failed. return -1; // Try again. status = IoGetDeviceProperty(pCard->PDO, DevicePropertyHardwareID , BufferLength, pPropertyBuffer, &ResultLength); if(!SPX_SUCCESS(status)) // IoGetDeviceProperty failed a second time. { ExFreePool(pPropertyBuffer); // Free buffer. return -1; } } else { ExFreePool(pPropertyBuffer); // Free buffer. return -1; } } // If we get to here then there is something in the PropertyBuffer. _wcsupr(pPropertyBuffer); // Convert HardwareID to uppercase // Speed 2 adapters if(wcsstr(pPropertyBuffer, SPD2_PCI_PCI954_HWID) != NULL) // SPEED 2 Port Adapter NtCardType = Speed2_Pci; if(wcsstr(pPropertyBuffer, SPD2AND4_PCI_NO_F1_HWID) != NULL) // SPEED 2/4 Port Adapter Local Bus (unused) NtCardType = Speed2and4_Pci_8BitBus; if(wcsstr(pPropertyBuffer, SPD2P_PCI_PCI954_HWID) != NULL) // SPEED+ 2 Port Adapter NtCardType = Speed2P_Pci; if(wcsstr(pPropertyBuffer, SPD2P_PCI_8BIT_LOCALBUS_HWID) != NULL) // SPEED+ 2 Port Adapter Local bus (not used) NtCardType = Speed2P_Pci_8BitBus; // SPEED 4 adapters if(wcsstr(pPropertyBuffer, SPD4_PCI_PCI954_HWID) != NULL) // SPEED 4 Port Adapter NtCardType = Speed4_Pci; if(wcsstr(pPropertyBuffer, SPD4P_PCI_PCI954_HWID) != NULL) // SPEED+ 4 Port Adapter NtCardType = Speed4P_Pci; if(wcsstr(pPropertyBuffer, SPD4P_PCI_8BIT_LOCALBUS_HWID) != NULL) // SPEED+ 4 Port Adapter Local bus (not used) NtCardType = Speed4P_Pci_8BitBus; // Chase Fast Cards if(wcsstr(pPropertyBuffer, FAST4_PCI_HWID) != NULL) // PCI-Fast 4 Port Adapter NtCardType = Fast4_Pci; if(wcsstr(pPropertyBuffer, FAST8_PCI_HWID) != NULL) // PCI-Fast 8 Port Adapter NtCardType = Fast8_Pci; if(wcsstr(pPropertyBuffer, FAST16_PCI_HWID) != NULL) // PCI-Fast 16 Port Adapter NtCardType = Fast16_Pci; if(wcsstr(pPropertyBuffer, FAST16FMC_PCI_HWID) != NULL) // PCI-Fast 16 FMC Port Adapter NtCardType = Fast16FMC_Pci; if(wcsstr(pPropertyBuffer, AT_FAST4_HWID) != NULL) // AT-Fast 4 Port Adapter NtCardType = Fast4_Isa; if(wcsstr(pPropertyBuffer, AT_FAST8_HWID) != NULL) // AT-Fast 8 Port Adapter NtCardType = Fast8_Isa; if(wcsstr(pPropertyBuffer, AT_FAST16_HWID) != NULL) // AT-Fast 16 Port Adapter NtCardType = Fast16_Isa; if(wcsstr(pPropertyBuffer, RAS4_PCI_HWID) != NULL) // PCI-RAS 4 Multi-modem Adapter NtCardType = RAS4_Pci; if(wcsstr(pPropertyBuffer, RAS8_PCI_HWID) != NULL) // PCI-RAS 8 Multi-modem Adapter NtCardType = RAS8_Pci; ExFreePool(pPropertyBuffer); // Free buffer. return(NtCardType); } // SpxGetNtCardType ////////////////////////////////////////////////////////////////////////////// // SetPortFiFoSettings // BOOLEAN SetPortFiFoSettings(PPORT_DEVICE_EXTENSION pPort) { // Store current settings. ULONG TxFIFOSize = pPort->BufferSizes.TxFIFOSize; ULONG TxFIFOTrigLevel = pPort->BufferSizes.TxFIFOTrigLevel; ULONG RxFIFOTrigLevel = pPort->BufferSizes.RxFIFOTrigLevel; ULONG LoFlowCtrlThreshold = pPort->UartConfig.LoFlowCtrlThreshold; ULONG HiFlowCtrlThreshold = pPort->UartConfig.HiFlowCtrlThreshold; // Get Tx FIFO Limit. if((pPort->TxFIFOSize > 0) && (pPort->TxFIFOSize <= pPort->MaxTxFIFOSize)) // Check for good value. { pPort->BufferSizes.TxFIFOSize = pPort->TxFIFOSize; } else goto SetFailure; // Get Tx FIFO Trigger Level. if(pPort->TxFIFOSize <= pPort->MaxTxFIFOSize) // Check for good value. { pPort->BufferSizes.TxFIFOTrigLevel = (BYTE) pPort->TxFIFOTrigLevel; } else goto SetFailure; // Get Rx FIFO Trigger Level. if(pPort->RxFIFOTrigLevel <= pPort->MaxRxFIFOSize) // Check for good value. { pPort->BufferSizes.RxFIFOTrigLevel = (BYTE) pPort->RxFIFOTrigLevel; } else goto SetFailure; // Attempt to change FIFO settings. if(pPort->pUartLib->UL_BufferControl_XXXX(pPort->pUart, &pPort->BufferSizes, UL_BC_OP_SET, UL_BC_FIFO | UL_BC_IN | UL_BC_OUT) != UL_STATUS_SUCCESS) { goto SetFailure; } // Get Low Flow Control Threshold Level. if(pPort->LoFlowCtrlThreshold <= pPort->MaxRxFIFOSize) // Check for good value. { pPort->UartConfig.LoFlowCtrlThreshold = (BYTE) pPort->LoFlowCtrlThreshold; } else goto SetFailure; // Get High Flow Control Threshold Level. if(pPort->HiFlowCtrlThreshold <= pPort->MaxRxFIFOSize) // Check for good value. { pPort->UartConfig.HiFlowCtrlThreshold = (BYTE) pPort->HiFlowCtrlThreshold; } else goto SetFailure; // Attempt to set the configuration. if(pPort->pUartLib->UL_SetConfig_XXXX(pPort->pUart, &pPort->UartConfig, UC_FC_THRESHOLD_SETTING_MASK) != UL_STATUS_SUCCESS) { goto SetFailure; } // Just do a quick get config to see if flow threshold have // changed as a result of changing the FIFO triggers. pPort->pUartLib->UL_GetConfig_XXXX(pPort->pUart, &pPort->UartConfig); // Update FIFO Flow Control Levels pPort->LoFlowCtrlThreshold = pPort->UartConfig.LoFlowCtrlThreshold; pPort->HiFlowCtrlThreshold = pPort->UartConfig.HiFlowCtrlThreshold; return TRUE; // Restore all settings to the way they were. SetFailure: // Restore settings. pPort->TxFIFOSize = TxFIFOSize; pPort->TxFIFOTrigLevel = TxFIFOTrigLevel; pPort->RxFIFOTrigLevel = RxFIFOTrigLevel; pPort->BufferSizes.TxFIFOSize = TxFIFOSize; pPort->BufferSizes.TxFIFOTrigLevel = (BYTE) TxFIFOTrigLevel; pPort->BufferSizes.RxFIFOTrigLevel = (BYTE) RxFIFOTrigLevel; pPort->pUartLib->UL_BufferControl_XXXX(pPort->pUart, &pPort->BufferSizes, UL_BC_OP_SET, UL_BC_FIFO | UL_BC_IN | UL_BC_OUT); // Restore settings. pPort->LoFlowCtrlThreshold = LoFlowCtrlThreshold; pPort->HiFlowCtrlThreshold = HiFlowCtrlThreshold; pPort->UartConfig.LoFlowCtrlThreshold = LoFlowCtrlThreshold; pPort->UartConfig.HiFlowCtrlThreshold = HiFlowCtrlThreshold; pPort->pUartLib->UL_SetConfig_XXXX(pPort->pUart, &pPort->UartConfig, UC_FC_THRESHOLD_SETTING_MASK); return FALSE; } NTSTATUS GetPortSettings(PDEVICE_OBJECT pDevObject) { PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension; HANDLE PnPKeyHandle; ULONG Data = 0; // Open PnP Reg Key if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pDevObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_READ, &PnPKeyHandle))) { if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, TX_FIFO_LIMIT, wcslen(TX_FIFO_LIMIT) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if((Data > 0) && (Data <= pPort->MaxTxFIFOSize)) // Check for good value. pPort->TxFIFOSize = Data; } if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, TX_FIFO_TRIG_LEVEL, wcslen(TX_FIFO_TRIG_LEVEL) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if(Data <= pPort->MaxTxFIFOSize) // Check for good value. pPort->TxFIFOTrigLevel = Data; } if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, RX_FIFO_TRIG_LEVEL, wcslen(RX_FIFO_TRIG_LEVEL) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if(Data <= pPort->MaxRxFIFOSize) // Check for good value. pPort->RxFIFOTrigLevel = Data; } if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, LO_FLOW_CTRL_LEVEL, wcslen(LO_FLOW_CTRL_LEVEL) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if(Data <= pPort->MaxRxFIFOSize) // Check for good value. pPort->LoFlowCtrlThreshold = Data; } if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, HI_FLOW_CTRL_LEVEL, wcslen(HI_FLOW_CTRL_LEVEL) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if(Data <= pPort->MaxRxFIFOSize) // Check for good value. pPort->HiFlowCtrlThreshold = Data; } ZwClose(PnPKeyHandle); } return STATUS_SUCCESS; } NTSTATUS GetCardSettings(PDEVICE_OBJECT pDevObject) { PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension; HANDLE PnPKeyHandle; ULONG Data = 0; // Open PnP Reg Key if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pCard->PDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_READ, &PnPKeyHandle))) { if((pCard->CardType == Fast16_Pci) || (pCard->CardType == Fast16FMC_Pci)) { if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, DELAY_INTERRUPT, wcslen(DELAY_INTERRUPT) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if(Data) { if(!(pCard->CardOptions & DELAY_INTERRUPT_OPTION)) // If not already set then set the option { if(KeSynchronizeExecution(pCard->Interrupt, SetCardToDelayInterrupt, pCard)) { pCard->CardOptions |= DELAY_INTERRUPT_OPTION; } } } else { if(pCard->CardOptions & DELAY_INTERRUPT_OPTION) // If set then unset the option. { if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToDelayInterrupt, pCard)) { pCard->CardOptions &= ~DELAY_INTERRUPT_OPTION; } } } } } if(pCard->CardType == Fast16_Pci) { if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, SWAP_RTS_FOR_DTR, wcslen(SWAP_RTS_FOR_DTR) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if(Data) { if(!(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)) // If not already set then set the option { if(KeSynchronizeExecution(pCard->Interrupt, SetCardToUseDTRInsteadOfRTS, pCard)) { pCard->CardOptions |= SWAP_RTS_FOR_DTR_OPTION; } } } else { if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION) // If set then unset the option. { if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToUseDTRInsteadOfRTS, pCard)) { pCard->CardOptions &= ~SWAP_RTS_FOR_DTR_OPTION; } } } } } if(SPX_SUCCESS(Spx_GetRegistryKeyValue(PnPKeyHandle, CLOCK_FREQ_OVERRIDE, wcslen(CLOCK_FREQ_OVERRIDE) * sizeof(WCHAR), &Data, sizeof(ULONG)))) { if(Data > 0) pCard->ClockRate = Data; // Store new clock rate to use. } ZwClose(PnPKeyHandle); } return STATUS_SUCCESS; }