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

📄 chipmode.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -