ReactOS 0.4.15-dev-8131-g4988de4
id_ata.cpp File Reference
#include "stdafx.h"
Include dependency graph for id_ata.cpp:

Go to the source code of this file.

Macros

#define RESET_COMPLETE_CURRENT   0x00
 
#define RESET_COMPLETE_ALL   0x01
 
#define RESET_COMPLETE_NONE   0x02
 
#define RETTYPE_XXableInterrupts   VOID
 
#define RETVAL_XXableInterrupts
 
#define ITEMS_TO_QUERY   2
 
#define AtapiWritePortN_template(_type, _Type, sz)
 
#define AtapiWritePortExN_template(_type, _Type, sz)
 
#define AtapiReadPortN_template(_type, _Type, sz)
 
#define AtapiReadPortExN_template(_type, _Type, sz)
 
#define AtapiReadPortBufferN_template(_type, _Type, sz)
 
#define AtapiWritePortBufferN_template(_type, _Type, sz)
 
#define SetCheckPoint(cp)
 
#define ITEMS_TO_QUERY   2
 
#define DEBUG_MSG_BUFFER_SIZE   512
 

Functions

BOOLEAN NTAPI AtapiResetController__ (IN PVOID HwDeviceExtension, IN ULONG PathId, IN UCHAR CompleteType)
 
