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

📄 par12843.c

📁 win2k kernel 的并口驱动程序模板
💻 C
📖 第 1 页 / 共 3 页
字号:

            // this is End-of-Chain device so no deselect neccessary
            PptDump2( PARINFO, ("DOT3 DESELECT_DEVICE %S - ID=%d - End-of-Chain - SUCCESS\n",
                        Extension->PnpInfo.PortName, DeviceID) );

            // check if requester wants to keep port or free port
            if( !(Command->CommandFlags & PAR_HAVE_PORT_KEEP_PORT) ) {
                PptFreePort( Extension );
            }
            Status = STATUS_SUCCESS;

        }  // endif - Check if End Of Chain

    } // endif - Validate ID

    return ( Status );
    
}


ULONG
Ppt1284_3AssignAddress(
    IN  PDEVICE_EXTENSION    DeviceExtension
    )

/*++

Routine Description:

    This routine initializes the 1284_3 bus.

Arguments:

    DeviceExtension    - Supplies Device Extension structure of the driver.

Return Value:

    Number of 1284.3 devices out there at the given address.

--*/

{

    //UCHAR  i, ii, value, newvalue, status;
    UCHAR  i, value, newvalue, status;
    PUCHAR CurrentPort, CurrentStatus, CurrentControl;
    ULONG  Delay = 5;
    UCHAR  number = 0;
    BOOLEAN lastdevice = FALSE;
    UCHAR   idx;

    CurrentPort = DeviceExtension->PortInfo.Controller;
    CurrentStatus  = CurrentPort + 1;
    CurrentControl = CurrentPort + 2;

    // get current ctl reg
    value = READ_PORT_UCHAR( 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);
    WRITE_PORT_UCHAR( CurrentControl, newvalue );    // make sure we can write 

    // bring nStrobe high
    WRITE_PORT_UCHAR( 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++ ) {
        WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[i] );
        KeStallExecutionProcessor( Delay );
    }

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

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

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

        // check for correct status
        status = READ_PORT_UCHAR( 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
            WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[5] );
            KeStallExecutionProcessor( Delay );

            // check for correct status
            status = READ_PORT_UCHAR( 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 );

                while ( number < 4 && !lastdevice ) {

                    // Asssign address byte
                    WRITE_PORT_UCHAR( CurrentPort, number );
                    number = (UCHAR)(number + 1);

                    KeStallExecutionProcessor( Delay );                    // wait a bit
                    if ( (READ_PORT_UCHAR( CurrentStatus ) & (UCHAR)DSR_NOT_BUSY ) == 0 ) {
                        // we saw last device
                        lastdevice = TRUE;    
                    }

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

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

                if ( number ) {
                    BOOLEAN bStlNon1284_3Found ;
                    BOOLEAN bStlNon1284_3Valid ;
                    bStlNon1284_3Found = PptCheckIfNon1284_3Present(DeviceExtension);
                    bStlNon1284_3Valid = FALSE ;
                    // as the earlier 1284 spec does not give the
                    // lastdevice status is BSY, number needs to
                    // be corrected in such cases
                    for ( idx = 0 ; idx < number ; idx++ ) {
                        if ( TRUE == PptCheckIfStl1284_3(DeviceExtension, idx, bStlNon1284_3Found ) ) {
                            continue ;
                        }
                        if ( TRUE == bStlNon1284_3Found ) {
                            if ( TRUE == PptCheckIfStlProductId(DeviceExtension, idx) ) {
                                bStlNon1284_3Valid = TRUE ;
                                continue ;
                            }
                        }
                        break ;
                    }
                    if ( TRUE == bStlNon1284_3Valid ) {
                        // we alter the count only if old adapters
                        // are in the chain
                        number = idx;
                    }
                }

            } // Third status

        } // Second status

    } // First status

    WRITE_PORT_UCHAR( CurrentControl, value );    // restore everything

    // returns last device ID + 1 or number of devices out there
    return ( (ULONG)number );

}

BOOLEAN
PptCheckIfNon1284_3Present(
    IN PDEVICE_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->PortInfo.Controller;
    CurrentStatus  = CurrentPort + 1;
    CurrentControl = CurrentPort + 2;

    // get current ctl reg
    value = READ_PORT_UCHAR( 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);
    WRITE_PORT_UCHAR( CurrentControl, newvalue );    // make sure we can write 

    // bring nStrobe high
    WRITE_PORT_UCHAR( 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++ ) {
        WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[i] );
        KeStallExecutionProcessor( Delay );
    }

    // check for correct status
    status = READ_PORT_UCHAR( 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
        WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[4] );
        KeStallExecutionProcessor( Delay );

        // check for correct status
        status = READ_PORT_UCHAR( 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
                WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[5] );
                KeStallExecutionProcessor( Delay );

                // check for correct status
                status = READ_PORT_UCHAR( 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
            WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[6] );

        } // Second status

    } // First status

    WRITE_PORT_UCHAR( CurrentControl, value );    // restore everything

    return bReturnValue ;
} // PptCheckIfNon1284_3Present


// Define 1284 Commands
#define CPP_QUERY_PRODID    0x10

// 1284 related SHTL prod id equates
#define SHTL_EPAT_PRODID    0xAAFF
#define SHTL_EPST_PRODID    0xA8FF

BOOLEAN
PptCheckIfStl1284_3(
    IN PDEVICE_EXTENSION    DeviceExtension,
    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 = DeviceExtension->PortInfo.Controller;
    CurrentStatus  = CurrentPort + 1;
    CurrentControl = CurrentPort + 2;

    // get current ctl reg
    value = READ_PORT_UCHAR( 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);
    WRITE_PORT_UCHAR( CurrentControl, newvalue );    // make sure we can write 

    // bring nStrobe high
    WRITE_PORT_UCHAR( 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++ ) {
        WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[i] );
        KeStallExecutionProcessor( Delay );
    }

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

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

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

        // check for correct status
        status = READ_PORT_UCHAR( 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
            WRITE_PORT_UCHAR( CurrentPort, ModeQualifier[5] );
            KeStallExecutionProcessor( Delay );

            // check for correct status
            status = READ_PORT_UCHAR( 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
                WRITE_PORT_UCHAR( CurrentPort, (UCHAR) ( 0x88 | ulDaisyIndex ) );
                KeStallExecutionProcessor( Delay );        // wait a bit

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

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

                }

                ucExpectedPattern = 0xF0 ;
                bReturnValue = TRUE ;

                while ( ucExpectedPattern ) {

                    KeStallExecutionProcessor( Delay );        // wait a bit

⌨️ 快捷键说明

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