📄 chipmode.c
字号:
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 ( Fdx->FilterMode ) {
Status = Fdx->ChipInfo.ParChipSetMode ( Fdx->ChipInfo.Context, ChipMode );
} else {
// If asked for ECP check to see if we can do it
if ( EcrMode == ECR_ECP_MODE ) {
if ((Fdx->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT) ^ PPT_ECP_PRESENT) {
// ECP Not Present
return STATUS_NO_SUCH_DEVICE;
}
Status = PptEcrSetMode ( Fdx, ChipMode );
goto ExitSetChipModeWithChanges;
}
// If asked for EPP check to see if we can do it
if ( EcrMode == ECR_EPP_MODE ) {
if ((Fdx->PnpInfo.HardwareCapabilities & PPT_EPP_PRESENT) ^ PPT_EPP_PRESENT) {
// EPP Not Present
return STATUS_NO_SUCH_DEVICE;
}
Status = PptEcrSetMode ( Fdx, ChipMode );
goto ExitSetChipModeWithChanges;
}
// If asked for Byte Mode check to see if it is still enabled
if ( EcrMode == ECR_BYTE_MODE ) {
if ((Fdx->PnpInfo.HardwareCapabilities & PPT_BYTE_PRESENT) ^ PPT_BYTE_PRESENT) {
// BYTE Not Present
return STATUS_NO_SUCH_DEVICE;
}
Status = PptSetByteMode ( Fdx, ChipMode );
goto ExitSetChipModeWithChanges;
}
}
ExitSetChipModeWithChanges:
if ( NT_SUCCESS(Status) ) {
Fdx->PnpInfo.CurrentMode = EcrMode;
} else {
DD((PCE)Fdx,DDW,"PptSetChipMode - failed w/status = %x\n",Status);
}
ExitSetChipModeNoChange:
return Status;
}
NTSTATUS
PptClearChipMode (
IN PFDO_EXTENSION Fdx,
IN UCHAR ChipMode
)
/*++
Routine Description:
This routine Clears the Given chip mode.
Arguments:
Fdx - 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;
// make sure we have a mode to clear
if ( EcrMode != Fdx->PnpInfo.CurrentMode ) {
DD((PCE)Fdx,DDW,"ParMode::PptClearChipMode: Mode to Clear != CurrentModen");
// 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 ( Fdx->FilterMode ) {
Status = Fdx->ChipInfo.ParChipClearMode ( Fdx->ChipInfo.Context, ChipMode );
} else {
// If ECP mode check to see if we can clear it
if ( EcrMode == ECR_ECP_MODE ) {
Status = PptEcrClearMode( Fdx );
goto ExitClearChipModeWithChanges;
}
// If EPP mode check to see if we can clear it
if ( EcrMode == ECR_EPP_MODE ) {
Status = PptEcrClearMode( Fdx );
goto ExitClearChipModeWithChanges;
}
// If BYTE mode clear it if use ECR register
if ( EcrMode == ECR_BYTE_MODE ) {
Status = PptClearByteMode( Fdx );
goto ExitClearChipModeWithChanges;
}
}
ExitClearChipModeWithChanges:
if( NT_SUCCESS(Status) ) {
Fdx->PnpInfo.CurrentMode = INITIAL_MODE;
}
ExitClearChipModeNoChange:
return Status;
}
NTSTATUS
PptEcrSetMode(
IN PFDO_EXTENSION Fdx,
IN UCHAR ChipMode
)
/*++
Routine Description:
This routine enables EPP mode through the ECR register.
Arguments:
Fdx - Supplies the device extension.
Return Value:
STATUS_SUCCESS - if the port type was detected.
!STATUS_SUCCESS - otherwise.
--*/
{
UCHAR ecr;
PUCHAR Controller;
PUCHAR wPortECR;
Controller = Fdx->PortInfo.Controller;
//
// Store the prior mode.
//
wPortECR = Fdx->PnpInfo.EcpController + ECR_OFFSET;
ecr = P5ReadPortUchar( wPortECR );
Fdx->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
P5WritePortUchar( wPortECR, (UCHAR)(ecr | ECR_BYTE_MODE) );
// Write new mode to ECR register
P5WritePortUchar( wPortECR, ChipMode );
return STATUS_SUCCESS;
}
NTSTATUS
PptSetByteMode(
IN PFDO_EXTENSION Fdx,
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:
Fdx - 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 ( Fdx->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT ) {
Status = PptEcrSetMode( Fdx, ChipMode );
}
Status = PptCheckByteMode( Fdx );
return Status;
}
NTSTATUS
PptClearByteMode(
IN PFDO_EXTENSION Fdx
)
/*++
Routine Description:
This routine Clears Byte mode through the ECR register if there otherwise
just returns success because nothing needs to be done.
Arguments:
Fdx - 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 ( Fdx->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT ) {
Status = PptEcrClearMode( Fdx );
}
return Status;
}
NTSTATUS
PptCheckByteMode(
IN PFDO_EXTENSION Fdx
)
/*++
Routine Description:
This routine checks to make sure we are still Byte capable before doing
any transfering of data.
Arguments:
Fdx - Supplies the device extension of the device we are
reporting resources for.
Return Value:
None.
--*/
{
PUCHAR Controller;
UCHAR dcr;
Controller = Fdx->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 = P5ReadPortUchar( Controller + DCR_OFFSET );
// put port into extended read mode
P5WritePortUchar( Controller + DCR_OFFSET, (UCHAR)(dcr | DCR_DIRECTION) );
// write the first pattern to the port
P5WritePortUchar( Controller, (UCHAR)0x55 );
if ( P5ReadPortUchar( Controller ) == (UCHAR)0x55 ) {
// same pattern, try the second pattern
P5WritePortUchar( Controller, (UCHAR)0xaa );
if ( P5ReadPortUchar( Controller ) == (UCHAR)0xaa ) {
// the port is NOT bi-directional capable
return STATUS_UNSUCCESSFUL;
}
}
// restore the control port to its original value
P5WritePortUchar( Controller + DCR_OFFSET, (UCHAR)dcr );
return STATUS_SUCCESS;
}
NTSTATUS
PptEcrClearMode(
IN PFDO_EXTENSION Fdx
)
/*++
Routine Description:
This routine disables EPP or ECP mode whichever one the chip
was in through the ECR register.
Arguments:
Fdx - Supplies the device extension.
Return Value:
STATUS_SUCCESS - if it was successful.
!STATUS_SUCCESS - otherwise.
--*/
{
UCHAR ecr;
PUCHAR Controller;
PUCHAR wPortECR;
Controller = Fdx->PortInfo.Controller;
//
// Restore the prior mode.
//
// Get original ECR register
ecr = Fdx->EcrPortData;
Fdx->EcrPortData = 0;
// some chips require to change modes only after
// you put it into spp mode
wPortECR = Fdx->PnpInfo.EcpController + ECR_OFFSET;
P5WritePortUchar( wPortECR, (UCHAR)(ecr & ECR_MODE_MASK) );
// Back to original mode
P5WritePortUchar( wPortECR, ecr );
return STATUS_SUCCESS;
}
NTSTATUS
PptBuildResourceList(
IN PFDO_EXTENSION Fdx,
IN ULONG Partial,
IN PUCHAR *Addresses,
OUT PCM_RESOURCE_LIST Resources
)
/*++
Routine Description:
This routine Builds a CM_RESOURCE_LIST with 1 Full Resource
Descriptor and as many Partial resource descriptors as you want
with the same parameters for the Full. No Interrupts or anything
else just IO addresses.
Arguments:
Fdx - Supplies the device extension.
Partial - Number (array size) of partial descriptors in Addresses[]
Addresses - Pointer to an Array of addresses of the partial descriptors
Resources - The returned CM_RESOURCE_LIST
Return Value:
STATUS_SUCCESS - if the building of the list was successful.
STATUS_UNSUCCESSFUL - otherwise.
--*/
{
UCHAR i;
//
// Number of Full Resource descriptors
//
Resources->Count = 1;
Resources->List[0].InterfaceType = Fdx->InterfaceType;
Resources->List[0].BusNumber = Fdx->BusNumber;
Resources->List[0].PartialResourceList.Version = 0;
Resources->List[0].PartialResourceList.Revision = 0;
Resources->List[0].PartialResourceList.Count = Partial;
//
// Going through the loop for each partial descriptor
//
for ( i = 0; i < Partial ; i++ ) {
//
// Setup port
//
Resources->List[0].PartialResourceList.PartialDescriptors[i].Type = CmResourceTypePort;
Resources->List[0].PartialResourceList.PartialDescriptors[i].ShareDisposition = CmResourceShareDriverExclusive;
Resources->List[0].PartialResourceList.PartialDescriptors[i].Flags = CM_RESOURCE_PORT_IO;
Resources->List[0].PartialResourceList.PartialDescriptors[i].u.Port.Start.QuadPart = (ULONG_PTR)Addresses[i];
Resources->List[0].PartialResourceList.PartialDescriptors[i].u.Port.Length = (ULONG)2;
}
return ( STATUS_SUCCESS );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -