📄 shuttle.c
字号:
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 ;
// 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
DD(NULL,DDW,"ParStlCheckIfStlProductId - returning %s\n",bReturnValue?"TRUE":"FALSE");
return bReturnValue ;
} // end ParStlCheckIfStlProductId()
PCHAR
ParStlQueryStlDeviceId(
IN PPDO_EXTENSION Extension,
OUT PCHAR CallerDeviceIdBuffer,
IN ULONG CallerBufferSize,
OUT PULONG DeviceIdSize,
IN BOOLEAN bReturnRawString
)
/*++
Routine Description:
This routine retrieves/constructs the unique device id
string from the selected shuttle device on the chain
and updates the caller's buffer with the same.
Arguments:
IN Extension : The device extension
OUT CallerDeviceIdBuffer : Caller's buffer
IN CallerBufferSize : Size of caller's buffer
OUT DeviceIdSize : Updated device id's size
IN bReturnRawString : Whether to return raw
string with the first two
bytes or not.
Return Value:
Pointer to the read device ID string, if successful.
NULL otherwise.
--*/
{
PUCHAR Controller = Extension->Controller;
NTSTATUS Status;
UCHAR idSizeBuffer[2];
ULONG bytesToRead;
ULONG bytesRead = 0;
USHORT deviceIdSize;
USHORT deviceIdBufferSize;
PCHAR deviceIdBuffer;
PCHAR readPtr;
DD(NULL,DDW,"ParStlQueryStlDeviceId - enter\n");
*DeviceIdSize = 0;
// assert idle state, to recover from undefined state,
// just in case it gets into
ParStlAssertIdleState ( Extension ) ;
//
// If we are currently connected to the peripheral via any 1284 mode
// other than Compatibility/Spp mode (which does not require an IEEE
// negotiation), we must first terminate the current mode/connection.
//
// dvdf - RMT - what if we are connected in a reverse mode?
//
if( (Extension->Connected) && (afpForward[Extension->IdxForwardProtocol].fnDisconnect) ) {
afpForward[Extension->IdxForwardProtocol].fnDisconnect (Extension);
}
//
// Negotiate the peripheral into nibble device id mode.
//
Status = ParEnterNibbleMode(Extension, REQUEST_DEVICE_ID);
if( !NT_SUCCESS(Status) ) {
ParTerminateNibbleMode(Extension);
goto targetContinue;
}
//
// Read first two bytes to get the total (including the 2 size bytes) size
// of the Device Id string.
//
bytesToRead = 2;
Status = ParNibbleModeRead(Extension, idSizeBuffer, bytesToRead, &bytesRead);
if( !NT_SUCCESS( Status ) || ( bytesRead != bytesToRead ) ) {
goto targetContinue;
}
//
// Compute size of DeviceId string (including the 2 byte size prefix)
//
deviceIdSize = (USHORT)( idSizeBuffer[0]*0x100 + idSizeBuffer[1] );
{
const USHORT minValidDevId = 14; // 2 size bytes + "MFG:x;" + "MDL:y;"
const USHORT maxValidDevId = 2048; // arbitrary, but we've never seen one > 1024
if( (deviceIdSize < minValidDevId) || (deviceIdSize > maxValidDevId) ) {
//
// The device is reporting a 1284 ID string length that is probably bogus.
// Ignore the device reported ID and skip to the code below that makes
// up a VID/PID based 1284 ID based on the specific SCM Micro chip used
// by the device.
//
goto targetContinue;
}
}
//
// Allocate a buffer to hold the DeviceId string and read the DeviceId into it.
//
if( bReturnRawString ) {
//
// Caller wants the raw string including the 2 size bytes
//
*DeviceIdSize = deviceIdSize;
deviceIdBufferSize = (USHORT)(deviceIdSize + sizeof(CHAR)); // ID size + ID + terminating NULL
} else {
//
// Caller does not want the 2 byte size prefix
//
*DeviceIdSize = deviceIdSize - 2*sizeof(CHAR);
deviceIdBufferSize = (USHORT)(deviceIdSize - 2*sizeof(CHAR) + sizeof(CHAR)); // ID + terminating NULL
}
deviceIdBuffer = (PCHAR)ExAllocatePool(PagedPool, deviceIdBufferSize);
if( !deviceIdBuffer ) {
goto targetContinue;
}
//
// NULL out the ID buffer to be safe
//
RtlZeroMemory( deviceIdBuffer, deviceIdBufferSize );
//
// Does the caller want the 2 byte size prefix?
//
if( bReturnRawString ) {
//
// Yes, caller wants the size prefix. Copy prefix to buffer to return.
//
*(deviceIdBuffer+0) = idSizeBuffer[0];
*(deviceIdBuffer+1) = idSizeBuffer[1];
readPtr = deviceIdBuffer + 2;
} else {
//
// No, discard size prefix
//
readPtr = deviceIdBuffer;
}
//
// Read remainder of DeviceId from device
//
bytesToRead = deviceIdSize - 2; // already have the 2 size bytes
Status = ParNibbleModeRead(Extension, readPtr, bytesToRead, &bytesRead);
ParTerminateNibbleMode( Extension );
if( !NT_SUCCESS(Status) || (bytesRead < 1) ) {
ExFreePool( deviceIdBuffer );
goto targetContinue;
}
if ( strstr ( readPtr, "MFG:" ) == 0 ) {
ExFreePool( deviceIdBuffer ) ;
goto targetContinue;
}
deviceIdSize = (USHORT)strlen(deviceIdBuffer);
*DeviceIdSize = deviceIdSize;
if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize) ) {
// caller supplied buffer is large enough, use it
RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
ExFreePool( deviceIdBuffer );
return CallerDeviceIdBuffer;
}
return deviceIdBuffer;
targetContinue:
// Builds later than 2080 fail to terminate in Compatibility mode.
//IEEETerminate1284Mode fails after Event 23 (Extension->CurrentEvent equals 23)
// with earlier 1284 draft.
//So, we terminate the adapter ourselves, in some cases may be redundant.
P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT);
KeStallExecutionProcessor( 5 );
P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT | DCR_AUTOFEED);
KeStallExecutionProcessor( 5 );
P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT);
ParStlAssertIdleState ( Extension ) ;
deviceIdBuffer = ParBuildStlDeviceId(Extension, bReturnRawString);
if( !deviceIdBuffer ) {
return NULL;
}
deviceIdSize = (USHORT)strlen(deviceIdBuffer);
*DeviceIdSize = deviceIdSize;
if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize) ) {
// caller supplied buffer is large enough, use it
RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
ExFreePool( deviceIdBuffer );
return CallerDeviceIdBuffer;
}
return deviceIdBuffer;
}
PCHAR
ParBuildStlDeviceId(
IN PPDO_EXTENSION Extension,
IN BOOLEAN bReturnRawString
)
/*++
Routine Description:
This function detects the type of shuttle adapter and
builds an appropriate device id string and returns it
back.
It is assumed that the device is already in the
selected state.
Arguments:
Nil.
Return Value:
Pointer to the read/built device ID string, if successful.
NULL otherwise.
--*/
{
ULONG size = 0x80 ;
PCHAR id ;
STL_DEVICE_TYPE dtDeviceType ;
CHAR szDeviceIdString[0x80] ;
CHAR szVidPidString[] = "MFG:VID_04E6;CLS:SCSIADAPTER;MDL:PID_" ;
CHAR szVidPidStringScan[] = "MFG:VID_04E6;CLS:IMAGE;MDL:PID_" ;
RtlZeroMemory(szDeviceIdString, sizeof(szDeviceIdString));
// identify the shuttle adapter type by calling
// Devtype routines here and build an unique id
// string here.
dtDeviceType = ParStlGetDeviceType(Extension, DEVICE_TYPE_AUTO_DETECT);
switch ( dtDeviceType ) {
case DEVICE_TYPE_NONE :
return NULL;
case DEVICE_TYPE_EPP_DEVICE :
dtDeviceType |= 0x80000000 ;
sprintf(szDeviceIdString, "%s%08X;", szVidPidStringScan, dtDeviceType);
break;
default :
dtDeviceType |= 0x80000000 ;
sprintf(szDeviceIdString, "%s%08X;", szVidPidString, dtDeviceType);
break;
}
id = ExAllocatePool(PagedPool, size);
if( id ) {
RtlZeroMemory( id, size );
if( bReturnRawString ) {
//
// Yes, caller wants the size prefix. Copy prefix to buffer to return.
//
*(id+0) = 0;
*(id+1) = 0x80-2;
RtlCopyMemory( id+2, szDeviceIdString, size - sizeof(NULL) - 2 );
} else {
RtlCopyMemory( id, szDeviceIdString, size - sizeof(NULL) );
}
return id;
}
return NULL;
}
STL_DEVICE_TYPE __cdecl
ParStlGetDeviceType (
IN PPDO_EXTENSION Extension,
IN int nPreferredDeviceType
)
{
STL_DEVICE_TYPE dtDeviceType = DEVICE_TYPE_NONE ;
ATAPIPARAMS atapiParams ;
int i;
for ( i=0 ; i<ATAPI_MAX_DRIVES ; i++){
atapiParams.dsDeviceState[i] = DEVICE_STATE_INVALID ;
}
do
{
if ( TRUE == ParStlCheckIfScsiDevice(Extension))
{
// SCSI Device identified.
dtDeviceType |= DEVICE_TYPE_SCSI_BIT ;
break ;
}
if ( TRUE == NeedToEnableIoPads () )
{
// in some adapters, the IO pads need to be enabled, before
// doing the device detection
ParStlWriteReg( Extension, CONFIG_INDEX_REGISTER, EP1284_POWER_CONTROL_REG );
ParStlWriteReg( Extension, CONFIG_DATA_REGISTER, ENABLE_IOPADS );
}
if ( TRUE == IsImpactSPresent() )
{
// as impact-s has been identified, the device type identification
// can be done through personality configuration info
dtDeviceType |= ParStlGetImpactSDeviceType( Extension, &atapiParams, nPreferredDeviceType );
break;
}
if ( TRUE == IsImpactPresent() )
{
// as impact has been identified, the device type identification
// can be done through personality configuration info
dtDeviceType |= ParStlGetImpactDeviceType( Extension, &atapiParams, nPreferredDeviceType );
break;
}
if (TRUE == ParStlCheckIfEppDevice(Extension))
{
// epp device identified
if ( TRUE == ParStlCheckUMAXScannerPresence(Extension) ) {
// umax identified
dtDeviceType |= DEVICE_TYPE_UMAX_BIT;
break;
}
if ( TRUE == ParStlCheckAvisionScannerPresence(Extension) ) {
// avision identified
dtDeviceType |= DEVICE_TYPE_AVISION_BIT;
break;
}
// generice scanner peripheral detected
dtDeviceType |= DEVICE_TYPE_EPP_DEVICE_BIT;
break;
}
if (TRUE == ParStlCheckIfSSFDC(Extension))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -