|
|
#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; }
|