ReactOS  0.4.15-dev-3295-gaa8fc87
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:39
if(dx==0 &&dy==0)
Definition: linetemp.h:174
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
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:39
if(dx==0 &&dy==0)
Definition: linetemp.h:174
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
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:39
if(dx==0 &&dy==0)
Definition: linetemp.h:174
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
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 11684 of file id_ata.cpp.

◆ ITEMS_TO_QUERY [1/2]

#define ITEMS_TO_QUERY   2

◆ ITEMS_TO_QUERY [2/2]

#define ITEMS_TO_QUERY   2

◆ RESET_COMPLETE_ALL

#define RESET_COMPLETE_ALL   0x01

Definition at line 144 of file id_ata.cpp.

◆ RESET_COMPLETE_CURRENT

#define RESET_COMPLETE_CURRENT   0x00

Definition at line 143 of file id_ata.cpp.

◆ RESET_COMPLETE_NONE

#define RESET_COMPLETE_NONE   0x02

Definition at line 145 of file id_ata.cpp.

◆ RETTYPE_XXableInterrupts

#define RETTYPE_XXableInterrupts   VOID

Definition at line 159 of file id_ata.cpp.

◆ RETVAL_XXableInterrupts

#define RETVAL_XXableInterrupts

Definition at line 160 of file id_ata.cpp.

◆ SetCheckPoint

#define SetCheckPoint (   cp)

Definition at line 8228 of file id_ata.cpp.

Function Documentation

◆ _PrintNtConsole()

VOID _cdecl _PrintNtConsole ( PCCH  DebugMessage,
  ... 
)

Definition at line 11689 of file id_ata.cpp.

11693 {
11694  //int len;
11695  UCHAR dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE];
11696 // UNICODE_STRING msgBuff;
11697  va_list ap;
11698  va_start(ap, DebugMessage);
11699 
11700  /*len =*/ _vsnprintf((PCHAR)&dbg_print_tmp_buff[0], DEBUG_MSG_BUFFER_SIZE-1, DebugMessage, ap);
11701 
11702  dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE-1] = 0;
11703 
11704  //DbgPrint(((PCHAR)&(dbg_print_tmp_buff[0]))); // already done in KdPrint macro
11705  HalDisplayString(dbg_print_tmp_buff);
11706 
11707 #ifdef _DEBUG
11708  if(g_LogToDisplay > 1) {
11710  }
11711 #endif // _DEBUG
11712 
11713  va_end(ap);
11714 
11715 } // end PrintNtConsole()
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
va_start(ap, x)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DEBUG_MSG_BUFFER_SIZE
Definition: id_ata.cpp:11684
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 1168 of file id_ata.cpp.

1180 {
1181  if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
1182  return AtaCommand48(deviceExtension, DeviceNumber, lChannel,
1183  command,
1184  (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1185  count, feature, wait_flags);
1186  } else {
1187  return UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
1189  NULL,
1190  0,
1191  command,
1192  (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1193  count,
1194  feature,
1195  0 /* ahci flags */ ,
1196  wait_flags,
1197  1000 /* timeout 1 sec */
1198  );
1199 
1200  }
1201 } // end AtaCommand()
INTERNETFEATURELIST feature
Definition: misc.c:1719
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:968
GLUquadricObj * cylinder
Definition: cylfrac.c:44
#define UNIATA_AHCI
Definition: bm_devs_decl.h:630
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
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 968 of file id_ata.cpp.

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

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

◆ AtapiAdapterControl()

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

Definition at line 11585 of file id_ata.cpp.

