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

📄 shuttle.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (C) SCM Micro Systems.

Module Name:

    parstl.c

Abstract:

    This is the module that generates unique device id
    for shuttle adapters, that do not have the capability
    to do so, by themselves.

Author:

    Devanathan NR   21-Jun-1999
    Sudheendran TL

Environment:

    Kernel mode

Revision History :


--*/

#include "pch.h"
#include "shuttle.h"

BOOLEAN
ParStlCheckIfStl(
    IN PPDO_EXTENSION    Extension,
    IN ULONG   ulDaisyIndex
    ) 
/*++

Routine Description:

    This function checks whether the indicated device
    is a shuttle device or not.

Arguments:

    Extension       - Device extension structure.

    ulDaisyIndex    - The daisy index on which to do the check.

Return Value:

    TRUE            - Yes, it was a Shuttle device.
    FALSE           - No, not a shuttle.

--*/
{
    BOOLEAN     bStlNon1284_3Found = FALSE ;

    DD(NULL,DDW,"ParStlCheckIfStl - enter\n");

    Extension->Ieee1284Flags &= ( ~ ( 1 << ulDaisyIndex ) ) ;
    bStlNon1284_3Found = ParStlCheckIfNon1284_3Present( Extension ) ;

    if ( TRUE == ParStlCheckIfStl1284_3 ( Extension, ulDaisyIndex, bStlNon1284_3Found ) ) {
        // this adapter is a Shuttle 1284_3 adapter
        Extension->Ieee1284Flags |= ( 1 << ulDaisyIndex ) ;
        return TRUE ;
    }
    if ( TRUE == bStlNon1284_3Found ) {
        if ( TRUE == ParStlCheckIfStlProductId ( Extension, ulDaisyIndex ) ) {
            // this adapter is Shuttle non-1284_3 adapter
            Extension->Ieee1284Flags |= ( 1 << ulDaisyIndex ) ;
            return TRUE ;
        }
    }
    return FALSE ;
}

BOOLEAN
ParStlCheckIfNon1284_3Present(
    IN PPDO_EXTENSION    Extension
    )
/*++

Routine Description:

    Indicates whether one of the devices of the earlier
    specification is present in the chain.


Arguments:

    Extension   - Device Extension structure


Return Value:

    TRUE    : Atleast one of the adapters are of earlier spec.
    FALSE   : None of the adapters of the earlier spec.

--*/
{
    BOOLEAN bReturnValue = FALSE ;
    UCHAR   i, value, newvalue, status;
    ULONG   Delay = 3;
    PUCHAR  CurrentPort, CurrentStatus, CurrentControl;
    UCHAR   ucAckStatus ;

    CurrentPort = Extension->Controller;
    CurrentStatus  = CurrentPort + 1;
    CurrentControl = CurrentPort + 2;

    // get current ctl reg
    value = P5ReadPortUchar( CurrentControl );

    // make sure 1284.3 devices do not get reseted
    newvalue = (UCHAR)((value & ~DCR_SELECT_IN) | DCR_NOT_INIT);

    // make sure we can write
    newvalue = (UCHAR)(newvalue & ~DCR_DIRECTION);
    P5WritePortUchar( CurrentControl, newvalue );    // make sure we can write 

    // bring nStrobe high
    P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );

    // send first four bytes of the 1284.3 mode qualifier sequence out
    for ( i = 0; i < MODE_LEN_1284_3 - 3; i++ ) {
        P5WritePortUchar( CurrentPort, ModeQualifier[i] );
        KeStallExecutionProcessor( Delay );
    }

    // check for correct status
    status = P5ReadPortUchar( CurrentStatus );

    if ( (status & (UCHAR)0xb8 ) 
         == ( DSR_NOT_BUSY | DSR_PERROR | DSR_SELECT | DSR_NOT_FAULT )) {

        ucAckStatus = status & 0x40 ;

        // continue with fifth byte of mode qualifier
        P5WritePortUchar( CurrentPort, ModeQualifier[4] );
        KeStallExecutionProcessor( Delay );

        // check for correct status
        status = P5ReadPortUchar( CurrentStatus );

        // note busy is high too but is opposite so we see it as a low
        if (( status & (UCHAR) 0xb8 ) == (DSR_SELECT | DSR_NOT_FAULT)) {

            if ( ucAckStatus != ( status & 0x40 ) ) {

                // save current ack status
                ucAckStatus = status & 0x40 ;

                // continue with sixth byte
                P5WritePortUchar( CurrentPort, ModeQualifier[5] );
                KeStallExecutionProcessor( Delay );

                // check for correct status
                status = P5ReadPortUchar( CurrentStatus );

                // if status is valid there is a device out there responding
                if ((status & (UCHAR) 0x30 ) == ( DSR_PERROR | DSR_SELECT )) {        

                    bReturnValue = TRUE ;

                } // Third status

            } // ack of earlier adapters not seen

            // last byte
            P5WritePortUchar( CurrentPort, ModeQualifier[6] );

        } // Second status

    } // First status

    P5WritePortUchar( CurrentControl, value );    // restore everything

    DD(NULL,DDW,"ParStlCheckIfNon1284_3Present - returning %s\n",bReturnValue?"TRUE":"FALSE");

    return bReturnValue ;
} // ParStlCheckIfNon1284_3Present

