📄 shuttle.c
字号:
/*++
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 + -