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

📄 daisychain.c

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

    // 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 ) ;
                ucProdIdLoByteHiNibble &= 0xF0 ;

                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                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

                ucProdIdLoByteLoNibble = P5ReadPortUchar( CurrentStatus ) ;
                ucProdIdLoByteLoNibble >>= 4 ;
                ucProdIdLoByte = ucProdIdLoByteHiNibble | ucProdIdLoByteLoNibble ;

                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                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

                ucProdIdHiByteHiNibble = P5ReadPortUchar( CurrentStatus ) ;
                ucProdIdHiByteHiNibble &= 0xF0 ;

                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                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

                ucProdIdHiByteLoNibble = P5ReadPortUchar( CurrentStatus ) ;
                ucProdIdHiByteLoNibble >>= 4 ;
                ucProdIdHiByte = ucProdIdHiByteHiNibble | ucProdIdHiByteLoNibble ;

                // issue the last strobe
                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                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

                usProdId = ( ucProdIdHiByte << 8 ) | ucProdIdLoByte ;

                if ( ( SHTL_EPAT_PRODID == usProdId ) ||\
                     ( SHTL_EPST_PRODID == usProdId ) ) {
                    // one of the devices that conform to the earlier
                    // draft is found
                    bReturnValue = TRUE ;
                }

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

            } // Third status

        } // Second status

    } // First status

    P5WritePortUchar( CurrentControl, value );    // restore everything

    return bReturnValue ;
} // end  PptCheckIfStlProductId()

BOOLEAN
PptSend1284_3Command(
    IN  PUCHAR  CurrentPort,
    IN  UCHAR   Command
    )
/*++

Routine Description:

    This routine sends the 1284_3 Command given to it
    down the parallel bus.

Arguments:


Return Value:

    None.

--*/
{
    UCHAR  i, value, newvalue, test;//, status;
    ULONG  ii;
    PUCHAR CurrentStatus, CurrentControl;
    ULONG  Delay = 3;
    BOOLEAN success = FALSE;

    CurrentStatus  = CurrentPort + 1;
    CurrentControl = CurrentPort + 2;

    // Get Upper 4 bits to see what Command it is
    test = (UCHAR)(Command & (UCHAR)CPP_COMMAND_FILTER);

    // 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) );
    KeStallExecutionProcessor( Delay );
    
    // 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 );
    }
    
    // wait up to 5 us : Spec says about 2 but we will be lienient
    if (CHECK_DSR(CurrentPort, INACTIVE, DONT_CARE, ACTIVE, ACTIVE, ACTIVE, 5 )) {

        // continue with fifth byte of mode qualifier
        P5WritePortUchar( CurrentPort, ModeQualifier[4] );
        KeStallExecutionProcessor( Delay );
        
        // wait up to 5 us : Spec says about 2 but we will be lienient
        if (CHECK_DSR(CurrentPort, ACTIVE, DONT_CARE, INACTIVE, ACTIVE, ACTIVE, 5 )) {

            // continue with sixth byte
            P5WritePortUchar( CurrentPort, ModeQualifier[5] );
            KeStallExecutionProcessor( Delay );
            
            // wait up to 5 us : Spec says about 2 but we will be lienient
            if (CHECK_DSR(CurrentPort, DONT_CARE, DONT_CARE, ACTIVE, ACTIVE, DONT_CARE, 5 )) {

                // Device is out there
                
                KeStallExecutionProcessor( Delay );

                // Command byte
                P5WritePortUchar( CurrentPort, Command );
                KeStallExecutionProcessor( Delay );        // wait a bit

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

                // NOTE NOTE NOTE
                // Assertion of strobe to be done ONLY after checking for the
                // FAULT feedback, as per the 1284_3 specification.

                // Selection does not work correctly yet to be able to check for lines
                switch ( test ) {
                    
                case CPP_SELECT:
                    // Check to make sure we are selected

                    // wait for upto 250 micro Secs for for selection time out.
                    for ( ii = 25000; ii > 0; ii-- ) {
                        
                        if ( ( P5ReadPortUchar( CurrentStatus ) & DSR_NOT_FAULT ) == DSR_NOT_FAULT ) {
                            // selection...
                            success = TRUE;
                            break;
                        }
                    }
                    break;

                case CPP_DESELECT:
                    // Check to make sure we are deselected                    

                    // wait for upto 250 micro Secs for for deselection time out.
                    for ( ii = 25000; ii > 0; ii-- ) {

                        if ( (P5ReadPortUchar( CurrentStatus ) & DSR_NOT_FAULT) != DSR_NOT_FAULT ) {
                            // deselection...
                            success = TRUE;
                            break;
                        }
                    }
                    break;

                default :
                    // there is a device out there and Command completed sucessfully
                    KeStallExecutionProcessor( Delay );        // wait a bit
                    success = TRUE;
                    break;

                } // End Switch

                // NOTE NOTE NOTE
                // the strobe is de-asserted now and the command is completed here
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );    // bring nStrobe high
                KeStallExecutionProcessor( Delay );        // wait a bit

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

            } // Third status
            
        } // Second status
        
    } // First status

    P5WritePortUchar( CurrentControl, value );    // restore everything

    // return TRUE if command succeeded, FALSE otherwise
    return success;
}


BOOLEAN
ParSelectDevice(
    IN  PPDO_EXTENSION  Pdx,
    IN  BOOLEAN         HavePort
    )

/*++

Routine Description:

    This routine acquires the ParPort and selects a 1284.3 device

Arguments:

    Pdx   - Supplies the device extension.

    HavePort    - TRUE  indicates that caller has already acquired port
                    so we should only do a SELECT_DEVICE
                - FALSE indicates that caller has not already acquired port
                    so we should do a combination ACQUIRE_PORT/SELECT_DEVICE

Return Value:

    TRUE    - success - the device was selected (and port acquired if needed)
    FALSE   - failure

--*/
{
    NTSTATUS                    status;
    PDEVICE_OBJECT              pPortDeviceObject;
    PARALLEL_1284_COMMAND       par1284Command;
    LARGE_INTEGER               timeOut;
    enum _PdoType               pdoType;

    //
    // Initialize command structure and extract parameters from the DeviceExtension
    //

    // reserved - always set to 0
    par1284Command.Port = 0;

    if( HavePort ) {
        par1284Command.CommandFlags = PAR_HAVE_PORT_KEEP_PORT;
    } else {
        par1284Command.CommandFlags = 0;
    }

    pdoType = Pdx->PdoType;
    switch( pdoType ) {
    case PdoTypeRawPort:
    case PdoTypeEndOfChain:
        par1284Command.ID = 0; // ignored, but set anyway
        par1284Command.CommandFlags |= PAR_END_OF_CHAIN_DEVICE;
        break;
    case PdoTypeLegacyZip:
        par1284Command.ID = DOT3_LEGACY_ZIP_ID;
        break;
    case PdoTypeDaisyChain:
        par1284Command.ID = Pdx->Ieee1284_3DeviceId;
        break;
    default:
        DD((PCE)Pdx,DDE,"Invalid pdoType = %x\n",pdoType);
        PptAssert(FALSE);
        break;
    }

    pPortDeviceObject = Pdx->PortDeviceObject;

    //
    // Send the request
    //
    timeOut.QuadPart = -(10*1000*500); // 500ms ( 100ns units )

    status = ParBuildSendInternalIoctl(IOCTL_INTERNAL_SELECT_DEVICE,
                                       pPortDeviceObject,
                                       &par1284Command, sizeof(PARALLEL_1284_COMMAND),
                                       NULL, 0,
                                       &timeOut);

    if( NT_SUCCESS( status ) ) {
        // SELECT succeeded
        DD((PCE)Pdx,DDT,"ParSelectDevice - SUCCESS\n");
        if( !HavePort ) {
            // note in the device extension that we have the port
            Pdx->bAllocated = TRUE;
        }
        return TRUE;
    } else {
        // SELECT failed
        DD((PCE)Pdx,DDT,"ParSelectDevice - FAIL\n");
        return FALSE;
    }
}

BOOLEAN
ParDeselectDevice(
    IN  PPDO_EXTENSION  Pdx,
    IN  BOOLEAN         KeepPort
    )
/*++

Routine Description:

    This routine deselects a 1284.3 or Legacy Zip device and optionally
    releases the ParPort

Arguments:

    Pdx   - Supplies the device extension.

    KeepPort    - TRUE  indicates that we should keep the port acquired,
                    so we should only do a DESELECT_DEVICE
                - FALSE indicates that we should not keep the port acquired,
                    so we should do a combination DESELECT_DEVICE/FREE_PORT

Return Value:

    TRUE    - The device was deselected (and the port released if requested)

--*/
{
    PARALLEL_1284_COMMAND       par1284Command;
    NTSTATUS                    status;
    enum _PdoType               pdoType;
    PDEVICE_OBJECT              fdo = Pdx->Fdo;
    PFDO_EXTENSION              fdx = fdo->DeviceExtension;

    //
    // If we don't have the port, succeed and return
    //
    if( !Pdx->bAllocated ) {
        DD((PCE)Pdx,DDW,"ParDeselectDevice - we do not have the port\n");
        return TRUE;
    }

    //
    // Initialize command structure and extract parameters from the DeviceExtension
    //

    // reserved - always set to 0
    par1284Command.Port = 0;

    if( KeepPort ) {
        par1284Command.CommandFlags = PAR_HAVE_PORT_KEEP_PORT;
    } else {
        par1284Command.CommandFlags = 0;
    }

    pdoType = Pdx->PdoType;
    switch( pdoType ) {
    case PdoTypeRawPort:
    case PdoTypeEndOfChain:
        par1284Command.ID = 0; // ignored, but set anyway
        par1284Command.CommandFlags |= PAR_END_OF_CHAIN_DEVICE;
        break;
    case PdoTypeLegacyZip:
        par1284Command.ID = DOT3_LEGACY_ZIP_ID;
        break;
    case PdoTypeDaisyChain:
        par1284Command.ID = Pdx->Ieee1284_3DeviceId;
        break;
    default:
        DD((PCE)Pdx,DDE,"Invalid pdoType = %x\n",pdoType);
        par1284Command.ID = 0; // choose a 1284.3 type deselect since this is harmless
        PptAssert(FALSE);
        break;
    }

    status = PptDeselectDevice( fdx, &par1284Command );

    if( status != STATUS_SUCCESS ) {
        // DESELECT failed?!? - there isn't anything that we can do
        DD((PCE)Pdx,DDE,"ParDeselectDevice - FAILED - nothing we can do - status=%x\n", status);
    } else {
        DD((PCE)Pdx,DDT,"ParDeselectDevice - SUCCESS\n", status);
    }

    if( !KeepPort ) {
        // note in the device extension that we gave up the port
        DD((PCE)Pdx,DDT,"ParDeselectDevice - gave up port\n");
        Pdx->bAllocated = FALSE;
    }

    return TRUE;
}

⌨️ 快捷键说明

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