VOID NTAPI AtapiHwInitialize__ (IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
 
VOID NTAPI UniataUserDeviceReset (PHW_DEVICE_EXTENSION deviceExtension, PHW_LU_EXTENSION LunExt, ULONG lChannel)
 
VOID NTAPI AtapiCallBack_X (IN PVOID HwDeviceExtension)
 
RETTYPE_XXableInterrupts NTAPI AtapiInterruptDpc (IN PVOID HwDeviceExtension)
 
RETTYPE_XXableInterrupts NTAPI AtapiEnableInterrupts__ (IN PVOID HwDeviceExtension)
 
VOID NTAPI AtapiQueueTimerDpc (IN PVOID HwDeviceExtension, IN ULONG lChannel, IN PHW_TIMER HwScsiTimer, IN ULONG MiniportTimerValue)
 
SCSI_ADAPTER_CONTROL_STATUS NTAPI AtapiAdapterControl (IN PVOID HwDeviceExtension, IN SCSI_ADAPTER_CONTROL_TYPE ControlType, IN PVOID Parameters)
 
BOOLEAN NTAPI AtapiRegGetStringParameterValue (IN PWSTR RegistryPath, IN PWSTR Name, IN PWCHAR Str, IN ULONG MaxLen)
 
VOID DDKFASTAPI UniataNanoSleep (ULONG nano)
 
 AtapiWritePortN_template (ULONG, Ulong, 4)
 
 AtapiWritePortN_template (USHORT, Ushort, 2)
 
 AtapiWritePortN_template (UCHAR, Uchar, 1)
 
 AtapiWritePortExN_template (ULONG, Ulong, 4)
 
 AtapiWritePortExN_template (UCHAR, Uchar, 1)
 
 AtapiReadPortN_template (ULONG, Ulong, 4)
 
 AtapiReadPortN_template (USHORT, Ushort, 2)
 
 AtapiReadPortN_template (UCHAR, Uchar, 1)
 
 AtapiReadPortExN_template (ULONG, Ulong, 4)
 
 AtapiReadPortExN_template (UCHAR, Uchar, 1)
 
 AtapiWritePortBufferN_template (ULONG, Ulong, 4)
 
 AtapiWritePortBufferN_template (USHORT, Ushort, 2)
 
 AtapiReadPortBufferN_template (ULONG, Ulong, 4)
 
 AtapiReadPortBufferN_template (USHORT, Ushort, 2)
 
UCHAR DDKFASTAPI AtapiSuckPort2 (IN PHW_CHANNEL chan)
 
ULONG DDKFASTAPI AtapiSuckPortBuffer2 (IN PHW_CHANNEL chan, IN PUSHORT Buffer, IN ULONG Count)
 
UCHAR DDKFASTAPI SelectDrive (IN PHW_CHANNEL chan, IN ULONG DeviceNumber)
 
UCHAR DDKFASTAPI WaitOnBusy (IN PHW_CHANNEL chan)
 
UCHAR DDKFASTAPI WaitOnBusyLong (IN PHW_CHANNEL chan)
 
UCHAR DDKFASTAPI WaitOnBaseBusy (IN PHW_CHANNEL chan)
 
UCHAR DDKFASTAPI WaitOnBaseBusyLong (IN PHW_CHANNEL chan)
 
UCHAR DDKFASTAPI UniataIsIdle (IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN UCHAR Status)
 
UCHAR DDKFASTAPI WaitForIdleLong (IN PHW_CHANNEL chan)
 
UCHAR DDKFASTAPI WaitForDrq (IN PHW_CHANNEL chan)
 
UCHAR DDKFASTAPI WaitShortForDrq (IN PHW_CHANNEL chan)
 
VOID DDKFASTAPI AtapiSoftReset (IN PHW_CHANNEL chan, IN ULONG DeviceNumber)
 
VOID DDKFASTAPI AtapiHardReset (IN struct _HW_CHANNEL *chan, IN BOOLEAN DisableInterrupts, IN ULONG Delay)
 
UCHAR NTAPI AtaCommand48 (IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature, IN ULONG wait_flags)
 
UCHAR NTAPI AtaCommand (IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN USHORT cylinder, IN UCHAR head, IN UCHAR sector, IN UCHAR count, IN UCHAR feature, IN ULONG wait_flags)
 
LONG NTAPI AtaPio2Mode (LONG pio)
 
LONG NTAPI AtaPioMode (PIDENTIFY_DATA2 ident)
 
LONG NTAPI AtaWmode (PIDENTIFY_DATA2 ident)
 
LONG NTAPI AtaUmode (PIDENTIFY_DATA2 ident)
 
LONG NTAPI AtaSAmode (PIDENTIFY_DATA2 ident)
 
VOID NTAPI AtapiTimerDpc (IN PVOID HwDeviceExtension)
 
VOID NTAPI UniataSnapAtaRegs (IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN OUT PIDEREGS_EX regs)
 
BOOLEAN NTAPI IssueIdentify (IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR Command, IN BOOLEAN NoSetup)
 
BOOLEAN NTAPI SetDriveParameters (IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel)
 
VOID NTAPI UniataForgetDevice (PHW_LU_EXTENSION LunExt)
 
BOOLEAN NTAPI AtapiResetController (IN PVOID HwDeviceExtension, IN ULONG PathId)
 
ULONG NTAPI MapError (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
BOOLEAN NTAPI AtapiHwInitialize (IN PVOID HwDeviceExtension)
 
VOID NTAPI AtapiHwInitializeChanger (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
 
ULONG NTAPI AtapiParseArgumentString (IN PCCH String, IN PCCH KeyWord)
 
VOID NTAPI AtapiCallBack__ (IN PVOID HwDeviceExtension, IN UCHAR lChannel)
 
BOOLEAN NTAPI AtapiInterrupt (IN PVOID HwDeviceExtension)
 
BOOLEAN NTAPI AtapiInterrupt2 (IN PKINTERRUPT Interrupt, IN PVOID Isr2HwDeviceExtension)
 
VOID NTAPI AtapiEnableInterrupts (IN PVOID HwDeviceExtension, IN ULONG c)
 
VOID NTAPI AtapiDisableInterrupts (IN PVOID HwDeviceExtension, IN ULONG c)
 
VOID UniataExpectChannelInterrupt (IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
 
BOOLEAN NTAPI AtapiCheckInterrupt__ (IN PVOID HwDeviceExtension, IN UCHAR c)
 
BOOLEAN NTAPI AtapiInterrupt__ (IN PVOID HwDeviceExtension, IN UCHAR c)
 
ULONG NTAPI IdeSendSmartCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG targetId)
 
ULONGLONG NTAPI UniAtaCalculateLBARegs (PHW_LU_EXTENSION LunExt, ULONGLONG startingSector, PULONG max_bcount)
 
ULONGLONG NTAPI UniAtaCalculateLBARegsBack (PHW_LU_EXTENSION LunExt, ULONGLONG lba)
 
ULONG NTAPI IdeReadWrite (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
 
ULONG NTAPI IdeVerify (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
ULONG NTAPI AtapiSendCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
 
ULONG NTAPI IdeSendCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
 
VOID NTAPI IdeMediaStatus (BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
 
ULONG NTAPI IdeBuildSenseBuffer (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
BOOLEAN NTAPI UniataNeedQueueing (PHW_DEVICE_EXTENSION deviceExtension, PHW_CHANNEL chan, BOOLEAN TopLevel)
 
BOOLEAN NTAPI AtapiStartIo (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
BOOLEAN NTAPI AtapiStartIo__ (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN BOOLEAN TopLevel)
 
ULONG NTAPI DriverEntry (IN PVOID DriverObject, IN PVOID Argument2)
 
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
ULONG NTAPI AtapiRegCheckDevLunValue (IN PVOID HwDeviceExtension, IN PCWCH NamePrefix, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
 
ULONG NTAPI EncodeVendorStr (OUT PWCHAR Buffer, IN PUCHAR Str, IN ULONG Length)
 
ULONG NTAPI AtapiRegCheckDevValue (IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
 
ULONG NTAPI AtapiRegCheckParameterValue (IN PVOID HwDeviceExtension, IN PCWSTR PathSuffix, IN PCWSTR Name, IN ULONG Default)
 
NTHALAPI VOID NTAPI HalDisplayString (PUCHAR String)
 
VOID _cdecl _PrintNtConsole (PCCH DebugMessage,...)
 

Variables

static const CHAR ver_string [] = "\n\nATAPI IDE MiniPort Driver (UniATA) v 0." UNIATA_VER_STR "\n"
 
static const CHAR uniata_comm_name [] = UNIATA_COMM_PORT_VENDOR_STR " \n"
 
UNICODE_STRING SavedRegPath
 
WCHAR SavedRegPathBuffer [256]
 
ULONG SkipRaids = 1
 
ULONG ForceSimplex = 0
 
LONGLONG g_Perf = 0
 
ULONG g_PerfDt = 0
 
ULONG g_WaitBusyInISR = 1
 
ULONG g_opt_WaitBusyResetCount = 10000
 
ULONG g_opt_WaitBusyCount = 200
 
ULONG g_opt_WaitBusyDelay = 10
 
ULONG g_opt_WaitDrqDelay = 10
 
ULONG g_opt_WaitBusyLongCount = 2000
 
ULONG g_opt_WaitBusyLongDelay = 250
 
ULONG g_opt_MaxIsrWait = 40
 
ULONG g_opt_DriveSelectNanoDelay = 0
 
BOOLEAN g_opt_AtapiSendDisableIntr = 0
 
BOOLEAN g_opt_AtapiDmaRawRead = 1
 
BOOLEAN g_opt_AtapiNoDma = FALSE
 
BOOLEAN g_opt_BochsDmaReadWorkaround = FALSE
 
BOOLEAN hasPCI = FALSE
 
ULONG g_opt_VirtualMachine = 0
 
BOOLEAN InDriverEntry = TRUE
 
BOOLEAN g_Dump = FALSE
 
BOOLEAN g_opt_Verbose = 0
 
BOOLEAN WinVer_WDM_Model = FALSE
 
ULONG CPU_num = 1
 
UCHAR g_foo = 0
 

Macro Definition Documentation

◆ AtapiReadPortBufferN_template

#define AtapiReadPortBufferN_template (   _type,
  _Type,
  sz 
)

Definition at line 404 of file id_ata.cpp.

◆ AtapiReadPortExN_template

#define AtapiReadPortExN_template (   _type,
  _Type,
  sz 
)
Value:
_type \
DDKFASTAPI \
AtapiReadPortEx##sz( \
IN PHW_CHANNEL chan, \
IN ULONGIO_PTR _port, \
IN ULONG offs \
) \
{ \
if(_port >= IDX_MAX_REG) { \
res = (PIORES)(_port); \
} else \
if(chan) { \
res = &chan->RegTranslation[_port]; \
} else { \
KdPrint(("invalid io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
return (_type)(-1); \
} \
if(res->Proc) { \
KdPrint(("PROC io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
ASSERT(FALSE); /* We should never get here */ \
} \
if(!res->MemIo) { \
return ScsiPortReadPort##_Type((_type*)(ULONGIO_PTR)(res->Addr+offs)); \
} else { \
/*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
return ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr+offs)); \
} \
}
#define IDX_MAX_REG
Definition: bsmaster.h:469
struct _IORES * PIORES
#define FALSE
Definition: types.h:117
#define ULONGIO_PTR
Definition: config.h:102
GLuint res
Definition: glext.h:9613
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59

Definition at line 369 of file id_ata.cpp.

◆ AtapiReadPortN_template

#define AtapiReadPortN_template (   _type,
  _Type,
  sz 
)
Value:
_type \
DDKFASTAPI \
AtapiReadPort##sz( \
IN PHW_CHANNEL chan, \
IN ULONGIO_PTR _port \
) \
{ \
if(_port >= IDX_MAX_REG) { \
res = (PIORES)(_port); \
} else \
if(chan) { \
res = &chan->RegTranslation[_port]; \
} else { \
KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \
return (_type)(-1); \
} \
if(res->Proc) { \
KdPrint(("PROC io read request @ ch %x, res* %x\n", chan, _port)); \
ASSERT(FALSE); /* We should never get here */ \
} \
if(!res->MemIo) { \
/*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
return ScsiPortReadPort##_Type((_type*)(ULONGIO_PTR)(res->Addr)); \
} else { \
/*KdPrint(("r_mem @ (%x) %x\n", _port, res->Addr));*/ \
return ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr)); \
} \
}

Definition at line 334 of file id_ata.cpp.

◆ AtapiWritePortBufferN_template

#define AtapiWritePortBufferN_template (   _type,
  _Type,
  sz 
)

Definition at line 449 of file id_ata.cpp.

◆ AtapiWritePortExN_template

#define AtapiWritePortExN_template (   _type,
  _Type,
  sz 
)

Definition at line 297 of file id_ata.cpp.

◆ AtapiWritePortN_template

#define AtapiWritePortN_template (   _type,
  _Type,
  sz 
)
Value:
VOID \
DDKFASTAPI \
AtapiWritePort##sz( \
IN PHW_CHANNEL chan, \
IN ULONGIO_PTR _port, \
IN _type data \
) \
{ \
if(_port >= IDX_MAX_REG) { \
res = (PIORES)(_port); \
} else \
if(chan) { \
res = &chan->RegTranslation[_port]; \
} else { \
KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \
return; \
} \
if(res->Proc) { \
KdPrint(("PROC io write request @ ch %x, res* %x\n", chan, _port)); \
ASSERT(FALSE); /* We should never get here */ \
} \
if(!res->MemIo) { \
ScsiPortWritePort##_Type((_type*)(ULONGIO_PTR)(res->Addr), data); \
} else { \
/*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
ScsiPortWriteRegister##_Type((_type*)(ULONG_PTR)(res->Addr), data); \
} \
return; \
}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Definition at line 261 of file id_ata.cpp.

◆ DEBUG_MSG_BUFFER_SIZE

#define DEBUG_MSG_BUFFER_SIZE   512

Definition at line 11684 of file id_ata.cpp.

◆ ITEMS_TO_QUERY [1/2]

#define ITEMS_TO_QUERY   2

◆ ITEMS_TO_QUERY [2/2]

#define ITEMS_TO_QUERY   2

◆ RESET_COMPLETE_ALL

#define RESET_COMPLETE_ALL   0x01

Definition at line 144 of file id_ata.cpp.

◆ RESET_COMPLETE_CURRENT

#define RESET_COMPLETE_CURRENT   0x00

Definition at line 143 of file id_ata.cpp.

◆ RESET_COMPLETE_NONE

#define RESET_COMPLETE_NONE   0x02

Definition at line 145 of file id_ata.cpp.

◆ RETTYPE_XXableInterrupts

#define RETTYPE_XXableInterrupts   VOID

Definition at line 159 of file id_ata.cpp.

◆ RETVAL_XXableInterrupts

#define RETVAL_XXableInterrupts

Definition at line 160 of file id_ata.cpp.

◆ SetCheckPoint

#define SetCheckPoint (   cp)

Definition at line 8228 of file id_ata.cpp.

Function Documentation

◆ _PrintNtConsole()

VOID _cdecl _PrintNtConsole ( PCCH  DebugMessage,
  ... 
)

Definition at line 11689 of file id_ata.cpp.

11693{
11694 //int len;
11695 UCHAR dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE];
11696// UNICODE_STRING msgBuff;
11697 va_list ap;
11698 va_start(ap, DebugMessage);
11699
11700 /*len =*/ _vsnprintf((PCHAR)&dbg_print_tmp_buff[0], DEBUG_MSG_BUFFER_SIZE-1, DebugMessage, ap);
11701
11702 dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE-1] = 0;
11703
11704 //DbgPrint(((PCHAR)&(dbg_print_tmp_buff[0]))); // already done in KdPrint macro
11705 HalDisplayString(dbg_print_tmp_buff);
11706
11707#ifdef _DEBUG
11708 if(g_LogToDisplay > 1) {
11710 }
11711#endif // _DEBUG
11712
11713 va_end(ap);
11714
11715} // end PrintNtConsole()
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define DEBUG_MSG_BUFFER_SIZE
Definition: id_ata.cpp:11684
char * PCHAR
Definition: typedefs.h:51
#define AtapiStallExecution(dt)
Definition: atapi.h:158
ULONG g_LogToDisplay
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define _vsnprintf
Definition: xmlstorage.h:202
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by DriverEntry().

◆ AtaCommand()

UCHAR NTAPI AtaCommand ( IN PHW_DEVICE_EXTENSION  deviceExtension,
IN ULONG  DeviceNumber,
IN ULONG  lChannel,
IN UCHAR  command,
IN USHORT  cylinder,
IN UCHAR  head,
IN UCHAR  sector,
IN UCHAR  count,
IN UCHAR  feature,
IN ULONG  wait_flags 
)

Definition at line 1168 of file id_ata.cpp.

1180{
1181 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
1182 return AtaCommand48(deviceExtension, DeviceNumber, lChannel,
1183 command,
1184 (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1185 count, feature, wait_flags);
1186 } else {
1187 return UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
1189 NULL,
1190 0,
1191 command,
1192 (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1193 count,
1194 feature,
1195 0 /* ahci flags */ ,
1196 wait_flags,
1197 1000 /* timeout 1 sec */
1198 );
1199
1200 }
1201} // end AtaCommand()
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define UNIATA_AHCI
Definition: bm_devs_decl.h:629
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
GLUquadricObj * cylinder
Definition: cylfrac.c:44
#define NULL
Definition: types.h:112
GLuint GLuint GLsizei count
Definition: gl.h:1545
UCHAR NTAPI AtaCommand48(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature, IN ULONG wait_flags)
Definition: id_ata.cpp:968
UCHAR NTAPI UniataAhciSendPIOCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG length, IN UCHAR command, IN ULONGLONG lba, IN USHORT bcount, IN USHORT feature, IN USHORT ahci_flags, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1538
uint32_t sector
Definition: isohybrid.c:61
INTERNETFEATURELIST feature
Definition: misc.c:1719

Referenced by AtapiHwInitialize__(), AtapiStartIo__(), IdeMediaStatus(), IdeSendCommand(), IdeSendSmartCommand(), IssueIdentify(), MapError(), and SetDriveParameters().

◆ AtaCommand48()

UCHAR NTAPI AtaCommand48 ( IN PHW_DEVICE_EXTENSION  deviceExtension,
IN ULONG  DeviceNumber,
IN ULONG  lChannel,
IN UCHAR  command,
IN ULONGLONG  lba,
IN USHORT  count,
IN USHORT  feature,
IN ULONG  wait_flags 
)

Definition at line 968 of file id_ata.cpp.

978{
979 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
980 UCHAR statusByte;
981 ULONG i;
982 PUCHAR plba;
983
984 KdPrint2((PRINT_PREFIX "AtaCommand48: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x count %#x feature %#x\n",
985 deviceExtension->DevIndex, deviceExtension->Channel, DeviceNumber, command, lba, count, feature ));
986
987 if(deviceExtension->HwFlags & UNIATA_AHCI) {
988 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
989
990 KdPrint3((" (ahci)\n"));
991
992 statusByte = UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
994 NULL,
995 0,
996 command,
997 lba, count,
998 feature,
999 0 /* ahci flags */ ,
1000 wait_flags,
1001 1000 /* timeout 1 sec */
1002 );
1003
1004 return statusByte;
1005 }
1006
1008
1009 statusByte = WaitOnBusy(chan);
1010
1011 /* ready to issue command ? */
1012 if (statusByte & IDE_STATUS_BUSY) {
1013 KdPrint2((PRINT_PREFIX " Returning BUSY status\n"));
1014 return statusByte;
1015 }
1016 // !!! We should not check ERROR condition here
1017 // ERROR bit may be asserted durring previous operation
1018 // and not cleared after SELECT
1019
1020 //>>>>>> NV: 2006/08/03
1023 KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
1024 return IDE_STATUS_ERROR;
1025 //return SRB_STATUS_ERROR;
1026 }
1027 //<<<<<< NV: 2006/08/03
1028
1029 /* only use 48bit addressing if needed because of the overhead */
1031 chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48)) {
1032
1033 KdPrint2((PRINT_PREFIX " dev %#x USE_LBA_48\n", DeviceNumber ));
1034 /* translate command into 48bit version */
1037 } else {
1038 KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1039 return (UCHAR)-1;
1040 }
1041
1043 plba = (PUCHAR)&lba;
1044
1049 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[3]));
1050 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[0]));
1051 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[4]));
1052 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[1]));
1053 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[5]));
1054 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[2]));
1055
1056 //KdPrint2((PRINT_PREFIX "AtaCommand48: dev %#x USE_LBA48 (2)\n", DeviceNumber ));
1058 } else {
1059
1060 plba = (PUCHAR)&lba; //ktp
1061 chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1062
1063 //if(feature ||
1064 // (chan->lun[DeviceNumber]->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))) {
1066 //}
1071 if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_LBA_ENABLED) {
1072 //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_LBA\n", DeviceNumber ));
1074 } else {
1075 //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_CHS\n", DeviceNumber ));
1077 }
1078 }
1079
1080 // write command code to device
1082
1083 switch (wait_flags) {
1084 case ATA_WAIT_INTR:
1085
1086 // caller requested wait for interrupt
1087 for(i=0;i<4;i++) {
1088 WaitOnBusy(chan);
1089 statusByte = WaitForDrq(chan);
1090 if (statusByte & IDE_STATUS_DRQ)
1091 break;
1093 KdPrint2((PRINT_PREFIX " retry waiting DRQ, status %#x\n", statusByte));
1094 }
1095
1096 return statusByte;
1097
1098 case ATA_WAIT_IDLE:
1099
1100 // caller requested wait for entering Wait state
1101 for (i=0; i<30 * 1000; i++) {
1102
1103 GetStatus(chan, statusByte);
1104 statusByte = UniataIsIdle(deviceExtension, statusByte);
1105 if(statusByte == IDE_STATUS_WRONG) {
1106 // no drive ?
1107 break;
1108 } else
1109 if(statusByte & IDE_STATUS_ERROR) {
1110 break;
1111 } else
1112 if(statusByte & IDE_STATUS_BUSY) {
1114 continue;
1115 } else
1116 if((statusByte & ~IDE_STATUS_INDEX) == IDE_STATUS_IDLE) {
1117 break;
1118 } else {
1119 //if(deviceExtension->HwFlags & UNIATA_SATA) {
1120 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1121 break;
1122 }
1124 }
1125 }
1126 //statusByte |= IDE_STATUS_BUSY;
1127 break;
1128
1129 case ATA_WAIT_READY:
1130 statusByte = WaitOnBusyLong(chan);
1131 break;
1133 statusByte = WaitOnBaseBusyLong(chan);
1134 break;
1135 case ATA_IMMEDIATE:
1136 GetStatus(chan, statusByte);
1137 if (statusByte & IDE_STATUS_ERROR) {
1138 KdPrint2((PRINT_PREFIX " Warning: Immed Status %#x :(\n", statusByte));
1139 if(statusByte == (IDE_STATUS_IDLE | IDE_STATUS_ERROR)) {
1140 break;
1141 }
1142 KdPrint2((PRINT_PREFIX " try to continue\n"));
1143 statusByte &= ~IDE_STATUS_ERROR;
1144
1145 } else {
1146 //KdPrint2((PRINT_PREFIX " send Status %#x\n", statusByte));
1147 }
1149 // !!!!!
1152
1153 statusByte = IDE_STATUS_SUCCESS;
1154 break;
1155 }
1156
1157 //KdPrint2((PRINT_PREFIX " Status %#x\n", statusByte));
1158
1159 return statusByte;
1160} // end AtaCommand48()
#define InterlockedExchange
Definition: armddk.h:54
UCHAR const AtaCommands48[256]
Definition: atacmd_map.h:5
UCHAR const AtaCommandFlags[256]
Definition: atacmd_map.h:25
#define WaitForDrq(BaseIoAddress, Status)
Definition: atapi.h:387
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
#define WaitOnBusy(BaseIoAddress, Status)
Definition: atapi.h:359
bool NTAPI CheckIfBadBlock(IN PHW_LU_EXTENSION LunExt, IN ULONGLONG lba, IN ULONG count)
#define ATA_WAIT_IDLE
Definition: bsmaster.h:63
#define ATA_WAIT_READY
Definition: bsmaster.h:57
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
#define CTRFLAGS_LBA48
Definition: bsmaster.h:1137
#define ATA_WAIT_BASE_READY
Definition: bsmaster.h:62
#define ATA_IMMEDIATE
Definition: bsmaster.h:55
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define ATA_WAIT_INTR
Definition: bsmaster.h:56
#define TRUE
Definition: types.h:120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IDE_STATUS_WRONG
Definition: hwide.h:121
#define IDX_IO1_o_BlockNumber
Definition: hwide.h:56
#define IDX_IO1_o_CylinderHigh
Definition: hwide.h:58
#define IDE_STATUS_INDEX
Definition: hwide.h:111
#define IDE_USE_LBA
Definition: hwide.h:133
#define IDE_STATUS_BUSY
Definition: hwide.h:119
#define IDE_STATUS_ERROR
Definition: hwide.h:110
#define IDE_STATUS_SUCCESS
Definition: hwide.h:109
#define IDE_DRIVE_SELECT_1
Definition: hwide.h:130
#define IDX_IO1_o_Feature
Definition: hwide.h:54
#define IDE_STATUS_DRQ
Definition: hwide.h:113
#define IDE_DRIVE_1
Definition: hwide.h:128
#define IDE_DRIVE_SELECT_2
Definition: hwide.h:131
#define IDE_STATUS_IDLE
Definition: hwide.h:118
#define IDX_IO1_o_DriveSelect
Definition: hwide.h:59
#define IDX_IO1_o_Command
Definition: hwide.h:60
#define IDE_DRIVE_2
Definition: hwide.h:129
#define IDX_IO1_o_BlockCount
Definition: hwide.h:55
#define IDX_IO1_o_CylinderLow
Definition: hwide.h:57
UCHAR DDKFASTAPI SelectDrive(IN PHW_CHANNEL chan, IN ULONG DeviceNumber)
Definition: id_ata.cpp:621
UCHAR DDKFASTAPI UniataIsIdle(IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN UCHAR Status)
Definition: id_ata.cpp:742
UCHAR DDKFASTAPI WaitOnBusyLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:674
UCHAR DDKFASTAPI WaitOnBaseBusyLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:718
VOID UniataExpectChannelInterrupt(IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
Definition: id_ata.cpp:4492
__inline BOOLEAN UniataIsSATARangeAvailable(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_sata.h:91
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
LONG CheckIntr
Definition: bsmaster.h:1062
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
unsigned char * PUCHAR
Definition: typedefs.h:53
#define lba
#define DFLAGS_LBA_ENABLED
Definition: atapi.h:247
#define UniAta_need_lba48(command, lba, count, supp48)
Definition: atapi.h:1609
#define ATA_CMD_FLAG_FUA
Definition: atapi.h:1601
#define KdPrint3(_x_)
Definition: atapi.h:153
#define KdPrint2(_x_)
Definition: atapi.h:154
#define ATA_CMD_FLAG_48supp
Definition: atapi.h:1598
#define PRINT_PREFIX
Definition: atapi.h:150
#define ATA_CMD_FLAG_LBAIOsupp
Definition: atapi.h:1597

Referenced by AtaCommand(), IdeReadWrite(), IdeVerify(), and IssueIdentify().

◆ AtapiAdapterControl()

SCSI_ADAPTER_CONTROL_STATUS NTAPI AtapiAdapterControl ( IN PVOID  HwDeviceExtension,
IN SCSI_ADAPTER_CONTROL_TYPE  ControlType,
IN PVOID  Parameters 
)

Definition at line 11585 of file id_ata.cpp.

11590{
11591 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11592 PSCSI_SUPPORTED_CONTROL_TYPE_LIST pControlTypeList;
11593 ULONG numberChannels = deviceExtension->NumberChannels;
11594 ULONG c;
11596
11597 KdPrint(( "AtapiAdapterControl: %#x\n", ControlType));
11598
11599 switch(ControlType) {
11601 BOOLEAN supportedTypes[ScsiAdapterControlMax] = {
11602 TRUE, // ScsiQuerySupportedControlTypes
11603 TRUE, // ScsiStopAdapter
11604 TRUE, // ScsiRestartAdapter
11605 FALSE, // ScsiSetBootConfig
11606 FALSE // ScsiSetRunningConfig
11607 };
11608
11610 ULONG i;
11611
11612 pControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST) Parameters;
11613
11614 if(pControlTypeList->MaxControlType < lim) {
11615 lim = pControlTypeList->MaxControlType;
11616 }
11617
11618 for(i = 0; i < lim; i++) {
11619 pControlTypeList->SupportedTypeList[i] = supportedTypes[i];
11620 }
11621
11622 break;
11623
11624 }
11625 case ScsiStopAdapter: {
11626
11627 KdPrint(( "AtapiAdapterControl: ScsiStopAdapter\n"));
11628 // Shut down all interrupts on the adapter. They'll get re-enabled
11629 // by the initialization routines.
11630 for (c = 0; c < numberChannels; c++) {
11631 AtapiResetController(deviceExtension, c);
11632 AtapiDisableInterrupts(deviceExtension, c);
11633 }
11634 if(deviceExtension->AdapterInterfaceType == PCIBus) {
11635 // we must never get here for non-PCI
11636 /*status =*/ UniataDisconnectIntr2(HwDeviceExtension);
11637 BMList[deviceExtension->DevIndex].Isr2Enable = FALSE;
11638 }
11639 break;
11640 }
11641 case ScsiRestartAdapter: {
11642
11643 KdPrint(( "AtapiAdapterControl: ScsiRestartAdapter\n"));
11644 // Enable all the interrupts on the adapter while port driver call
11645 // for power up an HBA that was shut down for power management
11646
11648 status = UniataConnectIntr2(HwDeviceExtension);
11649 if(NT_SUCCESS(status)) {
11650 for (c = 0; c < numberChannels; c++) {
11651 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, c);
11652 FindDevices(HwDeviceExtension, 0, c);
11653 AtapiEnableInterrupts(deviceExtension, c);
11654 AtapiHwInitialize__(deviceExtension, c);
11655 }
11656 if(deviceExtension->Isr2DevObj) {
11657 // we must never get here for non-PCI
11658 BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
11659 }
11660 }
11661
11662 break;
11663 }
11664
11665 default: {
11666 KdPrint(( "AtapiAdapterControl: default => return ScsiAdapterControlUnsuccessful\n"));
11668 }
11669 }
11670
11672} // end AtapiAdapterControl()
unsigned char BOOLEAN
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI UniataConnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2050
NTSTATUS NTAPI UniataDisconnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2172
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
MMRESULT FindDevices()
Definition: utils.c:159
@ ScsiRestartAdapter
Definition: srb.h:179
@ ScsiQuerySupportedControlTypes
Definition: srb.h:177
@ ScsiAdapterControlMax
Definition: srb.h:182
@ ScsiStopAdapter
Definition: srb.h:178
@ ScsiAdapterControlSuccess
Definition: srb.h:191
@ ScsiAdapterControlUnsuccessful
Definition: srb.h:192
struct _SCSI_SUPPORTED_CONTROL_TYPE_LIST * PSCSI_SUPPORTED_CONTROL_TYPE_LIST
#define KdPrint(x)
Definition: env_spec_w32.h:288
const GLubyte * c
Definition: glext.h:8905
@ PCIBus
Definition: hwresource.cpp:142
BOOLEAN NTAPI AtapiResetController(IN PVOID HwDeviceExtension, IN ULONG PathId)
Definition: id_ata.cpp:2411
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4397
VOID NTAPI AtapiHwInitialize__(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_ata.cpp:3378
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4457
#define c
Definition: ke_i.h:80
ULONG NumberChannels
Definition: atapi.c:68
INTERFACE_TYPE AdapterInterfaceType
Definition: bsmaster.h:1316
PDEVICE_OBJECT Isr2DevObj
Definition: bsmaster.h:1281
OUT BOOLEAN SupportedTypeList[0]
Definition: srb.h:221
Definition: ps.c:97
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1483
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1481
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869

Referenced by DriverEntry().

◆ AtapiCallBack__()

VOID NTAPI AtapiCallBack__ ( IN PVOID  HwDeviceExtension,
IN UCHAR  lChannel 
)

Definition at line 3872 of file id_ata.cpp.

3876{
3877
3878 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3879 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3880 ULONG c, _c;
3881
3883 UCHAR statusByte;
3884
3885 KdPrint2((PRINT_PREFIX "AtapiCallBack:\n"));
3886 // If the last command was DSC restrictive, see if it's set. If so, the device is
3887 // ready for a new request. Otherwise, reset the timer and come back to here later.
3888
3889 // If ISR decided to wait for BUSY or DRQ in DPC, we shall also get here.
3890 // In this case chan->ExpectingInterrupt == TRUE, but interrupts are disabled, thus,
3891 // we shall have no problem with interrupt handler.
3892 if (!srb || chan->ExpectingInterrupt) {
3893 KdPrint2((PRINT_PREFIX "AtapiCallBack: Calling ISR directly due to BUSY\n"));
3894 chan->DpcState = DPC_STATE_TIMER;
3895 if(!AtapiInterrupt__(HwDeviceExtension, lChannel)) {
3897 KdPrint2((PRINT_PREFIX "AtapiCallBack: What's fucking this ???\n"));
3898 }
3899 goto ReturnCallback;
3900 }
3901
3902#ifdef _DEBUG
3903 if (!IS_RDP((srb->Cdb[0]))) {
3904 KdPrint2((PRINT_PREFIX "AtapiCallBack: Invalid CDB marked as RDP - %#x\n", srb->Cdb[0]));
3905 }
3906#endif
3907 if(!(chan->RDP)) {
3908 goto ReturnEnableIntr;
3909 }
3910 GetStatus(chan, statusByte);
3911 if (statusByte & IDE_STATUS_DSC) {
3912
3913 UCHAR PathId = srb->PathId;
3914 UCHAR TargetId = srb->TargetId;
3915 UCHAR Lun = srb->Lun;
3916
3917 KdPrint2((PRINT_PREFIX "AtapiCallBack: Found DSC for RDP - %#x\n", srb->Cdb[0]));
3918 AtapiDmaDBSync(chan, srb);
3919 UniataRemoveRequest(chan, srb);
3920 ScsiPortNotification(RequestComplete, deviceExtension, srb);
3921 // Clear current SRB.
3922 if(!deviceExtension->simplexOnly) {
3923 srb = UniataGetCurRequest(chan);
3924 } else {
3925 srb = NULL;
3926 }
3927 chan->RDP = FALSE;
3928
3929 // Ask for next request.
3931 deviceExtension,
3932 PathId,
3933 TargetId,
3934 Lun);
3935 ScsiPortNotification(NextRequest, deviceExtension, NULL);
3936
3937 if(srb) {
3938 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
3939 }
3940
3941 } else {
3942 KdPrint2((PRINT_PREFIX "AtapiCallBack: Requesting another timer for Op %#x\n",
3943 srb->Cdb[0]));
3944
3945 AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
3947 1000);
3948
3949 goto ReturnCallback;
3950 }
3951
3952ReturnEnableIntr:
3953
3954 if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
3955 KdPrint2((PRINT_PREFIX "AtapiCallBack: CallDisableInterrupts\n"));
3956 //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3957#ifdef UNIATA_USE_XXableInterrupts
3959 // must be called on DISPATCH_LEVEL
3962#else
3963 AtapiEnableInterrupts(HwDeviceExtension, lChannel);
3966 // Will raise IRQL to DIRQL
3967 AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
3969 1);
3970 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
3971#endif // UNIATA_USE_XXableInterrupts
3972 } else {
3973 //ASSERT(!deviceExtension->simplexOnly);
3974 }
3975
3976ReturnCallback:
3977
3978 // Check other channel
3979 // In simplex mode no interrupts must appear on other channels
3980 for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
3981 c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
3982
3983 if(c == lChannel) {
3984 continue;
3985 }
3986
3987 chan = &(deviceExtension->chan[c]);
3988
3989 if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
3992 {
3993 //ASSERT(!deviceExtension->simplexOnly);
3994 chan->DpcState = DPC_STATE_ISR;
3995 if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
3997 }
3998 }
3999 }
4000 KdPrint2((PRINT_PREFIX "AtapiCallBack: return\n"));
4001 return;
4002
4003} // end AtapiCallBack__()
#define IS_RDP(OperationCode)
Definition: atapi.h:453
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1324
BOOLEAN NTAPI AtapiDmaDBSync(PHW_CHANNEL chan, PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:532
#define CTRFLAGS_ENABLE_INTR_REQ
Definition: bsmaster.h:1136
#define CHECK_INTR_DETECTED
Definition: bsmaster.h:1067
#define CHECK_INTR_ACTIVE
Definition: bsmaster.h:1066
#define DPC_STATE_ISR
Definition: bsmaster.h:1155
#define DPC_STATE_TIMER
Definition: bsmaster.h:1157
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1315
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1313
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1314
#define CRNT_ILK_PTYPE
Definition: config.h:104
#define CRNT_ILK_TYPE
Definition: config.h:103
@ CallDisableInterrupts
Definition: srb.h:535
@ RequestComplete
Definition: srb.h:531
@ NextRequest
Definition: srb.h:532
@ NextLuRequest
Definition: srb.h:533
#define IDE_STATUS_DSC
Definition: hwide.h:114
RETTYPE_XXableInterrupts NTAPI AtapiEnableInterrupts__(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4333
VOID NTAPI AtapiCallBack_X(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4007
VOID NTAPI AtapiQueueTimerDpc(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN PHW_TIMER HwScsiTimer, IN ULONG MiniportTimerValue)
Definition: id_ata.cpp:1378
BOOLEAN NTAPI AtapiStartIo__(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN BOOLEAN TopLevel)
Definition: id_ata.cpp:9288
BOOLEAN NTAPI AtapiInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4981
VOID NTAPI UniataRemoveRequest(IN PHW_CHANNEL chan, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_queue.cpp:265
PSCSI_REQUEST_BLOCK NTAPI UniataGetCurRequest(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:358
BOOLEAN RDP
Definition: bsmaster.h:1033
LONG DisableIntr
Definition: bsmaster.h:1061
UCHAR DpcState
Definition: bsmaster.h:1030
BOOLEAN ExpectingInterrupt
Definition: bsmaster.h:1032
PHW_CHANNEL chan
Definition: bsmaster.h:1257
UCHAR TargetId
Definition: srb.h:254
UCHAR PathId
Definition: srb.h:253
UCHAR Cdb[16]
Definition: srb.h:279

Referenced by AtapiCallBack_X().

◆ AtapiCallBack_X()

VOID NTAPI AtapiCallBack_X ( IN PVOID  HwDeviceExtension)

Definition at line 4007 of file id_ata.cpp.

4010{
4011 AtapiCallBack__(HwDeviceExtension, (UCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->ActiveDpcChan);
4012} // end AtapiCallBack_X()
VOID NTAPI AtapiCallBack__(IN PVOID HwDeviceExtension, IN UCHAR lChannel)
Definition: id_ata.cpp:3872

Referenced by AtapiCallBack__(), and AtapiInterrupt__().

◆ AtapiCheckInterrupt__()

BOOLEAN NTAPI AtapiCheckInterrupt__ ( IN PVOID  HwDeviceExtension,
IN UCHAR  c 
)
  • clear interrupt and get status *‍/

Definition at line 4512 of file id_ata.cpp.

4516{
4517 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4518 PHW_CHANNEL chan = &(deviceExtension->chan[c]);
4519 PHW_LU_EXTENSION LunExt;
4520
4521 ULONG VendorID = deviceExtension->DevID & 0xffff;
4522 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
4523
4524 ULONG status;
4525 ULONG pr_status = 0;
4526 UCHAR dma_status = 0;
4527 UCHAR reg8 = 0;
4528 ULONG reg32 = 0;
4529 UCHAR statusByte = 0;
4530 ULONG slotNumber = deviceExtension->slotNumber;
4531 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
4532 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
4533 UCHAR Channel;
4534 UCHAR lChannel;
4535 BOOLEAN DmaTransfer = FALSE;
4536 BOOLEAN OurInterrupt = FALSE;
4537 BOOLEAN StatusValid = FALSE;
4538// ULONG k;
4539 UCHAR interruptReason;
4540 BOOLEAN EarlyIntr = FALSE;
4541 BOOLEAN SingleBlockIntr = FALSE;
4542
4543 KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__:\n"));
4544
4545 lChannel = c;
4546 Channel = (UCHAR)(deviceExtension->Channel + lChannel);
4547 LunExt = chan->lun[chan->cur_cdev];
4548
4549 //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ chan %#x:\n", chan));
4550 //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ (%d/%d):\n", Channel, chan->cur_cdev));
4551
4552 if((ChipFlags & UNIATA_AHCI) &&
4553 UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4554
4555 if(!UniataAhciChanImplemented(deviceExtension, lChannel)) {
4556 return OurInterrupt;
4557 }
4558
4559 OurInterrupt = UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
4560 if((OurInterrupt == INTERRUPT_REASON_UNEXPECTED) &&
4561 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
4562 UniataAhciWaitCommandReady(chan, 2 /* ms */ );
4563 statusByte = (UCHAR)UniataAhciWaitReady(chan, 0 /* immediate */);
4564 if(!(statusByte & (IDE_STATUS_BUSY)) ) {
4565 KdPrint2((PRINT_PREFIX "ATAPI special case READY\n"));
4566 //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
4567 OurInterrupt = INTERRUPT_REASON_OUR;
4568 } else
4569 if((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRDY)) == (IDE_STATUS_BUSY | IDE_STATUS_DRDY) ) {
4570 KdPrint2((PRINT_PREFIX "ATAPI special case pre ERR-READY\n"));
4571 OurInterrupt = INTERRUPT_REASON_OUR;
4572 } else
4573 if(statusByte & IDE_STATUS_ERROR) {
4574 KdPrint2((PRINT_PREFIX "ATAPI special case ERR-READY\n"));
4575 OurInterrupt = INTERRUPT_REASON_OUR;
4576 } else {
4577 KdPrint2((PRINT_PREFIX "ATAPI special case ? %x\n", statusByte));
4578 OurInterrupt = INTERRUPT_REASON_OUR;
4579 }
4580 }
4581 return OurInterrupt;
4582 }
4583
4585 DmaTransfer = TRUE;
4586 KdPrint2((PRINT_PREFIX " cntrlr %#x:%#x, lch %#x DmaTransfer = TRUE\n", deviceExtension->DevIndex,
4587 deviceExtension->Channel + c, c));
4588 } else {
4589 KdPrint2((PRINT_PREFIX " cntrlr %#x:%#x, lch %#x DmaTransfer = FALSE\n", deviceExtension->DevIndex,
4590 deviceExtension->Channel + c, c));
4591 dma_status = GetDmaStatus(deviceExtension, lChannel);
4592 KdPrint2((PRINT_PREFIX " DMA status %#x\n", dma_status));
4593 }
4594
4595 // do controller-specific interrupt servicing staff
4596 if(deviceExtension->UnknownDev) {
4597 KdPrint2((PRINT_PREFIX " UnknownDev\n"));
4598 goto check_unknown;
4599 }
4600
4601 // Attention !
4602 // We can catch (BM_STATUS_ACTIVE + BM_STATUS_INTR) when operation is actually completed
4603 // Such behavior was observed with Intel ICH-xxx chips
4604 // This condition shall also be treated as 'our interrupt' because of BM_STATUS_INTR flag
4605
4606 switch(VendorID) {
4607
4608 case ATA_PROMISE_ID: {
4609 switch(ChipType) {
4610 case PROLD:
4611 case PRNEW:
4612 status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1c);
4613 if (!DmaTransfer)
4614 break;
4615 if (!(status &
4616 ((Channel) ? 0x00004000 : 0x00000400))) {
4617 KdPrint2((PRINT_PREFIX " Promise old/new unexpected\n"));
4619 }
4620 break;
4621 case PRTX:
4624 if (!DmaTransfer)
4625 break;
4626 if(!(status & 0x20)) {
4627 KdPrint2((PRINT_PREFIX " Promise tx unexpected\n"));
4629 }
4630 break;
4631 case PRMIO: {
4632 ULONG stat_reg = (ChipFlags & PRG2) ? 0x60 : 0x6c;
4633 status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40);
4634 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40, status);
4635
4636 if(status & (1 << (Channel+1))) {
4637 // our
4638 } else {
4639 KdPrint2((PRINT_PREFIX " Promise mio unexpected\n"));
4641 }
4642
4643 if(!(ChipFlags & UNIATA_SATA))
4644 break;
4645
4646 pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg);
4647 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg, (pr_status & (0x11 << Channel)));
4648 if(pr_status & (0x11 << Channel)) {
4649 // TODO: reset channel
4650 KdPrint2((PRINT_PREFIX " Promise mio unexpected + reset req\n"));
4651 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
4652 }
4653 if(!(status & (0x01 << Channel))) {
4654 // Connect event
4655 KdPrint2((PRINT_PREFIX " Promise mio unexpected attach\n"));
4656 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
4657 }
4658 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4659 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4660 } else {
4662 }
4663
4664 AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
4665 break; }
4666 }
4667 break; }
4668 case ATA_NVIDIA_ID: {
4669 if(!(ChipFlags & UNIATA_SATA) || (ChipFlags & NVGEN))
4670 break;
4671
4672 KdPrint2((PRINT_PREFIX "NVIDIA\n"));
4673
4674 ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
4675 ULONG shift = Channel * ((ChipFlags & NVQ) ? 4 : 16);
4676
4677 /* get and clear interrupt status */
4678 if(ChipFlags & NVQ) {
4679 pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
4680 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0fUL << shift) | 0x00f000f0);
4681 } else {
4682 pr_status = AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
4683 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0f << shift));
4684 }
4685 KdPrint2((PRINT_PREFIX " pr_status %x, shift %x\n", pr_status, shift));
4686
4687 /* check for and handle connect events */
4688 if(((pr_status & (0x0cUL << shift)) == (0x04UL << shift)) ) {
4689 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
4690 }
4691 /* check for and handle disconnect events */
4692 if((pr_status & (0x08UL << shift)) &&
4693 !((pr_status & (0x04UL << shift) &&
4695 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
4696 }
4697 /* do we have any device action ? */
4698 if(!(pr_status & (0x01UL << shift))) {
4699 KdPrint2((PRINT_PREFIX " nVidia unexpected\n"));
4700 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4701 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4702 } else {
4704 }
4705 }
4706
4707 break; }
4708 case ATA_ATI_ID:
4709 KdPrint2((PRINT_PREFIX "ATI\n"));
4710 if(ChipType == SIIMIO) {
4711 // fall to SiI
4712 } else {
4713 break;
4714 }
4716
4717 if(ChipType == SIIMIO) {
4718
4720 KdPrint2((PRINT_PREFIX " Sii DS0 %x\n", reg32));
4721 if(reg32 == 0xffffffff) {
4722 KdPrint2((PRINT_PREFIX " Sii mio unexpected\n"));
4724 }
4726 KdPrint2((PRINT_PREFIX " Sii mio unexpected (2)\n"));
4728 }
4729
4730 if(ChipFlags & UNIATA_SATA) {
4731 if(reg32 & (BM_DS0_SII_DMA_SATA_IRQ | BM_DS0_SII_IRQ)) {
4732
4733 /* SIEN doesn't mask SATA IRQs on some 3112s. Those
4734 * controllers continue to assert IRQ as long as
4735 * SError bits are pending. Clear SError immediately.
4736 */
4737 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4738 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4739 }
4740 }
4741 }
4742
4743 if (!DmaTransfer)
4744 break;
4745 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4746 KdPrint2((PRINT_PREFIX " Sii mio unexpected (3)\n"));
4747 return OurInterrupt;
4748 }
4749 AtapiWritePort1(chan, IDX_BM_Status, dma_status & ~BM_STATUS_ERR);
4750 goto skip_dma_stat_check;
4751
4752 } else {
4753 if(!(deviceExtension->HwFlags & SIIINTR))
4754 break;
4755 GetPciConfig1(0x71, reg8);
4756 KdPrint2((PRINT_PREFIX " 0x71 = %#x\n", reg8));
4757 if (!(reg8 &
4758 (Channel ? 0x08 : 0x04))) {
4760 }
4761 if (!DmaTransfer) {
4762 KdPrint2((PRINT_PREFIX " cmd our\n"));
4763 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4764 }
4765 SetPciConfig1(0x71, (Channel ? 0x08 : 0x04));
4766 }
4767 break;
4768
4769 case ATA_ACARD_ID:
4770 if (!DmaTransfer)
4771 break;
4772 //dma_status = GetDmaStatus(deviceExtension, lChannel);
4773 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4774 KdPrint2((PRINT_PREFIX " Acard unexpected\n"));
4776 }
4777 AtapiWritePort1(chan, IDX_BM_Status, dma_status | BM_STATUS_INTR);
4781 goto skip_dma_stat_check;
4782 case ATA_INTEL_ID:
4783 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4784 if(ChipFlags & UNIATA_AHCI) {
4785 // Do nothing here
4786 } else
4787 if(ChipFlags & UNIATA_SATA) {
4788 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4789 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4790 }
4791 if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
4793 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4794 }
4795 }
4796 }
4797 }
4798 break;
4799 default:
4800 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4801 if(ChipFlags & UNIATA_AHCI) {
4802 // Do nothing here
4803 } else
4804 if(ChipFlags & UNIATA_SATA) {
4805 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4806 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4807 }
4808 }
4809 }
4810 }
4811check_unknown:
4812 KdPrint2((PRINT_PREFIX " perform generic check\n"));
4813 if (DmaTransfer) {
4814 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4815 KdPrint2((PRINT_PREFIX " DmaTransfer + !BM_STATUS_INTR (%x)\n", dma_status));
4816 if(dma_status & BM_STATUS_ERR) {
4817 KdPrint2((PRINT_PREFIX " DmaTransfer + BM_STATUS_ERR -> our\n"));
4818 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4819 } else {
4820 KdPrint2((PRINT_PREFIX " getting status...\n"));
4821 GetStatus(chan, statusByte);
4822 StatusValid = 1;
4823 KdPrint2((PRINT_PREFIX " status %#x\n", statusByte));
4824 if(statusByte & IDE_STATUS_ERROR) {
4825 KdPrint2((PRINT_PREFIX " IDE_STATUS_ERROR -> our\n", statusByte));
4826 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4827 } else
4828 if ((statusByte & IDE_STATUS_DSC) &&
4829 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
4830 (dma_status == BM_STATUS_ACTIVE)) {
4831 KdPrint2((PRINT_PREFIX " special case DMA + ATAPI + IDE_STATUS_DSC -> our\n", statusByte));
4832 // some devices interrupts on each block transfer even in DMA mode
4833 if(LunExt->TransferMode >= ATA_SDMA && LunExt->TransferMode <= ATA_WDMA2) {
4834 KdPrint2((PRINT_PREFIX " wait for completion\n"));
4836 //GetBaseStatus(chan, statusByte);
4837 //return INTERRUPT_REASON_IGNORE;
4838 SingleBlockIntr = TRUE;
4839 }
4840 } else {
4842 }
4843 }
4844 }
4845 } else {
4846 if(dma_status & BM_STATUS_INTR) {
4847 // bullshit, we have DMA interrupt, but had never initiate DMA operation
4848 KdPrint2((PRINT_PREFIX " clear unexpected DMA intr\n"));
4849 AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
4850 // catch it !
4851 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4852 }
4853 }
4854skip_dma_stat_check:
4855 if(!(ChipFlags & UNIATA_SATA) && chan->ExpectingInterrupt) {
4857 }
4858
4859 /* if drive is busy it didn't interrupt */
4860 /* the exception is DCS + BSY state of ATAPI devices */
4861 if(!StatusValid) {
4862 KdPrint2((PRINT_PREFIX " getting status...\n"));
4863 GetStatus(chan, statusByte);
4864 }
4865 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4866 KdPrint3((PRINT_PREFIX " ATAPI status %#x\n", statusByte));
4867 } else {
4868 KdPrint2((PRINT_PREFIX " IDE status %#x\n", statusByte));
4869 }
4870 if (statusByte == IDE_STATUS_WRONG) {
4871 // interrupt from empty controller ?
4872 } else
4873 if (statusByte & IDE_STATUS_BUSY) {
4874 if(!chan->ExpectingInterrupt) {
4875 KdPrint3((PRINT_PREFIX " unexpected intr + BUSY\n"));
4876 return OurInterrupt;
4877 }
4878
4879 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4880 KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
4881 } else {
4882 KdPrint2((PRINT_PREFIX " expecting intr + BUSY (3), non ATAPI\n"));
4884 }
4885 if((statusByte & ~(IDE_STATUS_DRQ | IDE_STATUS_INDEX)) !=
4887 KdPrint3((PRINT_PREFIX " unexpected status, seems it is not our\n"));
4889 }
4890 if(!(LunExt->DeviceFlags & DFLAGS_INT_DRQ) && (statusByte & IDE_STATUS_DRQ)) {
4891 KdPrint3((PRINT_PREFIX " unexpected DRQ, seems it is not our\n"));
4893 }
4894
4895 EarlyIntr = TRUE;
4896
4897 if(dma_status & BM_STATUS_INTR) {
4898 KdPrint3((PRINT_PREFIX " our interrupt with BSY set, try wait in ISR or post to DPC\n"));
4899 /* clear interrupt and get status */
4900 GetBaseStatus(chan, statusByte);
4901 if(!(dma_status & BM_STATUS_ACTIVE)) {
4902 AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
4903 }
4904 KdPrint3((PRINT_PREFIX " base status %#x (+BM_STATUS_INTR)\n", statusByte));
4905 return INTERRUPT_REASON_OUR;
4906 }
4907
4908 if(g_WaitBusyInISR) {
4909 GetStatus(chan, statusByte);
4910 KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
4911 reg8 = AtapiReadPort1(chan, IDX_IO1_i_Error);
4912 KdPrint2((PRINT_PREFIX " Error reg (%#x)\n", reg8));
4913 if (!(statusByte & IDE_STATUS_BUSY)) {
4914 KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
4915 }
4916 if (statusByte & IDE_STATUS_BUSY) {
4917 KdPrint2((PRINT_PREFIX " still BUSY, seems it is not our\n"));
4919 }
4920 }
4921
4922 }
4923
4924 /* clear interrupt and get status */
4925 GetBaseStatus(chan, statusByte);
4926 KdPrint2((PRINT_PREFIX " base status %#x\n", statusByte));
4927 if (statusByte == IDE_STATUS_WRONG) {
4928 // interrupt from empty controller ?
4929 } else
4930 if(!(statusByte & (IDE_STATUS_DRQ | IDE_STATUS_DRDY))) {
4931 KdPrint2((PRINT_PREFIX " no DRQ/DRDY set\n"));
4932 return OurInterrupt;
4933 }
4934
4935#ifndef UNIATA_PIO_ONLY
4936 if(DmaTransfer) {
4937 if(!SingleBlockIntr && (!EarlyIntr || g_WaitBusyInISR)) {
4938 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
4939 } else {
4941 PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
4942
4943 //ASSERT(AtaReq);
4944
4945 if(SingleBlockIntr) {
4946 KdPrint2((PRINT_PREFIX " set REQ_STATE_ATAPI_EXPECTING_DATA_INTR2.\n"));
4947 } else {
4948 KdPrint2((PRINT_PREFIX " set REQ_STATE_EARLY_INTR.\n"));
4949 }
4950 if(AtaReq) {
4952 }
4953 }
4954 }
4955#endif //
4956
4957 if (!(chan->ExpectingInterrupt)) {
4958
4959 KdPrint2((PRINT_PREFIX " Unexpected interrupt.\n"));
4960
4961 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4962 KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
4963 } else {
4964 KdPrint2((PRINT_PREFIX " OurInterrupt = %d\n", OurInterrupt));
4965 return OurInterrupt;
4966 }
4968 KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason));
4969 return OurInterrupt;
4970 }
4971 //ASSERT(!chan->queue_depth || chan->cur_req);
4972
4973 KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__: exit with TRUE\n"));
4974 return INTERRUPT_REASON_OUR;
4975
4976} // end AtapiCheckInterrupt__()
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
#define DFLAGS_INT_DRQ
Definition: atapi.h:43
#define ATA_INTEL_ID
Definition: bm_devs_decl.h:184
#define NV4OFF
Definition: bm_devs_decl.h:697
#define PRNEW
Definition: bm_devs_decl.h:646
#define NVQ
Definition: bm_devs_decl.h:698
#define PRTX
Definition: bm_devs_decl.h:647
#define CHIPTYPE_MASK
Definition: bm_devs_decl.h:620
#define SIIMIO
Definition: bm_devs_decl.h:665
#define UNIATA_SATA
Definition: bm_devs_decl.h:626
#define ATA_ACARD_ID
Definition: bm_devs_decl.h:111
#define PRG2
Definition: bm_devs_decl.h:654
#define NVGEN
Definition: bm_devs_decl.h:699
#define PROLD
Definition: bm_devs_decl.h:645
#define ATA_PROMISE_ID
Definition: bm_devs_decl.h:454
#define PRMIO
Definition: bm_devs_decl.h:648
#define ATA_NVIDIA_ID
Definition: bm_devs_decl.h:355
#define ATA_ATI_ID
Definition: bm_devs_decl.h:147
#define SIIINTR
Definition: bm_devs_decl.h:668
#define CHIPFLAG_MASK
Definition: bm_devs_decl.h:621
#define ATA_SILICON_IMAGE_ID
Definition: bm_devs_decl.h:507
#define BM_DS0_SII_DMA_COMPLETE
Definition: bsmaster.h:160
UCHAR NTAPI AtapiDmaDone(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:685
#define BM_STATUS_ERR
Definition: bsmaster.h:143
VOID DDKFASTAPI AtapiWritePortEx1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN UCHAR data)
#define IDX_BM_DeviceSpecific1
Definition: bsmaster.h:170
#define BM_DS0_SII_DMA_ENABLE
Definition: bsmaster.h:156
#define IDX_BM_DeviceSpecific0
Definition: bsmaster.h:168
UCHAR DDKFASTAPI AtapiReadPort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
ULONG DDKFASTAPI AtapiReadPort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
#define GetPciConfig1(offs, op)
Definition: bsmaster.h:1620
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2
Definition: bsmaster.h:953
#define BM_STATUS_ACTIVE
Definition: bsmaster.h:142
VOID DDKFASTAPI AtapiWritePortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN ULONG data)
#define BM_DS0_SII_DMA_ERROR
Definition: bsmaster.h:159
#define IDX_BM_Status
Definition: bsmaster.h:169
#define BM_DS0_SII_IRQ
Definition: bsmaster.h:157
ULONG DDKFASTAPI AtapiReadPortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
#define BM_DS0_SII_DMA_SATA_IRQ
Definition: bsmaster.h:158
VOID DDKFASTAPI AtapiWritePort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG data)
union _ATA_REQ * PATA_REQ
#define IDX_BM_Command
Definition: bsmaster.h:167
#define REQ_STATE_EARLY_INTR
Definition: bsmaster.h:956
#define BM_STATUS_INTR
Definition: bsmaster.h:144
#define CTRFLAGS_NO_SLAVE
Definition: bsmaster.h:1139
#define IDX_SATA_SStatus
Definition: bsmaster.h:457
#define BM_COMMAND_START_STOP
Definition: bsmaster.h:150
UCHAR DDKFASTAPI AtapiReadPortEx1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
#define GetDmaStatus(de, c)
Definition: bsmaster.h:1711
#define SetPciConfig1(offs, op)
Definition: bsmaster.h:1630
#define CTRFLAGS_DMA_ACTIVE
Definition: bsmaster.h:1131
#define IDE_STATUS_DRDY
Definition: hwide.h:117
#define IDX_ATAPI_IO1_i_InterruptReason
Definition: hwide.h:89
#define IDX_IO1_i_Error
Definition: hwide.h:42
ULONG g_WaitBusyInISR
Definition: id_ata.cpp:87
ULONG NTAPI UniataAhciWaitReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1853
UCHAR NTAPI UniataAhciStatus(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1131
BOOLEAN NTAPI UniataSataClearErr(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN BOOLEAN do_connect, IN ULONG pm_port)
Definition: id_sata.cpp:186
UCHAR NTAPI UniataAhciWaitCommandReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1434
ULONG NTAPI UniataSataReadPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG pm_port)
Definition: id_sata.cpp:270
BOOLEAN NTAPI UniataSataEvent(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG Action, IN ULONG pm_port)
Definition: id_sata.cpp:233
#define UNIATA_SATA_IGNORE_CONNECT
Definition: id_sata.h:61
#define UNIATA_SATA_EVENT_ATTACH
Definition: id_sata.h:72
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415
#define UNIATA_SATA_DO_CONNECT
Definition: id_sata.h:60
#define UNIATA_SATA_EVENT_DETACH
Definition: id_sata.h:73
#define shift
Definition: input.c:1755
ULONG cur_cdev
Definition: bsmaster.h:1022
ULONG lChannel
Definition: bsmaster.h:1064
struct _HW_DEVICE_EXTENSION * DeviceExtension
Definition: bsmaster.h:1087
UCHAR TransferMode
Definition: bsmaster.h:1171
PVOID SrbExtension
Definition: srb.h:267
#define INTERRUPT_REASON_UNEXPECTED
Definition: atapi.h:1280
#define ATA_SDMA
Definition: atapi.h:317
#define ATA_WDMA2
Definition: atapi.h:325
#define ATAPI_IR_Mask
Definition: atapi.h:551
#define INTERRUPT_REASON_IGNORE
Definition: atapi.h:1278
#define INTERRUPT_REASON_OUR
Definition: atapi.h:1279
UCHAR ReqState
Definition: bsmaster.h:893