11590 {
11591  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11592  PSCSI_SUPPORTED_CONTROL_TYPE_LIST pControlTypeList;
11593  ULONG numberChannels = deviceExtension->NumberChannels;
11594  ULONG c;
11595  NTSTATUS status;
11596 
11597  KdPrint(( "AtapiAdapterControl: %#x\n", ControlType));
11598 
11599  switch(ControlType) {
11601  BOOLEAN supportedTypes[ScsiAdapterControlMax] = {
11602  TRUE, // ScsiQuerySupportedControlTypes
11603  TRUE, // ScsiStopAdapter
11604  TRUE, // ScsiRestartAdapter
11605  FALSE, // ScsiSetBootConfig
11606  FALSE // ScsiSetRunningConfig
11607  };
11608 
11610  ULONG i;
11611 
11612  pControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST) Parameters;
11613 
11614  if(pControlTypeList->MaxControlType < lim) {
11615  lim = pControlTypeList->MaxControlType;
11616  }
11617 
11618  for(i = 0; i < lim; i++) {
11619  pControlTypeList->SupportedTypeList[i] = supportedTypes[i];
11620  }
11621 
11622  break;
11623 
11624  }
11625  case ScsiStopAdapter: {
11626 
11627  KdPrint(( "AtapiAdapterControl: ScsiStopAdapter\n"));
11628  // Shut down all interrupts on the adapter. They'll get re-enabled
11629  // by the initialization routines.
11630  for (c = 0; c < numberChannels; c++) {
11631  AtapiResetController(deviceExtension, c);
11632  AtapiDisableInterrupts(deviceExtension, c);
11633  }
11634  if(deviceExtension->AdapterInterfaceType == PCIBus) {
11635  // we must never get here for non-PCI
11636  /*status =*/ UniataDisconnectIntr2(HwDeviceExtension);
11637  BMList[deviceExtension->DevIndex].Isr2Enable = FALSE;
11638  }
11639  break;
11640  }
11641  case ScsiRestartAdapter: {
11642 
11643  KdPrint(( "AtapiAdapterControl: ScsiRestartAdapter\n"));
11644  // Enable all the interrupts on the adapter while port driver call
11645  // for power up an HBA that was shut down for power management
11646 
11648  status = UniataConnectIntr2(HwDeviceExtension);
11649  if(NT_SUCCESS(status)) {
11650  for (c = 0; c < numberChannels; c++) {
11651  AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, c);
11652  FindDevices(HwDeviceExtension, 0, c);
11653  AtapiEnableInterrupts(deviceExtension, c);
11654  AtapiHwInitialize__(deviceExtension, c);
11655  }
11656  if(deviceExtension->Isr2DevObj) {
11657  // we must never get here for non-PCI
11658  BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
11659  }
11660  }
11661 
11662  break;
11663  }
11664 
11665  default: {
11666  KdPrint(( "AtapiAdapterControl: default => return ScsiAdapterControlUnsuccessful\n"));
11668  }
11669  }
11670 
11672 } // end AtapiAdapterControl()
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1483
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4397
#define TRUE
Definition: types.h:120
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:2411
NTSTATUS NTAPI UniataDisconnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2156
OUT BOOLEAN SupportedTypeList[0]
Definition: srb.h:213
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
VOID NTAPI AtapiHwInitialize__(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_ata.cpp:3378
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4457
#define 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
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
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 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 3872 of file id_ata.cpp.

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

Referenced by AtapiCallBack_X().

◆ AtapiCallBack_X()

VOID NTAPI AtapiCallBack_X ( IN PVOID  HwDeviceExtension)

Definition at line 4007 of file id_ata.cpp.

4010 {
4011  AtapiCallBack__(HwDeviceExtension, (UCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->ActiveDpcChan);
4012 } // end AtapiCallBack_X()
VOID NTAPI AtapiCallBack__(IN PVOID HwDeviceExtension, IN UCHAR lChannel)
Definition: id_ata.cpp:3872
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 4512 of file id_ata.cpp.

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

4461 {
4462  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4463  PHW_CHANNEL chan;
4464  if(c >= deviceExtension->NumberChannels) {
4465  KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: WRONG CHANNEL\n",c));
4466  return;
4467  }
4468  chan = &(deviceExtension->chan[c]);
4469  KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: %d\n",c, chan->DisableIntr));
4470  // mark channel as busy
4471  if(InterlockedIncrement(&chan->DisableIntr)) {
4472  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4474  } else {
4475  //SelectDrive(chan, 0);
4477  IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4478  //if(chan->NumberLuns) {
4479  // SelectDrive(chan, 1);
4480  // AtapiWritePort1(chan, IDX_IO2_o_Control,
4481  // IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4482  // SelectDrive(chan, chan->cur_cdev);
4483  //}
4484  }
4486  }
4487 
4488  return;
4489 } // end AtapiDisableInterrupts()
#define KdPrint2(_x_)
Definition: atapi.h:154
#define IDX_IO2_o_Control
Definition: hwide.h:62
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 IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
#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

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

◆ AtapiEnableInterrupts()

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

Definition at line 4397 of file id_ata.cpp.

4401 {
4402  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4403  PHW_CHANNEL chan;
4404  //UCHAR statusByte;
4405 
4406  if(c >= deviceExtension->NumberChannels) {
4407  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: WRONG CHANNEL\n",c));
4408  return;
4409  }
4410  if((deviceExtension->HwFlags & UNIATA_AHCI) &&
4411  !UniataAhciChanImplemented(deviceExtension, c)) {
4412  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: not imp. CHANNEL\n",c));
4413  return;
4414  }
4415 
4416  chan = &(deviceExtension->chan[c]);
4417  KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: %d\n",c, chan->DisableIntr));
4418  if(!InterlockedDecrement(&chan->DisableIntr)) {
4419  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4423  ((/*ch->pm_level == */0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
4424  ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | /* DEBUG */
4428  );
4429  } else {
4430  //SelectDrive(chan, 0);
4431  //GetBaseStatus(chan, statusByte);
4433  0 | IDE_DC_A_4BIT );
4434  //if(chan->NumberLuns) {
4435  // SelectDrive(chan, 1);
4436  // GetBaseStatus(chan, statusByte);
4437  // AtapiWritePort1(chan, IDX_IO2_o_Control,
4438  // IDE_DC_A_4BIT );
4439  // SelectDrive(chan, chan->cur_cdev);
4440  //}
4441  }
4443  } else {
4444  if(deviceExtension->HwFlags & UNIATA_AHCI) {
4445  // keep interrupts disabled
4447  } else {
4449  IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4450  }
4451  }
4452  return;
4453 } // end AtapiEnableInterrupts()
#define ATA_AHCI_P_IX_PC
Definition: bsmaster.h:505
#define KdPrint2(_x_)
Definition: atapi.h:154
#define IDX_IO2_o_Control
Definition: hwide.h:62
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 IDE_DC_A_4BIT
Definition: hwide.h:140
#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 IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
#define ATA_AHCI_P_IX_HBD
Definition: bsmaster.h:513
#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
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415

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