BOOLEAN
ParStlCheckIfStl1284_3(
    IN PPDO_EXTENSION    Extension,
    IN ULONG    ulDaisyIndex,
    IN BOOLEAN  bNoStrobe
    )
/*++

Routine Description:

    This function checks to see whether the device indicated
    is a Shuttle 1284_3 type of device. 

Arguments:

    Extension       - Device extension structure.

    ulDaisyIndex    - The daisy chain id of the device that
                      this function will check on.

    bNoStrobe       - If set, indicates that the query
                      Ep1284 command issued by this function
                      need not assert strobe to latch the
                      command.

Return Value:

    TRUE            - Yes. Device is Shuttle 1284_3 type of device.
    FALSE           - No. This may mean that this device is either
                      non-shuttle or Shuttle non-1284_3 type of
                      device.

--*/
{
    BOOLEAN bReturnValue = FALSE ;
    UCHAR   i, value, newvalue, status;
    ULONG   Delay = 3;
    UCHAR   ucExpectedPattern ;
    UCHAR   ucReadValue, ucReadPattern;
    PUCHAR  CurrentPort, CurrentStatus, CurrentControl;

    CurrentPort = Extension->Controller;
    CurrentStatus  = CurrentPort + 1;
    CurrentControl = CurrentPort + 2;

    // get current ctl reg
    value = P5ReadPortUchar( CurrentControl );

    // make sure 1284.3 devices do not get reseted
    newvalue = (UCHAR)((value & ~DCR_SELECT_IN) | DCR_NOT_INIT);

    // make sure we can write
    newvalue = (UCHAR)(newvalue & ~DCR_DIRECTION);
    P5WritePortUchar( CurrentControl, newvalue );    // make sure we can write 

    // bring nStrobe high
    P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );

    // send first four bytes of the 1284.3 mode qualifier sequence out
    for ( i = 0; i < MODE_LEN_1284_3 - 3; i++ ) {
        P5WritePortUchar( CurrentPort, ModeQualifier[i] );
        KeStallExecutionProcessor( Delay );
    }

    // check for correct status
    status = P5ReadPortUchar( CurrentStatus );

    if ( (status & (UCHAR)0xb8 ) 
         == ( DSR_NOT_BUSY | DSR_PERROR | DSR_SELECT | DSR_NOT_FAULT )) {

        // continue with fifth byte of mode qualifier
        P5WritePortUchar( CurrentPort, ModeQualifier[4] );
        KeStallExecutionProcessor( Delay );

        // check for correct status
        status = P5ReadPortUchar( CurrentStatus );

        // note busy is high too but is opposite so we see it as a low
        if (( status & (UCHAR) 0xb8 ) == (DSR_SELECT | DSR_NOT_FAULT)) {

            // continue with sixth byte
            P5WritePortUchar( CurrentPort, ModeQualifier[5] );
            KeStallExecutionProcessor( Delay );

            // check for correct status
            status = P5ReadPortUchar( CurrentStatus );

            // if status is valid there is a device out there responding
            if ((status & (UCHAR) 0x30 ) == ( DSR_PERROR | DSR_SELECT )) {        

                // Device is out there
                KeStallExecutionProcessor( Delay );

                // issue shuttle specific CPP command
                P5WritePortUchar( CurrentPort, (UCHAR) ( 0x88 | ulDaisyIndex ) );
                KeStallExecutionProcessor( Delay );        // wait a bit

                if ( ulDaisyIndex && ( bNoStrobe == FALSE ) ) {

                    P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );    // bring nStrobe high
                    P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) );    // bring nStrobe low
                    KeStallExecutionProcessor( Delay );        // wait a bit
                    P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );    // bring nStrobe high
                    KeStallExecutionProcessor( Delay );        // wait a bit

                }

                ucExpectedPattern = 0xF0 ;
                bReturnValue = TRUE ;

                while ( ucExpectedPattern ) {

                    KeStallExecutionProcessor( Delay );        // wait a bit
                    P5WritePortUchar( CurrentPort, (UCHAR) (0x80 | ulDaisyIndex )) ;

                    KeStallExecutionProcessor( Delay );        // wait a bit
                    P5WritePortUchar( CurrentPort, (UCHAR) (0x88 | ulDaisyIndex )) ;

                    KeStallExecutionProcessor( Delay );        // wait a bit
                    ucReadValue = P5ReadPortUchar( CurrentStatus ) ;
                    ucReadPattern = ( ucReadValue << 1 ) & 0x70 ;
                    ucReadPattern |= ( ucReadValue & 0x80 ) ;

                    if ( ucReadPattern != ucExpectedPattern ) {
                        // not Shuttle 1284_3 behaviour
                        bReturnValue = FALSE ;
                        break ;
                    }

                    ucExpectedPattern -= 0x10 ;
                }


                // last byte
                P5WritePortUchar( CurrentPort, ModeQualifier[6] );

            } // Third status

        } // Second status

    } // First status

    P5WritePortUchar( CurrentControl, value );    // restore everything

    DD(NULL,DDW,"ParStlCheckIfStl1284_3 - returning %s\n",bReturnValue?"TRUE":"FALSE");

    return bReturnValue ;
} // end  ParStlCheckIfStl1284_3()

