ReactOS  0.4.14-dev-49-gfb4591c
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 \
) \
{ \
PIORES res; \
if(_port >= IDX_MAX_REG) { \
res = (PIORES)(_port); \
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 IN
Definition: typedefs.h:38
uint32_t ULONG_PTR
Definition: typedefs.h:63
if(!(yy_init))
Definition: macro.lex.yy.c:714
struct _IORES * PIORES
#define IDX_MAX_REG
Definition: bsmaster.h:469
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
#define ULONGIO_PTR
Definition: config.h:102

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 \
) \
{ \
PIORES res; \
if(_port >= IDX_MAX_REG) { \
res = (PIORES)(_port); \
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)); \
} \
}
#define IN
Definition: typedefs.h:38
uint32_t ULONG_PTR
Definition: typedefs.h:63
if(!(yy_init))
Definition: macro.lex.yy.c:714
struct _IORES * PIORES
#define IDX_MAX_REG
Definition: bsmaster.h:469
GLuint res
Definition: glext.h:9613
#define ULONGIO_PTR
Definition: config.h:102

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 \
) \
{ \
PIORES res; \
if(_port >= IDX_MAX_REG) { \
res = (PIORES)(_port); \
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; \
}
#define IN
Definition: typedefs.h:38
uint32_t ULONG_PTR
Definition: typedefs.h:63
if(!(yy_init))
Definition: macro.lex.yy.c:714
struct _IORES * PIORES
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define IDX_MAX_REG
Definition: bsmaster.h:469
GLuint res
Definition: glext.h:9613
#define ULONGIO_PTR
Definition: config.h:102

Definition at line 261 of file id_ata.cpp.

◆ DEBUG_MSG_BUFFER_SIZE

#define DEBUG_MSG_BUFFER_SIZE   512

Definition at line 11545 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 8181 of file id_ata.cpp.

Function Documentation

◆ _PrintNtConsole()

VOID _cdecl _PrintNtConsole ( PCCH  DebugMessage,
  ... 
)

Definition at line 11550 of file id_ata.cpp.

11554 {
11555  //int len;
11556  UCHAR dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE];
11557 // UNICODE_STRING msgBuff;
11558  va_list ap;
11559  va_start(ap, DebugMessage);
11560 
11561  /*len =*/ _vsnprintf((PCHAR)&dbg_print_tmp_buff[0], DEBUG_MSG_BUFFER_SIZE-1, DebugMessage, ap);
11562 
11563  dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE-1] = 0;
11564 
11565  //DbgPrint(((PCHAR)&(dbg_print_tmp_buff[0]))); // already done in KdPrint macro
11566  HalDisplayString(dbg_print_tmp_buff);
11567 
11568 #ifdef _DEBUG
11569  if(g_LogToDisplay > 1) {
11571  }
11572 #endif // _DEBUG
11573 
11574  va_end(ap);
11575 
11576 } // end PrintNtConsole()
signed char * PCHAR
Definition: retypes.h:7
#define va_end(ap)
Definition: acmsvcex.h:90
ULONG g_LogToDisplay
char * va_list
Definition: acmsvcex.h:78
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DEBUG_MSG_BUFFER_SIZE
Definition: id_ata.cpp:11545
#define va_start(ap, A)
Definition: acmsvcex.h:91
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define _vsnprintf
Definition: xmlstorage.h:202
#define AtapiStallExecution(dt)
Definition: atapi.h:158
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32

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 1122 of file id_ata.cpp.

1134 {
1135  if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
1136  return AtaCommand48(deviceExtension, DeviceNumber, lChannel,
1137  command,
1138  (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1139  count, feature, wait_flags);
1140  } else {
1141  return UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
1143  NULL,
1144  0,
1145  command,
1146  (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1147  count,
1148  feature,
1149  0 /* ahci flags */ ,
1150  wait_flags,
1151  1000 /* timeout 1 sec */
1152  );
1153 
1154  }
1155 } // end AtaCommand()
INTERNETFEATURELIST feature
Definition: misc.c:1689
uint32_t sector
Definition: isohybrid.c:61
struct outqueuenode * head
Definition: adnsresfilter.c:66
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:922
GLUquadricObj * cylinder
Definition: cylfrac.c:44
smooth NULL
Definition: ftsmooth.c:416
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
unsigned int ULONG
Definition: retypes.h:1
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1036
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

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 922 of file id_ata.cpp.