◆ AtapiEnableInterrupts__()

RETTYPE_XXableInterrupts NTAPI AtapiEnableInterrupts__ ( IN PVOID  HwDeviceExtension)

Definition at line 4333 of file id_ata.cpp.

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

Referenced by AtapiCallBack__(), and AtapiInterrupt__().

◆ AtapiHardReset()

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

Definition at line 948 of file id_ata.cpp.

953 {
954  KdPrint2((PRINT_PREFIX "AtapiHardReset: %d, dis=%d\n", Delay, DisableInterrupts));
956  (DisableInterrupts ? IDE_DC_DISABLE_INTERRUPTS : 0));
957  chan->last_devsel = -1;
958  AtapiStallExecution(Delay);
960 } // end AtapiHardReset()
#define KdPrint2(_x_)
Definition: atapi.h:154
#define IDX_IO2_o_Control
Definition: hwide.h:62
#define IDE_DC_REENABLE_CONTROLLER
Definition: hwide.h:142
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
#define PRINT_PREFIX
Definition: atapi.h:150
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define IDE_DC_RESET_CONTROLLER
Definition: hwide.h:139

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

◆ AtapiHwInitialize()

BOOLEAN NTAPI AtapiHwInitialize ( IN PVOID  HwDeviceExtension)

Definition at line 3342 of file id_ata.cpp.

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

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

3671 {
3672  PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3673  ULONG lChannel = GET_CHANNEL(Srb);
3674  PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3676  PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
3677 
3678  if (MechanismStatus) {
3679  LunExt->DiscsPresent = MechanismStatus->NumberAvailableSlots;
3680  if (LunExt->DiscsPresent > 1) {
3681  LunExt->DeviceFlags |= DFLAGS_ATAPI_CHANGER;
3682  }
3683  }
3684  return;
3685 } // end AtapiHwInitializeChanger()
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
#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:1229
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 4033 of file id_ata.cpp.

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

Referenced by DriverEntry().

◆ AtapiInterrupt2()

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

Definition at line 4192 of file id_ata.cpp.

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

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