📄 shuttle.c
字号:
{
// SSFDC identified
dtDeviceType |= DEVICE_TYPE_SSFDC_BIT;
break;
}
if (TRUE == ParStlCheckIfMMC(Extension,&atapiParams))
{
// MMC device identified
dtDeviceType |= DEVICE_TYPE_MMC_BIT;
break;
}
// set the 16 bit mode of the adapter
ParStlSet16BitOperation(Extension) ;
if (TRUE == ParStlCheckIfAtaAtapiDevice(Extension, &atapiParams))
{
// necessary but not sufficient condition has passed
// proceed for sufficency checks
if (TRUE == ParStlCheckIfAtapiDevice(Extension, &atapiParams))
{
// sub-classify between HiFD and LS-120.
if ( TRUE == ParStlCheckIfLS120(Extension))
{
// LS Engine is found.
dtDeviceType |= DEVICE_TYPE_LS120_BIT ;
break ;
}
// Check for HiFD.
if (TRUE == ParStlCheckIfHiFD(Extension))
{
// HiFD device identified.
dtDeviceType |= DEVICE_TYPE_HIFD_BIT ;
break ;
}
// OtherWise, it is a generic ATAPI device.
dtDeviceType |= DEVICE_TYPE_ATAPI_BIT;
break ;
}
if (TRUE == ParStlCheckIfAtaDevice(Extension, &atapiParams))
{
// ata identified
dtDeviceType |= DEVICE_TYPE_ATA_BIT;
break;
}
}
if (TRUE == ParStlCheckIfDazzle(Extension))
{
// dazzle identified
dtDeviceType |= DEVICE_TYPE_DAZZLE_BIT;
break;
}
if (TRUE == ParStlCheckIfFlash(Extension))
{
// flash identified
dtDeviceType |= DEVICE_TYPE_FLASH_BIT;
break;
}
}
while ( FALSE ) ;
return dtDeviceType & nPreferredDeviceType ;
}
VOID
ParStlWaitForMicroSeconds (
int nMicroSecondsToWait
) {
KeStallExecutionProcessor ( nMicroSecondsToWait ) ;
}
BOOLEAN
ParStlCheckCardInsertionStatus (
IN PPDO_EXTENSION Extension
)
{
BOOLEAN bReturnValue = FALSE ;
UCHAR byPowerRegData ;
do
{
if ( FALSE == IsEp1284Present() )
{
break ;
}
ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER , 0x0F ) ;
byPowerRegData = (UCHAR) ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) ;
if ( byPowerRegData & SHTL_CARD_INSERTED_STATUS )
{
// as the card not inserted status is reported, it is ATA / ATAPI
// possibly, not flash. hence, we break here.
break ;
}
bReturnValue = TRUE ;
}
while ( FALSE ) ;
return ( bReturnValue ) ;
}
BOOLEAN
ParStlSelectAdapterSocket (
IN PPDO_EXTENSION Extension,
IN int nSocketNumber
)
{
BOOLEAN bReturnValue = FALSE ;
UCHAR bySCRControlReg , byISAControlReg ;
do
{
if ( ( nSocketNumber != SOCKET_0 ) &&
( nSocketNumber != SOCKET_1 ) )
{
// as an invalid socket number is provided, we
// break here with error.
break ;
}
ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
bySCRControlReg = (UCHAR) ParStlReadReg (Extension, CONFIG_DATA_REGISTER ) ;
ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , ISA_CONTROL_REGISTER ) ;
byISAControlReg = (UCHAR) ParStlReadReg (Extension, CONFIG_DATA_REGISTER ) ;
if ( SOCKET_1 == nSocketNumber )
{
bySCRControlReg |= (UCHAR)SOCKET_1 ;
bySCRControlReg |= (UCHAR)PERIPHERAL_RESET_1 ;
byISAControlReg &= ~(UCHAR)ISA_IO_SWAP ;
}
else
{
bySCRControlReg &= ~(UCHAR)SOCKET_1 ;
bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_0 ;
}
ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , ISA_CONTROL_REGISTER ) ;
ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , byISAControlReg ) ;
ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
if ( SOCKET_1 == nSocketNumber )
{
// Wait for a few milliseconds to provide an optimal puse width
// for reset.
ParStlWaitForMicroSeconds(1000);
bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_1 ;
}
else
{
bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_0 ;
}
ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
bReturnValue = TRUE ;
}
while ( FALSE ) ;
return bReturnValue ;
}
BOOLEAN
ParStlCheckIfAtaAtapiDevice (
IN PPDO_EXTENSION Extension,
IN OUT PATAPIPARAMS atapiParams
)
{
BOOLEAN bReturnValue = FALSE;
do
{
if ( TRUE == ParStlCheckCardInsertionStatus(Extension) )
{
// as the card insertion status is valid, its probably
// a flash
break ;
}
if ( FALSE == ParStlCheckDrivePresent(Extension, atapiParams) )
{
// as the ATA/ATAPI controller is not present, it cant be
// an ATA/ATAPI device
break ;
}
bReturnValue = TRUE;
}
while ( FALSE ) ;
return bReturnValue ;
}
BOOLEAN
ParStlCheckIfAtapiDevice (
IN PPDO_EXTENSION Extension,
IN OUT PATAPIPARAMS atapiParams
)
{
BOOLEAN bReturnValue = FALSE;
do
{
// return whatever ATAPI initialization module says
bReturnValue = ParStlAtapiInitialize(Extension, atapiParams) ;
}
while ( FALSE ) ;
return bReturnValue ;
}
BOOLEAN
ParStlCheckIfAtaDevice (
IN PPDO_EXTENSION Extension,
IN OUT PATAPIPARAMS atapiParams
)
{
BOOLEAN bReturnValue = FALSE;
do
{
// return whatever ATA initialization module says
bReturnValue = ParStlAtaInitialize(Extension, atapiParams) ;
}
while ( FALSE ) ;
return bReturnValue ;
}
BOOLEAN
ParStlCheckDrivePresent (
IN PPDO_EXTENSION Extension,
IN OUT PATAPIPARAMS atapiParams
)
{
BOOLEAN bReturnValue = FALSE ;
UCHAR byOrgCylHigh, byOrgCylLow ;
int nCurrentDrive = 0 , i ;
UCHAR nDrvHdArray[]={ATAPI_MASTER, ATAPI_SLAVE};
do
{
if ( atapiParams->dsDeviceState[nCurrentDrive] == DEVICE_STATE_VALID )
{
// this means that the MMC module had detected the presence
// of an ATA/ATAPI device. So, we make use of that and break out
bReturnValue = TRUE ;
break ;
}
ParStlWriteIoPort(Extension, ATA_DRVHD_REG, nDrvHdArray[nCurrentDrive]);
// The Atapi Fuji MO drive is found to de-assert BSY and still
// does not respond to reg. r/w when configured as slave with no media.
// However, after a delay, it works ok.
if ( nCurrentDrive )
{
ParStlWaitForMicroSeconds ( DELAY_1SECOND ) ;
}
// this dummy write of 0 is to zero out a possible
// floating bus
for ( i = 0 ; i < 16 ; i++ )
{
ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER, i) ;
if ( !( ParStlReadIoPort (Extension, ATA_TASK_STAT_REG ) & ATA_ST_BUSY ) )
{
break ;
}
}
if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
{
// as the busy has been found permanently set, we check
// for the slave also
continue;
}
// as the drive head setup might have been performed in a busy state,
// we set it up again after busy clears.
ParStlWriteIoPort(Extension, ATA_DRVHD_REG, nDrvHdArray[nCurrentDrive]);
if ( ( ParStlReadIoPort(Extension, ATA_DRVHD_REG) & ATAPI_SLAVE ) != nDrvHdArray[nCurrentDrive] )
{
continue ;
}
// read original contents of the cyl ATA high/low registers
byOrgCylLow = (UCHAR) ParStlReadIoPort(Extension, ATA_CYLLOW_REG);
byOrgCylHigh = (UCHAR) ParStlReadIoPort(Extension, ATA_CYLHIGH_REG);
// write a test pattern in the cyl ATA high/low registers
ParStlWriteIoPort(Extension, ATA_CYLLOW_REG, TEST_PATTERN_1);
ParStlWriteIoPort(Extension, ATA_CYLHIGH_REG, TEST_PATTERN_2);
// read the test pattern in the cyl ATA high/low registers
if ( ( TEST_PATTERN_1 != ParStlReadIoPort(Extension, ATA_CYLLOW_REG) ) ||\
( TEST_PATTERN_2 != ParStlReadIoPort(Extension, ATA_CYLHIGH_REG) ) )
{
// as we were not able to read back the written values
// we break out here, indicating the absence of the device
continue ;
}
// write back original contents in the cyl ATA high/low registers
ParStlWriteIoPort(Extension, ATA_CYLLOW_REG, byOrgCylLow);
ParStlWriteIoPort(Extension, ATA_CYLHIGH_REG, byOrgCylHigh);
bReturnValue = TRUE ;
atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_VALID ;
}
while ( ++nCurrentDrive < ATAPI_MAX_DRIVES );
// reset back to master state, as check drive present
// will be called successively
ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
return bReturnValue ;
}
BOOLEAN
ParStlAtapiInitialize (
IN PPDO_EXTENSION Extension,
IN OUT PATAPIPARAMS atapiParams
)
{
BOOLEAN bReturnValue = FALSE ;
int nCurrentDrive = 0, i ;
UCHAR byTempValue ;
UCHAR chAtapiIdentifyBuffer [ ATAPI_IDENTIFY_LENGTH ] ;
do
{
if ( DEVICE_STATE_VALID != atapiParams->dsDeviceState[nCurrentDrive] )
{
// the device is absent
continue ;
}
if ( nCurrentDrive )
{
// as it is the next drive, choose the slave
ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_SLAVE);
}
else
{
// choose the master
ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
}
if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
{
// as busy has permanently set after master/slave, we fail
// the detection process
continue ;
}
// check if the ATAPI signature is present in the cyl hi/lo
// registers. If present, it is definitely an ATAPI device
if ( ( ParStlReadIoPort(Extension, ATA_CYLLOW_REG) == ATAPI_SIGN_LOW ) &&\
( ParStlReadIoPort(Extension, ATA_CYLHIGH_REG) == ATAPI_SIGN_HI ) )
{
// as ATAPI signature is present, it is ATAPI type
bReturnValue = TRUE ;
// set this flag so that, ATA initialize will skip this
// target
atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_ATAPI ;
// for Impact, since Ls120 engine is always present,
// issuing ATAPI_IDENTIFY is mandatory.
if ( !IsImpactPresent())
{
continue ;
}
}
// issue the ata nop command
ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATA_NOP_COMMAND) ;
if ( FALSE == ParStlWaitForIrq(Extension) )
{
// ATAPI devices are expected to give interrrupt on NOP command
// mandatorily.
continue ;
}
if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
{
// as busy has permanently set, we proceed with the next
// drive
continue ;
}
// issue the atapi packet command
ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATAPI_IDENTIFY) ;
if ( FALSE == ParStlWaitForIrq(Extension) )
{
// ATAPI devices are expected to give interrrupt on 0xA1 command
// mandatorily.
continue ;
}
if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
{
// as busy has permanently set, we proceed with the next
// drive
continue ;
}
byTempValue = (UCHAR) ParStlReadIoPort ( Extension, ATA_TASK_STAT_REG ) ;
if ( ! ( byTempValue & ATA_ST_ERROR ) )
{
// as the drive has passed the packet command, this is an atapi
// drive
// Wait for DRQ to be sit, as some drives are known
// to remove busy too early and set DRQ after some time.
if ( FALSE == ParStlWaitForDrq(Extension) )
{
// as there was no DRQ set, we proceed with the next
// drive
continue ;
}
bReturnValue = TRUE ;
// as the DRQ is still asserted, quell it, as certain ATA/ATAPI-4
// spec. dictates it so
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -