ReactOS 0.4.16-dev-1067-ge98bba2
hwide.c File Reference
#include <freeldr.h>
#include <ata.h>
#include <scsi.h>
#include <hwide.h>
#include "hwidep.h"
#include <debug.h>
Include dependency graph for hwide.c:

Go to the source code of this file.

Macros

#define CHANNEL_MAX_CHANNELS   RTL_NUMBER_OF(AtapChannelBaseArray)
 

Functions

 DBG_DEFAULT_CHANNEL (DISK)
 
static VOID AtapSelectDevice (_In_ PIDE_REGISTERS Registers, _In_range_(0, 3) UCHAR DeviceNumber)
 
static BOOLEAN AtapWaitForNotBusy (_In_ PIDE_REGISTERS Registers, _In_range_(>, 0) ULONG Timeout, _Out_opt_ PUCHAR Result)
 
static BOOLEAN AtapWaitForIdle (_In_ PIDE_REGISTERS Registers, _Out_ PUCHAR Result)
 
static VOID AtapSendCdb (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
 
static VOID AtapPioDataIn (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ ULONG ByteCount)
 
static BOOLEAN AtapWaitForRegisterAccess (_In_ PIDE_REGISTERS Registers, _In_range_(0, 3) UCHAR DeviceNumber)
 
static VOID AtapSoftwareReset (_In_ PIDE_REGISTERS Registers)
 
static BOOLEAN AtapPerformSoftwareReset (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static UCHAR AtapProcessAtapiRequest (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
 
static UCHAR AtapProcessAtaRequest (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
 
static BOOLEAN AtapProcessRequest (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
 
static VOID AtapIssuePacketCommand (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
 
static VOID AtapLoadTaskFile (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
 
static UCHAR AtapSendCommand (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
 
static VOID AtapAtapiBuildRequestSense (_In_ PATA_DEVICE_REQUEST Request, _Out_ PSENSE_DATA SenseData)
 
static BOOLEAN AtapAtapiHandleError (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapIssueCommand (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
 
static UCHAR AtapGetReadCommand (_In_ PATA_DEVICE_REQUEST Request)
 
static VOID AtapBuildReadTaskFile (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ ULONG64 Lba, _In_ ULONG SectorCount)
 
static VOID AtapBuildReadPacketCommand (_In_ PATA_DEVICE_REQUEST Request, _In_ ULONG64 Lba, _In_ ULONG SectorCount)
 
static BOOLEAN AtapIsDevicePresent (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapReadIdentifyData (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ UCHAR Command)
 
static ATA_DEVICE_CLASS AtapIdentifyDevice (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapAtapiReadCapacity16 (_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PREAD_CAPACITY16_DATA CapacityData)
 
static BOOLEAN AtapAtapiReadCapacity10 (_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PREAD_CAPACITY_DATA CapacityData)
 
static VOID AtapAtapiDetectCapacity (_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PULONG64 TotalSectors, _Out_ PULONG SectorSize)
 
static BOOLEAN AtapAtapiTestUnitReady (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapAtapiRequestSense (_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PSENSE_DATA SenseData)
 
static BOOLEAN AtapAtapiReadToc (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapAtapiReadyCheck (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static VOID AtapAtapiClearUnitAttention (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapAtapiInitDevice (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static VOID AtapAtaSetMultipleMode (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapAtaInitDevice (_In_ PHW_DEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapAnalyzeIdentifyData (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ ATA_DEVICE_CLASS DeviceClass)
 
static BOOLEAN AtapInitDevice (_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ ATA_DEVICE_CLASS DeviceClass)
 
static BOOLEAN AtapIdentifyChannel (_In_ ULONG ChannelNumber, _Out_ PIDE_REGISTERS Registers)
 
BOOLEAN AtaReadLogicalSectors (_In_ PDEVICE_UNIT DeviceUnit, _In_ ULONG64 SectorNumber, _In_ ULONG SectorCount, _Out_writes_bytes_all_(SectorCount *DeviceUnit->SectorSize) PVOID Buffer)
 
PDEVICE_UNIT AtaGetDevice (_In_ UCHAR UnitNumber)
 
BOOLEAN AtaInit (_Out_ PUCHAR DetectedCount)
 

Variables

static const IDE_REG AtapChannelBaseArray []
 
static PHW_DEVICE_UNIT AtapUnits [CHANNEL_MAX_CHANNELS *CHANNEL_MAX_DEVICES]
 

Macro Definition Documentation

◆ CHANNEL_MAX_CHANNELS

#define CHANNEL_MAX_CHANNELS   RTL_NUMBER_OF(AtapChannelBaseArray)

Definition at line 35 of file hwide.c.

Function Documentation

◆ AtaGetDevice()

PDEVICE_UNIT AtaGetDevice ( _In_ UCHAR  UnitNumber)

Definition at line 1254 of file hwide.c.

1256{
1257 if (UnitNumber < RTL_NUMBER_OF(AtapUnits))
1258 return (PDEVICE_UNIT)AtapUnits[UnitNumber];
1259
1260 return NULL;
1261}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define NULL
Definition: types.h:112
static PHW_DEVICE_UNIT AtapUnits[CHANNEL_MAX_CHANNELS *CHANNEL_MAX_DEVICES]
Definition: hwide.c:37
Data structure for the ATA device.
Definition: hwide.h:12

Referenced by InitIdeDrive(), Pc98DiskReadLogicalSectorsLBA(), and XboxDiskInit().

◆ AtaInit()

BOOLEAN AtaInit ( _Out_ PUCHAR  DetectedCount)

Definition at line 1264 of file hwide.c.

1266{
1267 ULONG ChannelNumber;
1268
1269 *DetectedCount = 0;
1270
1271 /* Enumerate IDE channels */
1272 for (ChannelNumber = 0; ChannelNumber < CHANNEL_MAX_CHANNELS; ++ChannelNumber)
1273 {
1275 IDE_REGISTERS Registers;
1276
1277 if (!AtapIdentifyChannel(ChannelNumber, &Registers))
1278 continue;
1279
1280 /* Check for devices attached to the bus */
1282 {
1283 PHW_DEVICE_UNIT DeviceUnit;
1284 ATA_DEVICE_CLASS DeviceClass;
1285
1286 /* Allocate a new device unit structure */
1287 DeviceUnit = FrLdrTempAlloc(sizeof(*DeviceUnit), TAG_ATA_DEVICE);
1288 if (!DeviceUnit)
1289 {
1290 ERR("Failed to allocate device unit!\n");
1291 continue;
1292 }
1293 RtlZeroMemory(DeviceUnit, sizeof(*DeviceUnit));
1294
1295 /* Perform a minimal initialization */
1296 RtlCopyMemory(&DeviceUnit->Registers, &Registers, sizeof(Registers));
1297 DeviceUnit->DeviceNumber = DeviceNumber;
1298 DeviceUnit->P.SectorSize = 512;
1299 DeviceUnit->DeviceSelect = (DEV_SLAVE(DeviceNumber) << 4) | IDE_DRIVE_SELECT;
1300
1301 /* Let's see what kind of device this is */
1302 DeviceClass = AtapIdentifyDevice(DeviceUnit);
1303 if (DeviceClass == DEV_NONE)
1304 goto NextDevice;
1305
1306 TRACE("Found %lu device at %X:%u\n", DeviceClass, Registers.Data, DeviceNumber);
1307
1308 if (!AtapInitDevice(DeviceUnit, DeviceClass))
1309 goto NextDevice;
1310
1311 TRACE("Total sectors %I64u of size %lu, CHS %lu:%lu:%lu, %lx\n",
1312 DeviceUnit->P.TotalSectors,
1313 DeviceUnit->P.SectorSize,
1314 DeviceUnit->P.Cylinders,
1315 DeviceUnit->P.Heads,
1316 DeviceUnit->P.SectorsPerTrack,
1317 DeviceUnit->P.Flags);
1318
1319 AtapUnits[(*DetectedCount)++] = DeviceUnit;
1320 continue;
1321
1322NextDevice:
1323 FrLdrTempFree(DeviceUnit, TAG_ATA_DEVICE);
1324 }
1325 }
1326
1327 return (*DetectedCount > 0);
1328}
#define ERR(fmt,...)
Definition: precomp.h:57
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: heap.c:553
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
#define CHANNEL_MAX_CHANNELS
Definition: hwide.c:35
static BOOLEAN AtapIdentifyChannel(_In_ ULONG ChannelNumber, _Out_ PIDE_REGISTERS Registers)
Definition: hwide.c:1181
static BOOLEAN AtapInitDevice(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ ATA_DEVICE_CLASS DeviceClass)
Definition: hwide.c:1166
static ATA_DEVICE_CLASS AtapIdentifyDevice(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:773
enum _ATA_DEVICE_CLASS ATA_DEVICE_CLASS
@ DEV_NONE
Definition: hwidep.h:97
#define CHANNEL_MAX_DEVICES
Definition: hwidep.h:24
#define DEV_SLAVE(DeviceNumber)
Definition: hwidep.h:25
#define TAG_ATA_DEVICE
Definition: hwidep.h:10
#define IDE_DRIVE_SELECT
Definition: hwidep.h:54
#define TRACE(s)
Definition: solgame.cpp:4
ULONG Cylinders
Definition: hwide.h:14
ULONG SectorSize
Definition: hwide.h:23
ULONG SectorsPerTrack
Definition: hwide.h:20
ULONG64 TotalSectors
Definition: hwide.h:26
ULONG Flags
Definition: hwide.h:29
ULONG Heads
Definition: hwide.h:17
UCHAR DeviceNumber
Definition: hwidep.h:183
DEVICE_UNIT P
Definition: hwidep.h:176
UCHAR DeviceSelect
Definition: hwidep.h:184
IDE_REGISTERS Registers
Definition: hwidep.h:178
IDE_REG Data
Definition: hwidep.h:102
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by Pc98InitializeBootDevices(), and XboxDiskInit().

◆ AtapAnalyzeIdentifyData()

static BOOLEAN AtapAnalyzeIdentifyData ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ ATA_DEVICE_CLASS  DeviceClass 
)
static

Definition at line 1119 of file hwide.c.

1122{
1123 PIDENTIFY_DEVICE_DATA Id = &DeviceUnit->IdentifyDeviceData;
1124 ULONG i;
1125
1126 /* Verify the checksum */
1128 {
1129 ERR("Identify data CRC error\n");
1130 return FALSE;
1131 }
1132
1133 if (DeviceClass == DEV_ATAPI)
1134 {
1135 DeviceUnit->P.Flags |= ATA_DEVICE_ATAPI | ATA_DEVICE_LBA;
1136
1137 /* The returned string is not byteswapped */
1138 if (Id->ModelNumber[0] == 'N' &&
1139 Id->ModelNumber[1] == 'E' &&
1140 Id->ModelNumber[2] == 'C' &&
1141 Id->ModelNumber[3] == ' ')
1142 {
1143 DeviceUnit->P.Flags |= ATA_DEVICE_IS_NEC_CDR260;
1144 }
1145 }
1146
1147 /* Swap byte order of the ASCII data */
1148 for (i = 0; i < sizeof(Id->SerialNumber) / 2; ++i)
1149 ((PUSHORT)Id->SerialNumber)[i] = RtlUshortByteSwap(((PUSHORT)Id->SerialNumber)[i]);
1150
1151 for (i = 0; i < sizeof(Id->FirmwareRevision) / 2; ++i)
1152 ((PUSHORT)Id->FirmwareRevision)[i] = RtlUshortByteSwap(((PUSHORT)Id->FirmwareRevision)[i]);
1153
1154 for (i = 0; i < sizeof(Id->ModelNumber) / 2; ++i)
1155 ((PUSHORT)Id->ModelNumber)[i] = RtlUshortByteSwap(((PUSHORT)Id->ModelNumber)[i]);
1156
1157 TRACE("MN '%.*s'\n", sizeof(Id->ModelNumber), Id->ModelNumber);
1158 TRACE("FR '%.*s'\n", sizeof(Id->FirmwareRevision), Id->FirmwareRevision);
1159 TRACE("S/N '%.*s'\n", sizeof(Id->SerialNumber), Id->SerialNumber);
1160
1161 return TRUE;
1162}
DWORD Id
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ATA_DEVICE_LBA
Definition: hwide.h:31
#define ATA_DEVICE_IS_NEC_CDR260
Definition: hwide.h:33
#define ATA_DEVICE_ATAPI
Definition: hwide.h:30
FORCEINLINE BOOLEAN AtaDevIsIdentifyDataValid(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:196
@ DEV_ATAPI
Definition: hwidep.h:96
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3214

Referenced by AtapInitDevice().

◆ AtapAtaInitDevice()

static BOOLEAN AtapAtaInitDevice ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 1055 of file hwide.c.

1057{
1058 PIDENTIFY_DEVICE_DATA IdentifyData = &DeviceUnit->IdentifyDeviceData;
1059 ULONG64 TotalSectors;
1060 USHORT Cylinders, Heads, SectorsPerTrack;
1061
1062 DeviceUnit->MaximumTransferLength = 0xFF;
1063
1064 if (AtaDevIsCurrentGeometryValid(IdentifyData))
1065 AtaDevCurrentChsTranslation(IdentifyData, &Cylinders, &Heads, &SectorsPerTrack);
1066 else
1067 AtaDevDefaultChsTranslation(IdentifyData, &Cylinders, &Heads, &SectorsPerTrack);
1068
1069 /* Using LBA addressing mode */
1070 if (AtaDevHasLbaTranslation(IdentifyData))
1071 {
1072 DeviceUnit->P.Flags |= ATA_DEVICE_LBA;
1073
1074 if (AtaDevHas48BitAddressFeature(IdentifyData))
1075 {
1076 /* Using LBA48 addressing mode */
1077 TotalSectors = AtaDevUserAddressableSectors48Bit(IdentifyData);
1078 ASSERT(TotalSectors <= ATA_MAX_LBA_48);
1079
1080 DeviceUnit->P.Flags |= ATA_DEVICE_LBA48;
1081 DeviceUnit->MaximumTransferLength = 0x10000;
1082 }
1083 else
1084 {
1085 /* Using LBA28 addressing mode */
1086 TotalSectors = AtaDevUserAddressableSectors28Bit(IdentifyData);
1087 ASSERT(TotalSectors <= ATA_MAX_LBA_28);
1088 }
1089 }
1090 else
1091 {
1092 /* Using CHS addressing mode */
1093 TotalSectors = Cylinders * Heads * SectorsPerTrack;
1094 }
1095
1096 if (TotalSectors == 0)
1097 {
1098 ERR("Unknown geometry\n");
1099 return FALSE;
1100 }
1101
1102 DeviceUnit->P.TotalSectors = TotalSectors;
1103 DeviceUnit->P.Cylinders = Cylinders;
1104 DeviceUnit->P.Heads = Heads;
1105 DeviceUnit->P.SectorsPerTrack = SectorsPerTrack;
1106 DeviceUnit->P.SectorSize = AtaDevBytesPerLogicalSector(IdentifyData);
1107 ASSERT(DeviceUnit->P.SectorSize >= 512);
1108 DeviceUnit->P.SectorSize = max(DeviceUnit->P.SectorSize, 512);
1109
1110 AtapAtaSetMultipleMode(DeviceUnit);
1111
1112 TRACE("Multiple sector setting %u\n", DeviceUnit->MultiSectorTransfer);
1113
1114 return TRUE;
1115}
static VOID AtapAtaSetMultipleMode(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:1028
#define ATA_DEVICE_LBA48
Definition: hwide.h:32
FORCEINLINE VOID AtaDevDefaultChsTranslation(_In_ PIDENTIFY_DEVICE_DATA IdentifyData, _Out_ PUSHORT Cylinders, _Out_ PUSHORT Heads, _Out_ PUSHORT SectorsPerTrack)
Definition: hwidep.h:285
FORCEINLINE ULONG AtaDevBytesPerLogicalSector(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:357
#define ATA_MAX_LBA_48
Definition: hwidep.h:48
FORCEINLINE BOOLEAN AtaDevHas48BitAddressFeature(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:257
FORCEINLINE ULONG64 AtaDevUserAddressableSectors48Bit(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:248
FORCEINLINE BOOLEAN AtaDevHasLbaTranslation(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:230
FORCEINLINE ULONG AtaDevUserAddressableSectors28Bit(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:239
#define ATA_MAX_LBA_28
Definition: hwidep.h:47
FORCEINLINE BOOLEAN AtaDevIsCurrentGeometryValid(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:272
FORCEINLINE VOID AtaDevCurrentChsTranslation(_In_ PIDENTIFY_DEVICE_DATA IdentifyData, _Out_ PUSHORT Cylinders, _Out_ PUSHORT Heads, _Out_ PUSHORT SectorsPerTrack)
Definition: hwidep.h:303
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned short USHORT
Definition: pedump.c:61
#define max(a, b)
Definition: svc.c:63
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2071

Referenced by AtapInitDevice().

◆ AtapAtapiBuildRequestSense()

static VOID AtapAtapiBuildRequestSense ( _In_ PATA_DEVICE_REQUEST  Request,
_Out_ PSENSE_DATA  SenseData 
)
static

Definition at line 478 of file hwide.c.

481{
483 Request->DataBuffer = SenseData;
484 Request->DataTransferLength = sizeof(*SenseData);
486 Request->Cdb[4] = (UCHAR)Request->DataTransferLength;
487}
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
#define REQUEST_FLAG_PACKET_COMMAND
Definition: hwidep.h:164
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

Referenced by AtapAtapiHandleError(), and AtapAtapiRequestSense().

◆ AtapAtapiClearUnitAttention()

static VOID AtapAtapiClearUnitAttention ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 963 of file hwide.c.

965{
966 SENSE_DATA SenseData;
967 ULONG i;
968
969 for (i = 0; i < 5; ++i)
970 {
971 if (!AtapAtapiRequestSense(DeviceUnit, &SenseData))
972 continue;
973
974 if ((SenseData.SenseKey != SCSI_SENSE_UNIT_ATTENTION) &&
976 {
977 break;
978 }
979 }
980}
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSI_ADSENSE_BUS_RESET
Definition: cdrw_hw.h:1289
static BOOLEAN AtapAtapiRequestSense(_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PSENSE_DATA SenseData)
Definition: hwide.c:890
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
UCHAR SenseKey
Definition: cdrw_hw.h:1167

Referenced by AtapAtapiInitDevice().

◆ AtapAtapiDetectCapacity()

static VOID AtapAtapiDetectCapacity ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_Out_ PULONG64  TotalSectors,
_Out_ PULONG  SectorSize 
)
static

Definition at line 833 of file hwide.c.

837{
838 union
839 {
840 READ_CAPACITY_DATA Cmd10;
842 } CapacityData;
843 ULONG LastLba;
844
845 *TotalSectors = 0;
846 *SectorSize = 0;
847
848 if (!AtapAtapiReadCapacity10(DeviceUnit, &CapacityData.Cmd10))
849 return;
850
851 LastLba = RtlUlongByteSwap(CapacityData.Cmd10.LogicalBlockAddress);
852 if (LastLba == MAXULONG)
853 {
854 if (!AtapAtapiReadCapacity16(DeviceUnit, &CapacityData.Cmd16))
855 return;
856
857 *TotalSectors = RtlUlonglongByteSwap(CapacityData.Cmd16.LogicalBlockAddress.QuadPart) + 1;
858 *SectorSize = RtlUlongByteSwap(CapacityData.Cmd16.BytesPerBlock);
859 }
860 else
861 {
862 *TotalSectors = LastLba + 1;
863 *SectorSize = RtlUlongByteSwap(CapacityData.Cmd10.BytesPerBlock);
864 }
865
866 /*
867 * If device reports a non-zero block length, reset to defaults
868 * (we use a READ command instead of READ CD).
869 */
870 if (*SectorSize != 0)
871 *SectorSize = 2048;
872}
#define RtlUlongByteSwap(_x)
Definition: compat.h:815
static BOOLEAN AtapAtapiReadCapacity10(_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PREAD_CAPACITY_DATA CapacityData)
Definition: hwide.c:816
static BOOLEAN AtapAtapiReadCapacity16(_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PREAD_CAPACITY16_DATA CapacityData)
Definition: hwide.c:797
#define MAXULONG
Definition: typedefs.h:251
_In_ ULONG SectorSize
Definition: halfuncs.h:291
#define RtlUlonglongByteSwap(_x)
Definition: rtlfuncs.h:3216

Referenced by AtapAtapiInitDevice().

◆ AtapAtapiHandleError()

static BOOLEAN AtapAtapiHandleError ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 491 of file hwide.c.

493{
495 SENSE_DATA SenseData;
496
498 if (AtapSendCommand(DeviceUnit, &Request) != ATA_STATUS_SUCCESS)
499 return FALSE;
500
501 ERR("SK %02X, ASC %02X, ASCQ %02X\n",
502 SenseData.SenseKey,
503 SenseData.AdditionalSenseCode,
505
506 return TRUE;
507}
static UCHAR AtapSendCommand(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
Definition: hwide.c:437
static VOID AtapAtapiBuildRequestSense(_In_ PATA_DEVICE_REQUEST Request, _Out_ PSENSE_DATA SenseData)
Definition: hwide.c:478
#define ATA_STATUS_SUCCESS
Definition: hwidep.h:12
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176

Referenced by AtapIssueCommand().

◆ AtapAtapiInitDevice()

static BOOLEAN AtapAtapiInitDevice ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 984 of file hwide.c.

986{
987 PIDENTIFY_PACKET_DATA IdentifyPacketData = &DeviceUnit->IdentifyPacketData;
988 ULONG i;
989
990 DeviceUnit->CdbSize = AtaDevCdbSizeInWords(IdentifyPacketData);
991
992 /* Clear the ATAPI 'Bus reset' indication */
993 AtapAtapiClearUnitAttention(DeviceUnit);
994
995 /* Make the device ready */
996 for (i = 4; i > 0; i--)
997 {
998 if (AtapAtapiReadyCheck(DeviceUnit))
999 break;
1000 }
1001 if (i == 0)
1002 {
1003 ERR("Device not ready\n");
1004 return FALSE;
1005 }
1006
1007 /* Detect a medium's capacity */
1008 AtapAtapiDetectCapacity(DeviceUnit,
1009 &DeviceUnit->P.TotalSectors,
1010 &DeviceUnit->P.SectorSize);
1011 if (DeviceUnit->P.SectorSize == 0 || DeviceUnit->P.TotalSectors == 0)
1012 {
1013 TRACE("No media found\n");
1014 return FALSE;
1015 }
1016
1017 DeviceUnit->P.Cylinders = MAXULONG;
1018 DeviceUnit->P.Heads = MAXULONG;
1019 DeviceUnit->P.SectorsPerTrack = MAXULONG;
1020
1021 DeviceUnit->MaximumTransferLength = 0xFFFF;
1022
1023 return TRUE;
1024}
static BOOLEAN AtapAtapiReadyCheck(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:922
static VOID AtapAtapiDetectCapacity(_In_ PHW_DEVICE_UNIT DeviceUnit, _Out_ PULONG64 TotalSectors, _Out_ PULONG SectorSize)
Definition: hwide.c:833
static VOID AtapAtapiClearUnitAttention(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:963
FORCEINLINE UCHAR AtaDevCdbSizeInWords(_In_ PIDENTIFY_PACKET_DATA IdentifyPacketData)
Definition: hwidep.h:221

Referenced by AtapInitDevice().

◆ AtapAtapiReadCapacity10()

static BOOLEAN AtapAtapiReadCapacity10 ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_Out_ PREAD_CAPACITY_DATA  CapacityData 
)
static

Definition at line 816 of file hwide.c.

819{
821
822 /* Send the SCSI READ CAPACITY(10) command */
824 Request.DataBuffer = CapacityData;
825 Request.DataTransferLength = sizeof(*CapacityData);
827
828 return AtapIssueCommand(DeviceUnit, &Request);
829}
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
static BOOLEAN AtapIssueCommand(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
Definition: hwide.c:511

Referenced by AtapAtapiDetectCapacity().

◆ AtapAtapiReadCapacity16()

static BOOLEAN AtapAtapiReadCapacity16 ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_Out_ PREAD_CAPACITY16_DATA  CapacityData 
)
static

Definition at line 797 of file hwide.c.

800{
802
803 /* Send the SCSI READ CAPACITY(16) command */
805 Request.DataBuffer = CapacityData;
806 Request.DataTransferLength = sizeof(*CapacityData);
809 Request.Cdb[13] = sizeof(*CapacityData);
810
811 return AtapIssueCommand(DeviceUnit, &Request);
812}
#define SERVICE_ACTION_READ_CAPACITY16
Definition: scsi.h:474
#define SCSIOP_SERVICE_ACTION_IN16
Definition: scsi.h:368

Referenced by AtapAtapiDetectCapacity().

◆ AtapAtapiReadToc()

static BOOLEAN AtapAtapiReadToc ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 902 of file hwide.c.

904{
907
908 /* Send the SCSI READ TOC command */
910 Request.DataBuffer = DummyData;
911 Request.DataTransferLength = sizeof(DummyData);
912 Request.Cdb[0] = SCSIOP_READ_TOC;
913 Request.Cdb[7] = (MAXIMUM_CDROM_SIZE >> 8) & 0xFF;
914 Request.Cdb[8] = MAXIMUM_CDROM_SIZE & 0xFF;
915 Request.Cdb[9] = READ_TOC_FORMAT_SESSION << 6;
916
917 return AtapIssueCommand(DeviceUnit, &Request);
918}
#define SCSIOP_READ_TOC
Definition: cdrw_hw.h:927
ULONG DummyData
Definition: cmdata.c:18
#define MAXIMUM_CDROM_SIZE
Definition: hwidep.h:65
#define READ_TOC_FORMAT_SESSION
Definition: scsi.h:178

Referenced by AtapAtapiReadyCheck().

◆ AtapAtapiReadyCheck()

static BOOLEAN AtapAtapiReadyCheck ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 922 of file hwide.c.

924{
925 SENSE_DATA SenseData;
926
927 if (!AtapAtapiTestUnitReady(DeviceUnit))
928 return FALSE;
929
930 if (!AtapAtapiRequestSense(DeviceUnit, &SenseData))
931 return FALSE;
932
933 if (SenseData.SenseKey == SCSI_SENSE_NOT_READY)
934 {
936 return FALSE;
937
939 {
940 switch (SenseData.AdditionalSenseCodeQualifier)
941 {
943 /* Wait until the CD is spun up */
945 return FALSE;
946
948 /* The drive needs to be spun up */
949 AtapAtapiReadToc(DeviceUnit);
950 return FALSE;
951
952 default:
953 return FALSE;
954 }
955 }
956 }
957
958 return TRUE;
959}
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
static BOOLEAN AtapAtapiReadToc(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:902
static BOOLEAN AtapAtapiTestUnitReady(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:876
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60

Referenced by AtapAtapiInitDevice().

◆ AtapAtapiRequestSense()

static BOOLEAN AtapAtapiRequestSense ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_Out_ PSENSE_DATA  SenseData 
)
static

Definition at line 890 of file hwide.c.

893{
895
897 return AtapIssueCommand(DeviceUnit, &Request);
898}

Referenced by AtapAtapiClearUnitAttention(), and AtapAtapiReadyCheck().

◆ AtapAtapiTestUnitReady()

static BOOLEAN AtapAtapiTestUnitReady ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 876 of file hwide.c.

878{
880
881 /* Send the SCSI TEST UNIT READY command */
884
885 return AtapIssueCommand(DeviceUnit, &Request);
886}
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866

Referenced by AtapAtapiReadyCheck().

◆ AtapAtaSetMultipleMode()

static VOID AtapAtaSetMultipleMode ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 1028 of file hwide.c.

1030{
1032
1033#if !defined(ATA_ENABLE_MULTIPLE_MODE)
1034 /* Inherit multiple mode from the state the BIOS firmware left the device in during boot */
1035 DeviceUnit->MultiSectorTransfer = AtaDevCurrentSectorsPerDrq(&DeviceUnit->IdentifyDeviceData);
1036 if (DeviceUnit->MultiSectorTransfer != 0)
1037 return;
1038#endif
1039
1040 /* Use the maximum possible value */
1041 DeviceUnit->MultiSectorTransfer = AtaDevMaximumSectorsPerDrq(&DeviceUnit->IdentifyDeviceData);
1042 if (DeviceUnit->MultiSectorTransfer == 0)
1043 return;
1044
1045 Request.TaskFile.Command = IDE_COMMAND_SET_MULTIPLE;
1046 Request.TaskFile.Data[0].SectorCount = DeviceUnit->MultiSectorTransfer;
1047 if (!AtapIssueCommand(DeviceUnit, &Request))
1048 {
1049 DeviceUnit->MultiSectorTransfer = 0;
1050 }
1051}
#define IDE_COMMAND_SET_MULTIPLE
Definition: atapi.h:113
FORCEINLINE UCHAR AtaDevCurrentSectorsPerDrq(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:321
FORCEINLINE UCHAR AtaDevMaximumSectorsPerDrq(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:341

Referenced by AtapAtaInitDevice().

◆ AtapBuildReadPacketCommand()

static VOID AtapBuildReadPacketCommand ( _In_ PATA_DEVICE_REQUEST  Request,
_In_ ULONG64  Lba,
_In_ ULONG  SectorCount 
)
static

Definition at line 677 of file hwide.c.

681{
683
684 RtlZeroMemory(Request->Cdb, sizeof(Request->Cdb));
685
686 if (Lba > MAXULONG)
687 {
688 /* READ (16) */
689 Request->Cdb[0] = SCSIOP_READ16;
690 Request->Cdb[2] = (UCHAR)(Lba >> 56);
691 Request->Cdb[3] = (UCHAR)(Lba >> 48);
692 Request->Cdb[4] = (UCHAR)(Lba >> 40);
693 Request->Cdb[5] = (UCHAR)(Lba >> 32);
694 Request->Cdb[6] = (UCHAR)(Lba >> 24);
695 Request->Cdb[7] = (UCHAR)(Lba >> 16);
696 Request->Cdb[8] = (UCHAR)(Lba >> 8);
697 Request->Cdb[9] = (UCHAR)(Lba >> 0);
698 Request->Cdb[10] = (UCHAR)(SectorCount >> 24);
699 Request->Cdb[11] = (UCHAR)(SectorCount >> 16);
700 Request->Cdb[12] = (UCHAR)(SectorCount >> 8);
701 Request->Cdb[13] = (UCHAR)(SectorCount >> 0);
702 }
703 else
704 {
705 /* READ (10) */
706 Request->Cdb[0] = SCSIOP_READ;
707 Request->Cdb[2] = (UCHAR)(Lba >> 24);
708 Request->Cdb[3] = (UCHAR)(Lba >> 16);
709 Request->Cdb[4] = (UCHAR)(Lba >> 8);
710 Request->Cdb[5] = (UCHAR)(Lba >> 0);
711 Request->Cdb[7] = (UCHAR)(SectorCount >> 8);
712 Request->Cdb[8] = (UCHAR)(SectorCount >> 0);
713 }
714}
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSIOP_READ16
Definition: scsi.h:914
#define REQUEST_FLAG_READ_COMMAND
Definition: hwidep.h:167
ULONG SectorCount
Definition: part_xbox.c:31

Referenced by AtaReadLogicalSectors().

◆ AtapBuildReadTaskFile()

static VOID AtapBuildReadTaskFile ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request,
_In_ ULONG64  Lba,
_In_ ULONG  SectorCount 
)
static

Definition at line 606 of file hwide.c.

611{
612 PATA_TASKFILE TaskFile = &Request->TaskFile;
613 UCHAR DriveSelect;
614
616
617 if (DeviceUnit->MultiSectorTransfer != 0)
618 {
620 }
621
622 if (DeviceUnit->P.Flags & ATA_DEVICE_LBA)
623 {
624 DriveSelect = IDE_LBA_MODE;
625
626 TaskFile->Data[0].SectorCount = (UCHAR)SectorCount;
627 TaskFile->Data[0].LowLba = (UCHAR)Lba; // LBA bits 0-7
628 TaskFile->Data[0].MidLba = (UCHAR)(Lba >> 8); // LBA bits 8-15
629 TaskFile->Data[0].HighLba = (UCHAR)(Lba >> 16); // LBA bits 16-23
630
631 if ((DeviceUnit->P.Flags & ATA_DEVICE_LBA48) && (AtaCommandUseLba48(Lba, SectorCount)))
632 {
634
635 /* 48-bit command */
636 TaskFile->Data[1].SectorCount = (UCHAR)(SectorCount >> 8);
637 TaskFile->Data[1].LowLba = (UCHAR)(Lba >> 24); // LBA bits 24-31
638 TaskFile->Data[1].MidLba = (UCHAR)(Lba >> 32); // LBA bits 32-39
639 TaskFile->Data[1].HighLba = (UCHAR)(Lba >> 40); // LBA bits 40-47
640
641 Request->Flags |= REQUEST_FLAG_LBA48;
642 }
643 else
644 {
646
647 /* 28-bit command */
648 DriveSelect |= ((Lba >> 24) & 0x0F); // LBA bits 24-27
649 }
650 }
651 else
652 {
653 ULONG ChsTemp, Cylinder, Head, Sector;
654
655 ChsTemp = (ULONG)Lba / DeviceUnit->P.SectorsPerTrack;
656
657 /* Legacy CHS translation */
658 Cylinder = ChsTemp / DeviceUnit->P.Heads;
659 Head = ChsTemp % DeviceUnit->P.Heads;
660 Sector = ((ULONG)Lba % DeviceUnit->P.SectorsPerTrack) + 1;
661
662 ASSERT(Cylinder <= 65535 && Head <= 15 && Sector <= 255);
663
664 TaskFile->Data[0].SectorCount = (UCHAR)SectorCount;
665 TaskFile->Data[0].LowLba = (UCHAR)Sector;
666 TaskFile->Data[0].MidLba = (UCHAR)Cylinder;
667 TaskFile->Data[0].HighLba = (UCHAR)(Cylinder >> 8);
668
669 DriveSelect = Head;
670 }
671 TaskFile->DriveSelect = DeviceUnit->DeviceSelect | DriveSelect;
673}
#define IDE_LBA_MODE
Definition: ata.h:613
static UCHAR AtapGetReadCommand(_In_ PATA_DEVICE_REQUEST Request)
Definition: hwide.c:590
#define REQUEST_FLAG_LBA48
Definition: hwidep.h:162
FORCEINLINE BOOLEAN AtaCommandUseLba48(_In_ ULONG64 SectorNumber, _In_ ULONG SectorCount)
Definition: hwidep.h:381
#define REQUEST_FLAG_READ_WRITE_MULTIPLE
Definition: hwidep.h:163
#define REQUEST_FLAG_SET_DEVICE_REGISTER
Definition: hwidep.h:165
struct _ATA_TASKFILE::@177 Data[2]
UCHAR Command
Definition: hwidep.h:142
UCHAR DriveSelect
Definition: hwidep.h:141

Referenced by AtaReadLogicalSectors().

◆ AtapGetReadCommand()

static UCHAR AtapGetReadCommand ( _In_ PATA_DEVICE_REQUEST  Request)
static

Definition at line 590 of file hwide.c.

592{
593 static const UCHAR AtapReadCommandMap[2][2] =
594 {
595 /* Read Read EXT */
596 { IDE_COMMAND_READ, IDE_COMMAND_READ_EXT }, // PIO single
598 };
599
600 return AtapReadCommandMap[(Request->Flags & REQUEST_FLAG_READ_WRITE_MULTIPLE) ? 1 : 0]
601 [(Request->Flags & REQUEST_FLAG_LBA48) ? 1 : 0];
602}
#define IDE_COMMAND_READ_MULTIPLE_EXT
Definition: ata.h:648
#define IDE_COMMAND_READ_EXT
Definition: ata.h:645
#define IDE_COMMAND_READ_MULTIPLE
Definition: atapi.h:111
#define IDE_COMMAND_READ
Definition: atapi.h:104

Referenced by AtapBuildReadTaskFile().

◆ AtapIdentifyChannel()

static BOOLEAN AtapIdentifyChannel ( _In_ ULONG  ChannelNumber,
_Out_ PIDE_REGISTERS  Registers 
)
static

Definition at line 1181 of file hwide.c.

1184{
1185 const IDE_REG IoBase = AtapChannelBaseArray[ChannelNumber];
1186 ULONG Spare;
1187
1188#if defined(SARCH_PC98)
1189 if (ATA_READ(0x432) == 0xFF)
1190 return FALSE;
1191#endif
1192
1193#if defined(SARCH_PC98)
1194 Spare = 2;
1195 Registers->Control = 0x74C;
1196#else
1197 Spare = 1;
1198 Registers->Control = IoBase + 0x206;
1199#endif
1200 Registers->Data = IoBase + 0 * Spare;
1201 Registers->Error = IoBase + 1 * Spare;
1202 Registers->SectorCount = IoBase + 2 * Spare;
1203 Registers->LbaLow = IoBase + 3 * Spare;
1204 Registers->LbaMid = IoBase + 4 * Spare;
1205 Registers->LbaHigh = IoBase + 5 * Spare;
1206 Registers->Device = IoBase + 6 * Spare;
1207 Registers->Status = IoBase + 7 * Spare;
1208
1209 return TRUE;
1210}
static const IDE_REG AtapChannelBaseArray[]
Definition: hwide.c:25
ULONG_PTR IDE_REG
Definition: hwidep.h:44
#define ATA_READ(Port)
Definition: hwidep.h:84

Referenced by AtaInit().

◆ AtapIdentifyDevice()

static ATA_DEVICE_CLASS AtapIdentifyDevice ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 773 of file hwide.c.

775{
776 if (!AtapIsDevicePresent(DeviceUnit))
777 return DEV_NONE;
778
779 /*
780 * We don't check the device signature here,
781 * because the NEC CDR-260 drive reports an ATA signature.
782 */
783
784 /* Check for ATA */
786 return DEV_ATA;
787
788 /* Check for ATAPI */
790 return DEV_ATAPI;
791
792 return DEV_NONE;
793}
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
static BOOLEAN AtapIsDevicePresent(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:718
static BOOLEAN AtapReadIdentifyData(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ UCHAR Command)
Definition: hwide.c:755
@ DEV_ATA
Definition: hwidep.h:95

Referenced by AtaInit().

◆ AtapInitDevice()

static BOOLEAN AtapInitDevice ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ ATA_DEVICE_CLASS  DeviceClass 
)
static

Definition at line 1166 of file hwide.c.

1169{
1170 if (!AtapAnalyzeIdentifyData(DeviceUnit, DeviceClass))
1171 return FALSE;
1172
1173 if (DeviceClass == DEV_ATAPI)
1174 return AtapAtapiInitDevice(DeviceUnit);
1175 else
1176 return AtapAtaInitDevice(DeviceUnit);
1177}
static BOOLEAN AtapAtaInitDevice(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:1055
static BOOLEAN AtapAnalyzeIdentifyData(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ ATA_DEVICE_CLASS DeviceClass)
Definition: hwide.c:1119
static BOOLEAN AtapAtapiInitDevice(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:984

Referenced by AtaInit().

◆ AtapIsDevicePresent()

static BOOLEAN AtapIsDevicePresent ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 718 of file hwide.c.

720{
721 PIDE_REGISTERS Registers = &DeviceUnit->Registers;
722 UCHAR IdeStatus;
723
724 AtapSelectDevice(Registers, DeviceUnit->DeviceNumber);
725
726 IdeStatus = ATA_READ(Registers->Status);
727 if (IdeStatus == 0xFF || IdeStatus == 0x7F)
728 return FALSE;
729
730 ATA_WRITE(Registers->ByteCountLow, 0x55);
731 ATA_WRITE(Registers->ByteCountLow, 0xAA);
732 ATA_WRITE(Registers->ByteCountLow, 0x55);
733 if (ATA_READ(Registers->ByteCountLow) != 0x55)
734 return FALSE;
735 ATA_WRITE(Registers->ByteCountHigh, 0xAA);
736 ATA_WRITE(Registers->ByteCountHigh, 0x55);
737 ATA_WRITE(Registers->ByteCountHigh, 0xAA);
738 if (ATA_READ(Registers->ByteCountHigh) != 0xAA)
739 return FALSE;
740
741 if (!AtapWaitForNotBusy(Registers, ATA_TIME_BUSY_ENUM, &IdeStatus))
742 {
743 ERR("Device %X:%u is busy %02x\n", Registers->Data, DeviceUnit->DeviceNumber, IdeStatus);
744
745 /* Bring the device into a known state */
746 if (!AtapPerformSoftwareReset(DeviceUnit))
747 return FALSE;
748 }
749
750 return TRUE;
751}
static VOID AtapSelectDevice(_In_ PIDE_REGISTERS Registers, _In_range_(0, 3) UCHAR DeviceNumber)
Definition: hwide.c:58
static BOOLEAN AtapWaitForNotBusy(_In_ PIDE_REGISTERS Registers, _In_range_(>, 0) ULONG Timeout, _Out_opt_ PUCHAR Result)
Definition: hwide.c:73
static BOOLEAN AtapPerformSoftwareReset(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:238
#define ATA_TIME_BUSY_ENUM
1 ms
Definition: hwidep.h:69
#define ATA_WRITE(Port, Value)
Definition: hwidep.h:75
IDE_REG Status
Definition: hwidep.h:130
IDE_REG ByteCountHigh
Definition: hwidep.h:123
IDE_REG ByteCountLow
Definition: hwidep.h:117

Referenced by AtapIdentifyDevice().

◆ AtapIssueCommand()

static BOOLEAN AtapIssueCommand ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request 
)
static

Definition at line 511 of file hwide.c.

514{
515 ULONG RetryCount;
516
517 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
518 {
519 UCHAR AtaStatus;
520
521 AtaStatus = AtapSendCommand(DeviceUnit, Request);
522
523 if ((AtaStatus != ATA_STATUS_SUCCESS) &&
525 {
526 ERR("ATA%s command %02X failed %u %02X:%02X at %X:%u\n",
527 (Request->Flags & REQUEST_FLAG_PACKET_COMMAND) ? "PI" : "",
529 Request->Cdb[0] : Request->TaskFile.Command,
530 AtaStatus,
531 ATA_READ(DeviceUnit->Registers.Status),
532 ATA_READ(DeviceUnit->Registers.Error),
533 DeviceUnit->Registers.Data,
534 DeviceUnit->DeviceNumber);
535 }
536
537 switch (AtaStatus)
538 {
540 return TRUE;
541
542 case ATA_STATUS_RETRY:
543 break;
544
545 case ATA_STATUS_RESET:
546 {
548 {
549 /*
550 * Some controllers indicate status 0x00
551 * when the selected device does not exist,
552 * no point in going further.
553 */
554 if (ATA_READ(DeviceUnit->Registers.Status) == 0)
555 return FALSE;
556 }
557
558 /* Turn off various things and retry the command */
559 DeviceUnit->MultiSectorTransfer = 0;
560 DeviceUnit->P.Flags &= ~ATA_DEVICE_FLAG_IO32;
561
562 if (!AtapPerformSoftwareReset(DeviceUnit))
563 return FALSE;
564
565 break;
566 }
567
568 default:
569 {
571 {
572 if (!AtapAtapiHandleError(DeviceUnit))
573 return FALSE;
574 }
575
576 /* Only retry failed read commands */
577 if (!(Request->Flags & REQUEST_FLAG_READ_COMMAND))
578 return FALSE;
579
580 break;
581 }
582 }
583 }
584
585 return FALSE;
586}
static BOOLEAN AtapAtapiHandleError(_In_ PHW_DEVICE_UNIT DeviceUnit)
Definition: hwide.c:491
#define REQUEST_FLAG_IDENTIFY_COMMAND
Definition: hwidep.h:168
#define ATA_STATUS_RESET
Definition: hwidep.h:15
#define ATA_STATUS_RETRY
Definition: hwidep.h:16

Referenced by AtapAtapiReadCapacity10(), AtapAtapiReadCapacity16(), AtapAtapiReadToc(), AtapAtapiRequestSense(), AtapAtapiTestUnitReady(), AtapAtaSetMultipleMode(), AtapReadIdentifyData(), and AtaReadLogicalSectors().

◆ AtapIssuePacketCommand()

static VOID AtapIssuePacketCommand ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request 
)
static

Definition at line 380 of file hwide.c.

383{
385
387
388 /*
389 * If a larger transfer is attempted, the 16-bit ByteCount register might overflow.
390 * In this case we round down the length to the closest multiple of 2.
391 */
392 ByteCount = min(Request->DataTransferLength, 0xFFFE);
393
394 /* Prepare to transfer a device command */
395 ATA_WRITE(DeviceUnit->Registers.ByteCountLow, (UCHAR)(ByteCount >> 0));
396 ATA_WRITE(DeviceUnit->Registers.ByteCountHigh, (UCHAR)(ByteCount >> 8));
397 ATA_WRITE(DeviceUnit->Registers.Features, IDE_FEATURE_PIO);
398 ATA_WRITE(DeviceUnit->Registers.Command, IDE_COMMAND_ATAPI_PACKET);
399}
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
#define REQUEST_FLAG_AWAIT_CDB
Definition: hwidep.h:166
#define IDE_FEATURE_PIO
Definition: hwidep.h:50
#define min(a, b)
Definition: monoChain.cc:55
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099

Referenced by AtapSendCommand().

◆ AtapLoadTaskFile()

static VOID AtapLoadTaskFile ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request 
)
static

Definition at line 403 of file hwide.c.

406{
407 PATA_TASKFILE TaskFile = &Request->TaskFile;
408 ULONG i, BlockCount;
409
410 /* Store the extra information in the second byte of FIFO for 48-bit commands */
411 i = (Request->Flags & REQUEST_FLAG_LBA48) ? 2 : 1;
412
413 while (i--)
414 {
415 ATA_WRITE(DeviceUnit->Registers.Features, TaskFile->Data[i].Feature);
416 ATA_WRITE(DeviceUnit->Registers.SectorCount, TaskFile->Data[i].SectorCount);
417 ATA_WRITE(DeviceUnit->Registers.LbaLow, TaskFile->Data[i].LowLba);
418 ATA_WRITE(DeviceUnit->Registers.LbaMid, TaskFile->Data[i].MidLba);
419 ATA_WRITE(DeviceUnit->Registers.LbaHigh, TaskFile->Data[i].HighLba);
420 }
422 {
423 ATA_WRITE(DeviceUnit->Registers.Device, TaskFile->DriveSelect);
424 }
425 ATA_WRITE(DeviceUnit->Registers.Command, TaskFile->Command);
426
427 /* Set the byte count per DRQ data block */
429 BlockCount = DeviceUnit->MultiSectorTransfer;
430 else
431 BlockCount = 1;
432 DeviceUnit->DrqByteCount = BlockCount * DeviceUnit->P.SectorSize;
433}

Referenced by AtapSendCommand().

◆ AtapPerformSoftwareReset()

static BOOLEAN AtapPerformSoftwareReset ( _In_ PHW_DEVICE_UNIT  DeviceUnit)
static

Definition at line 238 of file hwide.c.

240{
241 PIDE_REGISTERS Registers = &DeviceUnit->Registers;
242
243 ERR("Reset device at %X:%u\n", Registers->Data, DeviceUnit->DeviceNumber);
244
245 /* Perform a software reset */
246 AtapSoftwareReset(Registers);
247
248 /* The reset will cause the master device to be selected */
249 if (DEV_SLAVE(DeviceUnit->DeviceNumber))
250 {
251 if (!AtapWaitForRegisterAccess(Registers, DeviceUnit->DeviceNumber))
252 return FALSE;
253 }
254
255 /* Now wait for busy to clear */
257 return FALSE;
258
259 return TRUE;
260}
static BOOLEAN AtapWaitForRegisterAccess(_In_ PIDE_REGISTERS Registers, _In_range_(0, 3) UCHAR DeviceNumber)
Definition: hwide.c:201
static VOID AtapSoftwareReset(_In_ PIDE_REGISTERS Registers)
Definition: hwide.c:227
#define ATA_TIME_BUSY_RESET
10 s
Definition: hwidep.h:70

Referenced by AtapIsDevicePresent(), and AtapIssueCommand().

◆ AtapPioDataIn()

static VOID AtapPioDataIn ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ ULONG  ByteCount 
)
static

Definition at line 174 of file hwide.c.

177{
178 ByteCount = min(ByteCount, DeviceUnit->BytesToTransfer);
179
180#if defined(ATA_SUPPORT_32_BIT_IO)
181 if (AtapIs32BitIoSupported(DeviceUnit))
182 {
183 ATA_READ_BLOCK_32(DeviceUnit->Registers.Data,
184 (PULONG)DeviceUnit->DataBuffer,
185 ByteCount / sizeof(ULONG));
186 }
187 else
188#endif
189 {
190 ATA_READ_BLOCK_16(DeviceUnit->Registers.Data,
191 (PUSHORT)DeviceUnit->DataBuffer,
192 ByteCount / sizeof(USHORT));
193 }
194
195 DeviceUnit->DataBuffer += ByteCount;
196 DeviceUnit->BytesToTransfer -= ByteCount;
197}
#define ATA_READ_BLOCK_16(Port, Buffer, Count)
Definition: hwidep.h:87
#define ATA_READ_BLOCK_32(Port, Buffer, Count)
Definition: hwidep.h:90
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by AtapProcessAtapiRequest(), and AtapProcessAtaRequest().

◆ AtapProcessAtapiRequest()

static UCHAR AtapProcessAtapiRequest ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request,
_In_ UCHAR  IdeStatus 
)
static

Definition at line 264 of file hwide.c.

268{
269 UCHAR InterruptReason;
270
271 InterruptReason = ATA_READ(DeviceUnit->Registers.InterruptReason);
272 InterruptReason &= ATAPI_INT_REASON_MASK;
273 InterruptReason |= IdeStatus & IDE_STATUS_DRQ;
274
275 switch (InterruptReason)
276 {
278 {
279 if (!(Request->Flags & REQUEST_FLAG_AWAIT_CDB))
280 return ATA_STATUS_RESET;
281
282 Request->Flags &= ~REQUEST_FLAG_AWAIT_CDB;
283
284 AtapSendCdb(DeviceUnit, Request);
285 return ATA_STATUS_PENDING;
286 }
287
289 {
291
292 if (!Request->DataBuffer || (Request->Flags & REQUEST_FLAG_AWAIT_CDB))
293 return ATA_STATUS_RESET;
294
295 ByteCount = ATA_READ(DeviceUnit->Registers.ByteCountLow);
296 ByteCount |= ATA_READ(DeviceUnit->Registers.ByteCountHigh) << 8;
297
298 AtapPioDataIn(DeviceUnit, ByteCount);
299 return ATA_STATUS_PENDING;
300 }
301
303 {
304 /* The NEC CDR-260 drive always clears CoD and IO on command completion */
305 if (!(DeviceUnit->P.Flags & ATA_DEVICE_IS_NEC_CDR260))
306 return ATA_STATUS_RESET;
307
309 }
311 {
312 if (IdeStatus & (IDE_STATUS_ERROR | IDE_STATUS_DEVICE_FAULT))
313 return ATA_STATUS_ERROR;
314
315 break;
316 }
317
318 default:
319 return ATA_STATUS_RESET;
320 }
321
322 return ATA_STATUS_SUCCESS;
323}
#define IDE_STATUS_DEVICE_FAULT
Definition: ata.h:624
#define IDE_STATUS_ERROR
Definition: atapi.h:125
#define IDE_STATUS_DRQ
Definition: atapi.h:128
static VOID AtapPioDataIn(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ ULONG ByteCount)
Definition: hwide.c:174
static VOID AtapSendCdb(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
Definition: hwide.c:131
#define ATA_STATUS_ERROR
Definition: hwidep.h:14
#define ATAPI_INT_REASON_STATUS_NEC
Definition: hwidep.h:60
#define ATAPI_INT_REASON_STATUS
Definition: hwidep.h:61
#define ATAPI_INT_REASON_MASK
Definition: hwidep.h:58
#define ATAPI_INT_REASON_AWAIT_CDB
Definition: hwidep.h:62
#define ATAPI_INT_REASON_DATA_IN
Definition: hwidep.h:63
#define ATA_STATUS_PENDING
Definition: hwidep.h:13
#define __fallthrough
Definition: sal_old.h:314

Referenced by AtapProcessRequest().

◆ AtapProcessAtaRequest()

static UCHAR AtapProcessAtaRequest ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request,
_In_ UCHAR  IdeStatus 
)
static

Definition at line 327 of file hwide.c.

331{
332 /* Check for errors */
333 if (IdeStatus & (IDE_STATUS_ERROR | IDE_STATUS_DEVICE_FAULT))
334 {
335 if (IdeStatus & IDE_STATUS_DRQ)
336 return ATA_STATUS_RESET;
337 else
338 return ATA_STATUS_ERROR;
339 }
340
341 /* Read command */
342 if (Request->DataBuffer)
343 {
344 if (!(IdeStatus & IDE_STATUS_DRQ))
345 return ATA_STATUS_RESET;
346
347 /* Read the next data block */
348 AtapPioDataIn(DeviceUnit, DeviceUnit->DrqByteCount);
349
350 if (DeviceUnit->BytesToTransfer != 0)
351 return ATA_STATUS_PENDING;
352
353 /* All data has been transferred, wait for DRQ to clear */
354 if (!AtapWaitForIdle(&DeviceUnit->Registers, &IdeStatus))
355 return ATA_STATUS_RESET;
356
357 if (IdeStatus & (IDE_STATUS_ERROR | IDE_STATUS_DEVICE_FAULT))
358 return ATA_STATUS_ERROR;
359 }
360
361 /* Status phase or non-data ATA command */
362 return ATA_STATUS_SUCCESS;
363}
static BOOLEAN AtapWaitForIdle(_In_ PIDE_REGISTERS Registers, _Out_ PUCHAR Result)
Definition: hwide.c:106

Referenced by AtapProcessRequest().

◆ AtapProcessRequest()

static BOOLEAN AtapProcessRequest ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request,
_In_ UCHAR  IdeStatus 
)
static

Definition at line 367 of file hwide.c.

371{
373 return AtapProcessAtapiRequest(DeviceUnit, Request, IdeStatus);
374 else
375 return AtapProcessAtaRequest(DeviceUnit, Request, IdeStatus);
376}
static UCHAR AtapProcessAtapiRequest(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
Definition: hwide.c:264
static UCHAR AtapProcessAtaRequest(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
Definition: hwide.c:327

Referenced by AtapSendCommand().

◆ AtapReadIdentifyData()

static BOOLEAN AtapReadIdentifyData ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ UCHAR  Command 
)
static

Definition at line 755 of file hwide.c.

758{
760 PIDENTIFY_DEVICE_DATA Id = &DeviceUnit->IdentifyDeviceData;
761
762 /* Send the identify command */
764 Request.DataBuffer = Id;
765 Request.DataTransferLength = sizeof(*Id);
766 Request.TaskFile.Command = Command;
767
768 return AtapIssueCommand(DeviceUnit, &Request);
769}
Definition: shell.h:41

Referenced by AtapIdentifyDevice().

◆ AtapSelectDevice()

static VOID AtapSelectDevice ( _In_ PIDE_REGISTERS  Registers,
_In_range_(0, 3) UCHAR  DeviceNumber 
)
static

Definition at line 58 of file hwide.c.

61{
62#if defined(SARCH_PC98)
63 /* Select the primary (0) or secondary (1) IDE channel */
64 ATA_WRITE(0x432, DeviceNumber >> 1);
65#endif
66
67 ATA_WRITE(Registers->Device, (DEV_SLAVE(DeviceNumber) << 4) | IDE_DRIVE_SELECT);
69}
#define ATA_IO_WAIT()
Definition: hwidep.h:37

Referenced by AtapIsDevicePresent(), AtapSendCommand(), and AtapWaitForRegisterAccess().

◆ AtapSendCdb()

static VOID AtapSendCdb ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request 
)
static

Definition at line 131 of file hwide.c.

134{
135#if defined(ATA_SUPPORT_32_BIT_IO)
136 if (AtapIs32BitIoSupported(DeviceUnit))
137 {
138 ATA_WRITE_BLOCK_32(DeviceUnit->Registers.Data,
139 Request->Cdb,
140 DeviceUnit->CdbSize / sizeof(USHORT));
141 }
142 else
143#endif
144 {
145 ATA_WRITE_BLOCK_16(DeviceUnit->Registers.Data,
146 Request->Cdb,
147 DeviceUnit->CdbSize);
148 }
149
150 /*
151 * In polled mode (interrupts disabled)
152 * the NEC CDR-260 drive clears BSY before updating the interrupt reason register.
153 * As a workaround, we will wait for the phase change.
154 */
155 if (DeviceUnit->P.Flags & ATA_DEVICE_IS_NEC_CDR260)
156 {
157 ULONG i;
158
159 ATA_IO_WAIT();
160
161 for (i = 0; i < ATA_TIME_PHASE_CHANGE; ++i)
162 {
163 UCHAR InterruptReason = ATA_READ(DeviceUnit->Registers.InterruptReason);
164 if (InterruptReason != ATAPI_INT_REASON_COD)
165 break;
166
168 }
169 }
170}
#define ATA_WRITE_BLOCK_16(Port, Buffer, Count)
Definition: hwidep.h:78
#define ATA_TIME_PHASE_CHANGE
1 ms
Definition: hwidep.h:73
#define ATAPI_INT_REASON_COD
Definition: hwidep.h:56
#define ATA_WRITE_BLOCK_32(Port, Buffer, Count)
Definition: hwidep.h:81

Referenced by AtapProcessAtapiRequest().

◆ AtapSendCommand()

static UCHAR AtapSendCommand ( _In_ PHW_DEVICE_UNIT  DeviceUnit,
_In_ PATA_DEVICE_REQUEST  Request 
)
static

Definition at line 437 of file hwide.c.

440{
441 UCHAR AtaStatus;
442
443 DeviceUnit->BytesToTransfer = Request->DataTransferLength;
444 DeviceUnit->DataBuffer = Request->DataBuffer;
445
446 /* Select the device */
447 AtapSelectDevice(&DeviceUnit->Registers, DeviceUnit->DeviceNumber);
448 if (!AtapWaitForNotBusy(&DeviceUnit->Registers, ATA_TIME_BUSY_SELECT, NULL))
449 return ATA_STATUS_RETRY;
450
451 /* Always disable interrupts, otherwise it may lead to problems in underlying BIOS firmware */
452 ATA_WRITE(DeviceUnit->Registers.Control, IDE_DC_DISABLE_INTERRUPTS | IDE_DC_ALWAYS);
453
455 AtapIssuePacketCommand(DeviceUnit, Request);
456 else
457 AtapLoadTaskFile(DeviceUnit, Request);
458
459 while (TRUE)
460 {
461 UCHAR IdeStatus;
462
463 ATA_IO_WAIT();
464
465 if (!AtapWaitForNotBusy(&DeviceUnit->Registers, ATA_TIME_BUSY_POLL, &IdeStatus))
466 return ATA_STATUS_RESET;
467
468 AtaStatus = AtapProcessRequest(DeviceUnit, Request, IdeStatus);
469 if (AtaStatus != ATA_STATUS_PENDING)
470 break;
471 }
472
473 return AtaStatus;
474}
#define IDE_DC_DISABLE_INTERRUPTS
Definition: atapi.h:145
static VOID AtapLoadTaskFile(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
Definition: hwide.c:403
static VOID AtapIssuePacketCommand(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request)
Definition: hwide.c:380
static BOOLEAN AtapProcessRequest(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
Definition: hwide.c:367
#define ATA_TIME_BUSY_POLL
5 s
Definition: hwidep.h:68
#define IDE_DC_ALWAYS
Definition: hwidep.h:52
#define ATA_TIME_BUSY_SELECT
20 ms
Definition: hwidep.h:67

Referenced by AtapAtapiHandleError(), and AtapIssueCommand().

◆ AtapSoftwareReset()

static VOID AtapSoftwareReset ( _In_ PIDE_REGISTERS  Registers)
static

Definition at line 227 of file hwide.c.

229{
230 ATA_WRITE(Registers->Control, IDE_DC_RESET_CONTROLLER | IDE_DC_ALWAYS);
234}
#define IDE_DC_RESET_CONTROLLER
Definition: atapi.h:146

Referenced by AtapPerformSoftwareReset().

◆ AtapWaitForIdle()

static BOOLEAN AtapWaitForIdle ( _In_ PIDE_REGISTERS  Registers,
_Out_ PUCHAR  Result 
)
static

Definition at line 106 of file hwide.c.

109{
110 UCHAR IdeStatus;
111 ULONG i;
112
113 for (i = 0; i < ATA_TIME_DRQ_CLEAR; ++i)
114 {
115 IdeStatus = ATA_READ(Registers->Status);
116 if (!(IdeStatus & (IDE_STATUS_DRQ | IDE_STATUS_BUSY)))
117 {
118 *Result = IdeStatus;
119 return TRUE;
120 }
121
123 }
124
125 *Result = IdeStatus;
126 return FALSE;
127}
#define IDE_STATUS_BUSY
Definition: atapi.h:132
#define ATA_TIME_DRQ_CLEAR
200 us
Definition: hwidep.h:72
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by AtapProcessAtaRequest().

◆ AtapWaitForNotBusy()

static BOOLEAN AtapWaitForNotBusy ( _In_ PIDE_REGISTERS  Registers,
_In_range_(>, 0) ULONG  Timeout,
_Out_opt_ PUCHAR  Result 
)
static

Definition at line 73 of file hwide.c.

77{
78 UCHAR IdeStatus;
79 ULONG i;
80
81 ASSERT(Timeout != 0);
82
83 for (i = 0; i < Timeout; ++i)
84 {
85 IdeStatus = ATA_READ(Registers->Status);
86 if (!(IdeStatus & IDE_STATUS_BUSY))
87 {
88 if (Result)
89 *Result = IdeStatus;
90 return TRUE;
91 }
92
93 if (IdeStatus == 0xFF)
94 break;
95
97 }
98
99 if (Result)
100 *Result = IdeStatus;
101 return FALSE;
102}
static ULONG Timeout
Definition: ping.c:61

Referenced by AtapIsDevicePresent(), AtapPerformSoftwareReset(), and AtapSendCommand().

◆ AtapWaitForRegisterAccess()

static BOOLEAN AtapWaitForRegisterAccess ( _In_ PIDE_REGISTERS  Registers,
_In_range_(0, 3) UCHAR  DeviceNumber 
)
static

Definition at line 201 of file hwide.c.

204{
205 ULONG i;
206
207 for (i = 0; i < ATA_TIME_RESET_SELECT; ++i)
208 {
209 /* Select the device again */
210 AtapSelectDevice(Registers, DeviceNumber);
211
212 /* Check whether the selection was successful */
213 ATA_WRITE(Registers->ByteCountLow, 0xAA);
214 ATA_WRITE(Registers->ByteCountLow, 0x55);
215 ATA_WRITE(Registers->ByteCountLow, 0xAA);
216 if (ATA_READ(Registers->ByteCountLow) == 0xAA)
217 return TRUE;
218
220 }
221
222 return FALSE;
223}
#define ATA_TIME_RESET_SELECT
2 s
Definition: hwidep.h:71

Referenced by AtapPerformSoftwareReset().

◆ AtaReadLogicalSectors()

BOOLEAN AtaReadLogicalSectors ( _In_ PDEVICE_UNIT  DeviceUnit,
_In_ ULONG64  SectorNumber,
_In_ ULONG  SectorCount,
_Out_writes_bytes_all_(SectorCount *DeviceUnit->SectorSize) PVOID  Buffer 
)

Definition at line 1215 of file hwide.c.

1220{
1221 PHW_DEVICE_UNIT Unit = (PHW_DEVICE_UNIT)DeviceUnit;
1223
1224 ASSERT((SectorNumber + SectorCount) <= Unit->P.TotalSectors);
1225 ASSERT(SectorCount != 0);
1226
1227 while (SectorCount > 0)
1228 {
1229 ULONG BlockCount;
1230
1231 BlockCount = min(SectorCount, Unit->MaximumTransferLength);
1232
1233 Request.DataBuffer = Buffer;
1234 Request.DataTransferLength = BlockCount * Unit->P.SectorSize;
1235
1236 if (Unit->P.Flags & ATA_DEVICE_ATAPI)
1237 AtapBuildReadPacketCommand(&Request, SectorNumber, BlockCount);
1238 else
1239 AtapBuildReadTaskFile(Unit, &Request, SectorNumber, BlockCount);
1240
1242 return FALSE;
1243
1244 SectorNumber += BlockCount;
1245 SectorCount -= BlockCount;
1246
1247 Buffer = (PVOID)((ULONG_PTR)Buffer + Unit->P.SectorSize);
1248 }
1249
1250 return TRUE;
1251}
Definition: bufpool.h:45
Unit
Definition: gdiplusenums.h:26
static VOID AtapBuildReadPacketCommand(_In_ PATA_DEVICE_REQUEST Request, _In_ ULONG64 Lba, _In_ ULONG SectorCount)
Definition: hwide.c:677
static VOID AtapBuildReadTaskFile(_In_ PHW_DEVICE_UNIT DeviceUnit, _In_ PATA_DEVICE_REQUEST Request, _In_ ULONG64 Lba, _In_ ULONG SectorCount)
Definition: hwide.c:606
struct _HW_DEVICE_UNIT * PHW_DEVICE_UNIT
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by Pc98DiskReadLogicalSectorsLBA(), and XboxDiskReadLogicalSectors().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( DISK  )

Variable Documentation

◆ AtapChannelBaseArray

const IDE_REG AtapChannelBaseArray[]
static
Initial value:
=
{
0x1F0, 0x170, 0x1E8, 0x168
}

IDE Channels base - Primary, Secondary, Tertiary, Quaternary

Definition at line 25 of file hwide.c.

Referenced by AtapIdentifyChannel().

◆ AtapUnits

Definition at line 37 of file hwide.c.

Referenced by AtaGetDevice(), and AtaInit().