Referenced by AtapiInterrupt(), AtapiInterrupt2(), and IdeSendCommand().

◆ AtapiDisableInterrupts()

VOID NTAPI AtapiDisableInterrupts ( IN PVOID  HwDeviceExtension,
IN ULONG  c 
)

Definition at line 4457 of file id_ata.cpp.

4461{
4462 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4463 PHW_CHANNEL chan;
4464 if(c >= deviceExtension->NumberChannels) {
4465 KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: WRONG CHANNEL\n",c));
4466 return;
4467 }
4468 chan = &(deviceExtension->chan[c]);
4469 KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: %d\n",c, chan->DisableIntr));
4470 // mark channel as busy
4471 if(InterlockedIncrement(&chan->DisableIntr)) {
4472 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4474 } else {
4475 //SelectDrive(chan, 0);
4477 IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4478 //if(chan->NumberLuns) {
4479 // SelectDrive(chan, 1);
4480 // AtapiWritePort1(chan, IDX_IO2_o_Control,
4481 // IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4482 // SelectDrive(chan, chan->cur_cdev);
4483 //}
4484 }
4486 }
4487
4488 return;
4489} // end AtapiDisableInterrupts()
#define InterlockedIncrement
Definition: armddk.h:53
#define IDX_AHCI_P_IE
Definition: bsmaster.h:685
#define CTRFLAGS_INTR_DISABLED
Definition: bsmaster.h:1134
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
#define IDX_IO2_o_Control
Definition: hwide.h:62
__inline VOID UniataAhciWriteChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data)
Definition: id_sata.h:302

Referenced by AtapiAdapterControl(), AtapiHwInitialize__(), AtapiInterrupt(), AtapiInterrupt__(), AtapiResetController__(), AtapiSendCommand(), AtapiStartIo__(), AtaSetTransferMode(), FindDevices(), IdeSendCommand(), IssueIdentify(), and UniataUserDeviceReset().

◆ AtapiEnableInterrupts()

VOID NTAPI AtapiEnableInterrupts ( IN PVOID  HwDeviceExtension,
IN ULONG  c 
)

Definition at line 4397 of file id_ata.cpp.

4401{
4402 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4403 PHW_CHANNEL chan;
4404 //UCHAR statusByte;
4405
4406 if(c >= deviceExtension->NumberChannels) {
4407 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: WRONG CHANNEL\n",c));
4408 return;
4409 }
4410 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
4411 !UniataAhciChanImplemented(deviceExtension, c)) {
4412 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: not imp. CHANNEL\n",c));
4413 return;
4414 }
4415
4416 chan = &(deviceExtension->chan[c]);
4417 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: %d\n",c, chan->DisableIntr));
4418 if(!InterlockedDecrement(&chan->DisableIntr)) {
4419 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4423 ((/*ch->pm_level == */0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
4424 ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | /* DEBUG */
4428 );
4429 } else {
4430 //SelectDrive(chan, 0);
4431 //GetBaseStatus(chan, statusByte);
4433 0 | IDE_DC_A_4BIT );
4434 //if(chan->NumberLuns) {
4435 // SelectDrive(chan, 1);
4436 // GetBaseStatus(chan, statusByte);
4437 // AtapiWritePort1(chan, IDX_IO2_o_Control,
4438 // IDE_DC_A_4BIT );
4439 // SelectDrive(chan, chan->cur_cdev);
4440 //}
4441 }
4442 chan->ChannelCtrlFlags &= ~CTRFLAGS_INTR_DISABLED;
4443 } else {
4444 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4445 // keep interrupts disabled
4447 } else {
4449 IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4450 }
4451 }
4452 return;
4453} // end AtapiEnableInterrupts()
#define InterlockedDecrement
Definition: armddk.h:52
#define ATA_AHCI_P_IX_PC
Definition: bsmaster.h:505
#define ATA_AHCI_P_IX_HBD
Definition: bsmaster.h:513
#define ATA_AHCI_P_IX_DS
Definition: bsmaster.h:501
#define ATA_AHCI_P_IX_TFE
Definition: bsmaster.h:515
#define ATA_AHCI_P_IX_DI
Definition: bsmaster.h:506
#define ATA_AHCI_P_IX_HBF
Definition: bsmaster.h:514
#define ATA_AHCI_P_IX_SDB
Definition: bsmaster.h:502
#define ATA_AHCI_P_IX_IF
Definition: bsmaster.h:512
#define ATA_AHCI_P_IX_DHR
Definition: bsmaster.h:499
#define ATA_AHCI_P_IX_DP
Definition: bsmaster.h:504
#define ATA_AHCI_P_IX_INF
Definition: bsmaster.h:511
#define ATA_AHCI_P_IX_PRC
Definition: bsmaster.h:508
#define ATA_AHCI_P_IX_UF
Definition: bsmaster.h:503
#define ATA_AHCI_P_IX_CPD
Definition: bsmaster.h:516
#define ATA_AHCI_P_IX_PS
Definition: bsmaster.h:500
#define ATA_AHCI_P_IX_OF
Definition: bsmaster.h:510
#define IDE_DC_A_4BIT
Definition: hwide.h:140

Referenced by AtapiAdapterControl(), AtapiCallBack__(), AtapiEnableInterrupts__(), AtapiHwInitialize__(), AtapiInterrupt(), AtapiInterrupt__(), AtapiResetController__(), AtapiSendCommand(), AtapiStartIo__(), AtaSetTransferMode(), FindDevices(), IdeSendCommand(), IssueIdentify(), and UniataUserDeviceReset().

◆ AtapiEnableInterrupts__()

RETTYPE_XXableInterrupts NTAPI AtapiEnableInterrupts__ ( IN PVOID  HwDeviceExtension)

Definition at line 4333 of file id_ata.cpp.

4336{
4337 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4338 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__():\n"));
4339 ULONG c;
4340 PHW_CHANNEL chan = NULL;
4341
4342 for(c=0; c<deviceExtension->NumberChannels; c++) {
4343 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__(2): %#x\n",c));
4344 chan = &(deviceExtension->chan[c]);
4345
4347 // enable intrs on requested channel
4348 chan->ChannelCtrlFlags &= ~CTRFLAGS_ENABLE_INTR_REQ;
4349 AtapiEnableInterrupts(HwDeviceExtension, c);
4352
4353 // check if current or other channel(s) interrupted
4354 //AtapiInterrupt(HwDeviceExtension);
4355
4356 if(deviceExtension->simplexOnly) {
4357 break;
4358 }
4359 } else {
4360 // check if other channel(s) interrupted
4361 // must do nothing in simplex mode
4362 if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
4365 continue;
4366 }
4367 //ASSERT(!deviceExtension->simplexOnly);
4368 chan->DpcState = DPC_STATE_ISR;
4369 if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
4371 }
4372 }
4373 }
4374 // In simplex mode next command must be sent to device here
4375 if(deviceExtension->simplexOnly && chan) {
4377 chan = UniataGetNextChannel(chan);
4378 if(chan) {
4379 srb = UniataGetCurRequest(chan);
4380 } else {
4381 srb = NULL;
4382 }
4383 if(srb) {
4384 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
4385 }
4386 }
4387
4389
4390} // end AtapiEnableInterrupts__()
#define RETVAL_XXableInterrupts
Definition: id_ata.cpp:160
PHW_CHANNEL NTAPI UniataGetNextChannel(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:376

Referenced by AtapiCallBack__(), and AtapiInterrupt__().

◆ AtapiHardReset()

VOID DDKFASTAPI AtapiHardReset ( IN struct _HW_CHANNEL chan,
IN BOOLEAN  DisableInterrupts,
IN ULONG  Delay 
)

Definition at line 948 of file id_ata.cpp.

953{
954 KdPrint2((PRINT_PREFIX "AtapiHardReset: %d, dis=%d\n", Delay, DisableInterrupts));
956 (DisableInterrupts ? IDE_DC_DISABLE_INTERRUPTS : 0));
957 chan->last_devsel = -1;
958 AtapiStallExecution(Delay);
960} // end AtapiHardReset()
#define IDE_DC_RESET_CONTROLLER
Definition: hwide.h:139
#define IDE_DC_REENABLE_CONTROLLER
Definition: hwide.h:142

Referenced by AtapiResetController__(), CheckDevice(), and FindDevices().

◆ AtapiHwInitialize()

BOOLEAN NTAPI AtapiHwInitialize ( IN PVOID  HwDeviceExtension)

Definition at line 3342 of file id_ata.cpp.

3345{
3346 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3347 ULONG numberChannels = deviceExtension->NumberChannels;
3348 ULONG c;
3349
3350 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base)\n"));
3351
3352 if(WinVer_WDM_Model) {
3354 }
3355 if(deviceExtension->MasterDev) {
3356 KdPrint2((PRINT_PREFIX " mark chan %d of master controller [%x] as inited\n",
3357 deviceExtension->Channel, deviceExtension->DevIndex));
3358 BMList[deviceExtension->DevIndex].ChanInitOk |= 0x01 << deviceExtension->Channel;
3359 }
3360
3361 /* do extra chipset specific setups */
3363/*
3364 if(deviceExtension->Isr2DevObj && (deviceExtension->HwFlags & UNIATA_SATA)) {
3365 KdPrint2((PRINT_PREFIX " enable ISR2 to catch unexpected interrupts\n"));
3366 BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
3367 }
3368*/
3369 for (c = 0; c < numberChannels; c++) {
3370 AtapiHwInitialize__(deviceExtension, c);
3371 }
3372 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base) done\n"));
3373 return TRUE;
3374} // end AtapiHwInitialize()
BOOLEAN WinVer_WDM_Model
Definition: id_ata.cpp:112
BOOLEAN NTAPI AtapiResetController__(IN PVOID HwDeviceExtension, IN ULONG PathId, IN UCHAR CompleteType)
Definition: id_ata.cpp:2422
#define RESET_COMPLETE_ALL
Definition: id_ata.cpp:144

Referenced by DriverEntry().

◆ AtapiHwInitialize__()

VOID NTAPI AtapiHwInitialize__ ( IN PHW_DEVICE_EXTENSION  deviceExtension,
IN ULONG  lChannel 
)

Definition at line 3378 of file id_ata.cpp.

3382{
3383 ULONG i;
3384 UCHAR statusByte, errorByte;
3385 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3386 PHW_LU_EXTENSION LunExt;
3387// ULONG tmp32;
3388 ULONG PreferedMode = 0xffffffff;
3389
3390 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
3391 !UniataAhciChanImplemented(deviceExtension, lChannel)) {
3392 return;
3393 }
3394
3395 AtapiChipInit(deviceExtension, DEVNUM_NOT_SPECIFIED, lChannel);
3396 FindDevices(deviceExtension, 0, lChannel);
3397
3398 for (i = 0; i < chan->NumberLuns; i++) {
3399
3400 KdPrint3((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x, dev %x\n", lChannel, i));
3401
3402 LunExt = chan->lun[i];
3403 // skip empty slots
3404 if (!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
3405 continue;
3406 }
3407
3408 AtapiDisableInterrupts(deviceExtension, lChannel);
3410
3411 if (!(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_MANUAL_CHS))) {
3412
3413 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: IDE branch\n"));
3414 // Enable media status notification
3415 IdeMediaStatus(TRUE,deviceExtension,lChannel,(UCHAR)i);
3416
3417 // If supported, setup Multi-block transfers.
3418 statusByte = AtaCommand(deviceExtension, i, lChannel,
3419 IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
3421
3422 // Check for errors. Reset the value to 0 (disable MultiBlock) if the
3423 // command was aborted.
3424 if (statusByte & IDE_STATUS_ERROR) {
3425
3426 // Read the error register.
3427 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
3428
3429 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
3430 statusByte,
3431 errorByte));
3432
3433 statusByte = AtaCommand(deviceExtension, i, lChannel,
3434 IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
3435 0, 0, ATA_WAIT_BASE_READY);
3436
3437 if (statusByte & IDE_STATUS_ERROR) {
3438 // Read the error register.
3439 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
3440
3441 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n",
3442 statusByte,
3443 errorByte));
3444 }
3445 // Adjust the devExt. value, if necessary.
3446 LunExt->MaximumBlockXfer = 0;
3447
3448 } else {
3450 "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
3451 i,
3452 LunExt->MaximumBlockXfer));
3453 }
3454
3455 if(LunExt->IdentifyData.MajorRevision) {
3456
3457 if(LunExt->opt_ReadCacheEnable) {
3458 KdPrint2((PRINT_PREFIX " Try Enable Read Cache\n"));
3459 // If supported, setup read/write cacheing
3460 statusByte = AtaCommand(deviceExtension, i, lChannel,
3461 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3463
3464 // Check for errors.
3465 if (statusByte & IDE_STATUS_ERROR) {
3467 "AtapiHwInitialize: Enable read/write cacheing on Device %d failed\n",
3468 i));
3469 LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
3470 } else {
3472 }
3473 } else {
3474 KdPrint2((PRINT_PREFIX " Disable Read Cache\n"));
3475 statusByte = AtaCommand(deviceExtension, i, lChannel,
3476 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3478 LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
3479 }
3480 if(LunExt->IdentifyData.FeaturesSupport.WriteCache) {
3481 if(LunExt->opt_WriteCacheEnable) {
3482 KdPrint2((PRINT_PREFIX " Try Enable Write Cache\n"));
3483 // If supported & allowed, setup write cacheing
3484 statusByte = AtaCommand(deviceExtension, i, lChannel,
3485 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3487 // Check for errors.
3488 if (statusByte & IDE_STATUS_ERROR) {
3490 "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
3491 i));
3492 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
3493 } else {
3495 }
3496 } else {
3497 KdPrint2((PRINT_PREFIX " Disable Write Cache\n"));
3498 statusByte = AtaCommand(deviceExtension, i, lChannel,
3499 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3501 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
3502 }
3503 }
3504
3505 if(/*LunExt->IdentifyData.FeaturesSupport.PowerMngt ||*/
3506 LunExt->IdentifyData.FeaturesSupport.APM) {
3507
3508 if(LunExt->opt_AdvPowerMode) {
3509 KdPrint2((PRINT_PREFIX " Try Enable Adv. Power Mgmt\n"));
3510 // setup APM
3511 statusByte = AtaCommand(deviceExtension, i, lChannel,
3512 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3514 // Check for errors.
3515 if (statusByte & IDE_STATUS_ERROR) {
3517 "AtapiHwInitialize: Enable APM on Device %d failed\n",
3518 i));
3519 }
3520 } else {
3521 KdPrint2((PRINT_PREFIX " Disable Adv. Power Mgmt\n"));
3522 statusByte = AtaCommand(deviceExtension, i, lChannel,
3523 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3525 }
3526 }
3527 if(LunExt->IdentifyData.FeaturesSupport.AutoAcoustic) {
3528 if(LunExt->opt_AcousticMode) {
3529 KdPrint2((PRINT_PREFIX " Try Enable Acoustic Mgmt\n"));
3530 // setup acoustic mgmt
3531 statusByte = AtaCommand(deviceExtension, i, lChannel,
3532 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3534 // Check for errors.
3535 if (statusByte & IDE_STATUS_ERROR) {
3537 "AtapiHwInitialize: Enable Acoustic Mgmt on Device %d failed\n",
3538 i));
3539 }
3540 } else {
3541 KdPrint2((PRINT_PREFIX " Disable Acoustic Mgmt\n"));
3542 statusByte = AtaCommand(deviceExtension, i, lChannel,
3543 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3545 }
3546 }
3547 if(LunExt->IdentifyData.FeaturesSupport.Standby) {
3548 KdPrint2((PRINT_PREFIX " Try init standby timer: %d\n"));
3549 // setup standby timer
3550 statusByte = AtaCommand(deviceExtension, i, lChannel,
3551 IDE_COMMAND_IDLE, 0, 0, 0,
3553 // Check for errors.
3554 if (statusByte & IDE_STATUS_ERROR) {
3556 "AtapiHwInitialize: standby timer on Device %d failed\n",
3557 i));
3558 }
3559 }
3560 }
3561
3562 } else if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)){
3563
3564 ULONG j;
3565 //BOOLEAN isSanyo = FALSE;
3566 CCHAR vendorId[26];
3567
3568 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: ATAPI/Changer branch\n"));
3569
3570 // Attempt to identify any special-case devices - psuedo-atapi changers, atapi changers, etc.
3571 for (j = 0; j < 26; j += 2) {
3572
3573 // Build a buffer based on the identify data.
3574 MOV_DW_SWP(vendorId[j], ((PUCHAR)LunExt->IdentifyData.ModelNumber)[j]);
3575 }
3576
3577 if (!AtapiStringCmp (vendorId, "CD-ROM CDR", 11)) {
3578
3579 // Inquiry string for older model had a '-', newer is '_'
3580 if (vendorId[12] == 'C') {
3581
3582 // Torisan changer. Set the bit. This will be used in several places
3583 // acting like 1) a multi-lun device and 2) building the 'special' TUR's.
3585 LunExt->DiscsPresent = 3;
3586 //isSanyo = TRUE;
3587 }
3588 }
3589 }
3590
3591 PreferedMode = LunExt->opt_MaxTransferMode;
3592 if((PreferedMode == 0xffffffff) || (PreferedMode > chan->MaxTransferMode)) {
3593 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
3594 PreferedMode = chan->MaxTransferMode;
3595 }
3596
3597 if(LunExt->opt_PreferedTransferMode != 0xffffffff) {
3598 KdPrint2((PRINT_PREFIX "PreferedTransferMode: %#x\n", PreferedMode));
3599 PreferedMode = min(LunExt->opt_PreferedTransferMode, PreferedMode);
3600 }
3601
3602 KdPrint2((PRINT_PREFIX " try mode %#x\n", PreferedMode));
3603 LunExt->LimitedTransferMode =
3604 LunExt->TransferMode =
3605 (CHAR)PreferedMode;
3606
3607 AtapiDmaInit__(deviceExtension, LunExt);
3608
3609 LunExt->LimitedTransferMode =
3610 LunExt->TransferMode;
3611 KdPrint2((PRINT_PREFIX "Using %#x mode\n", LunExt->TransferMode));
3612
3613 // We need to get our device ready for action before
3614 // returning from this function
3615
3616 // According to the atapi spec 2.5 or 2.6, an atapi device
3617 // clears its status BSY bit when it is ready for atapi commands.
3618 // However, some devices (Panasonic SQ-TC500N) are still
3619 // not ready even when the status BSY is clear. They don't react
3620 // to atapi commands.
3621 //
3622 // Since there is really no other indication that tells us
3623 // the drive is really ready for action. We are going to check BSY
3624 // is clear and then just wait for an arbitrary amount of time!
3625 //
3626 if (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
3627 ULONG waitCount;
3628
3629 // have to get out of the loop sometime!
3630 // 10000 * 100us = 1000,000us = 1000ms = 1s
3631 waitCount = 10000;
3632 GetStatus(chan, statusByte);
3633 if(statusByte == IDE_STATUS_WRONG) {
3634 waitCount = 0;
3635 }
3636 while ((statusByte & IDE_STATUS_BUSY) && waitCount) {
3637
3638 KdPrint2((PRINT_PREFIX "Wait for ATAPI (status %x)\n", statusByte));
3639 // Wait for Busy to drop.
3641 GetStatus(chan, statusByte);
3642 waitCount--;
3643 }
3644
3645 // 5000 * 100us = 500,000us = 500ms = 0.5s
3646 if(statusByte != IDE_STATUS_WRONG) {
3647 waitCount = 5000;
3648 do {
3650 } while (waitCount--);
3651 }
3652 }
3653 GetBaseStatus(chan, statusByte);
3654 AtapiEnableInterrupts(deviceExtension, lChannel);
3656 }
3657
3658 return;
3659
3660} // end AtapiHwInitialize__()
#define MOV_DW_SWP(a, b)
Definition: atactl.cpp:20
#define DFLAGS_SANYO_ATAPI_CHANGER
Definition: atapi.h:49
#define DFLAGS_CHANGER_INITED
Definition: atapi.h:50
#define IDE_COMMAND_SET_MULTIPLE
Definition: atapi.h:113
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
#define CHAR(Char)
VOID NTAPI AtapiDmaInit__(IN PHW_DEVICE_EXTENSION deviceExtension, IN PHW_LU_EXTENSION LunExt)
Definition: id_dma.cpp:857
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
UCHAR NTAPI AtaCommand(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN USHORT cylinder, IN UCHAR head, IN UCHAR sector, IN UCHAR count, IN UCHAR feature, IN ULONG wait_flags)
Definition: id_ata.cpp:1168
VOID NTAPI IdeMediaStatus(BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_ata.cpp:9069
#define min(a, b)
Definition: monoChain.cc:55
ULONG NumberLuns
Definition: bsmaster.h:1090
ULONG MaxTransferMode
Definition: bsmaster.h:1057
UCHAR opt_StandbyTimer
Definition: bsmaster.h:1202
UCHAR opt_AdvPowerMode
Definition: bsmaster.h:1200
BOOLEAN opt_ReadCacheEnable
Definition: bsmaster.h:1197
ULONG opt_MaxTransferMode
Definition: bsmaster.h:1195
IDENTIFY_DATA2 IdentifyData
Definition: bsmaster.h:1162
UCHAR MaximumBlockXfer
Definition: bsmaster.h:1168
ULONG DiscsPresent
Definition: bsmaster.h:1165
UCHAR LimitedTransferMode
Definition: bsmaster.h:1172
ULONG opt_PreferedTransferMode
Definition: bsmaster.h:1196
BOOLEAN opt_WriteCacheEnable
Definition: bsmaster.h:1198
UCHAR opt_AcousticMode
Definition: bsmaster.h:1201
USHORT ModelNumber[20]
Definition: atapi.h:262
char CCHAR
Definition: typedefs.h:51
#define ATA_C_F_DIS_RCACHE
Definition: atapi.h:567
#define ATA_C_F_DIS_WCACHE
Definition: atapi.h:564
#define DFLAGS_MANUAL_CHS
Definition: atapi.h:255
#define DFLAGS_WCACHE_ENABLED
Definition: atapi.h:249
#define IDE_COMMAND_SET_FEATURES
Definition: atapi.h:407
#define ATA_C_F_DIS_APM
Definition: atapi.h:579
#define DFLAGS_RCACHE_ENABLED
Definition: atapi.h:250
#define ATA_C_F_ENAB_RCACHE
Definition: atapi.h:566
#define ATA_C_F_ENAB_APM
Definition: atapi.h:578
#define AtapiStringCmp(s1, s2, n)
Definition: atapi.h:1256
#define ATA_C_F_DIS_ACOUSTIC
Definition: atapi.h:585
#define ATA_C_F_ENAB_ACOUSTIC
Definition: atapi.h:584
#define ATA_C_F_ENAB_WCACHE
Definition: atapi.h:563
#define IDE_COMMAND_IDLE
Definition: atapi.h:398

Referenced by AtapiAdapterControl(), AtapiHwInitialize(), and AtapiResetController__().

◆ AtapiHwInitializeChanger()

VOID NTAPI AtapiHwInitializeChanger ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb,
IN PMECHANICAL_STATUS_INFORMATION_HEADER  MechanismStatus 
)

Definition at line 3667 of file id_ata.cpp.

3671{
3672 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3673 ULONG lChannel = GET_CHANNEL(Srb);
3674 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3676 PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
3677
3678 if (MechanismStatus) {
3679 LunExt->DiscsPresent = MechanismStatus->NumberAvailableSlots;
3680 if (LunExt->DiscsPresent > 1) {
3682 }
3683 }
3684 return;
3685} // end AtapiHwInitializeChanger()
#define DFLAGS_ATAPI_CHANGER
Definition: atapi.h:48
#define GET_CDEV(Srb)
Definition: bsmaster.h:1850
#define GET_CHANNEL(Srb)
Definition: bsmaster.h:1847
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989

Referenced by AtapiInterrupt__().

◆ AtapiInterrupt()

BOOLEAN NTAPI AtapiInterrupt ( IN PVOID  HwDeviceExtension)

Definition at line 4033 of file id_ata.cpp.

4036{
4037 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4038 ULONG c, _c;
4040 ULONG c_state;
4041 ULONG i_res = 0;
4042 ULONG pass;
4043 //BOOLEAN checked[AHCI_MAX_PORT];
4044 ULONG hIS;
4045 ULONG checked;
4046
4047 KdPrint2((PRINT_PREFIX "Intr: DeviceID+VendorID/Rev %#x/%#x (ex %d)\n",
4048 deviceExtension->DevID, deviceExtension->RevID, deviceExtension->ExpectingInterrupt ));
4049
4050 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4051 // AHCI may generate state change notification, never skip this check
4052 hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
4053 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
4054 if(!hIS) {
4055 return FALSE;
4056 }
4057 // assume all non-interrupted ports to be already checked
4058 checked = ~hIS;
4059 // assume all not implemented ports to be already checked
4060 checked |= ~deviceExtension->AHCI_PI;
4061 } else {
4062 checked = 0; // assume all ports are not checked
4063 }
4064
4065 if(!deviceExtension->ExpectingInterrupt) {
4066 // if we do not expect interrupt, exit now,
4067 // but keep in mind that it can be unexpected one
4068 // Note: this is just a hint, not exact counter
4069 KdPrint2((PRINT_PREFIX "unexpected, 1st chance\n"));
4070 //deviceExtension->ExpectingInterrupt++;
4071 //return FALSE;
4072 }
4073 // clear this flag now, it can be set again in sub-calls
4074 deviceExtension->ExpectingInterrupt=0;
4075
4076
4077// for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
4078// checked[_c] = (UCHAR)((hIS >> _c) & 0x01);
4079// }
4080
4081// fc =
4082 for(pass=0; pass<2; pass++) {
4083 //KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): pass %d\n", pass));
4084 if(status && pass) {
4085 // we catched some expected interrupts now.
4086 // do not touch unexpected until next ISR call
4087 break;
4088 }
4089 for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
4090
4091 c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
4092
4093 if((checked>>c) & 0x01)
4094 continue;
4095
4096 // check non-empty and expecting interrupt channels first
4097 if(!pass && !deviceExtension->chan[c].ExpectingInterrupt)
4098 continue;
4099
4100 checked |= (ULONG)1 << c;
4101
4102 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
4103
4104 if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
4105 // we get here on idle channels or when ISR is posted to DPC
4106 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): disabled INTR on ch %d\n", c));
4107 continue;
4108 }
4109 // lock channel. Wait, while 2nd ISR checks interrupt on this channel
4110 do {
4111 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): try lock\n"));
4112 // c_state = deviceExtension->chan[c].CheckIntr;
4113 // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_DETECTED) {
4114 // deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE;
4115 // }
4116 c_state =
4117 (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4120 if(c_state == CHECK_INTR_IDLE) {
4121 // c_state = deviceExtension->chan[c].CheckIntr;
4122 // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_IDLE) {
4123 // deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE
4124 // }
4125 c_state =
4126 (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4129 }
4130 } while(c_state == CHECK_INTR_CHECK);
4131 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): locked\n"));
4132 // check if already serviced
4133 if(c_state == CHECK_INTR_ACTIVE) {
4134 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): CHECK_INTR_ACTIVE\n"));
4135 continue;
4136 }
4137
4138 if((c_state == CHECK_INTR_DETECTED) ||
4139 (i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
4140
4141 if(i_res == INTERRUPT_REASON_UNEXPECTED) {
4142 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): Catch unexpected\n"));
4143 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4144 //return TRUE;
4145 status = TRUE;
4146 continue;
4147 }
4148 // disable interrupts on other channel of legacy mode
4149 // ISA-bridged onboard controller
4150 if(deviceExtension->simplexOnly /*||
4151 ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
4152 AtapiDisableInterrupts(deviceExtension, !c);
4153 }
4154
4155 deviceExtension->chan[c].DpcState = DPC_STATE_ISR;
4156 if(AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
4157 deviceExtension->LastInterruptedChannel = (UCHAR)c;
4158 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): return status TRUE\n"));
4159 status = TRUE;
4160 } else {
4161 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE\n"));
4162 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4163 }
4164
4165 // re-enable interrupts on other channel
4166 if(deviceExtension->simplexOnly /*||
4167 ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
4168 AtapiEnableInterrupts(deviceExtension, !c);
4169 }
4170
4171 } else {
4172 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE (2)\n"));
4173 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4174 }
4175
4176 }
4177 }
4178 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): exit with status %#x\n", status));
4179 if(status) {
4180 deviceExtension->FirstChannelToCheck++;
4181 if(deviceExtension->FirstChannelToCheck >= deviceExtension->NumberChannels)
4182 deviceExtension->FirstChannelToCheck = 0;
4183 }
4184 return status;
4185} // end AtapiInterrupt()
#define CHECK_INTR_CHECK
Definition: bsmaster.h:1068
#define IDX_AHCI_IS
Definition: bsmaster.h:272
BOOLEAN NTAPI AtapiCheckInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4512
#define UniataAhciReadHostPort4(deviceExtension, io_port_ndx)
Definition: id_sata.h:313
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
UCHAR LastInterruptedChannel
Definition: bsmaster.h:1259
pass
Definition: typegen.h:25

Referenced by DriverEntry().

◆ AtapiInterrupt2()

BOOLEAN NTAPI AtapiInterrupt2 ( IN PKINTERRUPT  Interrupt,
IN PVOID  Isr2HwDeviceExtension 
)

Definition at line 4192 of file id_ata.cpp.

4196{
4197 // This ISR is intended to catch interrupts when we are already in other ISR instance
4198 // for the same device. This may happen when we have multiple channels,
4199 // especially on SMP machines
4200
4201 PISR2_DEVICE_EXTENSION Isr2DeviceExtension = (PISR2_DEVICE_EXTENSION)Isr2HwDeviceExtension;
4202 PHW_DEVICE_EXTENSION deviceExtension = Isr2DeviceExtension->HwDeviceExtension;
4203 ULONG c;
4205 ULONG c_count = 0;
4206 ULONG i_res;
4207 ULONG hIS;
4208 ULONG checked;
4209
4210 // we should never get here for ISA/MCA
4211 if(!BMList[deviceExtension->DevIndex].Isr2Enable) {
4212 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: NOT ACTIVE cntrlr %#x chan %#x\n",deviceExtension->DevIndex, deviceExtension->Channel));
4213 return FALSE;
4214 }
4215
4216 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4217 // AHCI may generate state change notification, never skip this check
4218 hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
4219 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
4220 if(!hIS) {
4221 return FALSE;
4222 }
4223 // assume all non-interrupted ports to be already checked
4224 checked = ~hIS;
4225 // assume all not implemented ports to be already checked
4226 checked |= ~deviceExtension->AHCI_PI;
4227
4228 } else {
4229 checked = 0; // assume all ports are not checked
4230 }
4231 if(!deviceExtension->ExpectingInterrupt) {
4232 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !deviceExtension->ExpectingInterrupt\n"));
4233 deviceExtension->ExpectingInterrupt++;
4234 return FALSE;
4235 }
4236 //deviceExtension->ExpectingInterrupt = 0;
4237
4238 for(c=0; c<deviceExtension->NumberChannels; c++) {
4239 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
4240
4241 if((checked>>c) & 0x01)
4242 continue;
4243
4244 checked |= (ULONG)1 << c;
4245
4246 if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
4247 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: disabled INTR\n"));
4248 continue;
4249 }
4250
4251 if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4254 {
4255 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !CHECK_INTR_IDLE\n"));
4256 // hunt on unexpected intr (Some devices generate double interrupts,
4257 // some controllers (at least CMD649) interrupt twice with small delay.
4258 // If interrupts are disabled, they queue interrupt and re-issue it later,
4259 // when we do not expect it.
4260 continue;
4261 }
4262
4263 c_count++;
4264 if((i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
4265
4266 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: intr\n"));
4267 if(i_res == INTERRUPT_REASON_UNEXPECTED) {
4268 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: Catch unexpected\n"));
4269 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4270 return TRUE;
4271 }
4272
4273 status = TRUE;
4275 } else {
4276 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4277 }
4278 }
4279 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: status %d, c_count %d\n", status, c_count));
4280 if(status && (c_count != deviceExtension->NumberChannels)) {
4281 // there is an active ISR/DPC for one channel, but
4282 // we have an interrupt from another one
4283 // Lets inform current ISR/DPC about new interrupt
4285 } else {
4286 status = FALSE;
4287 }
4288 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: return %d\n", status));
4289 return status;
4290
4291} // end AtapiInterrupt2()
struct _ISR2_DEVICE_EXTENSION * PISR2_DEVICE_EXTENSION
PHW_DEVICE_EXTENSION HwDeviceExtension
Definition: bsmaster.h:1351

Referenced by UniataConnectIntr2().

◆ AtapiInterrupt__()

BOOLEAN NTAPI AtapiInterrupt__ ( IN PVOID  HwDeviceExtension,
IN UCHAR  c 
)

atapiDev &&

deviceExtension->DWordIO

Definition at line 4981 of file id_ata.cpp.

4985{
4986 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4987 PHW_CHANNEL chan = &(deviceExtension->chan[c]);
4988 // Get current Srb
4990 PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
4991
4992 ULONG wordCount = 0, wordsThisInterrupt = DEV_BSIZE/2;
4994 UCHAR dma_status = 0;
4995 ULONG i;
4996 ULONG k;
4997 UCHAR statusByte = 0,interruptReason;
4998
4999 BOOLEAN atapiDev = FALSE;
5000
5001#ifdef _DEBUG
5002 UCHAR Channel;
5003#endif //_DEBUG
5004 UCHAR lChannel;
5006 BOOLEAN DmaTransfer = FALSE;
5007 UCHAR error = 0;
5008 ULONG TimerValue = 1000;
5009 ULONG TotalTimerValue = 0;
5010#ifdef UNIATA_USE_XXableInterrupts
5012#else
5013 BOOLEAN InDpc = (chan->DpcState != DPC_STATE_ISR);
5014#endif // UNIATA_USE_XXableInterrupts
5015 BOOLEAN UseDpc = deviceExtension->UseDpc;
5016// BOOLEAN RestoreUseDpc = FALSE;
5017 BOOLEAN DataOverrun = FALSE;
5018 BOOLEAN NoStartIo = TRUE;
5020
5021 KdPrint2((PRINT_PREFIX "AtapiInterrupt:\n"));
5022 if(InDpc) {
5023 KdPrint2((PRINT_PREFIX " InDpc = TRUE\n"));
5024 //ASSERT((chan->ChannelCtrlFlags & CTRFLAGS_INTR_DISABLED));
5025 }
5026
5027 UCHAR PathId;
5029 UCHAR Lun;
5030 UCHAR OldReqState = REQ_STATE_NONE;
5031 //ULONG ldev;
5032 PHW_LU_EXTENSION LunExt;
5033
5034 lChannel = c;
5035
5036#ifdef _DEBUG
5037 Channel = (UCHAR)(deviceExtension->Channel + lChannel);
5038
5039 KdPrint2((PRINT_PREFIX " cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c));
5040#endif //_DEBUG
5041
5043 (AtaReq && (AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) ||
5044 (deviceExtension->HwFlags & UNIATA_AHCI)) {
5045 DmaTransfer = TRUE;
5046 KdPrint2((PRINT_PREFIX " DmaTransfer = TRUE\n"));
5047 }
5048
5049 if (srb) {
5050 PathId = srb->PathId;
5051 TargetId = srb->TargetId;
5052 Lun = srb->Lun;
5053 } else {
5054 PathId = (UCHAR)c;
5055 TargetId =
5056 Lun = 0;
5057 goto enqueue_next_req;
5058 }
5059
5060 //ldev = GET_LDEV2(PathId, TargetId, Lun);
5062 LunExt = chan->lun[DeviceNumber];
5063 atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
5064 KdPrint2((PRINT_PREFIX " dev_type %s\n", atapiDev ? "ATAPI" : "IDE"));
5065
5066 // check if we are in ISR DPC
5067 if(InDpc) {
5068 KdPrint2((PRINT_PREFIX " InDpc -> CTRFLAGS_INTR_DISABLED\n"));
5069 goto ServiceInterrupt;
5070 }
5071
5072 if (DmaTransfer) {
5073 dma_status = GetDmaStatus(deviceExtension, lChannel);
5074 }
5075
5076 if (!(chan->ExpectingInterrupt)) {
5077
5078 KdPrint2((PRINT_PREFIX " Unexpected interrupt for this channel.\n"));
5079 return FALSE;
5080 }
5081
5082 // change request state
5083 if(AtaReq) {
5084 OldReqState = AtaReq->ReqState;
5086 KdPrint2((PRINT_PREFIX " OldReqState = %x\n", OldReqState));
5087 }
5088
5089 // We don't want using DPC for fast operations, like
5090 // DMA completion, sending CDB, short ATAPI transfers, etc.
5091 // !!!! BUT !!!!
5092 // We MUST use DPC, because of interprocessor synchronization
5093 // on multiprocessor platforms
5094
5095 if(DmaTransfer)
5096 goto ServiceInterrupt;
5097
5098 switch(OldReqState) {
5100 KdPrint3((PRINT_PREFIX " EXPECTING_CMD_INTR\n"));
5105 KdPrint2((PRINT_PREFIX " continue service interrupt\n"));
5106 goto ServiceInterrupt;
5108 KdPrint2((PRINT_PREFIX " do nothing on interrupt\n"));
5109 return TRUE;
5110 }
5111
5112 if((!DmaTransfer && !atapiDev) || deviceExtension->DriverMustPoll) {
5113 KdPrint2((PRINT_PREFIX " service PIO HDD\n"));
5114 UseDpc = FALSE;
5115 }
5116
5117#ifndef UNIATA_CORE
5118
5119 if(!UseDpc)
5120 goto ServiceInterrupt;
5121
5122#ifdef UNIATA_USE_XXableInterrupts
5123 if(InDpc) {
5124 KdPrint2((PRINT_PREFIX " Unexpected InDpc\n"));
5125 ASSERT(FALSE);
5126 // shall never get here
5127 TimerValue = 1;
5128 goto CallTimerDpc;
5129 }
5130
5131 KdPrint2((PRINT_PREFIX " this is direct DPC call on DRQL\n"));
5132 if(AtaReq) {
5134 KdPrint2((PRINT_PREFIX " ReqState -> REQ_STATE_DPC_INTR_REQ\n"));
5135 } else {
5136 KdPrint2((PRINT_PREFIX " DPC without AtaReq!!!\n"));
5137 }
5138#else
5139 KdPrint2((PRINT_PREFIX "call service interrupt\n"));
5140 goto ServiceInterrupt;
5141#endif // UNIATA_USE_XXableInterrupts
5142
5143PostToDpc:
5144
5145 // Attention !!!
5146 // AtapiInterruptDpc() is called on DISPATCH_LEVEL
5147 // We always get here when are called from timer callback, which is invoked on DRQL.
5148 // It is intended to lower IRQL and let other interrupts to be serviced while we are waiting for BUSY release
5149
5150 KdPrint2((PRINT_PREFIX "AtapiInterrupt: start DPC init...\n"));
5151 // disable interrupts for this channel,
5152 // but avoid recursion and double-disable
5153 if(OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5155 AtapiDisableInterrupts(deviceExtension, lChannel);
5156 }
5157 // go to ISR DPC
5159
5160#ifdef UNIATA_USE_XXableInterrupts
5161 // Will lower IRQL to DISPATCH_LEVEL
5162 ScsiPortNotification(CallEnableInterrupts, HwDeviceExtension,
5163 /*c ?*/ AtapiInterruptDpc/*_1 : AtapiInterruptDpc_0*/);
5164 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DPC inited\n"));
5165#else
5166 // Will raise IRQL to DIRQL
5167 AtapiQueueTimerDpc(HwDeviceExtension, c,
5169 TimerValue);
5170 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
5171#endif // UNIATA_USE_XXableInterrupts
5172 return TRUE;
5173
5174#ifndef UNIATA_CORE
5175CallTimerDpc:
5177CallTimerDpc2:
5178 if(!InDpc && OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5179 // we must block interrupts from this channel
5180 // If device generate new interrupt before we get to DPC,
5181 // ISR will assume, that it is NOT our interrupt
5182 AtapiDisableInterrupts(deviceExtension, lChannel);
5183 // We should not clean ExpectingInterrupt flag on channel, since it is used in DPC
5184 }
5185 // Will raise IRQL to DIRQL
5186 AtapiQueueTimerDpc(HwDeviceExtension, c,
5188 TimerValue);
5189 return TRUE;
5190#endif //UNIATA_CORE
5191
5192ServiceInterrupt:
5193
5194 if(AtaReq && InDpc) {
5195 switch(AtaReq->ReqState) {
5197 goto PIO_wait_DRQ0;
5199 goto PIO_wait_busy;
5201 goto PIO_wait_DRQ;
5203 goto continue_err;
5206 // continue normal execution
5207 break;
5208 }
5209 }
5210#else
5211ServiceInterrupt:
5212#endif //UNIATA_CORE
5213/*
5214 // make additional delay for old devices (if we are not in DPC)
5215 if((!LunExt->IdentifyData.MajorRevision || (deviceExtension->lun[DeviceNumber].TransferMode < ATA_PIO4))
5216 &&
5217 !InDpc &&
5218 !atapiDev &&
5219 !(deviceExtension->HwFlags & UNIATA_SATA)
5220 ) {
5221 KdPrint2((PRINT_PREFIX " additional delay 10us for old devices\n"));
5222 AtapiStallExecution(10);
5223 }
5224*/
5225
5226 /* clear interrupt and get status */
5227 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5228 UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, srb);
5229 statusByte = (UCHAR)(AtaReq->ahci.in_status & IDE_STATUS_MASK);
5230
5232 KdPrint3((PRINT_PREFIX "Err intr (%#x), SE (%#x)\n",
5234 chan->AhciLastSError));
5235 if(chan->AhciLastIS & ~ATA_AHCI_P_IX_OF) {
5236
5237 if((chan->AhciLastIS == ATA_AHCI_P_IX_INF) &&
5238 !(statusByte & IDE_STATUS_ERROR) &&
5239 !chan->AhciLastSError &&
5240 srb && (srb->SrbFlags & SRB_FLAGS_DATA_IN)
5241 ) {
5242 KdPrint3((PRINT_PREFIX "ATA_AHCI_P_IX_INF on READ, assume underflow\n"));
5243 // continue processing in regular way
5244 } else {
5245
5246 //KdPrint3((PRINT_PREFIX "Err mask (%#x)\n", chan->AhciLastIS & ~ATA_AHCI_P_IX_OF));
5247 // We have some other error except Overflow
5248 // Just signal ERROR, operation will be aborted in ERROR branch.
5249 statusByte |= IDE_STATUS_ERROR;
5250 AtaReq->ahci.in_serror = chan->AhciLastSError;
5252 KdPrint2((PRINT_PREFIX "Unrecoverable\n"));
5253 NoRetry = TRUE;
5254 }
5255 }
5256 } else {
5257 // We have only Overflow. Abort operation and continue
5258#ifdef _DEBUG
5259 UniataDumpAhciPortRegs(chan);
5260#endif
5261 if(!UniataAhciAbortOperation(chan)) {
5262 KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5263 }
5264#ifdef _DEBUG
5265 UniataDumpAhciPortRegs(chan);
5266#endif
5268 }
5269 }
5270
5271 } else {
5272 GetBaseStatus(chan, statusByte);
5273 }
5274 if(atapiDev) {
5275 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Entered with status (%#x)\n", statusByte));
5276 } else {
5277 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte));
5278 }
5279
5280 if(!UseDpc) {
5281 KdPrint2((PRINT_PREFIX " operate like in DPC\n"));
5282 InDpc = TRUE;
5283 }
5284
5285 if (!atapiDev) {
5286 // IDE
5287 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5288 KdPrint3((PRINT_PREFIX " AHCI branch (IDE)\n"));
5289 } else
5290 if (statusByte & IDE_STATUS_BUSY) {
5291 if (deviceExtension->DriverMustPoll) {
5292 // Crashdump is polling and we got caught with busy asserted.
5293 // Just go away, and we will be polled again shortly.
5294 KdPrint2((PRINT_PREFIX " Hit BUSY while polling during crashdump.\n"));
5295 goto ReturnEnableIntr;
5296 }
5297try_dpc_wait:
5298 // Ensure BUSY is non-asserted.
5299 // make a very small idle before falling to DPC
5300 k = (InDpc && UseDpc) ? 1000 : 2;
5301
5302 for (i = 0; i < k; i++) {
5303
5304 GetBaseStatus(chan, statusByte);
5305 if (!(statusByte & IDE_STATUS_BUSY)) {
5306 break;
5307 }
5309 }
5310
5311 if (!InDpc && UseDpc && i == 2) {
5312
5313 KdPrint2((PRINT_PREFIX " BUSY on entry. Status %#x, Base IO %#x\n", statusByte));
5314
5315 TimerValue = 50;
5317
5318#ifndef UNIATA_CORE
5319 goto PostToDpc;
5320#else //UNIATA_CORE
5321 AtapiStallExecution(TimerValue);
5322 goto ServiceInterrupt;
5323#endif //UNIATA_CORE
5324 } else
5325 if (InDpc && i == k) {
5326 // reset the controller.
5328 " Resetting due to BUSY on entry - %#x.\n",
5329 statusByte));
5330 goto IntrPrepareResetController;
5331 }
5332 }
5333 } else {
5334 // ATAPI
5335 if(!LunExt->IdentifyData.MajorRevision &&
5336 InDpc &&
5338 !(deviceExtension->HwFlags & UNIATA_SATA)
5339 ) {
5340 //KdPrint2((PRINT_PREFIX " additional delay 10us for old devices (2)\n"));
5341 //AtapiStallExecution(10);
5342 }
5343 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5344 KdPrint3((PRINT_PREFIX " AHCI branch (ATAPI)\n"));
5345 } else {
5347 KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5348 }
5349
5350 if (statusByte & IDE_STATUS_BUSY) {
5351 //if(chan->ChannelCtrlFlags & CTRFLAGS_DSC_BSY) {}
5352/*
5353#ifndef UNIATA_CORE
5354 // This is just workaround
5355 // We should DISABLE interrupts before entering WAIT state
5356 UniataExpectChannelInterrupt(chan, TRUE);
5357#endif //UNIATA_CORE
5358*/
5359 KdPrint3((PRINT_PREFIX " BUSY on ATAPI device, waiting %d us\n", LunExt->AtapiReadyWaitDelay));
5360#ifndef UNIATA_CORE
5361 if(LunExt->AtapiReadyWaitDelay && (LunExt->AtapiReadyWaitDelay > g_opt_MaxIsrWait) && !InDpc && UseDpc) {
5362 TimerValue = LunExt->AtapiReadyWaitDelay;
5363 KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC (0)\n"));
5365 goto CallTimerDpc2;
5366 }
5367#endif //UNIATA_CORE
5368 TimerValue = 10;
5369 for(k=20; k; k--) {
5370 GetBaseStatus(chan, statusByte);
5371 KdPrint3((PRINT_PREFIX " status re-check %#x\n", statusByte));
5372 KdPrint3((PRINT_PREFIX " Error reg (%#x)\n",
5374 if (!(statusByte & IDE_STATUS_BUSY)) {
5375 KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
5376 break;
5377 }
5378 TotalTimerValue += TimerValue;
5379 if(k <= 1) {
5380 KdPrint3((PRINT_PREFIX " too long wait -> DPC\n"));
5381 if(!InDpc) {
5382 KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC\n"));
5383 TimerValue = 100;
5385 } else {
5386 KdPrint2((PRINT_PREFIX " too long wait: DPC -> DPC\n"));
5387 TimerValue = 1000;
5389 }
5390#ifndef UNIATA_CORE
5391 if(UseDpc) {
5392 if(!LunExt->AtapiReadyWaitDelay) {
5393 LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5394 }
5395 goto CallTimerDpc2;
5396 }
5397#endif //UNIATA_CORE
5398 }
5399
5400 AtapiStallExecution(TimerValue);
5401 TimerValue += 10;
5402 }
5403 if(!LunExt->AtapiReadyWaitDelay) {
5404 LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5405 KdPrint2((PRINT_PREFIX " store AtapiReadyWaitDelay: %d\n", LunExt->AtapiReadyWaitDelay));
5406 }
5407 if (statusByte & IDE_STATUS_BUSY) {
5408 KdPrint3((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n"));
5409 goto try_dpc_wait;
5410 }
5411 }
5412 }
5413
5414 if(AtaReq && DmaTransfer && !(deviceExtension->HwFlags & UNIATA_AHCI)) {
5415 switch(OldReqState) {
5418
5420 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DMA still active\n"));
5421 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5422 }
5423 break;
5424 }
5425 }
5426
5427//retry_check:
5428 // Check for error conditions.
5429 if ((statusByte & IDE_STATUS_ERROR) ||
5430 (dma_status & BM_STATUS_ERR)) {
5431
5432 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5433 error = AtaReq->ahci.in_error;
5434 // wait ready
5435#ifdef _DEBUG
5436 UniataDumpAhciPortRegs(chan);
5437#endif
5438 if(!UniataAhciAbortOperation(chan)) {
5439 KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5440 }
5441 // clear interrupts again
5443#ifdef _DEBUG
5444 UniataDumpAhciPortRegs(chan);
5445#endif
5446 UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
5447 if(NoRetry) {
5448 AtaReq->retry += MAX_RETRIES;
5449 if(!error && (statusByte & IDE_STATUS_ERROR)) {
5450 KdPrint2((PRINT_PREFIX "AtapiInterrupt: force error status\n"));
5452 }
5453 }
5454#ifdef _DEBUG
5455 UniataDumpAhciPortRegs(chan);
5456#endif
5457 } else {
5459 }
5460 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error %#x\n", error));
5461/*
5462 if(error & IDE_STATUS_CORRECTED_ERROR) {
5463 KdPrint2((PRINT_PREFIX "AtapiInterrupt: (corrected)\n"));
5464 statusByte &= ~IDE_STATUS_ERROR;
5465 goto retry_check;
5466 }
5467*/
5468 if(AtaReq) {
5469 KdPrint2((PRINT_PREFIX " Bad Lba %#I64x\n", AtaReq->lba));
5470 } else {
5471 KdPrint2((PRINT_PREFIX " Bad Lba unknown\n"));
5472 }
5473
5474 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5475 KdPrint2((PRINT_PREFIX " no wait ready after error\n"));
5476 } else
5477 if(!atapiDev) {
5478 KdPrint2((PRINT_PREFIX " wait 100 ready after IDE error\n"));
5480 } else {
5481 KdPrint2((PRINT_PREFIX " wait 10 ready after ATAPI error\n"));
5483 }
5484continue_err:
5485
5486 KdPrint3((PRINT_PREFIX " Intr on DRQ %x\n",
5487 LunExt->DeviceFlags & DFLAGS_INT_DRQ));
5488
5489 for (k = atapiDev ? 0 : 200; k; k--) {
5490 GetBaseStatus(chan, statusByte);
5491 if (!(statusByte & IDE_STATUS_DRQ)) {
5493 } else {
5494 break;
5495 }
5496 }
5497
5498 if (!atapiDev) {
5499 /* if this is a UDMA CRC error, reinject request */
5500
5501 AtaReq->retry++;
5502 if(AtaReq->retry < MAX_RETRIES) {
5503#ifdef IO_STATISTICS
5504 chan->lun[DeviceNumber]->ModeErrorCount[AtaReq->retry]++;
5505#endif //IO_STATISTICS
5506 if(DmaTransfer /*&&
5507 (error & IDE_ERROR_ICRC)*/) {
5508 KdPrint2((PRINT_PREFIX "Errors in DMA mode\n"));
5509 if(AtaReq->retry < MAX_RETRIES) {
5510//fallback_pio:
5511 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
5512 //AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5513 // Downrate will happen in AtapiDmaReinit(), try UDMA-2 for HDD only
5514 AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5515 }
5516 AtaReq->ReqState = REQ_STATE_QUEUED;
5517 goto reenqueue_req;
5518 }
5519 } else {
5520 if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5521 AtaReq->retry++;
5522 }
5523 KdPrint2((PRINT_PREFIX "Errors in PIO mode\n"));
5524 }
5525 }
5526 } else {
5528 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
5529
5530 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
5531 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5532 // Do nothing here
5533 } else
5534 if(deviceExtension->HwFlags & UNIATA_SATA) {
5535 UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, 0);
5536 }
5537 }
5538
5539 if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
5540 ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
5541 if(AtaReq->retry < MAX_RETRIES) {
5542//fallback_pio:
5543 // Downrate will happen in AtapiDmaReinit(), use PIO immediately for ATAPI
5544 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5545 AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5546// LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
5547 AtaReq->ReqState = REQ_STATE_QUEUED;
5548 goto reenqueue_req;
5549 }
5550 } else {
5551 if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5552 AtaReq->retry++;
5553 }
5554 KdPrint3((PRINT_PREFIX "Errors in PIO mode\n"));
5555 }
5556 }
5557
5558 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error\n"));
5559 if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
5560 // Fail this request.
5562 goto CompleteRequest;
5563 } else {
5564 KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n"));
5565 }
5566 } else
5567 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE_LBA48) {
5568 KdPrint2((PRINT_PREFIX "DMA doesn't work right with LBA48\n"));
5569 deviceExtension->HbaCtrlFlags |= HBAFLAGS_DMA_DISABLED_LBA48;
5570 } else
5571 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
5572#ifdef IO_STATISTICS
5573 KdPrint2((PRINT_PREFIX "Some higher mode doesn't work right :((\n"));
5574 KdPrint2((PRINT_PREFIX "Recovery stats[%d]: %d vs %d\n",
5575 AtaReq->retry,
5576 LunExt->RecoverCount[AtaReq->retry],
5577 LunExt->BlockIoCount
5578 ));
5579 LunExt->RecoverCount[AtaReq->retry]++;
5580 if(LunExt->RecoverCount[AtaReq->retry] >= LunExt->BlockIoCount/3 ||
5581 (deviceExtension->HwFlags & UNIATA_NO80CHK)
5582 ) {
5583#else
5584 if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
5585#endif //IO_STATISTICS
5586 KdPrint2((PRINT_PREFIX "Limit transfer rate to %x\n", LunExt->TransferMode));
5587 LunExt->LimitedTransferMode =
5588 LunExt->TransferMode;
5589 }
5590 }
5591#ifdef IO_STATISTICS
5592 if(AtaReq->bcount) {
5593 // we need stats for Read/Write operations
5594 LunExt->BlockIoCount++;
5595 }
5596 LunExt->IoCount++;
5597#endif //IO_STATISTICS
5598
5599continue_PIO:
5600
5601 // check reason for this interrupt.
5602 if (atapiDev) {
5603
5604 KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
5605 // ATAPI branch
5606
5608 KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5609 if(DmaTransfer) {
5610 wordsThisInterrupt = DEV_BSIZE/2*512;
5611 } else {
5612 wordsThisInterrupt = DEV_BSIZE/2;
5613 }
5614
5615 } else {
5616
5617 // ATA branch
5618
5619 if(DmaTransfer) {
5620 // simulate DRQ for DMA transfers
5621 statusByte |= IDE_STATUS_DRQ;
5622 }
5623 if (statusByte & IDE_STATUS_DRQ) {
5624
5625 if(DmaTransfer) {
5626 wordsThisInterrupt = DEV_BSIZE/2*512;
5627 } else
5628 if (LunExt->MaximumBlockXfer) {
5629 wordsThisInterrupt = DEV_BSIZE/2 * LunExt->MaximumBlockXfer;
5630 }
5631
5632 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5633
5634 interruptReason = ATAPI_IR_IO_toHost;
5635
5636 } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5637 interruptReason = ATAPI_IR_IO_toDev;
5638
5639 } else {
5641 goto CompleteRequest;
5642 }
5643
5644 } else if (statusByte & IDE_STATUS_BUSY) {
5645
5646 //AtapiEnableInterrupts(deviceExtension, lChannel);
5647 KdPrint2((PRINT_PREFIX "AtapiInterrupt: return FALSE on ATA IDE_STATUS_BUSY\n"));
5648 return FALSE;
5649
5650 } else {
5651
5652 KdPrint2((PRINT_PREFIX "AtapiInterrupt: !DRQ, !BUSY, WordsLeft %#x\n", AtaReq->WordsLeft));
5653 if (AtaReq->WordsLeft) {
5654
5655 // Funky behaviour seen with PCI IDE (not all, just one).
5656PIO_wait_DRQ0:
5657 // The ISR hits with DRQ low, but comes up later.
5658 for (k = 0; k < 5000; k++) {
5659 GetBaseStatus(chan, statusByte);
5660 if (statusByte & IDE_STATUS_DRQ) {
5661 break;
5662 }
5663 if(!InDpc) {
5664 // goto DPC
5666 TimerValue = 100;
5667 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq0)\n"));
5668#ifndef UNIATA_CORE
5669 goto PostToDpc;
5670#else //UNIATA_CORE
5671 AtapiStallExecution(TimerValue);
5672 goto ServiceInterrupt;
5673#endif //UNIATA_CORE
5674 }
5676 }
5677 if (k == 5000) {
5678 // reset the controller.
5679 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ not up. Status %#x\n",
5680 statusByte));
5681IntrPrepareResetController:
5682 AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_CURRENT);
5683 goto ReturnEnableIntr;
5684
5685 } else {
5686 interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? ATAPI_IR_IO_toHost : ATAPI_IR_IO_toDev;
5687 }
5688
5689 } else {
5690 // Command complete - verify, write, or the SMART enable/disable.
5691 // Also get_media_status
5692 interruptReason = ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd;
5693 }
5694 }
5695 }
5696
5697 KdPrint2((PRINT_PREFIX "AtapiInterrupt: i-reason=%d, status=%#x\n", interruptReason, statusByte));
5698 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5699 KdPrint2((PRINT_PREFIX " AHCI path, WordsTransfered %x, WordsLeft %x\n", AtaReq->WordsTransfered, AtaReq->WordsLeft));
5700/* if(chan->AhciLastIS & ATA_AHCI_P_IX_OF) {
5701 //status = SRB_STATUS_DATA_OVERRUN;
5702 DataOverrun = TRUE;
5703 } else {
5704 status = SRB_STATUS_SUCCESS;
5705 }*/
5706 if(AtaReq->WordsTransfered >= AtaReq->WordsLeft) {
5707 AtaReq->WordsLeft = 0;
5708 } else {
5709 AtaReq->WordsLeft -= AtaReq->WordsTransfered;
5710 }
5711 //if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
5712 // status = SRB_STATUS_DATA_OVERRUN;
5713 //}
5715 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5716 goto CompleteRequest;
5717 } else
5718 if ((interruptReason == ATAPI_IR_COD_Cmd) && (statusByte & IDE_STATUS_DRQ)) {
5720 AtapiDmaDBPreSync(HwDeviceExtension, chan, srb);
5721 }
5722 // Write the packet.
5723 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
5724 // Send CDB to device.
5725 WriteBuffer(chan, (PUSHORT)srb->Cdb,
5726 LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
5727 /*0*/ PIO0_TIMING);
5729
5731 KdPrint2((PRINT_PREFIX "AtapiInterrupt: AtapiDmaStart().\n"));
5732 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, srb);
5733 }
5734
5735 goto ReturnEnableIntr;
5736
5737 } else if ((interruptReason == ATAPI_IR_IO_toDev) && (statusByte & IDE_STATUS_DRQ)) {
5738
5739 // Write the data.
5740 if (atapiDev) {
5741
5742 // Pick up bytes to transfer and convert to words.
5743 wordCount =
5745
5746 wordCount |=
5748
5749 // Covert bytes to words.
5750 wordCount >>= 1;
5751 KdPrint2((PRINT_PREFIX "AtapiInterrupt: get W wordCount %#x\n", wordCount));
5752
5753 if (wordCount != AtaReq->WordsLeft) {
5755 "AtapiInterrupt: %d words requested; %d words xferred\n",
5756 AtaReq->WordsLeft,
5757 wordCount));
5758 }
5759
5760 // Verify this makes sense.
5761 if (wordCount > AtaReq->WordsLeft) {
5762 wordCount = AtaReq->WordsLeft;
5764 "AtapiInterrupt: Write underrun\n"));
5765 DataOverrun = TRUE;
5766 }
5767
5768 } else {
5769
5770 // IDE path. Check if words left is at least DEV_BSIZE/2 = 256.
5771 if (AtaReq->WordsLeft < wordsThisInterrupt) {
5772 // Transfer only words requested.
5773 wordCount = AtaReq->WordsLeft;
5774 } else {
5775 // Transfer next block.
5776 wordCount = wordsThisInterrupt;
5777 }
5778 }
5779
5780 if (DmaTransfer &&
5782 //ASSERT(AtaReq->WordsLeft == wordCount);
5785 "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5786 if(AtaReq->WordsLeft > wordCount) {
5787 AtaReq->WordsLeft -= wordCount;
5788 AtaReq->WordsTransfered += wordCount;
5790 goto ReturnEnableIntr;
5791 }
5792 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5793 }
5794 AtaReq->WordsTransfered = AtaReq->WordsLeft;
5795 AtaReq->WordsLeft = 0;
5797 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5798 goto CompleteRequest;
5799 }
5800
5801 // Ensure that this is a write command.
5802 if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5803
5805 "AtapiInterrupt: Write interrupt\n"));
5806
5807 statusByte = WaitOnBusy(chan);
5808
5809 if (/*atapiDev || */ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED)
5810 || (wordCount & 1)) {
5811
5812 WriteBuffer(chan,
5813 AtaReq->DataBuffer,
5814 wordCount,
5815 UniataGetPioTiming(LunExt));
5816 } else {
5817
5818 WriteBuffer2(chan,
5819 (PULONG)(AtaReq->DataBuffer),
5820 wordCount / 2,
5821 UniataGetPioTiming(LunExt));
5822 }
5823 } else {
5824
5826 "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5827 interruptReason,
5828 srb));
5829
5830 // Fail this request.
5832 if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) {
5833 // some devices feel bad after incorrect commands and may need reset
5835 "AtapiInterrupt: Try ATAPI reset\n"));
5836
5837 AtapiDisableInterrupts(deviceExtension, lChannel);
5839 AtapiEnableInterrupts(deviceExtension, lChannel);
5842
5843// goto IntrPrepareResetController;
5844 }
5845 goto CompleteRequest;
5846 }
5847 // Advance data buffer pointer and bytes left.
5848 AtaReq->DataBuffer += wordCount;
5849 AtaReq->WordsLeft -= wordCount;
5850 AtaReq->WordsTransfered += wordCount;
5851
5852 if (atapiDev) {
5854 }
5855
5856 goto ReturnEnableIntr;
5857
5858 } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) {
5859
5860continue_read_drq:
5861
5862 if (atapiDev) {
5863
5864 // Pick up bytes to transfer and convert to words.
5865 wordCount =
5868
5869 // Convert bytes to words.
5870 KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R byteCount %#x\n", wordCount));
5871 wordCount >>= 1;
5872 /*
5873 When ATAPI 64k PIO read is requested we may have 0xfffe byte
5874 count reported for 0x10000 bytes in single interrupt.
5875 It is not allowed to read entire 64k block with DwordIo intead of
5876 wait for last word.
5877 */
5878 if (wordCount != AtaReq->WordsLeft) {
5880 "AtapiInterrupt: %d words requested; %d words xferred\n",
5881 AtaReq->WordsLeft,
5882 wordCount));
5883 }
5884
5885 // Verify this makes sense.
5886 if (wordCount > AtaReq->WordsLeft) {
5887 wordCount = AtaReq->WordsLeft;
5888 DataOverrun = TRUE;
5889 }
5890
5891 } else {
5892
5893 // Check if words left is at least 256.
5894 if (AtaReq->WordsLeft < wordsThisInterrupt) {
5895 // Transfer only words requested.
5896 wordCount = AtaReq->WordsLeft;
5897 } else {
5898 // Transfer next block.
5899 wordCount = wordsThisInterrupt;
5900 }
5901 }
5902
5903 if(DmaTransfer &&
5907 "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5908 if(AtaReq->WordsLeft > wordCount) {
5909 AtaReq->WordsLeft -= wordCount;
5910 AtaReq->WordsTransfered += wordCount;
5912 goto ReturnEnableIntr;
5913 }
5914 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5915 }
5916 //ASSERT(AtaReq->WordsLeft == wordCount);
5917 AtaReq->WordsTransfered = AtaReq->WordsLeft;
5918 AtaReq->WordsLeft = 0;
5920 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5921 goto CompleteRequest;
5922 }
5923 // Ensure that this is a read command.
5924 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5925
5926/* KdPrint2((
5927 "AtapiInterrupt: Read interrupt\n"));*/
5928
5929 statusByte = WaitOnBusy(chan);
5930
5931 if(wordCount&1 && atapiDev && (g_opt_VirtualMachine == VM_BOCHS)) {
5933 "IdeIntr: unaligned ATAPI %#x Words\n", wordCount));
5934 } else
5935 if(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) {
5937 "IdeIntr: pre-Read %#x Dwords\n", wordCount/2));
5938
5939 ReadBuffer2(chan,
5940 (PULONG)(AtaReq->DataBuffer),
5941 wordCount / 2,
5942 UniataGetPioTiming(LunExt));
5943 // Advance data buffer pointer and bytes left.
5944 AtaReq->DataBuffer += wordCount & ~1;
5945 AtaReq->WordsLeft -= wordCount & ~1;
5946 AtaReq->WordsTransfered += wordCount & ~1;
5947 wordCount &= 1;
5948 }
5949 if (wordCount) {
5951 "IdeIntr: Read %#x words\n", wordCount));
5952
5953 ReadBuffer(chan,
5954 AtaReq->DataBuffer,
5955 wordCount,
5956 UniataGetPioTiming(LunExt));
5957 }
5958
5959 KdPrint2(("IdeIntr: PIO Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x\n", AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)-1) ));
5960 //KdDump(AtaReq->DataBuffer, wordCount*2);
5961 if(srb && atapiDev && srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
5962 KdDump(AtaReq->DataBuffer, wordCount*2);
5963 }
5964
5965 GetBaseStatus(chan, statusByte);
5966 KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
5967
5968 if(DataOverrun) {
5969 KdPrint2((PRINT_PREFIX " DataOverrun\n"));
5970 AtapiSuckPort2(chan);
5971 GetBaseStatus(chan, statusByte);
5972 }
5973
5974 if(statusByte & IDE_STATUS_BUSY) {
5975 for (i = 0; i < 2; i++) {
5977 GetBaseStatus(chan, statusByte);
5978 if (!(statusByte & IDE_STATUS_BUSY)) {
5979 break;
5980 }
5981 }
5982 }
5983
5984 } else {
5985
5987 "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5988 interruptReason,
5989 srb));
5990
5991 // Fail this request.
5993 goto CompleteRequest;
5994 }
5995//continue_atapi_pio_read:
5996 // Advance data buffer pointer and bytes left.
5997 AtaReq->DataBuffer += wordCount;
5998 AtaReq->WordsLeft -= wordCount;
5999 AtaReq->WordsTransfered += wordCount;
6000
6001 // Check for read command complete.
6002 if (AtaReq->WordsLeft == 0) {
6003
6004 KdPrint2((PRINT_PREFIX "AtapiInterrupt: all transferred, AtaReq->WordsLeft == 0\n"));
6005 if (atapiDev) {
6006
6007 if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM) {
6008
6009 // Work around to make many atapi devices return correct sector size
6010 // of 2048. Also certain devices will have sector count == 0x00, check
6011 // for that also.
6012 if (srb->Cdb[0] == SCSIOP_READ_CAPACITY) {
6013
6014 AtaReq->DataBuffer -= AtaReq->WordsTransfered;
6015 if (AtaReq->DataBuffer[0] == 0x00) {
6016 *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F;
6017 }
6018
6019 *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000;
6020 AtaReq->DataBuffer += AtaReq->WordsTransfered;
6021 }
6022#ifndef UNIATA_INIT_CHANGERS
6023 else
6024 if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
6025
6026 KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
6027 // Bingo!!
6028 AtapiHwInitializeChanger (HwDeviceExtension,
6029 srb,
6032 KdPrint2((PRINT_PREFIX " set DFLAGS_CHANGER_INITED\n"));
6033 }
6034#endif // UNIATA_INIT_CHANGERS
6035 }
6036 GetStatus(chan, statusByte);
6037 if(!(statusByte & IDE_STATUS_BUSY)) {
6038 // Assume command is completed if BUSY is cleared
6039 // and all data read
6040 // Optionally, we may receive COMPLETE interrupt later and
6041 // treat it as unexpected
6042 KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete ? status %x\n", statusByte));
6043
6045 goto CompleteRequest;
6046 }
6047
6048 } else {
6049
6050 /*
6051 // Completion for IDE drives.
6052 if (AtaReq->WordsLeft) {
6053 status = SRB_STATUS_DATA_OVERRUN;
6054 } else {
6055 status = SRB_STATUS_SUCCESS;
6056 }
6057
6058 goto CompleteRequest;
6059 */
6061 goto CompleteRequest;
6062
6063 }
6064 } else {
6065 if (atapiDev) {
6067 GetStatus(chan, statusByte);
6068 if(!(statusByte & IDE_STATUS_BUSY)) {
6069 // Assume command is completed if BUSY is cleared
6070 // even if NOT all data read
6071 // Optionally, we may receive COMPLETE interrupt later and
6072 // treat it as unexpected
6073 KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete + underrun ? status %x\n", statusByte));
6074
6076 goto CompleteRequest;
6077 }
6078 } else {
6079 if(!atapiDev && !DataOverrun && (srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
6080 ((statusByte & ~IDE_STATUS_INDEX) == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) {
6081 KdPrint2((PRINT_PREFIX " HDD read data ready \n"));
6082 goto continue_read_drq;
6083 }
6084 }
6085 }
6086
6087 goto ReturnEnableIntr;
6088
6089 } else if (interruptReason == (ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd) && !(statusByte & IDE_STATUS_DRQ)) {
6090
6091 KdPrint2((PRINT_PREFIX "AtapiInterrupt: interruptReason = CompleteRequest\n"));
6092 // Command complete. We exactly know this because of IReason.
6093
6094 if(DmaTransfer) {
6095 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was DmaTransfer\n"));
6096 AtaReq->WordsTransfered += AtaReq->WordsLeft;
6097 AtaReq->WordsLeft = 0;
6098 } else {
6099 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was PIO\n"));
6100
6101 wordCount = AtaReq->WordsLeft;
6102 // Advance data buffer pointer and bytes left.
6103 AtaReq->DataBuffer += wordCount;
6104 AtaReq->WordsLeft -= wordCount;
6105 AtaReq->WordsTransfered += wordCount;
6106
6107 KdPrint2((PRINT_PREFIX "AtapiInterrupt: wordCount %#x, WordsTransfered %#x\n", wordCount, AtaReq->WordsTransfered));
6108
6109 }
6110 //if (AtaReq->WordsLeft) {
6111 // status = SRB_STATUS_DATA_OVERRUN;
6112 //} else {
6114 //}
6115
6116#ifdef UNIATA_DUMP_ATAPI
6117 if(srb &&
6118 srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6119 UCHAR ScsiCommand;
6120 PCDB Cdb;
6121 PCHAR CdbData;
6122 PCHAR ModeSelectData;
6123 ULONG CdbDataLen;
6125
6126 Cdb = (PCDB)(Srb->Cdb);
6127 ScsiCommand = Cdb->CDB6.OperationCode;
6128 CdbData = (PCHAR)(Srb->DataBuffer);
6129 CdbDataLen = Srb->DataTransferLength;
6130
6131 if(CdbDataLen > 0x1000) {
6132 CdbDataLen = 0x1000;
6133 }
6134
6135 KdPrint(("--\n"));
6136 KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
6137 KdPrint2(("P:T:D=%d:%d:%d\n",
6138 Srb->PathId,
6139 Srb->TargetId,
6140 Srb->Lun));
6141 KdPrint(("Complete SCSI Command %2.2x\n", ScsiCommand));
6142 KdDump(Cdb, 16);
6143
6144 if(ScsiCommand == SCSIOP_MODE_SENSE) {
6145 KdPrint(("ModeSense 6\n"));
6147 ModeSelectData = CdbData+4;
6148 KdDump(CdbData, CdbDataLen);
6149 } else
6150 if(ScsiCommand == SCSIOP_MODE_SENSE10) {
6151 KdPrint(("ModeSense 10\n"));
6153 ModeSelectData = CdbData+8;
6154 KdDump(CdbData, CdbDataLen);
6155 } else {
6156 if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6157 KdPrint(("Read buffer from device:\n"));
6158 KdDump(CdbData, CdbDataLen);
6159 }
6160 }
6161 KdPrint(("--\n"));
6162 }
6163#endif //UNIATA_DUMP_ATAPI
6164
6166
6167 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, srbstatus %x\n", status));
6168 // Check and see if we are processing our secret (mechanism status/request sense) srb
6169
6170 if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
6171 KdPrint2((PRINT_PREFIX "WordsLeft %#x -> SRB_STATUS_DATA_OVERRUN\n", AtaReq->WordsLeft));
6173 }
6174
6175 if (AtaReq->OriginalSrb) {
6176
6177 ULONG srbStatus;
6178
6179 KdPrint2((PRINT_PREFIX "AtapiInterrupt: OriginalSrb != NULL\n"));
6180 if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
6181#ifdef UNIATA_INIT_CHANGERS
6182 // We can get here only when UNIATA_INIT_CHANGERS is defined
6183 KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
6184 if (status == SRB_STATUS_SUCCESS) {
6185 // Bingo!!
6186 AtapiHwInitializeChanger (HwDeviceExtension,
6187 srb,
6189
6190 // Get ready to issue the original srb
6191 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6192 AtaReq->OriginalSrb = NULL;
6193
6194 } else {
6195 // failed! Get the sense key and maybe try again
6196 srb = AtaReq->Srb = BuildRequestSenseSrb (
6197 HwDeviceExtension,
6198 AtaReq->OriginalSrb);
6199 }
6200/*
6201 // do not enable interrupts in DPC, do not waste time, do it now!
6202 if(UseDpc && chan->DisableIntr) {
6203 AtapiEnableInterrupts(HwDeviceExtension, c);
6204 UseDpc = FALSE;
6205 RestoreUseDpc = TRUE;
6206 }
6207*/
6208 srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
6209
6210 KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
6211
6212 if (srbStatus == SRB_STATUS_PENDING) {
6213 KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (1)\n"));
6214 goto ReturnEnableIntr;
6215 }
6216/*
6217 if(RestoreUseDpc) {
6218 // restore state on error
6219 UseDpc = TRUE;
6220 AtapiDisableInterrupts(HwDeviceExtension, c);
6221 }
6222*/
6223#else
6224 KdPrint((PRINT_PREFIX "AtapiInterrupt: ERROR: internal SCSIOP_MECHANISM_STATUS !!!!\n"));
6225 ASSERT(FALSE);
6226#endif // UNIATA_INIT_CHANGERS
6227 } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE)
6228
6229 PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
6230#ifdef __REACTOS__
6231 (void)senseData;
6232#endif
6233
6234 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status));
6236 // Check to see if we at least get mininum number of bytes
6237 if ((srb->DataTransferLength - AtaReq->WordsLeft) >
6238 (FIELD_OFFSET (SENSE_DATA, AdditionalSenseLength) + sizeof(senseData->AdditionalSenseLength))) {
6240 }
6241 }
6242
6243 if (status == SRB_STATUS_SUCCESS) {
6244#ifndef UNIATA_CORE
6245#ifdef UNIATA_INIT_CHANGERS
6246 if ((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) &&
6247 FALSE &&
6248 chan->MechStatusRetryCount) {
6249
6250 KdPrint3((PRINT_PREFIX "AtapiInterrupt: MechStatusRetryCount %#x\n", chan->MechStatusRetryCount));
6251 // The sense key doesn't say the last request is illegal, so try again
6252 chan->MechStatusRetryCount--;
6253 srb = AtaReq->Srb = BuildMechanismStatusSrb (
6254 HwDeviceExtension,
6255 AtaReq->OriginalSrb);
6256 } else
6257#endif // UNIATA_INIT_CHANGERS
6258 {
6259 // Get ready to issue the original srb
6260 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6261 AtaReq->OriginalSrb = NULL;
6262 }
6263#endif //UNIATA_CORE
6264/*
6265 // do not enable interrupts in DPC, do not waste time, do it now!
6266 if(UseDpc && chan->DisableIntr) {
6267 AtapiEnableInterrupts(HwDeviceExtension, c);
6268 UseDpc = FALSE;
6269 RestoreUseDpc = TRUE;
6270 }
6271*/
6272 srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
6273
6274 KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt));
6275
6276 if (srbStatus == SRB_STATUS_PENDING) {
6277 KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (2)\n"));
6278 goto ReturnEnableIntr;
6279 }
6280/*
6281 if(RestoreUseDpc) {
6282 // restore state on error
6283 UseDpc = TRUE;
6284 AtapiDisableInterrupts(HwDeviceExtension, c);
6285 }
6286*/
6287 }
6288 }
6289
6290 // If we get here, it means AtapiSendCommand() has failed
6291 // Can't recover. Pretend the original srb has failed and complete it.
6292
6293 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n"));
6294
6295 if (AtaReq->OriginalSrb) {
6296 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6297 AtaReq->OriginalSrb = NULL;
6298 }
6299
6300 KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (3)\n", chan->ExpectingInterrupt));
6301
6302 // fake an error and read no data
6304 srb->ScsiStatus = 0;
6305 AtaReq->DataBuffer = (PUSHORT)(srb->DataBuffer);
6306 AtaReq->WordsLeft = srb->DataTransferLength;
6307 chan->RDP = FALSE;
6308
6309 } else if (status == SRB_STATUS_ERROR) {
6310
6311 // Map error to specific SRB status and handle request sense.
6312 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n"));
6313 status = MapError(deviceExtension,
6314 srb);
6315
6316 chan->RDP = FALSE;
6317
6318 } else if(!DmaTransfer) {
6319
6320 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion\n"));
6321 // Command complete.
6322PIO_wait_busy:
6323 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion, wait BUSY\n"));
6324 // Wait for busy to drop.
6325 for (i = 0; i < 5*30; i++) {
6326 GetBaseStatus(chan, statusByte);
6327 if (!(statusByte & IDE_STATUS_BUSY)) {
6328 break;
6329 }
6330 if(!InDpc) {
6331 // goto DPC
6333 TimerValue = 200;
6334 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (busy)\n"));
6335#ifndef UNIATA_CORE
6336 goto PostToDpc;
6337#else //UNIATA_CORE
6338 AtapiStallExecution(TimerValue);
6339 goto ServiceInterrupt;
6340#endif //UNIATA_CORE
6341 }
6343 }
6344
6345 if (i == 5*30) {
6346
6347 // reset the controller.
6349 "AtapiInterrupt: Resetting due to BSY still up - %#x.\n",
6350 statusByte));
6351 goto IntrPrepareResetController;
6352 }
6353 // Check to see if DRQ is still up.
6354 if(statusByte & IDE_STATUS_DRQ) {
6355 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DRQ...\n"));
6356 if(srb) {
6357 if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6358 KdPrint2((PRINT_PREFIX "srb %x data in\n", srb));
6359 } else {
6360 KdPrint2((PRINT_PREFIX "srb %x data out\n", srb));
6361 }
6362 } else {
6363 KdPrint2((PRINT_PREFIX "srb NULL\n"));
6364 }
6365 if(AtaReq) {
6366 KdPrint2((PRINT_PREFIX "AtaReq %x AtaReq->WordsLeft=%x\n", AtaReq, AtaReq->WordsLeft));
6367 } else {
6368 KdPrint2((PRINT_PREFIX "AtaReq NULL\n"));
6369 }
6370 if(AtaReq && AtaReq->WordsLeft /*&&
6371 !(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))*/) {
6372 KdPrint2((PRINT_PREFIX "DRQ+AtaReq->WordsLeft -> next portion\n"));
6373 goto continue_PIO;
6374 }
6375 }
6376 //if (atapiDev && (statusByte & IDE_STATUS_DRQ)) {}
6377 //if ((statusByte & IDE_STATUS_DRQ)) {}
6378 if((statusByte & IDE_STATUS_DRQ) &&
6380
6381PIO_wait_DRQ:
6382 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO_wait_DRQ\n"));
6383 for (i = 0; i < 200; i++) {
6384 GetBaseStatus(chan, statusByte);
6385 if (!(statusByte & IDE_STATUS_DRQ)) {
6386 break;
6387 }
6388 if(!InDpc) {
6389 // goto DPC
6390 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq)\n"));
6392 TimerValue = 100;
6393#ifndef UNIATA_CORE
6394 goto PostToDpc;
6395#else //UNIATA_CORE
6396 AtapiStallExecution(TimerValue);
6397 goto ServiceInterrupt;
6398#endif //UNIATA_CORE
6399 }
6401 }
6402
6403 if (i == 200) {
6404 // reset the controller.
6405 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ still up - %#x\n",
6406 statusByte));
6407 goto IntrPrepareResetController;
6408 }
6409 }
6410 if(atapiDev) {
6411 KdPrint2(("IdeIntr: ATAPI Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x, len %#x\n",
6412 AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)(-1)), srb->DataTransferLength ));
6413 //KdDump(srb->DataBuffer, srb->DataTransferLength);
6414 }
6415 if(!AtapiDmaPioSync(HwDeviceExtension, srb, (PUCHAR)(srb->DataBuffer), srb->DataTransferLength)) {
6416 KdPrint2(("IdeIntr: Can't sync DMA and PIO buffers\n"));
6417 }
6418 }
6419
6420 // Clear interrupt expecting flag.
6422 // clear this flag now, it can be set again in sub-calls
6425
6426 // Sanity check that there is a current request.
6427 if(srb != NULL) {
6428 // Set status in SRB.
6429 srb->SrbStatus = (UCHAR)status;
6430
6431 // Check for underflow.
6432 if(AtaReq->WordsLeft) {
6433
6434 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Check for underflow, AtaReq->WordsLeft %x\n", AtaReq->WordsLeft));
6435 // Subtract out residual words and update if filemark hit,
6436 // setmark hit , end of data, end of media...
6437 if (!(LunExt->DeviceFlags & DFLAGS_TAPE_DEVICE)) {
6439 srb->DataTransferLength -= AtaReq->WordsLeft*2;
6440 } else {
6441 srb->DataTransferLength = 0;
6442 }
6443 } else {
6444 srb->DataTransferLength -= AtaReq->WordsLeft*2;
6445 }
6446 }
6447 if(status == SRB_STATUS_SUCCESS) {
6448 //if(!(deviceExtension->HwFlags & UNIATA_AHCI) && !atapiDev) {
6449 // // This should be set in UniataAhciEndTransaction() for AHCI
6450 // AtaReq->WordsTransfered += AtaReq->bcount * DEV_BSIZE/2;
6451 //}
6452 if(!atapiDev &&
6453 AtaReq->WordsTransfered*2 < AtaReq->TransferLength) {
6454 KdPrint2((PRINT_PREFIX "AtapiInterrupt: more I/O required (%x of %x bytes) -> reenqueue\n",
6455 AtaReq->WordsTransfered*2, AtaReq->TransferLength));
6456 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
6458 goto reenqueue_req;
6459 } else {
6460 KdPrint2((PRINT_PREFIX " Transfered %x, full size %x\n",
6461 AtaReq->WordsTransfered*2, AtaReq->TransferLength));
6462 }
6463 }
6464
6465 if (srb->Function != SRB_FUNCTION_IO_CONTROL) {
6466
6467CompleteRDP:
6468 // Indicate command complete.
6469 if (!(chan->RDP)) {
6470 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete\n"));
6471IntrCompleteReq:
6472
6473 if (status == SRB_STATUS_SUCCESS &&
6474 srb->SenseInfoBuffer &&
6475 srb->SenseInfoBufferLength >= sizeof(SENSE_DATA)) {
6476
6477 PSENSE_DATA senseBuffer = (PSENSE_DATA)srb->SenseInfoBuffer;
6478
6479 KdPrint2((PRINT_PREFIX "AtapiInterrupt: set AutoSense\n"));
6480 senseBuffer->ErrorCode = 0;
6481 senseBuffer->Valid = 1;
6482 senseBuffer->AdditionalSenseLength = 0xb;
6483 senseBuffer->SenseKey = 0;
6484 senseBuffer->AdditionalSenseCode = 0;
6485 senseBuffer->AdditionalSenseCodeQualifier = 0;
6486
6488 }
6489 AtapiDmaDBSync(chan, srb);
6490 KdPrint2((PRINT_PREFIX "AtapiInterrupt: remove srb %#x, status %x\n", srb, status));
6491 UniataRemoveRequest(chan, srb);
6492 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete, srb %#x\n", srb));
6494 deviceExtension,
6495 srb);
6496 }
6497 } else {
6498
6499 KdPrint2((PRINT_PREFIX "AtapiInterrupt: IOCTL completion\n"));
6500
6501 if (status != SRB_STATUS_SUCCESS) {
6503 KdPrint2((PRINT_PREFIX "AtapiInterrupt: error %#x\n", error));
6504 }
6505
6506 if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(srb->DataBuffer))->Signature),"SCSIDISK",sizeof("SCSIDISK")-1)) {
6507
6508 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6509 // Build the SMART status block depending upon the completion status.
6510 cmdOutParameters->cBufferSize = wordCount;
6511 cmdOutParameters->DriverStatus.bDriverError = (error) ? SMART_IDE_ERROR : 0;
6512 cmdOutParameters->DriverStatus.bIDEError = error;
6513
6514 // If the sub-command is return smart status, jam the value from cylinder low and high, into the
6515 // data buffer.
6516 if (chan->SmartCommand == RETURN_SMART_STATUS) {
6517 PIDEREGS_EX regs = (PIDEREGS_EX)&(cmdOutParameters->bBuffer);
6518
6519 regs->bOpFlags = 0;
6520 UniataSnapAtaRegs(chan, 0, regs);
6521
6522 regs->bCommandReg = SMART_CMD;
6523 regs->bFeaturesReg = RETURN_SMART_STATUS;
6524
6525 cmdOutParameters->cBufferSize = 8;
6526 }
6527 chan->SmartCommand = 0; // cleanup after execution
6528 }
6529 // Indicate command complete.
6530 goto IntrCompleteReq;
6531 }
6532
6533 } else {
6534
6535 KdPrint2((PRINT_PREFIX "AtapiInterrupt: No SRB!\n"));
6536 }
6537
6538 if (chan->RDP) {
6539 // Check DSC
6540 for (i = 0; i < 5; i++) {
6541 GetBaseStatus(chan, statusByte);
6542 if(!(statusByte & IDE_STATUS_BUSY)) {
6543 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RDP + cleared BUSY\n"));
6544 chan->RDP = FALSE;
6545 goto CompleteRDP;
6546 } else
6547 if (statusByte & IDE_STATUS_DSC) {
6548 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Clear RDP\n"));
6549 chan->RDP = FALSE;
6550 goto CompleteRDP;
6551 }
6553 }
6554 }
6555 // RDP can be cleared since previous check
6556 if (chan->RDP) {
6557 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestTimerCall 2000\n"));
6558
6559 TimerValue = 2000;
6560#ifndef UNIATA_CORE
6561 goto CallTimerDpc;
6562#else //UNIATA_CORE
6563 AtapiStallExecution(TimerValue);
6564 goto ServiceInterrupt;
6565#endif //UNIATA_CORE
6566 }
6567
6568// ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
6569enqueue_next_req:
6570 // Get next request
6571 srb = UniataGetCurRequest(chan);
6572
6573reenqueue_req:
6574
6575#ifndef UNIATA_CORE
6576 KdPrint2((PRINT_PREFIX "AtapiInterrupt: NextRequest, srb=%#x\n",srb));
6577 if(!srb) {
6579 deviceExtension,
6580 NULL);
6581 } else {
6583 deviceExtension,
6584 PathId,
6585 TargetId,
6586 Lun);
6587 // in simplex mode next command must NOT be sent here
6588 if(!deviceExtension->simplexOnly) {
6589 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
6590 }
6591 }
6592 // Try to get SRB fron any non-empty queue (later)
6593 if(deviceExtension->simplexOnly) {
6594 NoStartIo = FALSE;
6595 }
6596#endif //UNIATA_CORE
6597
6598 goto ReturnEnableIntr;
6599
6600 } else {
6601
6602 // Unexpected int. Catch it
6603 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Unexpected ATAPI interrupt. InterruptReason %#x. Status %#x.\n",
6604 interruptReason,
6605 statusByte));
6606
6608 if(interruptReason == ATAPI_IR_IO_toDev && !(statusByte & IDE_STATUS_DRQ) && !DmaTransfer) {
6609 statusByte = WaitForDrq(chan);
6610 if(statusByte & IDE_STATUS_DRQ) {
6611 goto continue_PIO;
6612 }
6613 }
6614 }
6615
6616 if(OldReqState == REQ_STATE_DPC_WAIT_BUSY0 &&
6617 AtaReq->WordsLeft == 0) {
6618 KdPrint2((PRINT_PREFIX "AtapiInterrupt: pending WAIT_BUSY0. Complete.\n"));
6620 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
6621 goto CompleteRequest;
6622 }
6623 }
6624
6625ReturnEnableIntr:
6626
6627 KdPrint2((PRINT_PREFIX "AtapiInterrupt: ReturnEnableIntr\n",srb));
6628 //UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
6629 deviceExtension->ExpectingInterrupt = TRUE;
6630 if(UseDpc) {
6631 if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
6632 KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiEnableInterrupts__()\n"));
6633#ifdef UNIATA_USE_XXableInterrupts
6634 //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
6636 // must be called on DISPATCH_LEVEL
6639#else
6640 AtapiEnableInterrupts(HwDeviceExtension, c);
6643 // Will raise IRQL to DIRQL
6644#ifndef UNIATA_CORE
6645 AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
6647 1);
6648#endif // UNIATA_CORE
6649 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
6650#endif // UNIATA_USE_XXableInterrupts
6651 }
6652 }
6653
6655 // in simplex mode next command must be sent here if
6656 // DPC is not used
6657 KdPrint2((PRINT_PREFIX "AtapiInterrupt: exiting, UseDpc=%d, NoStartIo=%d\n", UseDpc, NoStartIo));
6658
6659#ifndef UNIATA_CORE
6660 if(!UseDpc && /*deviceExtension->simplexOnly &&*/ !NoStartIo) {
6661 chan = UniataGetNextChannel(chan);
6662 if(chan) {
6663 srb = UniataGetCurRequest(chan);
6664 } else {
6665 srb = NULL;
6666 }
6667 KdPrint2((PRINT_PREFIX "AtapiInterrupt: run srb %x\n", srb));
6668 if(srb) {
6669 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
6670 }
6671 }
6672#endif //UNIATA_CORE
6673 return TRUE;
6674
6675} // end AtapiInterrupt__()
#define WriteBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:344
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
#define WriteBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:354
#define ReadBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:349
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
#define SMART_CMD
Definition: helper.h:21
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
#define UNIATA_NO80CHK
Definition: bm_devs_decl.h:630
#define PIO0_TIMING
Definition: bm_devs_decl.h:53
#define UniataGetPioTiming(LunExt)
Definition: bm_devs_decl.h:56
#define REQ_STATE_PROCESSING_INTR
Definition: bsmaster.h:958
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR
Definition: bsmaster.h:952
#define ATA_SE_HANDSHAKE_ERR
Definition: bsmaster.h:421
#define CTRFLAGS_DPC_REQ
Definition: bsmaster.h:1135
BOOLEAN NTAPI AtapiDmaDBPreSync(IN PVOID HwDeviceExtension, PHW_CHANNEL chan, PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:553
#define VM_BOCHS
Definition: bsmaster.h:1906
#define REQ_STATE_DPC_WAIT_BUSY0
Definition: bsmaster.h:964
#define REQ_STATE_DPC_WAIT_DRQ
Definition: bsmaster.h:967
#define REQ_FLAG_DMA_OPERATION
Definition: bsmaster.h:932
#define REQ_FLAG_FORCE_DOWNRATE
Definition: bsmaster.h:931
#define REQ_STATE_DPC_WAIT_BUSY
Definition: bsmaster.h:966
#define REQ_STATE_DPC_WAIT_BUSY1
Definition: bsmaster.h:965
#define REQ_STATE_NONE
Definition: bsmaster.h:943
#define REQ_FLAG_FORCE_DOWNRATE_LBA48
Definition: bsmaster.h:937
#define HBAFLAGS_DMA_DISABLED_LBA48
Definition: bsmaster.h:1359
#define VM_QEMU
Definition: bsmaster.h:1905
#define ATA_SE_LINKSEQ_ERR
Definition: bsmaster.h:422
#define REQ_STATE_ATAPI_DO_NOTHING_INTR
Definition: bsmaster.h:954
#define CTRFLAGS_DMA_OPERATION
Definition: bsmaster.h:1133
#define DEV_BSIZE
Definition: bsmaster.h:103
#define ATA_SE_UNKNOWN_FIS
Definition: bsmaster.h:424
#define REQ_STATE_ATAPI_EXPECTING_CMD_INTR
Definition: bsmaster.h:951
BOOLEAN NTAPI AtapiDmaPioSync(PVOID HwDeviceExtension, PSCSI_REQUEST_BLOCK Srb, PUCHAR data, ULONG count)
Definition: id_dma.cpp:467
#define REQ_STATE_PREPARE_TO_NEXT
Definition: bsmaster.h:947
#define ATA_SE_TRANSPORT_ERR
Definition: bsmaster.h:423
#define REQ_STATE_TRANSFER_COMPLETE
Definition: bsmaster.h:971
#define REQ_STATE_DPC_WAIT_DRQ_ERR
Definition: bsmaster.h:969
#define REQ_STATE_QUEUED
Definition: bsmaster.h:944
#define REQ_STATE_DPC_WAIT_DRQ0
Definition: bsmaster.h:968
#define REQ_STATE_DPC_INTR_REQ
Definition: bsmaster.h:960
VOID NTAPI AtapiDmaStart(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:588
#define MAX_RETRIES
Definition: bsmaster.h:72
#define CMD_ACTION_ALL
Definition: bsmaster.h:976
#define SCSIOP_MODE_SENSE10
Definition: cdrw_hw.h:946
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
struct _SENSE_DATA * PSENSE_DATA
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
#define SCSIOP_MECHANISM_STATUS
Definition: cdrw_hw.h:966
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
union _CDB * PCDB
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
#define SRB_STATUS_BUS_RESET
Definition: srb.h:353
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:317
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_STATUS_PENDING
Definition: srb.h:340
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:387
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_STATUS_ERROR
Definition: srb.h:344
@ CallEnableInterrupts
Definition: srb.h:536
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
#define KdDump(a, b)
Definition: env_spec_w32.h:312
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
@ NoRetry
Definition: fxpkgpnp.hpp:202
#define IDX_ATAPI_IO1_i_ByteCountHigh
Definition: hwide.h:92
#define IDE_STATUS_MASK
Definition: hwide.h:122
#define IDX_ATAPI_IO1_i_ByteCountLow
Definition: hwide.h:91
#define IDX_ATAPI_IO1_i_Error
Definition: hwide.h:88
ULONG NTAPI AtapiSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
Definition: id_ata.cpp:7377
#define RESET_COMPLETE_CURRENT
Definition: id_ata.cpp:143
VOID NTAPI UniataSnapAtaRegs(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN OUT PIDEREGS_EX regs)
Definition: id_ata.cpp:1476
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:11251
UCHAR DDKFASTAPI AtapiSuckPort2(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:503
VOID NTAPI AtapiHwInitializeChanger(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
Definition: id_ata.cpp:3667
ULONG NTAPI MapError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:2951
ULONG g_opt_VirtualMachine
Definition: id_ata.cpp:105
RETTYPE_XXableInterrupts NTAPI AtapiInterruptDpc(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4295
ULONG g_opt_MaxIsrWait
Definition: id_ata.cpp:95
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:11207
BOOLEAN NTAPI UniataAhciAbortOperation(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:1765
UCHAR NTAPI UniataAhciEndTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2294
#define error(str)
Definition: mkdosfs.c:1605
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
int k
Definition: mpi.c:3369
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:753
#define SMART_IDE_ERROR
Definition: ntdddisk.h:706
unsigned short USHORT
Definition: pedump.c:61
struct @5021 regs[]
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
struct _SRB_IO_CONTROL SRB_IO_CONTROL
UCHAR bIDEError
Definition: helper.h:3
UCHAR bDriverError
Definition: helper.h:2
ULONG MechStatusRetryCount
Definition: bsmaster.h:1054
ULONG AhciLastIS
Definition: bsmaster.h:1108
ULONG AhciLastSError
Definition: bsmaster.h:1109
UCHAR SmartCommand
Definition: bsmaster.h:1039
BOOLEAN DriverMustPoll
Definition: atapi.c:111
LONGLONG RecoverCount[MAX_RETRIES]
Definition: bsmaster.h:1230
LONGLONG IoCount
Definition: bsmaster.h:1231
ULONG AtapiReadyWaitDelay
Definition: bsmaster.h:1191
LONGLONG BlockIoCount
Definition: bsmaster.h:1232
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID DataBuffer
Definition: srb.h:263
PVOID SenseInfoBuffer
Definition: srb.h:264
UCHAR Function
Definition: srb.h:250
UCHAR ScsiStatus
Definition: srb.h:252
ULONG DataTransferLength
Definition: srb.h:261
ULONG SrbFlags
Definition: srb.h:260
UCHAR SrbStatus
Definition: srb.h:251
UCHAR bBuffer[1]
Definition: helper.h:27
ULONG cBufferSize
Definition: helper.h:25
DRIVERSTATUS DriverStatus
Definition: helper.h:26
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
UCHAR ErrorCode
Definition: cdrw_hw.h:1164
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
UCHAR SenseKey
Definition: cdrw_hw.h:1167
UCHAR Valid
Definition: cdrw_hw.h:1165
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint16_t * PUSHORT
Definition: typedefs.h:56
struct _IDEREGS_EX * PIDEREGS_EX
#define ATAPI_IR_IO_toHost
Definition: atapi.h:549
#define ATA_UDMA2
Definition: atapi.h:330
#define ATAPI_TYPE_CDROM
Definition: atapi.h:623
#define DFLAGS_DWORDIO_ENABLED
Definition: atapi.h:248
#define ATAPI_IR_COD_Cmd
Definition: atapi.h:545
#define ATAPI_IR_IO_toDev
Definition: atapi.h:548
ULONG bcount
Definition: bsmaster.h:887