932 {
933  PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
934  UCHAR statusByte;
935  ULONG i;
936  PUCHAR plba;
937 
938  KdPrint2((PRINT_PREFIX "AtaCommand48: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x count %#x feature %#x\n",
939  deviceExtension->DevIndex, deviceExtension->Channel, DeviceNumber, command, lba, count, feature ));
940 
941  if(deviceExtension->HwFlags & UNIATA_AHCI) {
942  //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
943 
944  KdPrint3((" (ahci)\n"));
945 
946  statusByte = UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
948  NULL,
949  0,
950  command,
951  lba, count,
952  feature,
953  0 /* ahci flags */ ,
954  wait_flags,
955  1000 /* timeout 1 sec */
956  );
957 
958  return statusByte;
959  }
960 
961  SelectDrive(chan, DeviceNumber);
962 
963  statusByte = WaitOnBusy(chan);
964 
965  /* ready to issue command ? */
966  if (statusByte & IDE_STATUS_BUSY) {
967  KdPrint2((PRINT_PREFIX " Returning BUSY status\n"));
968  return statusByte;
969  }
970  // !!! We should not check ERROR condition here
971  // ERROR bit may be asserted durring previous operation
972  // and not cleared after SELECT
973 
974  //>>>>>> NV: 2006/08/03
977  KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
978  return IDE_STATUS_ERROR;
979  //return SRB_STATUS_ERROR;
980  }
981  //<<<<<< NV: 2006/08/03
982 
983  /* only use 48bit addressing if needed because of the overhead */
985  chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48)) {
986 
987  KdPrint2((PRINT_PREFIX " dev %#x USE_LBA_48\n", DeviceNumber ));
988  /* translate command into 48bit version */
991  } else {
992  KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
993  return (UCHAR)-1;
994  }
995 
997  plba = (PUCHAR)&lba;
998 
1003  AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[3]));
1004  AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[0]));
1005  AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[4]));
1006  AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[1]));
1007  AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[5]));
1008  AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[2]));
1009 
1010  //KdPrint2((PRINT_PREFIX "AtaCommand48: dev %#x USE_LBA48 (2)\n", DeviceNumber ));
1012  } else {
1013 
1014  plba = (PUCHAR)&lba; //ktp
1015  chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1016 
1017  //if(feature ||
1018  // (chan->lun[DeviceNumber]->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))) {
1020  //}
1022  AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)plba[0]);
1023  AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)plba[1]);
1024  AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)plba[2]);
1025  if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_LBA_ENABLED) {
1026  //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_LBA\n", DeviceNumber ));
1028  } else {
1029  //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_CHS\n", DeviceNumber ));
1031  }
1032  }
1033 
1034  // write command code to device
1036 
1037  switch (wait_flags) {
1038  case ATA_WAIT_INTR:
1039 
1040  // caller requested wait for interrupt
1041  for(i=0;i<4;i++) {
1042  WaitOnBusy(chan);
1043  statusByte = WaitForDrq(chan);
1044  if (statusByte & IDE_STATUS_DRQ)
1045  break;
1046  AtapiStallExecution(500);
1047  KdPrint2((PRINT_PREFIX " retry waiting DRQ, status %#x\n", statusByte));
1048  }
1049 
1050  return statusByte;
1051 
1052  case ATA_WAIT_IDLE:
1053 
1054  // caller requested wait for entering Wait state
1055  for (i=0; i<30 * 1000; i++) {
1056 
1057  GetStatus(chan, statusByte);
1058  statusByte = UniataIsIdle(deviceExtension, statusByte);
1059  if(statusByte == IDE_STATUS_WRONG) {
1060  // no drive ?
1061  break;
1062  } else
1063  if(statusByte & IDE_STATUS_ERROR) {
1064  break;
1065  } else
1066  if(statusByte & IDE_STATUS_BUSY) {
1067  AtapiStallExecution(100);
1068  continue;
1069  } else
1070  if((statusByte & ~IDE_STATUS_INDEX) == IDE_STATUS_IDLE) {
1071  break;
1072  } else {
1073  //if(deviceExtension->HwFlags & UNIATA_SATA) {
1074  if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1075  break;
1076  }
1077  AtapiStallExecution(100);
1078  }
1079  }
1080  //statusByte |= IDE_STATUS_BUSY;
1081  break;
1082 
1083  case ATA_WAIT_READY:
1084  statusByte = WaitOnBusyLong(chan);
1085  break;
1086  case ATA_WAIT_BASE_READY:
1087  statusByte = WaitOnBaseBusyLong(chan);
1088  break;
1089  case ATA_IMMEDIATE:
1090  GetStatus(chan, statusByte);
1091  if (statusByte & IDE_STATUS_ERROR) {
1092  KdPrint2((PRINT_PREFIX " Warning: Immed Status %#x :(\n", statusByte));
1093  if(statusByte == (IDE_STATUS_IDLE | IDE_STATUS_ERROR)) {
1094  break;
1095  }
1096  KdPrint2((PRINT_PREFIX " try to continue\n"));
1097  statusByte &= ~IDE_STATUS_ERROR;
1098 
1099  } else {
1100  //KdPrint2((PRINT_PREFIX " send Status %#x\n", statusByte));
1101  }
1103  // !!!!!
1104  InterlockedExchange(&(chan->CheckIntr),
1105  CHECK_INTR_IDLE);
1106 
1107  statusByte = IDE_STATUS_SUCCESS;
1108  break;
1109  }
1110 
1111  //KdPrint2((PRINT_PREFIX " Status %#x\n", statusByte));
1112 
1113  return statusByte;
1114 } // end AtaCommand48()
INTERNETFEATURELIST feature
Definition: misc.c:1689
#define ATA_CMD_FLAG_48supp
Definition: atapi.h:1600
UCHAR const AtaCommandFlags[256]
Definition: atacmd_map.h:25
#define IDX_IO1_o_DriveSelect
Definition: atapi.h:214
#define TRUE
Definition: types.h:120
#define KdPrint2(_x_)
Definition: atapi.h:154
#define IDX_IO1_o_CylinderHigh
Definition: atapi.h:213
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
#define IDE_STATUS_DRQ
Definition: atapi.h:128
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned char * PUCHAR
Definition: retypes.h:3
#define IDX_IO1_o_Command
Definition: atapi.h:215
bool NTAPI CheckIfBadBlock(IN PHW_LU_EXTENSION LunExt, IN ULONGLONG lba, IN ULONG count)
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
UCHAR DDKFASTAPI UniataIsIdle(IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN UCHAR Status)
Definition: id_ata.cpp:696
VOID UniataExpectChannelInterrupt(IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
Definition: id_ata.cpp:4446
#define IDE_STATUS_WRONG
Definition: atapi.h:431
#define IDE_DRIVE_SELECT_1
Definition: atapi.h:138
#define lba
#define IDE_STATUS_INDEX
Definition: atapi.h:126
#define CTRFLAGS_LBA48
Definition: bsmaster.h:1137
#define IDE_DRIVE_1
Definition: atapi.h:440
#define IDX_IO1_o_Feature
Definition: atapi.h:209
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 ATA_WAIT_IDLE
Definition: bsmaster.h:63
UCHAR DDKFASTAPI WaitOnBusy(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:606
smooth NULL
Definition: ftsmooth.c:416
#define ATA_CMD_FLAG_FUA
Definition: atapi.h:1603
UCHAR const AtaCommands48[256]
Definition: atacmd_map.h:5
#define ATA_WAIT_INTR
Definition: bsmaster.h:56
__inline BOOLEAN UniataIsSATARangeAvailable(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_sata.h:91
#define IDE_STATUS_IDLE
Definition: atapi.h:131
#define IDE_STATUS_SUCCESS
Definition: atapi.h:418
#define IDX_IO1_o_BlockNumber
Definition: atapi.h:211
#define ATA_IMMEDIATE
Definition: bsmaster.h:55
#define UniAta_need_lba48(command, lba, count, supp48)
Definition: atapi.h:1611
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DFLAGS_LBA_ENABLED
Definition: atapi.h:247
#define KdPrint3(_x_)
Definition: atapi.h:153
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
LONG CheckIntr
Definition: bsmaster.h:1062
#define InterlockedExchange
Definition: armddk.h:54
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define IDX_IO1_o_CylinderLow
Definition: atapi.h:212
#define IDX_IO1_o_BlockCount
Definition: atapi.h:210
#define IDE_STATUS_BUSY
Definition: atapi.h:132
UCHAR DDKFASTAPI SelectDrive(IN PHW_CHANNEL chan, IN ULONG DeviceNumber)
Definition: id_ata.cpp:575
#define ATA_WAIT_READY
Definition: bsmaster.h:57
UCHAR DDKFASTAPI WaitOnBusyLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:628
#define PRINT_PREFIX
Definition: atapi.h:150
#define ATA_CMD_FLAG_LBAIOsupp
Definition: atapi.h:1599
int command(const char *fmt,...)
Definition: ftp.c:266
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define IDE_STATUS_ERROR
Definition: atapi.h:125
unsigned int ULONG
Definition: retypes.h:1
UCHAR DDKFASTAPI WaitOnBaseBusyLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:672
#define IDE_DRIVE_SELECT_2
Definition: atapi.h:139
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1036
#define ATA_WAIT_BASE_READY
Definition: bsmaster.h:62
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
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
#define IDE_DRIVE_2
Definition: atapi.h:441
#define IDE_USE_LBA
Definition: atapi.h:446
UCHAR DDKFASTAPI WaitForDrq(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:752

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 11446 of file id_ata.cpp.

11451 {
11452  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11453  PSCSI_SUPPORTED_CONTROL_TYPE_LIST pControlTypeList;
11454  ULONG numberChannels = deviceExtension->NumberChannels;
11455  ULONG c;
11456  NTSTATUS status;
11457 
11458  KdPrint(( "AtapiAdapterControl: %#x\n", ControlType));
11459 
11460  switch(ControlType) {
11462  BOOLEAN supportedTypes[ScsiAdapterControlMax] = {
11463  TRUE, // ScsiQuerySupportedControlTypes
11464  TRUE, // ScsiStopAdapter
11465  TRUE, // ScsiRestartAdapter
11466  FALSE, // ScsiSetBootConfig
11467  FALSE // ScsiSetRunningConfig
11468  };
11469 
11471  ULONG i;
11472 
11473  pControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST) Parameters;
11474 
11475  if(pControlTypeList->MaxControlType < lim) {
11476  lim = pControlTypeList->MaxControlType;
11477  }
11478 
11479  for(i = 0; i < lim; i++) {
11480  pControlTypeList->SupportedTypeList[i] = supportedTypes[i];
11481  }
11482 
11483  break;
11484 
11485  }
11486  case ScsiStopAdapter: {
11487 
11488  KdPrint(( "AtapiAdapterControl: ScsiStopAdapter\n"));
11489  // Shut down all interrupts on the adapter. They'll get re-enabled
11490  // by the initialization routines.
11491  for (c = 0; c < numberChannels; c++) {
11492  AtapiResetController(deviceExtension, c);
11493  AtapiDisableInterrupts(deviceExtension, c);
11494  }
11495  if(deviceExtension->AdapterInterfaceType == PCIBus) {
11496  // we must never get here for non-PCI
11497  /*status =*/ UniataDisconnectIntr2(HwDeviceExtension);
11498  BMList[deviceExtension->DevIndex].Isr2Enable = FALSE;
11499  }
11500  break;
11501  }
11502  case ScsiRestartAdapter: {
11503 
11504  KdPrint(( "AtapiAdapterControl: ScsiRestartAdapter\n"));
11505  // Enable all the interrupts on the adapter while port driver call
11506  // for power up an HBA that was shut down for power management
11507 
11509  status = UniataConnectIntr2(HwDeviceExtension);
11510  if(NT_SUCCESS(status)) {
11511  for (c = 0; c < numberChannels; c++) {
11512  AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, c);
11513  FindDevices(HwDeviceExtension, 0, c);
11514  AtapiEnableInterrupts(deviceExtension, c);
11515  AtapiHwInitialize__(deviceExtension, c);
11516  }
11517  if(deviceExtension->Isr2DevObj) {
11518  // we must never get here for non-PCI
11519  BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
11520  }
11521  }
11522 
11523  break;
11524  }
11525 
11526  default: {
11527  KdPrint(( "AtapiAdapterControl: default => return ScsiAdapterControlUnsuccessful\n"));
11529  }
11530  }
11531 
11533 } // end AtapiAdapterControl()
#define TRUE
Definition: types.h:120
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1483
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4351
LONG NTSTATUS
Definition: precomp.h:26
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
PDEVICE_OBJECT Isr2DevObj
Definition: bsmaster.h:1281
BOOLEAN NTAPI AtapiResetController(IN PVOID HwDeviceExtension, IN ULONG PathId)
Definition: id_ata.cpp:2365
NTSTATUS NTAPI UniataDisconnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2156
OUT BOOLEAN SupportedTypeList[0]
Definition: srb.h:213
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
unsigned char BOOLEAN
VOID NTAPI AtapiHwInitialize__(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_ata.cpp:3332
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4411
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _SCSI_SUPPORTED_CONTROL_TYPE_LIST * PSCSI_SUPPORTED_CONTROL_TYPE_LIST
const GLubyte * c
Definition: glext.h:8905
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1485
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
MMRESULT FindDevices()
Definition: utils.c:159
static SERVICE_STATUS status
Definition: service.c:31
#define KdPrint(x)
Definition: env_spec_w32.h:288
ULONG NumberChannels
Definition: atapi.c:68
INTERFACE_TYPE AdapterInterfaceType
Definition: bsmaster.h:1316
NTSTATUS NTAPI UniataConnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2034
Definition: ps.c:97

Referenced by DriverEntry().

◆ AtapiCallBack__()

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

Definition at line 3826 of file id_ata.cpp.

3830 {
3831 
3832  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3833  PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3834  ULONG c, _c;
3835 
3837  UCHAR statusByte;
3838 
3839  KdPrint2((PRINT_PREFIX "AtapiCallBack:\n"));
3840  // If the last command was DSC restrictive, see if it's set. If so, the device is
3841  // ready for a new request. Otherwise, reset the timer and come back to here later.
3842 
3843  // If ISR decided to wait for BUSY or DRQ in DPC, we shall also get here.
3844  // In this case chan->ExpectingInterrupt == TRUE, but interrupts are disabled, thus,
3845  // we shall have no problem with interrupt handler.
3846  if (!srb || chan->ExpectingInterrupt) {
3847  KdPrint2((PRINT_PREFIX "AtapiCallBack: Calling ISR directly due to BUSY\n"));
3848  chan->DpcState = DPC_STATE_TIMER;
3849  if(!AtapiInterrupt__(HwDeviceExtension, lChannel)) {
3851  KdPrint2((PRINT_PREFIX "AtapiCallBack: What's fucking this ???\n"));
3852  }
3853  goto ReturnCallback;
3854  }
3855 
3856 #ifdef _DEBUG
3857  if (!IS_RDP((srb->Cdb[0]))) {
3858  KdPrint2((PRINT_PREFIX "AtapiCallBack: Invalid CDB marked as RDP - %#x\n", srb->Cdb[0]));
3859  }
3860 #endif
3861  if(!(chan->RDP)) {
3862  goto ReturnEnableIntr;
3863  }
3864  GetStatus(chan, statusByte);
3865  if (statusByte & IDE_STATUS_DSC) {
3866 
3867  UCHAR PathId = srb->PathId;
3868  UCHAR TargetId = srb->TargetId;
3869  UCHAR Lun = srb->Lun;
3870 
3871  KdPrint2((PRINT_PREFIX "AtapiCallBack: Found DSC for RDP - %#x\n", srb->Cdb[0]));
3872  AtapiDmaDBSync(chan, srb);
3873  UniataRemoveRequest(chan, srb);
3874  ScsiPortNotification(RequestComplete, deviceExtension, srb);
3875  // Clear current SRB.
3876  if(!deviceExtension->simplexOnly) {
3877  srb = UniataGetCurRequest(chan);
3878  } else {
3879  srb = NULL;
3880  }
3881  chan->RDP = FALSE;
3882 
3883  // Ask for next request.
3885  deviceExtension,
3886  PathId,
3887  TargetId,
3888  Lun);
3889  ScsiPortNotification(NextRequest, deviceExtension, NULL);
3890 
3891  if(srb) {
3892  AtapiStartIo__(HwDeviceExtension, srb, FALSE);
3893  }
3894 
3895  } else {
3896  KdPrint2((PRINT_PREFIX "AtapiCallBack: Requesting another timer for Op %#x\n",
3897  srb->Cdb[0]));
3898 
3899  AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
3901  1000);
3902 
3903  goto ReturnCallback;
3904  }
3905 
3906 ReturnEnableIntr:
3907 
3908  if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
3909  KdPrint2((PRINT_PREFIX "AtapiCallBack: CallDisableInterrupts\n"));
3910  //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3911 #ifdef UNIATA_USE_XXableInterrupts
3913  // must be called on DISPATCH_LEVEL
3914  ScsiPortNotification(CallDisableInterrupts, HwDeviceExtension,
3916 #else
3917  AtapiEnableInterrupts(HwDeviceExtension, lChannel);
3918  InterlockedExchange(&(chan->CheckIntr),
3919  CHECK_INTR_IDLE);
3920  // Will raise IRQL to DIRQL
3921  AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
3923  1);
3924  KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
3925 #endif // UNIATA_USE_XXableInterrupts
3926  } else {
3927  //ASSERT(!deviceExtension->simplexOnly);
3928  }
3929 
3930 ReturnCallback:
3931 
3932  // Check other channel
3933  // In simplex mode no interrupts must appear on other channels
3934  for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
3935  c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
3936 
3937  if(c == lChannel) {
3938  continue;
3939  }
3940 
3941  chan = &(deviceExtension->chan[c]);
3942 
3943  if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
3946  {
3947  //ASSERT(!deviceExtension->simplexOnly);
3948  chan->DpcState = DPC_STATE_ISR;
3949  if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
3951  }
3952  }
3953  }
3954  KdPrint2((PRINT_PREFIX "AtapiCallBack: return\n"));
3955  return;
3956 
3957 } // end AtapiCallBack__()
RETTYPE_XXableInterrupts NTAPI AtapiEnableInterrupts__(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4287
#define KdPrint2(_x_)
Definition: atapi.h:154
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1117
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
UCHAR DpcState
Definition: bsmaster.h:1030
UCHAR Cdb[16]
Definition: srb.h:271
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4351
BOOLEAN ExpectingInterrupt
Definition: bsmaster.h:1032
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
#define CTRFLAGS_ENABLE_INTR_REQ
Definition: bsmaster.h:1136
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
LONG DisableIntr
Definition: bsmaster.h:1061
PHW_CHANNEL chan
Definition: bsmaster.h:1257
#define DPC_STATE_TIMER
Definition: bsmaster.h:1157
VOID NTAPI AtapiCallBack_X(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:3961
#define CHECK_INTR_DETECTED
Definition: bsmaster.h:1067
#define DPC_STATE_ISR
Definition: bsmaster.h:1155
VOID NTAPI UniataRemoveRequest(IN PHW_CHANNEL chan, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_queue.cpp:261
smooth NULL
Definition: ftsmooth.c:416
UCHAR TargetId
Definition: srb.h:246
BOOLEAN NTAPI AtapiStartIo__(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN BOOLEAN TopLevel)
Definition: id_ata.cpp:9237
BOOLEAN NTAPI AtapiDmaDBSync(PHW_CHANNEL chan, PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:532
PSCSI_REQUEST_BLOCK NTAPI UniataGetCurRequest(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:354
const GLubyte * c
Definition: glext.h:8905
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1308
LONG CheckIntr
Definition: bsmaster.h:1062
#define InterlockedExchange
Definition: armddk.h:54
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
#define IS_RDP(OperationCode)
Definition: atapi.h:453
UCHAR PathId
Definition: srb.h:245
#define PRINT_PREFIX
Definition: atapi.h:150
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define IDE_STATUS_DSC
Definition: atapi.h:129
#define CHECK_INTR_ACTIVE
Definition: bsmaster.h:1066
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
VOID NTAPI AtapiQueueTimerDpc(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN PHW_TIMER HwScsiTimer, IN ULONG MiniportTimerValue)
Definition: id_ata.cpp:1332
#define CRNT_ILK_PTYPE
Definition: config.h:104
ULONG NumberChannels
Definition: atapi.c:68
BOOLEAN RDP
Definition: bsmaster.h:1033
#define CRNT_ILK_TYPE
Definition: config.h:103
BOOLEAN NTAPI AtapiInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4935

Referenced by AtapiCallBack_X().

◆ AtapiCallBack_X()

VOID NTAPI AtapiCallBack_X ( IN PVOID  HwDeviceExtension)

Definition at line 3961 of file id_ata.cpp.

3964 {
3965  AtapiCallBack__(HwDeviceExtension, (UCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->ActiveDpcChan);
3966 } // end AtapiCallBack_X()
VOID NTAPI AtapiCallBack__(IN PVOID HwDeviceExtension, IN UCHAR lChannel)
Definition: id_ata.cpp:3826
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by AtapiCallBack__(), and AtapiInterrupt__().

◆ AtapiCheckInterrupt__()

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

Definition at line 4466 of file id_ata.cpp.

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

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

◆ AtapiDisableInterrupts()

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

Definition at line 4411 of file id_ata.cpp.

4415 {
4416  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4417  PHW_CHANNEL chan;
4418  if(c >= deviceExtension->NumberChannels) {
4419  KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: WRONG CHANNEL\n",c));
4420  return;
4421  }
4422  chan = &(deviceExtension->chan[c]);
4423  KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: %d\n",c, chan->DisableIntr));
4424  // mark channel as busy
4425  if(InterlockedIncrement(&chan->DisableIntr)) {
4426  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4428  } else {
4429  //SelectDrive(chan, 0);
4431  IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4432  //if(chan->NumberLuns) {
4433  // SelectDrive(chan, 1);
4434  // AtapiWritePort1(chan, IDX_IO2_o_Control,
4435  // IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4436  // SelectDrive(chan, chan->cur_cdev);
4437  //}
4438  }
4440  }
4441 
4442  return;
4443 } // end AtapiDisableInterrupts()
#define KdPrint2(_x_)
Definition: atapi.h:154
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
LONG DisableIntr
Definition: bsmaster.h:1061
PHW_CHANNEL chan
Definition: bsmaster.h:1257
#define CTRFLAGS_INTR_DISABLED
Definition: bsmaster.h:1134
__inline VOID UniataAhciWriteChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data)
Definition: id_sata.h:302
#define IDX_AHCI_P_IE
Definition: bsmaster.h:685
const GLubyte * c
Definition: glext.h:8905
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define InterlockedIncrement
Definition: armddk.h:53
#define PRINT_PREFIX
Definition: atapi.h:150
#define c
Definition: ke_i.h:80
ULONG NumberChannels
Definition: atapi.c:68
#define IDX_IO2_o_Control
Definition: atapi.h:231
#define IDE_DC_DISABLE_INTERRUPTS
Definition: atapi.h:145

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 4351 of file id_ata.cpp.

4355 {
4356  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4357  PHW_CHANNEL chan;
4358  //UCHAR statusByte;
4359 
4360  if(c >= deviceExtension->NumberChannels) {
4361  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: WRONG CHANNEL\n",c));
4362  return;
4363  }
4364  if((deviceExtension->HwFlags & UNIATA_AHCI) &&
4365  !UniataAhciChanImplemented(deviceExtension, c)) {
4366  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: not imp. CHANNEL\n",c));
4367  return;
4368  }
4369 
4370  chan = &(deviceExtension->chan[c]);
4371  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: %d\n",c, chan->DisableIntr));
4372  if(!InterlockedDecrement(&chan->DisableIntr)) {
4373  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4377  ((/*ch->pm_level == */0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
4378  ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | /* DEBUG */
4382  );
4383  } else {
4384  //SelectDrive(chan, 0);
4385  //GetBaseStatus(chan, statusByte);
4387  0 | IDE_DC_A_4BIT );
4388  //if(chan->NumberLuns) {
4389  // SelectDrive(chan, 1);
4390  // GetBaseStatus(chan, statusByte);
4391  // AtapiWritePort1(chan, IDX_IO2_o_Control,
4392  // IDE_DC_A_4BIT );
4393  // SelectDrive(chan, chan->cur_cdev);
4394  //}
4395  }
4397  } else {
4398  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4399  // keep interrupts disabled
4401  } else {
4403  IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4404  }
4405  }
4406  return;
4407 } // end AtapiEnableInterrupts()
#define ATA_AHCI_P_IX_PC
Definition: bsmaster.h:505
#define KdPrint2(_x_)
Definition: atapi.h:154
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
#define ATA_AHCI_P_IX_INF
Definition: bsmaster.h:511
LONG DisableIntr
Definition: bsmaster.h:1061
#define ATA_AHCI_P_IX_UF
Definition: bsmaster.h:503
PHW_CHANNEL chan
Definition: bsmaster.h:1257
#define CTRFLAGS_INTR_DISABLED
Definition: bsmaster.h:1134
#define ATA_AHCI_P_IX_DP
Definition: bsmaster.h:504
__inline VOID UniataAhciWriteChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data)
Definition: id_sata.h:302
#define ATA_AHCI_P_IX_CPD
Definition: bsmaster.h:516
#define IDX_AHCI_P_IE
Definition: bsmaster.h:685
#define ATA_AHCI_P_IX_DHR
Definition: bsmaster.h:499
#define ATA_AHCI_P_IX_DS
Definition: bsmaster.h:501
const GLubyte * c
Definition: glext.h:8905
#define ATA_AHCI_P_IX_HBF
Definition: bsmaster.h:514
#define ATA_AHCI_P_IX_IF
Definition: bsmaster.h:512
#define ATA_AHCI_P_IX_SDB
Definition: bsmaster.h:502
#define InterlockedDecrement
Definition: armddk.h:52
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define ATA_AHCI_P_IX_PS
Definition: bsmaster.h:500
#define ATA_AHCI_P_IX_HBD
Definition: bsmaster.h:513
#define IDE_DC_A_4BIT
Definition: atapi.h:454
#define ATA_AHCI_P_IX_OF
Definition: bsmaster.h:510
#define PRINT_PREFIX
Definition: atapi.h:150
#define ATA_AHCI_P_IX_PRC
Definition: bsmaster.h:508
#define c
Definition: ke_i.h:80
#define ATA_AHCI_P_IX_DI
Definition: bsmaster.h:506
#define ATA_AHCI_P_IX_TFE
Definition: bsmaster.h:515
ULONG NumberChannels
Definition: atapi.c:68
#define IDX_IO2_o_Control
Definition: atapi.h:231
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415
#define IDE_DC_DISABLE_INTERRUPTS
Definition: atapi.h:145

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 4287 of file id_ata.cpp.

4290 {
4291  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4292  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__():\n"));
4293  ULONG c;
4294  PHW_CHANNEL chan = NULL;
4295 
4296  for(c=0; c<deviceExtension->NumberChannels; c++) {
4297  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__(2): %#x\n",c));
4298  chan = &(deviceExtension->chan[c]);
4299 
4301  // enable intrs on requested channel
4303  AtapiEnableInterrupts(HwDeviceExtension, c);
4304  InterlockedExchange(&(chan->CheckIntr),
4305  CHECK_INTR_IDLE);
4306 
4307  // check if current or other channel(s) interrupted
4308  //AtapiInterrupt(HwDeviceExtension);
4309 
4310  if(deviceExtension->simplexOnly) {
4311  break;
4312  }
4313  } else {
4314  // check if other channel(s) interrupted
4315  // must do nothing in simplex mode
4316  if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
4319  continue;
4320  }
4321  //ASSERT(!deviceExtension->simplexOnly);
4322  chan->DpcState = DPC_STATE_ISR;
4323  if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
4325  }
4326  }
4327  }
4328  // In simplex mode next command must be sent to device here
4329  if(deviceExtension->simplexOnly && chan) {
4330  PSCSI_REQUEST_BLOCK srb;
4331  chan = UniataGetNextChannel(chan);
4332  if(chan) {
4333  srb = UniataGetCurRequest(chan);
4334  } else {
4335  srb = NULL;
4336  }
4337  if(srb) {
4338  AtapiStartIo__(HwDeviceExtension, srb, FALSE);
4339  }
4340  }
4341 
4342  return RETVAL_XXableInterrupts;
4343 
4344 } // end AtapiEnableInterrupts__()
#define KdPrint2(_x_)
Definition: atapi.h:154
UCHAR DpcState
Definition: bsmaster.h:1030
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4351
#define CTRFLAGS_ENABLE_INTR_REQ
Definition: bsmaster.h:1136
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
#define RETVAL_XXableInterrupts
Definition: id_ata.cpp:160
PHW_CHANNEL chan
Definition: bsmaster.h:1257
#define CHECK_INTR_DETECTED
Definition: bsmaster.h:1067
#define DPC_STATE_ISR
Definition: bsmaster.h:1155
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN NTAPI AtapiStartIo__(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN BOOLEAN TopLevel)
Definition: id_ata.cpp:9237
PSCSI_REQUEST_BLOCK NTAPI UniataGetCurRequest(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:354
const GLubyte * c
Definition: glext.h:8905
unsigned char UCHAR
Definition: xmlstorage.h:181
LONG CheckIntr
Definition: bsmaster.h:1062
#define InterlockedExchange
Definition: armddk.h:54
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
#define PRINT_PREFIX
Definition: atapi.h:150
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
PHW_CHANNEL NTAPI UniataGetNextChannel(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:372
#define CHECK_INTR_ACTIVE
Definition: bsmaster.h:1066
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
#define CRNT_ILK_PTYPE
Definition: config.h:104
ULONG NumberChannels
Definition: atapi.c:68
#define CRNT_ILK_TYPE
Definition: config.h:103
BOOLEAN NTAPI AtapiInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4935

Referenced by AtapiCallBack__(), and AtapiInterrupt__().

◆ AtapiHardReset()

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

Definition at line 902 of file id_ata.cpp.

907 {
908  KdPrint2((PRINT_PREFIX "AtapiHardReset: %d, dis=%d\n", Delay, DisableInterrupts));
910  (DisableInterrupts ? IDE_DC_DISABLE_INTERRUPTS : 0));
911  chan->last_devsel = -1;
912  AtapiStallExecution(Delay);
914 } // end AtapiHardReset()
#define IDE_DC_RESET_CONTROLLER
Definition: atapi.h:146
#define KdPrint2(_x_)
Definition: atapi.h:154
#define IDE_DC_REENABLE_CONTROLLER
Definition: atapi.h:147
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define PRINT_PREFIX
Definition: atapi.h:150
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define IDX_IO2_o_Control
Definition: atapi.h:231
#define IDE_DC_DISABLE_INTERRUPTS
Definition: atapi.h:145

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

◆ AtapiHwInitialize()

BOOLEAN NTAPI AtapiHwInitialize ( IN PVOID  HwDeviceExtension)

Definition at line 3296 of file id_ata.cpp.

3299 {
3300  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3301  ULONG numberChannels = deviceExtension->NumberChannels;
3302  ULONG c;
3303 
3304  KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base)\n"));
3305 
3306  if(WinVer_WDM_Model) {
3308  }
3309  if(deviceExtension->MasterDev) {
3310  KdPrint2((PRINT_PREFIX " mark chan %d of master controller [%x] as inited\n",
3311  deviceExtension->Channel, deviceExtension->DevIndex));
3312  BMList[deviceExtension->DevIndex].ChanInitOk |= 0x01 << deviceExtension->Channel;
3313  }
3314 
3315  /* do extra chipset specific setups */
3317 /*
3318  if(deviceExtension->Isr2DevObj && (deviceExtension->HwFlags & UNIATA_SATA)) {
3319  KdPrint2((PRINT_PREFIX " enable ISR2 to catch unexpected interrupts\n"));
3320  BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
3321  }
3322 */
3323  for (c = 0; c < numberChannels; c++) {
3324  AtapiHwInitialize__(deviceExtension, c);
3325  }
3326  KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base) done\n"));
3327  return TRUE;
3328 } // end AtapiHwInitialize()
#define TRUE
Definition: types.h:120
#define KdPrint2(_x_)
Definition: atapi.h:154
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1483
BOOLEAN NTAPI AtapiResetController__(IN PVOID HwDeviceExtension, IN ULONG PathId, IN UCHAR CompleteType)
Definition: id_ata.cpp:2376
#define RESET_COMPLETE_ALL
Definition: id_ata.cpp:144
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
BOOLEAN WinVer_WDM_Model
Definition: id_ata.cpp:112
VOID NTAPI AtapiHwInitialize__(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_ata.cpp:3332
const GLubyte * c
Definition: glext.h:8905
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1485
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
#define PRINT_PREFIX
Definition: atapi.h:150
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
ULONG NumberChannels
Definition: atapi.c:68

Referenced by DriverEntry().

◆ AtapiHwInitialize__()

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

Definition at line 3332 of file id_ata.cpp.

3336 {
3337  ULONG i;
3338  UCHAR statusByte, errorByte;
3339  PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3340  PHW_LU_EXTENSION LunExt;
3341 // ULONG tmp32;
3342  ULONG PreferedMode = 0xffffffff;
3343 
3344  if((deviceExtension->HwFlags & UNIATA_AHCI) &&
3345  !UniataAhciChanImplemented(deviceExtension, lChannel)) {
3346  return;
3347  }
3348 
3349  AtapiChipInit(deviceExtension, DEVNUM_NOT_SPECIFIED, lChannel);
3350  FindDevices(deviceExtension, 0, lChannel);
3351 
3352  for (i = 0; i < chan->NumberLuns; i++) {
3353 
3354  KdPrint3((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x, dev %x\n", lChannel, i));
3355 
3356  LunExt = chan->lun[i];
3357  // skip empty slots
3358  if (!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
3359  continue;
3360  }
3361 
3362  AtapiDisableInterrupts(deviceExtension, lChannel);
3364 
3365  if (!(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_MANUAL_CHS))) {
3366 
3367  KdPrint2((PRINT_PREFIX "AtapiHwInitialize: IDE branch\n"));
3368  // Enable media status notification
3369  IdeMediaStatus(TRUE,deviceExtension,lChannel,(UCHAR)i);
3370 
3371  // If supported, setup Multi-block transfers.
3372  statusByte = AtaCommand(deviceExtension, i, lChannel,
3373  IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
3375 
3376  // Check for errors. Reset the value to 0 (disable MultiBlock) if the
3377  // command was aborted.
3378  if (statusByte & IDE_STATUS_ERROR) {
3379 
3380  // Read the error register.
3381  errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
3382 
3383  KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
3384  statusByte,
3385  errorByte));
3386 
3387  statusByte = AtaCommand(deviceExtension, i, lChannel,
3388  IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
3389  0, 0, ATA_WAIT_BASE_READY);
3390 
3391  if (statusByte & IDE_STATUS_ERROR) {
3392  // Read the error register.
3393  errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
3394 
3395  KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n",
3396  statusByte,
3397  errorByte));
3398  }
3399  // Adjust the devExt. value, if necessary.
3400  LunExt->MaximumBlockXfer = 0;
3401 
3402  } else {
3404  "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
3405  i,
3406  LunExt->MaximumBlockXfer));
3407  }
3408 
3409  if(LunExt->IdentifyData.MajorRevision) {
3410 
3411  if(LunExt->opt_ReadCacheEnable) {
3412  KdPrint2((PRINT_PREFIX " Try Enable Read Cache\n"));
3413  // If supported, setup read/write cacheing
3414  statusByte = AtaCommand(deviceExtension, i, lChannel,
3415  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3417 
3418  // Check for errors.
3419  if (statusByte & IDE_STATUS_ERROR) {
3421  "AtapiHwInitialize: Enable read/write cacheing on Device %d failed\n",
3422  i));
3423  LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
3424  } else {
3426  }
3427  } else {
3428  KdPrint2((PRINT_PREFIX " Disable Read Cache\n"));
3429  statusByte = AtaCommand(deviceExtension, i, lChannel,
3430  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3432  LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
3433  }
3434  if(LunExt->IdentifyData.FeaturesSupport.WriteCache) {
3435  if(LunExt->opt_WriteCacheEnable) {
3436  KdPrint2((PRINT_PREFIX " Try Enable Write Cache\n"));
3437  // If supported & allowed, setup write cacheing
3438  statusByte = AtaCommand(deviceExtension, i, lChannel,
3439  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3441  // Check for errors.
3442  if (statusByte & IDE_STATUS_ERROR) {
3444  "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
3445  i));
3446  LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
3447  } else {
3449  }
3450  } else {
3451  KdPrint2((PRINT_PREFIX " Disable Write Cache\n"));
3452  statusByte = AtaCommand(deviceExtension, i, lChannel,
3453  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3455  LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
3456  }
3457  }
3458 
3459  if(/*LunExt->IdentifyData.FeaturesSupport.PowerMngt ||*/
3460  LunExt->IdentifyData.FeaturesSupport.APM) {
3461 
3462  if(LunExt->opt_AdvPowerMode) {
3463  KdPrint2((PRINT_PREFIX " Try Enable Adv. Power Mgmt\n"));
3464  // setup APM
3465  statusByte = AtaCommand(deviceExtension, i, lChannel,
3466  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3468  // Check for errors.
3469  if (statusByte & IDE_STATUS_ERROR) {
3471  "AtapiHwInitialize: Enable APM on Device %d failed\n",
3472  i));
3473  }
3474  } else {
3475  KdPrint2((PRINT_PREFIX " Disable Adv. Power Mgmt\n"));
3476  statusByte = AtaCommand(deviceExtension, i, lChannel,
3477  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3479  }
3480  }
3481  if(LunExt->IdentifyData.FeaturesSupport.AutoAcoustic) {
3482  if(LunExt->opt_AcousticMode) {
3483  KdPrint2((PRINT_PREFIX " Try Enable Acoustic Mgmt\n"));
3484  // setup acoustic mgmt
3485  statusByte = AtaCommand(deviceExtension, i, lChannel,
3486  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3488  // Check for errors.
3489  if (statusByte & IDE_STATUS_ERROR) {
3491  "AtapiHwInitialize: Enable Acoustic Mgmt on Device %d failed\n",
3492  i));
3493  }
3494  } else {
3495  KdPrint2((PRINT_PREFIX " Disable Acoustic Mgmt\n"));
3496  statusByte = AtaCommand(deviceExtension, i, lChannel,
3497  IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3499  }
3500  }
3501  if(LunExt->IdentifyData.FeaturesSupport.Standby) {
3502  KdPrint2((PRINT_PREFIX " Try init standby timer: %d\n"));
3503  // setup standby timer
3504  statusByte = AtaCommand(deviceExtension, i, lChannel,
3505  IDE_COMMAND_IDLE, 0, 0, 0,
3507  // Check for errors.
3508  if (statusByte & IDE_STATUS_ERROR) {
3510  "AtapiHwInitialize: standby timer on Device %d failed\n",
3511  i));
3512  }
3513  }
3514  }
3515 
3516  } else if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)){
3517 
3518  ULONG j;
3519  //BOOLEAN isSanyo = FALSE;
3520  CCHAR vendorId[26];
3521 
3522  KdPrint2((PRINT_PREFIX "AtapiHwInitialize: ATAPI/Changer branch\n"));
3523 
3524  // Attempt to identify any special-case devices - psuedo-atapi changers, atapi changers, etc.
3525  for (j = 0; j < 26; j += 2) {
3526 
3527  // Build a buffer based on the identify data.
3528  MOV_DW_SWP(vendorId[j], ((PUCHAR)LunExt->IdentifyData.ModelNumber)[j]);
3529  }
3530 
3531  if (!AtapiStringCmp (vendorId, "CD-ROM CDR", 11)) {
3532 
3533  // Inquiry string for older model had a '-', newer is '_'
3534  if (vendorId[12] == 'C') {
3535 
3536  // Torisan changer. Set the bit. This will be used in several places
3537  // acting like 1) a multi-lun device and 2) building the 'special' TUR's.
3539  LunExt->DiscsPresent = 3;
3540  //isSanyo = TRUE;
3541  }
3542  }
3543  }
3544 
3545  PreferedMode = LunExt->opt_MaxTransferMode;
3546  if((PreferedMode == 0xffffffff) || (PreferedMode > chan->MaxTransferMode)) {
3547  KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
3548  PreferedMode = chan->MaxTransferMode;
3549  }
3550 
3551  if(LunExt->opt_PreferedTransferMode != 0xffffffff) {
3552  KdPrint2((PRINT_PREFIX "PreferedTransferMode: %#x\n", PreferedMode));
3553  PreferedMode = min(LunExt->opt_PreferedTransferMode, PreferedMode);
3554  }
3555 
3556  KdPrint2((PRINT_PREFIX " try mode %#x\n", PreferedMode));
3557  LunExt->LimitedTransferMode =
3558  LunExt->TransferMode =
3559  (CHAR)PreferedMode;
3560 
3561  AtapiDmaInit__(deviceExtension, LunExt);
3562 
3563  LunExt->LimitedTransferMode =
3564  LunExt->TransferMode;
3565  KdPrint2((PRINT_PREFIX "Using %#x mode\n", LunExt->TransferMode));
3566 
3567  // We need to get our device ready for action before
3568  // returning from this function
3569 
3570  // According to the atapi spec 2.5 or 2.6, an atapi device
3571  // clears its status BSY bit when it is ready for atapi commands.
3572  // However, some devices (Panasonic SQ-TC500N) are still
3573  // not ready even when the status BSY is clear. They don't react
3574  // to atapi commands.
3575  //
3576  // Since there is really no other indication that tells us
3577  // the drive is really ready for action. We are going to check BSY
3578  // is clear and then just wait for an arbitrary amount of time!
3579  //
3580  if (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
3581  ULONG waitCount;
3582 
3583  // have to get out of the loop sometime!
3584  // 10000 * 100us = 1000,000us = 1000ms = 1s
3585  waitCount = 10000;
3586  GetStatus(chan, statusByte);
3587  if(statusByte == IDE_STATUS_WRONG) {
3588  waitCount = 0;
3589  }
3590  while ((statusByte & IDE_STATUS_BUSY) && waitCount) {
3591 
3592  KdPrint2((PRINT_PREFIX "Wait for ATAPI (status %x)\n", statusByte));
3593  // Wait for Busy to drop.
3594  AtapiStallExecution(100);
3595  GetStatus(chan, statusByte);
3596  waitCount--;
3597  }
3598 
3599  // 5000 * 100us = 500,000us = 500ms = 0.5s
3600  if(statusByte != IDE_STATUS_WRONG) {
3601  waitCount = 5000;
3602  do {
3603  AtapiStallExecution(100);
3604  } while (waitCount--);
3605  }
3606  }
3607  GetBaseStatus(chan, statusByte);
3608  AtapiEnableInterrupts(deviceExtension, lChannel);
3609  AtapiStallExecution(10);
3610  }
3611 
3612  return;
3613 
3614 } // end AtapiHwInitialize__()
IDENTIFY_DATA2 IdentifyData
Definition: bsmaster.h:1162
#define TRUE
Definition: types.h:120
#define KdPrint2(_x_)
Definition: atapi.h:154
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
VOID NTAPI AtapiDmaInit__(IN PHW_DEVICE_EXTENSION deviceExtension, IN PHW_LU_EXTENSION LunExt)
Definition: id_dma.cpp:857
ULONG opt_MaxTransferMode
Definition: bsmaster.h:1195
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4351
UCHAR opt_AcousticMode
Definition: bsmaster.h:1201
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG MaxTransferMode
Definition: bsmaster.h:1057
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define IDE_STATUS_WRONG
Definition: atapi.h:431
#define MOV_DW_SWP(a, b)
Definition: atactl.cpp:20
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
UCHAR opt_AdvPowerMode
Definition: bsmaster.h:1200
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
USHORT ModelNumber[20]
Definition: atapi.h:262
#define ATA_C_F_ENAB_APM
Definition: atapi.h:579
#define DFLAGS_CHANGER_INITED
Definition: atapi.h:50
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:1122
#define ATA_C_F_DIS_ACOUSTIC
Definition: atapi.h:586
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
#define DFLAGS_MANUAL_CHS
Definition: atapi.h:255
UCHAR DDKFASTAPI AtapiReadPort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4411
#define ATA_C_F_DIS_RCACHE
Definition: atapi.h:568
char CCHAR
Definition: typedefs.h:50
#define ATA_C_F_ENAB_ACOUSTIC
Definition: atapi.h:585
#define ATA_C_F_DIS_APM
Definition: atapi.h:580
#define ATA_C_F_DIS_WCACHE
Definition: atapi.h:565
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1485
BOOLEAN opt_WriteCacheEnable
Definition: bsmaster.h:1198
#define DFLAGS_RCACHE_ENABLED
Definition: atapi.h:250
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IDE_COMMAND_SET_MULTIPLE
Definition: atapi.h:113
UCHAR opt_StandbyTimer
Definition: bsmaster.h:1202
#define KdPrint3(_x_)
Definition: atapi.h:153
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
#define DFLAGS_WCACHE_ENABLED
Definition: atapi.h:249
UCHAR MaximumBlockXfer
Definition: bsmaster.h:1168
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
BOOLEAN opt_ReadCacheEnable
Definition: bsmaster.h:1197
#define IDE_STATUS_BUSY
Definition: atapi.h:132
LONG NTAPI AtapiStringCmp(PCHAR FirstStr, PCHAR SecondStr, ULONG Count)
Definition: atapi.c:6333
#define min(a, b)
Definition: monoChain.cc:55
#define ATA_C_F_ENAB_RCACHE
Definition: atapi.h:567
#define PRINT_PREFIX
Definition: atapi.h:150
#define DFLAGS_SANYO_ATAPI_CHANGER
Definition: atapi.h:49
UCHAR LimitedTransferMode
Definition: bsmaster.h:1172
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define IDE_STATUS_ERROR
Definition: atapi.h:125
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
#define IDX_IO1_i_Error
Definition: atapi.h:197
#define IDE_COMMAND_IDLE
Definition: atapi.h:398
MMRESULT FindDevices()
Definition: utils.c:159
#define IDE_COMMAND_SET_FEATURES
Definition: atapi.h:407
ULONG NumberLuns
Definition: bsmaster.h:1090
ULONG opt_PreferedTransferMode
Definition: bsmaster.h:1196
#define ATA_C_F_ENAB_WCACHE
Definition: atapi.h:564
VOID NTAPI IdeMediaStatus(BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_ata.cpp:9018
#define CHAR(Char)
#define ATA_WAIT_BASE_READY
Definition: bsmaster.h:62
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415
ULONG DiscsPresent
Definition: bsmaster.h:1165
UCHAR TransferMode
Definition: bsmaster.h:1171

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 3621 of file id_ata.cpp.

3625 {
3626  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3627  ULONG lChannel = GET_CHANNEL(Srb);
3628  PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3630  PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
3631 
3632  if (MechanismStatus) {
3633  LunExt->DiscsPresent = MechanismStatus->NumberAvailableSlots;
3634  if (LunExt->DiscsPresent > 1) {
3635  LunExt->DeviceFlags |= DFLAGS_ATAPI_CHANGER;
3636  }
3637  }
3638  return;
3639 } // end AtapiHwInitializeChanger()
#define DFLAGS_ATAPI_CHANGER
Definition: atapi.h:48
PHW_CHANNEL chan
Definition: bsmaster.h:1257
#define GET_CHANNEL(Srb)
Definition: bsmaster.h:1847
#define GET_CDEV(Srb)
Definition: bsmaster.h:1850
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
unsigned int ULONG
Definition: retypes.h:1
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1036
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
ULONG DiscsPresent
Definition: bsmaster.h:1165

Referenced by AtapiInterrupt__().

◆ AtapiInterrupt()

BOOLEAN NTAPI AtapiInterrupt ( IN PVOID  HwDeviceExtension)

Definition at line 3987 of file id_ata.cpp.

3990 {
3991  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3992  ULONG c, _c;
3993  BOOLEAN status = FALSE;
3994  ULONG c_state;
3995  ULONG i_res = 0;
3996  ULONG pass;
3997  //BOOLEAN checked[AHCI_MAX_PORT];
3998  ULONG hIS;
3999  ULONG checked;
4000 
4001  KdPrint2((PRINT_PREFIX "Intr: DeviceID+VendorID/Rev %#x/%#x (ex %d)\n",
4002  deviceExtension->DevID, deviceExtension->RevID, deviceExtension->ExpectingInterrupt ));
4003 
4004  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4005  // AHCI may generate state change notification, never skip this check
4006  hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
4007  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
4008  if(!hIS) {
4009  return FALSE;
4010  }
4011  // assume all non-interrupted ports to be already checked
4012  checked = ~hIS;
4013  // assume all not implemented ports to be already checked
4014  checked |= ~deviceExtension->AHCI_PI;
4015  } else {
4016  checked = 0; // assume all ports are not checked
4017  }
4018 
4019  if(!deviceExtension->ExpectingInterrupt) {
4020  // if we do not expect interrupt, exit now,
4021  // but keep in mind that it can be unexpected one
4022  // Note: this is just a hint, not exact counter
4023  KdPrint2((PRINT_PREFIX "unexpected, 1st chance\n"));
4024  //deviceExtension->ExpectingInterrupt++;
4025  //return FALSE;
4026  }
4027  // clear this flag now, it can be set again in sub-calls
4028  deviceExtension->ExpectingInterrupt=0;
4029 
4030 
4031 // for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
4032 // checked[_c] = (UCHAR)((hIS >> _c) & 0x01);
4033 // }
4034 
4035 // fc =
4036  for(pass=0; pass<2; pass++) {
4037  //KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): pass %d\n", pass));
4038  if(status && pass) {
4039  // we catched some expected interrupts now.
4040  // do not touch unexpected until next ISR call
4041  break;
4042  }
4043  for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
4044 
4045  c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
4046 
4047  if((checked>>c) & 0x01)
4048  continue;
4049 
4050  // check non-empty and expecting interrupt channels first
4051  if(!pass && !deviceExtension->chan[c].ExpectingInterrupt)
4052  continue;
4053 
4054  checked |= (ULONG)1 << c;
4055 
4056  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
4057 
4058  if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
4059  // we get here on idle channels or when ISR is posted to DPC
4060  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): disabled INTR on ch %d\n", c));
4061  continue;
4062  }
4063  // lock channel. Wait, while 2nd ISR checks interrupt on this channel
4064  do {
4065  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): try lock\n"));
4066  // c_state = deviceExtension->chan[c].CheckIntr;
4067  // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_DETECTED) {
4068  // deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE;
4069  // }
4070  c_state =
4071  (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4074  if(c_state == CHECK_INTR_IDLE) {
4075  // c_state = deviceExtension->chan[c].CheckIntr;
4076  // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_IDLE) {
4077  // deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE
4078  // }
4079  c_state =
4080  (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4083  }
4084  } while(c_state == CHECK_INTR_CHECK);
4085  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): locked\n"));
4086  // check if already serviced
4087  if(c_state == CHECK_INTR_ACTIVE) {
4088  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): CHECK_INTR_ACTIVE\n"));
4089  continue;
4090  }
4091 
4092  if((c_state == CHECK_INTR_DETECTED) ||
4093  (i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
4094 
4095  if(i_res == INTERRUPT_REASON_UNEXPECTED) {
4096  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): Catch unexpected\n"));
4097  InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4098  //return TRUE;
4099  status = TRUE;
4100  continue;
4101  }
4102  // disable interrupts on other channel of legacy mode
4103  // ISA-bridged onboard controller
4104  if(deviceExtension->simplexOnly /*||
4105  ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
4106  AtapiDisableInterrupts(deviceExtension, !c);
4107  }
4108 
4109  deviceExtension->chan[c].DpcState = DPC_STATE_ISR;
4110  if(AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
4111  deviceExtension->LastInterruptedChannel = (UCHAR)c;
4112  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): return status TRUE\n"));
4113  status = TRUE;
4114  } else {
4115  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE\n"));
4116  InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4117  }
4118 
4119  // re-enable interrupts on other channel
4120  if(deviceExtension->simplexOnly /*||
4121  ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
4122  AtapiEnableInterrupts(deviceExtension, !c);
4123  }
4124 
4125  } else {
4126  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE (2)\n"));
4127  InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4128  }
4129 
4130  }
4131  }
4132  KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): exit with status %#x\n", status));
4133  if(status) {
4134  deviceExtension->FirstChannelToCheck++;
4135  if(deviceExtension->FirstChannelToCheck >= deviceExtension->NumberChannels)
4136  deviceExtension->FirstChannelToCheck = 0;
4137  }
4138  return status;
4139 } // end AtapiInterrupt()
UCHAR LastInterruptedChannel
Definition: bsmaster.h:1259
#define TRUE
Definition: types.h:120
#define KdPrint2(_x_)
Definition: atapi.h:154
UCHAR DpcState
Definition: bsmaster.h:1030
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4351
BOOLEAN ExpectingInterrupt
Definition: bsmaster.h:1032
#define IDX_AHCI_IS
Definition: bsmaster.h:272
LONG DisableIntr
Definition: bsmaster.h:1061
PHW_CHANNEL chan
Definition: bsmaster.h:1257
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
#define CHECK_INTR_CHECK
Definition: bsmaster.h:1068
pass
Definition: typegen.h:24
#define CHECK_INTR_DETECTED
Definition: bsmaster.h:1067
#define DPC_STATE_ISR
Definition: bsmaster.h:1155
#define UniataAhciReadHostPort4(deviceExtension, io_port_ndx)
Definition: id_sata.h:313
unsigned char BOOLEAN
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4411
const GLubyte * c
Definition: glext.h:8905
BOOLEAN NTAPI AtapiCheckInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4466
unsigned char UCHAR
Definition: xmlstorage.h:181
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
LONG CheckIntr
Definition: bsmaster.h:1062
#define InterlockedExchange
Definition: armddk.h:54
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
#define INTERRUPT_REASON_UNEXPECTED
Definition: atapi.h:1282
#define PRINT_PREFIX
Definition: atapi.h:150
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define CHECK_INTR_ACTIVE
Definition: bsmaster.h:1066
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
static SERVICE_STATUS status
Definition: service.c:31
#define CRNT_ILK_PTYPE
Definition: config.h:104
ULONG NumberChannels
Definition: atapi.c:68
#define CRNT_ILK_TYPE
Definition: config.h:103
BOOLEAN NTAPI AtapiInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4935
Definition: ps.c:97

Referenced by DriverEntry().

◆ AtapiInterrupt2()

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

Definition at line 4146 of file id_ata.cpp.

4150 {
4151  // This ISR is intended to catch interrupts when we are already in other ISR instance
4152  // for the same device. This may happen when we have multiple channels,
4153  // especially on SMP machines
4154 
4155  PISR2_DEVICE_EXTENSION Isr2DeviceExtension = (PISR2_DEVICE_EXTENSION)Isr2HwDeviceExtension;
4156  PHW_DEVICE_EXTENSION deviceExtension = Isr2DeviceExtension->HwDeviceExtension;
4157  ULONG c;
4158  BOOLEAN status = FALSE;
4159  ULONG c_count = 0;
4160  ULONG i_res;
4161  ULONG hIS;
4162  ULONG checked;
4163 
4164  // we should never get here for ISA/MCA
4165  if(!BMList[deviceExtension->DevIndex].Isr2Enable) {
4166  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: NOT ACTIVE cntrlr %#x chan %#x\n",deviceExtension->DevIndex, deviceExtension->Channel));
4167  return FALSE;
4168  }
4169 
4170  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4171  // AHCI may generate state change notification, never skip this check
4172  hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
4173  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
4174  if(!hIS) {
4175  return FALSE;
4176  }
4177  // assume all non-interrupted ports to be already checked
4178  checked = ~hIS;
4179  // assume all not implemented ports to be already checked
4180  checked |= ~deviceExtension->AHCI_PI;
4181 
4182  } else {
4183  checked = 0; // assume all ports are not checked
4184  }
4185  if(!deviceExtension->ExpectingInterrupt) {
4186  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !deviceExtension->ExpectingInterrupt\n"));
4187  deviceExtension->ExpectingInterrupt++;
4188  return FALSE;
4189  }
4190  //deviceExtension->ExpectingInterrupt = 0;
4191 
4192  for(c=0; c<deviceExtension->NumberChannels; c++) {
4193  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
4194 
4195  if((checked>>c) & 0x01)
4196  continue;
4197 
4198  checked |= (ULONG)1 << c;
4199 
4200  if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
4201  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: disabled INTR\n"));
4202  continue;
4203  }
4204 
4205  if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4208  {
4209  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !CHECK_INTR_IDLE\n"));
4210  // hunt on unexpected intr (Some devices generate double interrupts,
4211  // some controllers (at least CMD649) interrupt twice with small delay.
4212  // If interrupts are disabled, they queue interrupt and re-issue it later,
4213  // when we do not expect it.
4214  continue;
4215  }
4216 
4217  c_count++;
4218  if((i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
4219 
4220  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: intr\n"));
4221  if(i_res == INTERRUPT_REASON_UNEXPECTED) {
4222  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: Catch unexpected\n"));
4223  InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4224  return TRUE;
4225  }
4226 
4227  status = TRUE;
4228  InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_DETECTED);
4229  } else {
4230  InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4231  }
4232  }
4233  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: status %d, c_count %d\n", status, c_count));
4234  if(status && (c_count != deviceExtension->NumberChannels)) {
4235  // there is an active ISR/DPC for one channel, but
4236  // we have an interrupt from another one
4237  // Lets inform current ISR/DPC about new interrupt
4238  InterlockedExchange(&(deviceExtension->ReCheckIntr), CHECK_INTR_DETECTED);
4239  } else {
4240  status = FALSE;
4241  }
4242  KdPrint2((PRINT_PREFIX "AtapiInterrupt2: return %d\n", status));
4243  return status;
4244 
4245 } // end AtapiInterrupt2()
#define TRUE
Definition: types.h:120
#define KdPrint2(_x_)
Definition: atapi.h:154
#define IDX_AHCI_IS
Definition: bsmaster.h:272
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
LONG DisableIntr
Definition: bsmaster.h:1061
PHW_CHANNEL chan
Definition: bsmaster.h:1257
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
#define CHECK_INTR_CHECK
Definition: bsmaster.h:1068
#define CHECK_INTR_DETECTED
Definition: bsmaster.h:1067
#define UniataAhciReadHostPort4(deviceExtension, io_port_ndx)
Definition: id_sata.h:313
unsigned char BOOLEAN
struct _ISR2_DEVICE_EXTENSION * PISR2_DEVICE_EXTENSION
const GLubyte * c
Definition: glext.h:8905
BOOLEAN NTAPI AtapiCheckInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4466
unsigned char UCHAR
Definition: xmlstorage.h:181
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
LONG CheckIntr
Definition: bsmaster.h:1062
#define InterlockedExchange
Definition: armddk.h:54
PHW_DEVICE_EXTENSION HwDeviceExtension
Definition: bsmaster.h:1351
#define INTERRUPT_REASON_UNEXPECTED
Definition: atapi.h:1282
#define PRINT_PREFIX
Definition: atapi.h:150
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
static SERVICE_STATUS status
Definition: service.c:31
#define CRNT_ILK_PTYPE
Definition: config.h:104
ULONG NumberChannels
Definition: atapi.c:68
#define CRNT_ILK_TYPE
Definition: config.h:103
Definition: ps.c:97

Referenced by UniataConnectIntr2().

◆ AtapiInterrupt__()

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

atapiDev &&

deviceExtension->DWordIO

Definition at line 4935 of file id_ata.cpp.

4939 {
4940  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4941  PHW_CHANNEL chan = &(deviceExtension->chan[c]);
4942  // Get current Srb
4944  PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
4945 
4946  ULONG wordCount = 0, wordsThisInterrupt = DEV_BSIZE/2;
4948  UCHAR dma_status = 0;
4949  ULONG i;
4950  ULONG k;
4951  UCHAR statusByte = 0,interruptReason;
4952 
4953  BOOLEAN atapiDev = FALSE;
4954 
4955 #ifdef _DEBUG
4956  UCHAR Channel;
4957 #endif //_DEBUG
4958  UCHAR lChannel;
4960  BOOLEAN DmaTransfer = FALSE;
4961  UCHAR error = 0;
4962  ULONG TimerValue = 1000;
4963  ULONG TotalTimerValue = 0;
4964 #ifdef UNIATA_USE_XXableInterrupts
4965  BOOLEAN InDpc = (KeGetCurrentIrql() == DISPATCH_LEVEL);
4966 #else
4967  BOOLEAN InDpc = (chan->DpcState != DPC_STATE_ISR);
4968 #endif // UNIATA_USE_XXableInterrupts
4969  BOOLEAN UseDpc = deviceExtension->UseDpc;
4970 // BOOLEAN RestoreUseDpc = FALSE;
4971  BOOLEAN DataOverrun = FALSE;
4972  BOOLEAN NoStartIo = TRUE;
4973  BOOLEAN NoRetry = FALSE;
4974 
4975  KdPrint2((PRINT_PREFIX "AtapiInterrupt:\n"));
4976  if(InDpc) {
4977  KdPrint2((PRINT_PREFIX " InDpc = TRUE\n"));
4978  //ASSERT((chan->ChannelCtrlFlags & CTRFLAGS_INTR_DISABLED));
4979  }
4980 
4981  UCHAR PathId;
4982  UCHAR TargetId;
4983  UCHAR Lun;
4984  UCHAR OldReqState = REQ_STATE_NONE;
4985  //ULONG ldev;
4986  PHW_LU_EXTENSION LunExt;
4987 
4988  lChannel = c;
4989 
4990 #ifdef _DEBUG
4991  Channel = (UCHAR)(deviceExtension->Channel + lChannel);
4992 
4993  KdPrint2((PRINT_PREFIX " cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c));
4994 #endif //_DEBUG
4995 
4996  if((chan->ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) ||
4997  (AtaReq && (AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) ||
4998  (deviceExtension->HwFlags & UNIATA_AHCI)) {
4999  DmaTransfer = TRUE;
5000  KdPrint2((PRINT_PREFIX " DmaTransfer = TRUE\n"));
5001  }
5002 
5003  if (srb) {
5004  PathId = srb->PathId;
5005  TargetId = srb->TargetId;
5006  Lun = srb->Lun;
5007  } else {
5008  PathId = (UCHAR)c;
5009  TargetId =
5010  Lun = 0;
5011  goto enqueue_next_req;
5012  }
5013 
5014  //ldev = GET_LDEV2(PathId, TargetId, Lun);
5016  LunExt = chan->lun[DeviceNumber];
5017  atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
5018  KdPrint2((PRINT_PREFIX " dev_type %s\n", atapiDev ? "ATAPI" : "IDE"));
5019 
5020  // check if we are in ISR DPC
5021  if(InDpc) {
5022  KdPrint2((PRINT_PREFIX " InDpc -> CTRFLAGS_INTR_DISABLED\n"));
5023  goto ServiceInterrupt;
5024  }
5025 
5026  if (DmaTransfer) {
5027  dma_status = GetDmaStatus(deviceExtension, lChannel);
5028  }
5029 
5030  if (!(chan->ExpectingInterrupt)) {
5031 
5032  KdPrint2((PRINT_PREFIX " Unexpected interrupt for this channel.\n"));
5033  return FALSE;
5034  }
5035 
5036  // change request state
5037  if(AtaReq) {
5038  OldReqState = AtaReq->ReqState;
5040  KdPrint2((PRINT_PREFIX " OldReqState = %x\n", OldReqState));
5041  }
5042 
5043  // We don't want using DPC for fast operations, like
5044  // DMA completion, sending CDB, short ATAPI transfers, etc.
5045  // !!!! BUT !!!!
5046  // We MUST use DPC, because of interprocessor synchronization
5047  // on multiprocessor platforms
5048 
5049  if(DmaTransfer)
5050  goto ServiceInterrupt;
5051 
5052  switch(OldReqState) {
5054  KdPrint3((PRINT_PREFIX " EXPECTING_CMD_INTR\n"));
5059  KdPrint2((PRINT_PREFIX " continue service interrupt\n"));
5060  goto ServiceInterrupt;
5062  KdPrint2((PRINT_PREFIX " do nothing on interrupt\n"));
5063  return TRUE;
5064  }
5065 
5066  if((!DmaTransfer && !atapiDev) || deviceExtension->DriverMustPoll) {
5067  KdPrint2((PRINT_PREFIX " service PIO HDD\n"));
5068  UseDpc = FALSE;
5069  }
5070 
5071 #ifndef UNIATA_CORE
5072 
5073  if(!UseDpc)
5074  goto ServiceInterrupt;
5075 
5076 #ifdef UNIATA_USE_XXableInterrupts
5077  if(InDpc) {
5078  KdPrint2((PRINT_PREFIX " Unexpected InDpc\n"));
5079  ASSERT(FALSE);
5080  // shall never get here
5081  TimerValue = 1;
5082  goto CallTimerDpc;
5083  }
5084 
5085  KdPrint2((PRINT_PREFIX " this is direct DPC call on DRQL\n"));
5086  if(AtaReq) {
5087  AtaReq->ReqState = REQ_STATE_DPC_INTR_REQ;
5088  KdPrint2((PRINT_PREFIX " ReqState -> REQ_STATE_DPC_INTR_REQ\n"));
5089  } else {
5090  KdPrint2((PRINT_PREFIX " DPC without AtaReq!!!\n"));
5091  }
5092 #else
5093  KdPrint2((PRINT_PREFIX "call service interrupt\n"));
5094  goto ServiceInterrupt;
5095 #endif // UNIATA_USE_XXableInterrupts
5096 
5097 PostToDpc:
5098 
5099  // Attention !!!
5100  // AtapiInterruptDpc() is called on DISPATCH_LEVEL
5101  // We always get here when are called from timer callback, which is invoked on DRQL.
5102  // It is intended to lower IRQL and let other interrupts to be serviced while we are waiting for BUSY release
5103 
5104  KdPrint2((PRINT_PREFIX "AtapiInterrupt: start DPC init...\n"));
5105  // disable interrupts for this channel,
5106  // but avoid recursion and double-disable
5107  if(OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5109  AtapiDisableInterrupts(deviceExtension, lChannel);
5110  }
5111  // go to ISR DPC
5113 
5114 #ifdef UNIATA_USE_XXableInterrupts
5115  // Will lower IRQL to DISPATCH_LEVEL
5116  ScsiPortNotification(CallEnableInterrupts, HwDeviceExtension,
5117  /*c ?*/ AtapiInterruptDpc/*_1 : AtapiInterruptDpc_0*/);
5118  KdPrint2((PRINT_PREFIX "AtapiInterrupt: DPC inited\n"));
5119 #else
5120  // Will raise IRQL to DIRQL
5121  AtapiQueueTimerDpc(HwDeviceExtension, c,
5123  TimerValue);
5124  KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
5125 #endif // UNIATA_USE_XXableInterrupts
5126  return TRUE;
5127 
5128 #ifndef UNIATA_CORE
5129 CallTimerDpc:
5131 CallTimerDpc2:
5132  if(!InDpc && OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5133  // we must block interrupts from this channel
5134  // If device generate new interrupt before we get to DPC,
5135  // ISR will assume, that it is NOT our interrupt
5136  AtapiDisableInterrupts(deviceExtension, lChannel);
5137  // We should not clean ExpectingInterrupt flag on channel, since it is used in DPC
5138  }
5139  // Will raise IRQL to DIRQL
5140  AtapiQueueTimerDpc(HwDeviceExtension, c,
5142  TimerValue);
5143  return TRUE;
5144 #endif //UNIATA_CORE
5145 
5146 ServiceInterrupt:
5147 
5148  if(AtaReq && InDpc) {
5149  switch(AtaReq->ReqState) {
5151  goto PIO_wait_DRQ0;
5153  goto PIO_wait_busy;
5155  goto PIO_wait_DRQ;
5157  goto continue_err;
5160  // continue normal execution
5161  break;
5162  }
5163  }
5164 #else
5165 ServiceInterrupt:
5166 #endif //UNIATA_CORE
5167 /*
5168  // make additional delay for old devices (if we are not in DPC)
5169  if((!LunExt->IdentifyData.MajorRevision || (deviceExtension->lun[DeviceNumber].TransferMode < ATA_PIO4))
5170  &&
5171  !InDpc &&
5172  !atapiDev &&
5173  !(deviceExtension->HwFlags & UNIATA_SATA)
5174  ) {
5175  KdPrint2((PRINT_PREFIX " additional delay 10us for old devices\n"));
5176  AtapiStallExecution(10);
5177  }
5178 */
5179 
5180  /* clear interrupt and get status */
5181  if(deviceExtension->HwFlags & UNIATA_AHCI) {
5182  UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, srb);
5183  statusByte = (UCHAR)(AtaReq->ahci.in_status & IDE_STATUS_MASK);
5184 
5186  KdPrint3((PRINT_PREFIX "Err intr (%#x), SE (%#x)\n",
5188  chan->AhciLastSError));
5189  if(chan->AhciLastIS & ~ATA_AHCI_P_IX_OF) {
5190 
5191  if((chan->AhciLastIS == ATA_AHCI_P_IX_INF) &&
5192  !(statusByte & IDE_STATUS_ERROR) &&
5193  !chan->AhciLastSError &&
5194  srb && (srb->SrbFlags & SRB_FLAGS_DATA_IN)
5195  ) {
5196  KdPrint3((PRINT_PREFIX "ATA_AHCI_P_IX_INF on READ, assume underflow\n"));
5197  // continue processing in regular way
5198  } else {
5199 
5200  //KdPrint3((PRINT_PREFIX "Err mask (%#x)\n", chan->AhciLastIS & ~ATA_AHCI_P_IX_OF));
5201  // We have some other error except Overflow
5202  // Just signal ERROR, operation will be aborted in ERROR branch.
5203  statusByte |= IDE_STATUS_ERROR;
5204  AtaReq->ahci.in_serror = chan->AhciLastSError;
5206  KdPrint2((PRINT_PREFIX "Unrecoverable\n"));
5207  NoRetry = TRUE;
5208  }
5209  }
5210  } else {
5211  // We have only Overflow. Abort operation and continue
5212 #ifdef _DEBUG
5213  UniataDumpAhciPortRegs(chan);
5214 #endif
5215  if(!UniataAhciAbortOperation(chan)) {
5216  KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5217  }
5218 #ifdef _DEBUG
5219  UniataDumpAhciPortRegs(chan);
5220 #endif
5221  UniataAhciWaitCommandReady(chan, 10);
5222  }
5223  }
5224 
5225  } else {
5226  GetBaseStatus(chan, statusByte);
5227  }
5228  if(atapiDev) {
5229  KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Entered with status (%#x)\n", statusByte));
5230  } else {
5231  KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte));
5232  }
5233 
5234  if(!UseDpc) {
5235  KdPrint2((PRINT_PREFIX " operate like in DPC\n"));
5236  InDpc = TRUE;
5237  }
5238 
5239  if (!atapiDev) {
5240  // IDE
5241  if(deviceExtension->HwFlags & UNIATA_AHCI) {
5242  KdPrint3((PRINT_PREFIX " AHCI branch (IDE)\n"));
5243  } else
5244  if (statusByte & IDE_STATUS_BUSY) {
5245  if (deviceExtension->DriverMustPoll) {
5246  // Crashdump is polling and we got caught with busy asserted.
5247  // Just go away, and we will be polled again shortly.
5248  KdPrint2((PRINT_PREFIX " Hit BUSY while polling during crashdump.\n"));
5249  goto ReturnEnableIntr;
5250  }
5251 try_dpc_wait:
5252  // Ensure BUSY is non-asserted.
5253  // make a very small idle before falling to DPC
5254  k = (InDpc && UseDpc) ? 1000 : 2;
5255 
5256  for (i = 0; i < k; i++) {
5257 
5258  GetBaseStatus(chan, statusByte);
5259  if (!(statusByte & IDE_STATUS_BUSY)) {
5260  break;
5261  }
5262  AtapiStallExecution(10);
5263  }
5264 
5265  if (!InDpc && UseDpc && i == 2) {
5266 
5267  KdPrint2((PRINT_PREFIX " BUSY on entry. Status %#x, Base IO %#x\n", statusByte));
5268 
5269  TimerValue = 50;
5271 
5272 #ifndef UNIATA_CORE
5273  goto PostToDpc;
5274 #else //UNIATA_CORE
5275  AtapiStallExecution(TimerValue);
5276  goto ServiceInterrupt;
5277 #endif //UNIATA_CORE
5278  } else
5279  if (InDpc && i == k) {
5280  // reset the controller.
5282  " Resetting due to BUSY on entry - %#x.\n",
5283  statusByte));
5284  goto IntrPrepareResetController;
5285  }
5286  }
5287  } else {
5288  // ATAPI
5289  if(!LunExt->IdentifyData.MajorRevision &&
5290  InDpc &&
5292  !(deviceExtension->HwFlags & UNIATA_SATA)
5293  ) {
5294  //KdPrint2((PRINT_PREFIX " additional delay 10us for old devices (2)\n"));
5295  //AtapiStallExecution(10);
5296  }
5297  if(deviceExtension->HwFlags & UNIATA_AHCI) {
5298  KdPrint3((PRINT_PREFIX " AHCI branch (ATAPI)\n"));
5299  } else {
5300  interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
5301  KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5302  }
5303 
5304  if (statusByte & IDE_STATUS_BUSY) {
5305  //if(chan->ChannelCtrlFlags & CTRFLAGS_DSC_BSY) {}
5306 /*
5307 #ifndef UNIATA_CORE
5308  // This is just workaround
5309  // We should DISABLE interrupts before entering WAIT state
5310  UniataExpectChannelInterrupt(chan, TRUE);
5311 #endif //UNIATA_CORE
5312 */
5313  KdPrint3((PRINT_PREFIX " BUSY on ATAPI device, waiting %d us\n", LunExt->AtapiReadyWaitDelay));
5314 #ifndef UNIATA_CORE
5315  if(LunExt->AtapiReadyWaitDelay && (LunExt->AtapiReadyWaitDelay > g_opt_MaxIsrWait) && !InDpc && UseDpc) {
5316  TimerValue = LunExt->AtapiReadyWaitDelay;
5317  KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC (0)\n"));
5319  goto CallTimerDpc2;
5320  }
5321 #endif //UNIATA_CORE
5322  TimerValue = 10;
5323  for(k=20; k; k--) {
5324  GetBaseStatus(chan, statusByte);
5325  KdPrint3((PRINT_PREFIX " status re-check %#x\n", statusByte));
5326  KdPrint3((PRINT_PREFIX " Error reg (%#x)\n",
5328  if (!(statusByte & IDE_STATUS_BUSY)) {
5329  KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
5330  break;
5331  }
5332  TotalTimerValue += TimerValue;
5333  if(k <= 1) {
5334  KdPrint3((PRINT_PREFIX " too long wait -> DPC\n"));
5335  if(!InDpc) {
5336  KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC\n"));
5337  TimerValue = 100;
5339  } else {
5340  KdPrint2((PRINT_PREFIX " too long wait: DPC -> DPC\n"));
5341  TimerValue = 1000;
5343  }
5344 #ifndef UNIATA_CORE
5345  if(UseDpc) {
5346  if(!LunExt->AtapiReadyWaitDelay) {
5347  LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5348  }
5349  goto CallTimerDpc2;
5350  }
5351 #endif //UNIATA_CORE
5352  }
5353 
5354  AtapiStallExecution(TimerValue);
5355  TimerValue += 10;
5356  }
5357  if(!LunExt->AtapiReadyWaitDelay) {
5358  LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5359  KdPrint2((PRINT_PREFIX " store AtapiReadyWaitDelay: %d\n", LunExt->AtapiReadyWaitDelay));
5360  }
5361  if (statusByte & IDE_STATUS_BUSY) {
5362  KdPrint3((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n"));
5363  goto try_dpc_wait;
5364  }
5365  }
5366  }
5367 
5368  if(AtaReq && DmaTransfer && !(deviceExtension->HwFlags & UNIATA_AHCI)) {
5369  switch(OldReqState) {
5370  case REQ_STATE_EARLY_INTR:
5372 
5374  KdPrint2((PRINT_PREFIX "AtapiInterrupt: DMA still active\n"));
5375  dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5376  }
5377  break;
5378  }
5379  }
5380 
5381 //retry_check:
5382  // Check for error conditions.
5383  if ((statusByte & IDE_STATUS_ERROR) ||
5384  (dma_status & BM_STATUS_ERR)) {
5385 
5386  if(deviceExtension->HwFlags & UNIATA_AHCI) {
5387  error = AtaReq->ahci.in_error;
5388  // wait ready
5389 #ifdef _DEBUG
5390  UniataDumpAhciPortRegs(chan);
5391 #endif
5392  if(!UniataAhciAbortOperation(chan)) {
5393  KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5394  }
5395  // clear interrupts again
5396  UniataAhciWaitCommandReady(chan, 10);
5397 #ifdef _DEBUG
5398  UniataDumpAhciPortRegs(chan);
5399 #endif
5400  UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
5401  if(NoRetry) {
5402  AtaReq->retry += MAX_RETRIES;
5403  if(!error && (statusByte & IDE_STATUS_ERROR)) {
5404  KdPrint2((PRINT_PREFIX "AtapiInterrupt: force error status\n"));
5406  }
5407  }
5408 #ifdef _DEBUG
5409  UniataDumpAhciPortRegs(chan);
5410 #endif
5411  } else {
5413  }
5414  KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error %#x\n", error));
5415 /*
5416  if(error & IDE_STATUS_CORRECTED_ERROR) {
5417  KdPrint2((PRINT_PREFIX "AtapiInterrupt: (corrected)\n"));
5418  statusByte &= ~IDE_STATUS_ERROR;
5419  goto retry_check;
5420  }
5421 */
5422  if(AtaReq) {
5423  KdPrint2((PRINT_PREFIX " Bad Lba %#I64x\n", AtaReq->lba));
5424  } else {
5425  KdPrint2((PRINT_PREFIX " Bad Lba unknown\n"));
5426  }
5427 
5428  if(deviceExtension->HwFlags & UNIATA_AHCI) {
5429  KdPrint2((PRINT_PREFIX " no wait ready after error\n"));
5430  } else
5431  if(!atapiDev) {
5432  KdPrint2((PRINT_PREFIX " wait 100 ready after IDE error\n"));
5433  AtapiStallExecution(100);
5434  } else {
5435  KdPrint2((PRINT_PREFIX " wait 10 ready after ATAPI error\n"));
5436  AtapiStallExecution(10);
5437  }
5438 continue_err:
5439 
5440  KdPrint3((PRINT_PREFIX " Intr on DRQ %x\n",
5441  LunExt->DeviceFlags & DFLAGS_INT_DRQ));
5442 
5443  for (k = atapiDev ? 0 : 200; k; k--) {
5444  GetBaseStatus(chan, statusByte);
5445  if (!(statusByte & IDE_STATUS_DRQ)) {
5446  AtapiStallExecution(50);
5447  } else {
5448  break;
5449  }
5450  }
5451 
5452  if (!atapiDev) {
5453  /* if this is a UDMA CRC error, reinject request */
5454 
5455  AtaReq->retry++;
5456  if(AtaReq->retry < MAX_RETRIES) {
5457 #ifdef IO_STATISTICS
5458  chan->lun[DeviceNumber]->ModeErrorCount[AtaReq->retry]++;
5459 #endif //IO_STATISTICS
5460  if(DmaTransfer /*&&
5461  (error & IDE_ERROR_ICRC)*/) {
5462  KdPrint2((PRINT_PREFIX "Errors in DMA mode\n"));
5463  if(AtaReq->retry < MAX_RETRIES) {
5464 //fallback_pio:
5465  if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
5466  //AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5467  // Downrate will happen in AtapiDmaReinit(), try UDMA-2 for HDD only
5468  AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5469  }
5470  AtaReq->ReqState = REQ_STATE_QUEUED;
5471  goto reenqueue_req;
5472  }
5473  } else {
5474  if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5475  AtaReq->retry++;
5476  }
5477  KdPrint2((PRINT_PREFIX "Errors in PIO mode\n"));
5478  }
5479  }
5480  } else {
5481  interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
5482  KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
5483 
5484  if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
5485  if(deviceExtension->HwFlags & UNIATA_AHCI) {
5486  // Do nothing here
5487  } else
5488  if(deviceExtension->HwFlags & UNIATA_SATA) {
5489  UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, 0);
5490  }
5491  }
5492 
5493  if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
5494  ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
5495  if(AtaReq->retry < MAX_RETRIES) {
5496 //fallback_pio:
5497  // Downrate will happen in AtapiDmaReinit(), use PIO immediately for ATAPI
5498  AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5499  AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5500 // LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
5501  AtaReq->ReqState = REQ_STATE_QUEUED;
5502  goto reenqueue_req;
5503  }
5504  } else {
5505  if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5506  AtaReq->retry++;
5507  }
5508  KdPrint3((PRINT_PREFIX "Errors in PIO mode\n"));
5509  }
5510  }
5511 
5512  KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error\n"));
5513  if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
5514  // Fail this request.
5516  goto CompleteRequest;
5517  } else {
5518  KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n"));
5519  }
5520  } else
5521  if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE_LBA48) {
5522  KdPrint2((PRINT_PREFIX "DMA doesn't work right with LBA48\n"));
5523  deviceExtension->HbaCtrlFlags |= HBAFLAGS_DMA_DISABLED_LBA48;
5524  } else
5525  if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
5526 #ifdef IO_STATISTICS
5527  KdPrint2((PRINT_PREFIX "Some higher mode doesn't work right :((\n"));
5528  KdPrint2((PRINT_PREFIX "Recovery stats[%d]: %d vs %d\n",
5529  AtaReq->retry,
5530  LunExt->RecoverCount[AtaReq->retry],
5531  LunExt->BlockIoCount
5532  ));
5533  LunExt->RecoverCount[AtaReq->retry]++;
5534  if(LunExt->RecoverCount[AtaReq->retry] >= LunExt->BlockIoCount/3 ||
5535  (deviceExtension->HwFlags & UNIATA_NO80CHK)
5536  ) {
5537 #else
5538  if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
5539 #endif //IO_STATISTICS
5540  KdPrint2((PRINT_PREFIX "Limit transfer rate to %x\n", LunExt->TransferMode));
5541  LunExt->LimitedTransferMode =
5542  LunExt->TransferMode;
5543  }
5544  }
5545 #ifdef IO_STATISTICS
5546  if(AtaReq->bcount) {
5547  // we need stats for Read/Write operations
5548  LunExt->BlockIoCount++;
5549  }
5550  LunExt->IoCount++;
5551 #endif //IO_STATISTICS
5552 
5553 continue_PIO:
5554 
5555  // check reason for this interrupt.
5556  if (atapiDev) {
5557 
5558  KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
5559  // ATAPI branch
5560 
5561  interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
5562  KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5563  if(DmaTransfer) {
5564  wordsThisInterrupt = DEV_BSIZE/2*512;
5565  } else {
5566  wordsThisInterrupt = DEV_BSIZE/2;
5567  }
5568 
5569  } else {
5570 
5571  // ATA branch
5572 
5573  if(DmaTransfer) {
5574  // simulate DRQ for DMA transfers
5575  statusByte |= IDE_STATUS_DRQ;
5576  }
5577  if (statusByte & IDE_STATUS_DRQ) {
5578 
5579  if(DmaTransfer) {
5580  wordsThisInterrupt = DEV_BSIZE/2*512;
5581  } else
5582  if (LunExt->MaximumBlockXfer) {
5583  wordsThisInterrupt = DEV_BSIZE/2 * LunExt->MaximumBlockXfer;
5584  }
5585 
5586  if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5587 
5588  interruptReason = ATAPI_IR_IO_toHost;
5589 
5590  } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5591  interruptReason = ATAPI_IR_IO_toDev;
5592 
5593  } else {
5595  goto CompleteRequest;
5596  }
5597 
5598  } else if (statusByte & IDE_STATUS_BUSY) {
5599 
5600  //AtapiEnableInterrupts(deviceExtension, lChannel);
5601  KdPrint2((PRINT_PREFIX "AtapiInterrupt: return FALSE on ATA IDE_STATUS_BUSY\n"));
5602  return FALSE;
5603 
5604  } else {
5605 
5606  KdPrint2((PRINT_PREFIX "AtapiInterrupt: !DRQ, !BUSY, WordsLeft %#x\n", AtaReq->WordsLeft));
5607  if (AtaReq->WordsLeft) {
5608 
5609  // Funky behaviour seen with PCI IDE (not all, just one).
5610 PIO_wait_DRQ0:
5611  // The ISR hits with DRQ low, but comes up later.
5612  for (k = 0; k < 5000; k++) {
5613  GetBaseStatus(chan, statusByte);
5614  if (statusByte & IDE_STATUS_DRQ) {
5615  break;
5616  }
5617  if(!InDpc) {
5618  // goto DPC
5620  TimerValue = 100;
5621  KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq0)\n"));
5622 #ifndef UNIATA_CORE
5623  goto PostToDpc;
5624 #else //UNIATA_CORE
5625  AtapiStallExecution(TimerValue);
5626  goto ServiceInterrupt;
5627 #endif //UNIATA_CORE
5628  }
5629  AtapiStallExecution(100);
5630  }
5631  if (k == 5000) {
5632  // reset the controller.
5633  KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ not up. Status %#x\n",
5634  statusByte));
5635 IntrPrepareResetController:
5636  AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_CURRENT);
5637  goto ReturnEnableIntr;
5638 
5639  } else {
5640  interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? ATAPI_IR_IO_toHost : ATAPI_IR_IO_toDev;
5641  }
5642 
5643  } else {
5644  // Command complete - verify, write, or the SMART enable/disable.
5645  // Also get_media_status
5646  interruptReason = ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd;
5647  }
5648  }
5649  }
5650 
5651  KdPrint2((PRINT_PREFIX "AtapiInterrupt: i-reason=%d, status=%#x\n", interruptReason, statusByte));
5652  if(deviceExtension->HwFlags & UNIATA_AHCI) {
5653  KdPrint2((PRINT_PREFIX " AHCI path, WordsTransfered %x, WordsLeft %x\n", AtaReq->WordsTransfered, AtaReq->WordsLeft));
5654 /* if(chan->AhciLastIS & ATA_AHCI_P_IX_OF) {
5655  //status = SRB_STATUS_DATA_OVERRUN;
5656  DataOverrun = TRUE;
5657  } else {
5658  status = SRB_STATUS_SUCCESS;
5659  }*/
5660  if(AtaReq->WordsTransfered >= AtaReq->WordsLeft) {
5661  AtaReq->WordsLeft = 0;
5662  } else {
5663  AtaReq->WordsLeft -= AtaReq->WordsTransfered;
5664  }
5665  //if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
5666  // status = SRB_STATUS_DATA_OVERRUN;
5667  //}
5670  goto CompleteRequest;
5671  } else
5672  if ((interruptReason == ATAPI_IR_COD_Cmd) && (statusByte & IDE_STATUS_DRQ)) {
5674  AtapiDmaDBPreSync(HwDeviceExtension, chan, srb);
5675  }
5676  // Write the packet.
5677  KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
5678  // Send CDB to device.
5679  WriteBuffer(chan, (PUSHORT)srb->Cdb,
5680  LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
5681  /*0*/ PIO0_TIMING);
5683 
5685  KdPrint2((PRINT_PREFIX "AtapiInterrupt: AtapiDmaStart().\n"));
5686  AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, srb);
5687  }
5688 
5689  goto ReturnEnableIntr;
5690 
5691  } else if ((interruptReason == ATAPI_IR_IO_toDev) && (statusByte & IDE_STATUS_DRQ)) {
5692 
5693  // Write the data.
5694  if (atapiDev) {
5695 
5696  // Pick up bytes to transfer and convert to words.
5697  wordCount =
5699 
5700  wordCount |=
5702 
5703  // Covert bytes to words.
5704  wordCount >>= 1;
5705  KdPrint2((PRINT_PREFIX "AtapiInterrupt: get W wordCount %#x\n", wordCount));
5706 
5707  if (wordCount != AtaReq->WordsLeft) {
5709  "AtapiInterrupt: %d words requested; %d words xferred\n",
5710  AtaReq->WordsLeft,
5711  wordCount));
5712  }
5713 
5714  // Verify this makes sense.
5715  if (wordCount > AtaReq->WordsLeft) {
5716  wordCount = AtaReq->WordsLeft;
5718  "AtapiInterrupt: Write underrun\n"));
5719  DataOverrun = TRUE;
5720  }
5721 
5722  } else {
5723 
5724  // IDE path. Check if words left is at least DEV_BSIZE/2 = 256.
5725  if (AtaReq->WordsLeft < wordsThisInterrupt) {
5726  // Transfer only words requested.
5727  wordCount = AtaReq->WordsLeft;
5728  } else {
5729  // Transfer next block.
5730  wordCount = wordsThisInterrupt;
5731  }
5732  }
5733 
5734  if (DmaTransfer &&
5736  //ASSERT(AtaReq->WordsLeft == wordCount);
5739  "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5740  if(AtaReq->WordsLeft > wordCount) {
5741  AtaReq->WordsLeft -= wordCount;
5742  AtaReq->WordsTransfered += wordCount;
5744  goto ReturnEnableIntr;
5745  }
5746  dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5747  }
5748  AtaReq->WordsTransfered = AtaReq->WordsLeft;
5749  AtaReq->WordsLeft = 0;
5752  goto CompleteRequest;
5753  }
5754 
5755  // Ensure that this is a write command.
5756  if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5757 
5759  "AtapiInterrupt: Write interrupt\n"));
5760 
5761  statusByte = WaitOnBusy(chan);
5762 
5763  if (/*atapiDev || */ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED)
5764  || (wordCount & 1)) {
5765 
5766  WriteBuffer(chan,
5767  AtaReq->DataBuffer,
5768  wordCount,
5769  UniataGetPioTiming(LunExt));
5770  } else {
5771 
5772  WriteBuffer2(chan,
5773  (PULONG)(AtaReq->DataBuffer),
5774  wordCount / 2,
5775  UniataGetPioTiming(LunExt));
5776  }
5777  } else {
5778 
5780  "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5781  interruptReason,
5782  srb));
5783 
5784  // Fail this request.
5786  if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) {
5787  // some devices feel bad after incorrect commands and may need reset
5789  "AtapiInterrupt: Try ATAPI reset\n"));
5790 
5791  AtapiDisableInterrupts(deviceExtension, lChannel);
5793  AtapiEnableInterrupts(deviceExtension, lChannel);
5796 
5797 // goto IntrPrepareResetController;
5798  }
5799  goto CompleteRequest;
5800  }
5801  // Advance data buffer pointer and bytes left.
5802  AtaReq->DataBuffer += wordCount;
5803  AtaReq->WordsLeft -= wordCount;
5804  AtaReq->WordsTransfered += wordCount;
5805 
5806  if (atapiDev) {
5808  }
5809 
5810  goto ReturnEnableIntr;
5811 
5812  } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) {
5813 
5814 continue_read_drq:
5815 
5816  if (atapiDev) {
5817 
5818  // Pick up bytes to transfer and convert to words.
5819  wordCount =
5822 
5823  // Convert bytes to words.
5824  KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R byteCount %#x\n", wordCount));
5825  wordCount >>= 1;
5826  /*
5827  When ATAPI 64k PIO read is requested we may have 0xfffe byte
5828  count reported for 0x10000 bytes in single interrupt.
5829  It is not allowed to read entire 64k block with DwordIo intead of
5830  wait for last word.
5831  */
5832  if (wordCount != AtaReq->WordsLeft) {
5834  "AtapiInterrupt: %d words requested; %d words xferred\n",
5835  AtaReq->WordsLeft,
5836  wordCount));
5837  }
5838 
5839  // Verify this makes sense.
5840  if (wordCount > AtaReq->WordsLeft) {
5841  wordCount = AtaReq->WordsLeft;
5842  DataOverrun = TRUE;
5843  }
5844 
5845  } else {
5846 
5847  // Check if words left is at least 256.
5848  if (AtaReq->WordsLeft < wordsThisInterrupt) {
5849  // Transfer only words requested.
5850  wordCount = AtaReq->WordsLeft;
5851  } else {
5852  // Transfer next block.
5853  wordCount = wordsThisInterrupt;
5854  }
5855  }
5856 
5857  if(DmaTransfer &&
5861  "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5862  if(AtaReq->WordsLeft > wordCount) {
5863  AtaReq->WordsLeft -= wordCount;
5864  AtaReq->WordsTransfered += wordCount;
5866  goto ReturnEnableIntr;
5867  }
5868  dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5869  }
5870  //ASSERT(AtaReq->WordsLeft == wordCount);
5871  AtaReq->WordsTransfered = AtaReq->WordsLeft;
5872  AtaReq->WordsLeft = 0;
5875  goto CompleteRequest;
5876  }
5877  // Ensure that this is a read command.
5878  if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5879 
5880 /* KdPrint2((
5881  "AtapiInterrupt: Read interrupt\n"));*/
5882 
5883  statusByte = WaitOnBusy(chan);
5884 
5885  if(wordCount&1 && atapiDev && (g_opt_VirtualMachine == VM_BOCHS)) {
5887  "IdeIntr: unaligned ATAPI %#x Words\n", wordCount));
5888  } else
5889  if(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) {
5891  "IdeIntr: pre-Read %#x Dwords\n", wordCount/2));
5892 
5893  ReadBuffer2(chan,
5894  (PULONG)(AtaReq->DataBuffer),
5895  wordCount / 2,
5896  UniataGetPioTiming(LunExt));
5897  // Advance data buffer pointer and bytes left.
5898  AtaReq->DataBuffer += wordCount & ~1;
5899  AtaReq->WordsLeft -= wordCount & ~1;
5900  AtaReq->WordsTransfered += wordCount & ~1;
5901  wordCount &= 1;
5902  }
5903  if (wordCount) {
5905  "IdeIntr: Read %#x words\n", wordCount));
5906 
5907  ReadBuffer(chan,
5908  AtaReq->DataBuffer,
5909  wordCount,
5910  UniataGetPioTiming(LunExt));
5911  }
5912 
5913  KdPrint2(("IdeIntr: PIO Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x\n", AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)-1) ));
5914  //KdDump(AtaReq->DataBuffer, wordCount*2);
5915  if(srb && atapiDev && srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
5916  KdDump(AtaReq->DataBuffer, wordCount*2);
5917  }
5918 
5919  GetBaseStatus(chan, statusByte);
5920  KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
5921 
5922  if(DataOverrun) {
5923  KdPrint2((PRINT_PREFIX " DataOverrun\n"));
5924  AtapiSuckPort2(chan);
5925  GetBaseStatus(chan, statusByte);
5926  }
5927 
5928  if(statusByte & IDE_STATUS_BUSY) {
5929  for (i = 0; i < 2; i++) {
5930  AtapiStallExecution(10);
5931  GetBaseStatus(chan, statusByte);
5932  if (!(statusByte & IDE_STATUS_BUSY)) {
5933  break;
5934  }
5935  }
5936  }
5937 
5938  } else {
5939 
5941  "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5942  interruptReason,
5943  srb));
5944 
5945  // Fail this request.
5947  goto CompleteRequest;
5948  }
5949 //continue_atapi_pio_read:
5950  // Advance data buffer pointer and bytes left.
5951  AtaReq->DataBuffer += wordCount;
5952  AtaReq->WordsLeft -= wordCount;
5953  AtaReq->WordsTransfered += wordCount;
5954 
5955  // Check for read command complete.
5956  if (AtaReq->WordsLeft == 0) {
5957 
5958  KdPrint2((PRINT_PREFIX "AtapiInterrupt: all transferred, AtaReq->WordsLeft == 0\n"));
5959  if (atapiDev) {
5960 
5961  if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM) {
5962 
5963  // Work around to make many atapi devices return correct sector size
5964  // of 2048. Also certain devices will have sector count == 0x00, check
5965  // for that also.
5966  if (srb->Cdb[0] == SCSIOP_READ_CAPACITY) {
5967 
5968  AtaReq->DataBuffer -= AtaReq->WordsTransfered;
5969  if (AtaReq->DataBuffer[0] == 0x00) {
5970  *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F;
5971  }
5972 
5973  *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000;
5974  AtaReq->DataBuffer += AtaReq->WordsTransfered;
5975  }
5976 #ifndef UNIATA_INIT_CHANGERS
5977  else
5978  if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
5979 
5980  KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
5981  // Bingo!!
5982  AtapiHwInitializeChanger (HwDeviceExtension,
5983  srb,
5986  KdPrint2((PRINT_PREFIX " set DFLAGS_CHANGER_INITED\n"));
5987  }
5988 #endif // UNIATA_INIT_CHANGERS
5989  }
5990  GetStatus(chan, statusByte);
5991  if(!(statusByte & IDE_STATUS_BUSY)) {
5992  // Assume command is completed if BUSY is cleared
5993  // and all data read
5994  // Optionally, we may receive COMPLETE interrupt later and
5995  // treat it as unexpected
5996  KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete ? status %x\n", statusByte));
5997 
5999  goto CompleteRequest;
6000  }
6001 
6002  } else {
6003 
6004  /*
6005  // Completion for IDE drives.
6006  if (AtaReq->WordsLeft) {
6007  status = SRB_STATUS_DATA_OVERRUN;
6008  } else {
6009  status = SRB_STATUS_SUCCESS;
6010  }
6011 
6012  goto CompleteRequest;
6013  */
6015  goto CompleteRequest;
6016 
6017  }
6018  } else {
6019  if (atapiDev) {
6021  GetStatus(chan, statusByte);
6022  if(!(statusByte & IDE_STATUS_BUSY)) {
6023  // Assume command is completed if BUSY is cleared
6024  // even if NOT all data read
6025  // Optionally, we may receive COMPLETE interrupt later and
6026  // treat it as unexpected
6027  KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete + underrun ? status %x\n", statusByte));
6028 
6030  goto CompleteRequest;
6031  }
6032  } else {
6033  if(!atapiDev && !DataOverrun && (srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
6034  ((statusByte & ~IDE_STATUS_INDEX) == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) {
6035  KdPrint2((PRINT_PREFIX " HDD read data ready \n"));
6036  goto continue_read_drq;
6037  }
6038  }
6039  }
6040 
6041  goto ReturnEnableIntr;
6042 
6043  } else if (interruptReason == (ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd) && !(statusByte & IDE_STATUS_DRQ)) {
6044 
6045  KdPrint2((PRINT_PREFIX "AtapiInterrupt: interruptReason = CompleteRequest\n"));
6046  // Command complete. We exactly know this because of IReason.
6047 
6048  if(DmaTransfer) {
6049  KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was DmaTransfer\n"));
6050  AtaReq->WordsTransfered += AtaReq->WordsLeft;
6051  AtaReq->WordsLeft = 0;
6052  } else {
6053  KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was PIO\n"));
6054 
6055  wordCount = AtaReq->WordsLeft;
6056  // Advance data buffer pointer and bytes left.
6057  AtaReq->DataBuffer += wordCount;
6058  AtaReq->WordsLeft -= wordCount;
6059  AtaReq->WordsTransfered += wordCount;
6060 
6061  KdPrint2((PRINT_PREFIX "AtapiInterrupt: wordCount %#x, WordsTransfered %#x\n", wordCount, AtaReq->WordsTransfered));
6062 
6063  }
6064  //if (AtaReq->WordsLeft) {
6065  // status = SRB_STATUS_DATA_OVERRUN;
6066  //} else {
6068  //}
6069 
6070 #ifdef UNIATA_DUMP_ATAPI
6071  if(srb &&
6072  srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6073  UCHAR ScsiCommand;
6074  PCDB Cdb;
6075  PCHAR CdbData;
6076  PCHAR ModeSelectData;
6077  ULONG CdbDataLen;
6078  PSCSI_REQUEST_BLOCK Srb = srb;
6079 
6080  Cdb = (PCDB)(Srb->Cdb);
6081  ScsiCommand = Cdb->CDB6.OperationCode;
6082  CdbData = (PCHAR)(Srb->DataBuffer);
6083  CdbDataLen = Srb->DataTransferLength;
6084 
6085  if(CdbDataLen > 0x1000) {
6086  CdbDataLen = 0x1000;
6087  }
6088 
6089  KdPrint(("--\n"));
6090  KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
6091  KdPrint2(("P:T:D=%d:%d:%d\n",
6092  Srb->PathId,
6093  Srb->TargetId,
6094  Srb->Lun));
6095  KdPrint(("Complete SCSI Command %2.2x\n", ScsiCommand));
6096  KdDump(Cdb, 16);
6097 
6098  if(ScsiCommand == SCSIOP_MODE_SENSE) {
6099  KdPrint(("ModeSense 6\n"));
6100  PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
6101  ModeSelectData = CdbData+4;
6102  KdDump(CdbData, CdbDataLen);
6103  } else
6104  if(ScsiCommand == SCSIOP_MODE_SENSE10) {
6105  KdPrint(("ModeSense 10\n"));
6106  PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
6107  ModeSelectData = CdbData+8;
6108  KdDump(CdbData, CdbDataLen);
6109  } else {