⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parmode.c

📁 win2k kernel 的并口驱动程序模板
💻 C
📖 第 1 页 / 共 4 页
字号:
        }
                
    } 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 + -