BOOLEAN
ParStlCheckIfStlProductId(
    IN PPDO_EXTENSION    Extension,
    IN ULONG   ulDaisyIndex
    )
/*++

Routine Description:

    This function checks to see whether the device indicated
    is a Shuttle non-1284_3 type of device. 

Arguments:

    Extension       - Device extension structure.

    ulDaisyIndex    - The daisy chain id of the device that
                      this function will check on.

Return Value:

    TRUE            - Yes. Device is Shuttle non-1284_3 type of device.
    FALSE           - No. This may mean that this device is 
                      non-shuttle.

--*/
{
    BOOLEAN bReturnValue = FALSE ;
    UCHAR   i, value, newvalue, status;
    ULONG   Delay = 3;
    UCHAR   ucProdIdHiByteHiNibble, ucProdIdHiByteLoNibble ;
    UCHAR   ucProdIdLoByteHiNibble, ucProdIdLoByteLoNibble ;
    UCHAR   ucProdIdHiByte, ucProdIdLoByte ;
    USHORT  usProdId ;
    PUCHAR  CurrentPort, CurrentStatus, CurrentControl;

    CurrentPort = Extension->Controller;
    CurrentStatus  = CurrentPort + 1;
    CurrentControl = CurrentPort + 2;

    // get current ctl reg
    value = P5ReadPortUchar( CurrentControl );

    // make sure 1284.3 devices do not get reseted
    newvalue = (UCHAR)((value & ~DCR_SELECT_IN) | DCR_NOT_INIT);

    // make sure we can write
    newvalue = (UCHAR)(newvalue & ~DCR_DIRECTION);
    P5WritePortUchar( CurrentControl, newvalue );    // make sure we can write 

    // bring nStrobe high
    P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );

    // send first four bytes of the 1284.3 mode qualifier sequence out
    for ( i = 0; i < MODE_LEN_1284_3 - 3; i++ ) {
        P5WritePortUchar( CurrentPort, ModeQualifier[i] );
        KeStallExecutionProcessor( Delay );
    }

    // check for correct status
    status = P5ReadPortUchar( CurrentStatus );

    if ( (status & (UCHAR)0xb8 ) 
         == ( DSR_NOT_BUSY | DSR_PERROR | DSR_SELECT | DSR_NOT_FAULT )) {

        // continue with fifth byte of mode qualifier
        P5WritePortUchar( CurrentPort, ModeQualifier[4] );
        KeStallExecutionProcessor( Delay );

        // check for correct status
        status = P5ReadPortUchar( CurrentStatus );

        // note busy is high too but is opposite so we see it as a low
        if (( status & (UCHAR) 0xb8 ) == (DSR_SELECT | DSR_NOT_FAULT)) {

            // continue with sixth byte
            P5WritePortUchar( CurrentPort, ModeQualifier[5] );
            KeStallExecutionProcessor( Delay );

            // check for correct status
            status = P5ReadPortUchar( CurrentStatus );

            // if status is valid there is a device out there responding
            if ((status & (UCHAR) 0x30 ) == ( DSR_PERROR | DSR_SELECT )) {

                P5WritePortUchar ( CurrentPort, (UCHAR) (CPP_QUERY_PRODID | ulDaisyIndex )) ;
                KeStallExecutionProcessor( Delay );

                // Device is out there
                KeStallExecutionProcessor( Delay );
                ucProdIdLoByteHiNibble = P5ReadPortUchar( CurrentStatus ) ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -