📄 parmode.c
字号:
}
} else {
// FIFO status didn't pan out, may not be an ECP chip after all
PptDump2(PARINITDEV, ("ParMode::PptDetermineFifoDepth:: Bad Fifo\n"));
WRITE_PORT_UCHAR(wPortECR, ecrLast);
return;
}
// put chip into spp mode
WRITE_PORT_UCHAR( wPortECR, ecrLast );
Extension->PnpInfo.FifoDepth = wFifoDepth;
}
VOID
PptDetermineFifoWidth(
IN PDEVICE_EXTENSION Extension
)
{
PUCHAR Controller;
UCHAR bConfigA;
PUCHAR wPortECR;
PptDump2(PARINITDEV, ("ParMode::PptDetermineFifoWidth: Start\n"));
Controller = Extension->PortInfo.Controller;
#if (0 == DVRH_USE_PARPORT_ECP_ADDR)
wPortECR = Controller + ECR_OFFSET;
#else
wPortECR = Extension->PnpInfo.EcpController + ECR_OFFSET;
#endif
// Put chip into configuration mode so we can access the ConfigA register
WRITE_PORT_UCHAR( wPortECR, DEFAULT_ECR_CONFIGURATION );
// The FIFO width is bits <6:4> of the ConfigA register.
#if (0 == DVRH_USE_PARPORT_ECP_ADDR)
bConfigA = READ_PORT_UCHAR( Controller + CNFGA_OFFSET );
#else
bConfigA = READ_PORT_UCHAR( Extension->PnpInfo.EcpController );
#endif
Extension->PnpInfo.FifoWidth = (ULONG)(( bConfigA & CNFGA_IMPID_MASK ) >> CNFGA_IMPID_SHIFT);
// Put the chip back in compatibility mode.
WRITE_PORT_UCHAR(wPortECR, DEFAULT_ECR_COMPATIBILITY );
return;
}
NTSTATUS
PptSetChipMode (
IN PDEVICE_EXTENSION Extension,
IN UCHAR ChipMode
)
/*++
Routine Description:
This function will put the current parallel chip into the
given mode if supported. The determination of supported mode
was in the PptDetectPortType function.
Arguments:
Extension - Supplies the device extension.
Return Value:
STATUS_SUCCESS - if the port type was detected.
!STATUS_SUCCESS - otherwise.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
UCHAR EcrMode = (UCHAR)( ChipMode & ~ECR_MODE_MASK );
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: Start\n"));
// Also allow PptSetChipMode from PS/2 mode - we need this for HWECP
// bus flip from Forward to Reverse in order to meet the required
// sequence specified in the Microsoft ECP Port Spec version 1.06,
// July 14, 1993, to switch directly from PS/2 mode with output
// drivers disabled (direction bit set to "read") to HWECP via
// the ECR. Changed 2000-02-11.
if ( Extension->PnpInfo.CurrentMode != INITIAL_MODE &&
Extension->PnpInfo.CurrentMode != ECR_BYTE_MODE ) {
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: CurrentMode != INITIAL_MODE.\n"));
// Current mode is not valid to put in EPP or ECP mode
Status = STATUS_INVALID_DEVICE_STATE;
goto ExitSetChipModeNoChange;
}
// need to find out what mode it was and try to take it out of it
// Check to see if we need to use the filter to set the mode
if ( Extension->FilterMode ) {
PptDumpV(("PptSetChipMode: Chip Filter Present.\n"));
Status = Extension->ChipInfo.ParChipSetMode ( Extension->ChipInfo.Context, ChipMode );
} else {
PptDumpV(("PptSetChipMode: Chip Filter NOT Present.\n"));
// If asked for ECP check to see if we can do it
if ( EcrMode == ECR_ECP_MODE ) {
if ((Extension->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT) ^ PPT_ECP_PRESENT) {
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: ECP Not Present.\n"));
return STATUS_NO_SUCH_DEVICE;
}
Status = PptEcrSetMode ( Extension, ChipMode );
goto ExitSetChipModeWithChanges;
}
// If asked for EPP check to see if we can do it
if ( EcrMode == ECR_EPP_MODE ) {
if ((Extension->PnpInfo.HardwareCapabilities & PPT_EPP_PRESENT) ^ PPT_EPP_PRESENT) {
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: EPP Not Present.\n"));
return STATUS_NO_SUCH_DEVICE;
}
Status = PptEcrSetMode ( Extension, ChipMode );
goto ExitSetChipModeWithChanges;
}
// If asked for Byte Mode check to see if it is still enabled
if ( EcrMode == ECR_BYTE_MODE ) {
if ((Extension->PnpInfo.HardwareCapabilities & PPT_BYTE_PRESENT) ^ PPT_BYTE_PRESENT) {
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: BYTE Not Present.\n"));
return STATUS_NO_SUCH_DEVICE;
}
Status = PptSetByteMode ( Extension, ChipMode );
goto ExitSetChipModeWithChanges;
}
}
ExitSetChipModeWithChanges:
if ( NT_SUCCESS(Status) ) {
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: Mode Set.\n"));
Extension->PnpInfo.CurrentMode = EcrMode;
} else {
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: Mode Not Set.\n"));
}
ExitSetChipModeNoChange:
PptDump2(PARINITDEV, ("ParMode::PptSetChipMode: Exit with Status - %x\n", Status ));
return Status;
}
NTSTATUS
PptClearChipMode (
IN PDEVICE_EXTENSION Extension,
IN UCHAR ChipMode
)
/*++
Routine Description:
This routine Clears the Given chip mode.
Arguments:
Extension - Supplies the device extension.
ChipMode - The given mode to clear from the Chip
Return Value:
STATUS_SUCCESS - if the port type was detected.
!STATUS_SUCCESS - otherwise.
--*/
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG EcrMode = ChipMode & ~ECR_MODE_MASK;
PptDump2(PARINITDEV, ("ParMode::PptClearChipMode: Start\n"));
// make sure we have a mode to clear
if ( EcrMode != Extension->PnpInfo.CurrentMode ) {
PptDump2(PARINITDEV, ("ParMode::PptClearChipMode: Mode to Clear != CurrentMode.\n"));
// Current mode is not the same as requested to take it out of
Status = STATUS_INVALID_DEVICE_STATE;
goto ExitClearChipModeNoChange;
}
// need to find out what mode it was and try to take it out of it
// check to see if we used the filter to set the mode
if ( Extension->FilterMode ) {
PptDumpV(("PptClearChipMode: Chip Filter Present.\n"));
Status = Extension->ChipInfo.ParChipClearMode ( Extension->ChipInfo.Context, ChipMode );
} else {
PptDumpV(("PptClearChipMode: Chip Filter NOT Present.\n"));
// If ECP mode check to see if we can clear it
if ( EcrMode == ECR_ECP_MODE ) {
Status = PptEcrClearMode( Extension );
goto ExitClearChipModeWithChanges;
}
// If EPP mode check to see if we can clear it
if ( EcrMode == ECR_EPP_MODE ) {
Status = PptEcrClearMode( Extension );
goto ExitClearChipModeWithChanges;
}
// If BYTE mode clear it if use ECR register
if ( EcrMode == ECR_BYTE_MODE ) {
Status = PptClearByteMode( Extension );
goto ExitClearChipModeWithChanges;
}
}
ExitClearChipModeWithChanges:
if ( NT_SUCCESS(Status) ) {
PptDump2(PARINITDEV, ("ParMode::PptClearChipMode: Clearing Mode Returned Success.\n"));
Extension->PnpInfo.CurrentMode = INITIAL_MODE;
}
ExitClearChipModeNoChange:
PptDump2(PARINITDEV, ("ParMode::PptClearChipMode: Exit with Status - %x\n", Status ));
return Status;
}
NTSTATUS
PptEcrSetMode(
IN PDEVICE_EXTENSION Extension,
IN UCHAR ChipMode
)
/*++
Routine Description:
This routine enables EPP mode through the ECR register.
Arguments:
Extension - Supplies the device extension.
Return Value:
STATUS_SUCCESS - if the port type was detected.
!STATUS_SUCCESS - otherwise.
--*/
{
UCHAR ecr;
PUCHAR Controller;
PUCHAR wPortECR;
PptDump2(PARINITDEV, ("ParMode::PptEcrSetMode: Start.\n"));
Controller = Extension->PortInfo.Controller;
//
// Store the prior mode.
//
#if (0 == DVRH_USE_PARPORT_ECP_ADDR)
wPortECR = Controller + ECR_OFFSET;
#else
wPortECR = Extension->PnpInfo.EcpController + ECR_OFFSET;
#endif
PptDump2(PARINFO, ("PptEcrSetMode:: wPortECR : %p.\n", wPortECR ));
ecr = READ_PORT_UCHAR( wPortECR );
Extension->EcrPortData = ecr;
// get rid of prior mode which is the top three bits
ecr &= ECR_MODE_MASK;
// Write out SPP mode first to the chip
WRITE_PORT_UCHAR( wPortECR, (UCHAR)(ecr | ECR_BYTE_MODE) );
// Write new mode to ECR register
WRITE_PORT_UCHAR( wPortECR, ChipMode );
PptDump2(PARINITDEV, ("ParMode::PptEcrSetMode: Exit.\n"));
return STATUS_SUCCESS;
}
NTSTATUS
PptSetByteMode(
IN PDEVICE_EXTENSION Extension,
IN UCHAR ChipMode
)
/*++
Routine Description:
This routine enables Byte mode either through the ECR register
(if available). Or just checks it to see if it works
Arguments:
Extension - Supplies the device extension.
Return Value:
STATUS_SUCCESS - if the port type was detected.
!STATUS_SUCCESS - otherwise.
--*/
{
NTSTATUS Status;
// Checking to see if ECR register is there and if there use it
if ( Extension->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT ) {
Status = PptEcrSetMode( Extension, ChipMode );
}
Status = PptCheckByteMode( Extension );
return Status;
}
NTSTATUS
PptClearByteMode(
IN PDEVICE_EXTENSION Extension
)
/*++
Routine Description:
This routine Clears Byte mode through the ECR register if there otherwise
just returns success because nothing needs to be done.
Arguments:
Extension - Supplies the device extension.
Return Value:
STATUS_SUCCESS - if the port type was detected.
!STATUS_SUCCESS - otherwise.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
// Put ECR register back to original if it was there
if ( Extension->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT ) {
Status = PptEcrClearMode( Extension );
}
return Status;
}
NTSTATUS
PptCheckByteMode(
IN PDEVICE_EXTENSION Extension
)
/*++
Routine Description:
This routine checks to make sure we are still Byte capable before doing
any transfering of data.
Arguments:
Extension - Supplies the device extension of the device we are
reporting resources for.
Return Value:
None.
--*/
{
PUCHAR Controller;
UCHAR dcr;
Controller = Extension->PortInfo.Controller;
//
// run the test again to make sure somebody didn't take us out of a
// bi-directional capable port.
//
// 1. put in extended read mode.
// 2. write data pattern
// 3. read data pattern
// 4. if bi-directional capable, then data patterns will be different.
// 5. if patterns are the same, then check one more pattern.
// 6. if patterns are still the same, then port is NOT bi-directional.
//
// get the current control port value for later restoration
dcr = READ_PORT_UCHAR( Controller + DCR_OFFSET );
// put port into extended read mode
WRITE_PORT_UCHAR( Controller + DCR_OFFSET, (UCHAR)(dcr | DCR_DIRECTION) );
// write the first pattern to the port
WRITE_PORT_UCHAR( Controller, (UCHAR)0x55 );
if ( READ_PORT_UCHAR( Controller ) == (UCHAR)0x55 ) {
// same pattern, try the second pattern
WRITE_PORT_UCHAR( Controller, (UCHAR)0xaa );
if ( READ_PORT_UCHAR( Controller ) == (UCHAR)0xaa ) {
// the port is NOT bi-directional capable
return STATUS_UNSUCCESSFUL;
}
}
// restore the control port to its original value
WRITE_PORT_UCHAR( Controller + DCR_OFFSET, (UCHAR)dcr );
return STATUS_SUCCESS;
}
NTSTATUS
PptEcrClearMode(
IN PDEVICE_EXTENSION Extension
)
/*++
Routine Description:
This routine disables EPP or ECP mode whichever one the chip
was in through the ECR register.
Arguments:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -