ReactOS  0.4.15-dev-1206-g731eddf
hwide.c File Reference
#include <freeldr.h>
#include <hwide.h>
#include <ata.h>
#include <scsi.h>
#include <debug.h>
Include dependency graph for hwide.c:

Go to the source code of this file.

Macros

#define TAG_ATA_DEVICE   'DatA'
 
#define ATAPI_PACKET_SIZE(IdentifyData)   (IdentifyData.AtapiCmdSize ? 16 : 12)
 
#define ATA_STATUS_TIMEOUT   31e5
 
#define AtaWritePort(Channel, Port, Data)   WRITE_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port)), (Data))
 
#define AtaReadPort(Channel, Port)   READ_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port)))
 
#define AtaWriteBuffer(Channel, Buffer, Count)
 
#define AtaReadBuffer(Channel, Buffer, Count)
 
#define MAX_CHANNELS   RTL_NUMBER_OF(BaseArray)
 
#define MAX_DEVICES   2 /* Master/Slave */
 

Functions

 DBG_DEFAULT_CHANNEL (DISK)
 
static BOOLEAN WaitForFlags (IN UCHAR Channel, IN UCHAR Flags, IN UCHAR ExpectedValue, IN ULONG Timeout)
 
static BOOLEAN WaitForFlagsOr (IN UCHAR Channel, IN UCHAR FirstValue, IN UCHAR SecondValue, IN ULONG Timeout)
 
static BOOLEAN WaitForBusy (IN UCHAR Channel, IN ULONG Timeout)
 
static VOID SelectDevice (IN UCHAR Channel, IN UCHAR DeviceNumber)
 
static BOOLEAN IdentifyDevice (IN UCHAR Channel, IN UCHAR DeviceNumber, OUT PDEVICE_UNIT *DeviceUnit)
 
static BOOLEAN AtapiRequestSense (IN PDEVICE_UNIT DeviceUnit, OUT PSENSE_DATA SenseData)
 
static VOID AtapiPrintSenseData (IN PDEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapiReadyCheck (IN OUT PDEVICE_UNIT DeviceUnit)
 
static BOOLEAN AtapiReadLogicalSectorLBA (IN PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, OUT PVOID Buffer)
 
static BOOLEAN AtaReadLogicalSectorsLBA (IN PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
 
BOOLEAN AtaInit (OUT PUCHAR DetectedCount)
 
VOID AtaFree (VOID)
 
PDEVICE_UNIT AtaGetDevice (IN UCHAR UnitNumber)
 
BOOLEAN AtaAtapiReadLogicalSectorsLBA (IN OUT PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
 
static BOOLEAN AtaSendAtapiPacket (IN UCHAR Channel, IN PUCHAR AtapiPacket, IN UCHAR PacketSize, IN USHORT ByteCount)
 
static VOID AtapiCapacityDetect (IN PDEVICE_UNIT DeviceUnit, OUT PULONGLONG TotalSectors, OUT PULONG SectorSize)
 
static VOID AtaHardReset (IN UCHAR Channel)
 

Variables

static const ULONG BaseArray []
 
static PDEVICE_UNIT Units [MAX_CHANNELS *MAX_DEVICES]
 

Macro Definition Documentation

◆ ATA_STATUS_TIMEOUT

#define ATA_STATUS_TIMEOUT   31e5

Definition at line 24 of file hwide.c.

◆ ATAPI_PACKET_SIZE

#define ATAPI_PACKET_SIZE (   IdentifyData)    (IdentifyData.AtapiCmdSize ? 16 : 12)

Definition at line 23 of file hwide.c.

◆ AtaReadBuffer

#define AtaReadBuffer (   Channel,
  Buffer,
  Count 
)
Value:
(PUSHORT)(Buffer), (Count)/sizeof(USHORT))
#define IDX_IO1_i_Data
Definition: hwide.h:41
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
Definition: bufpool.h:45
#define UlongToPtr(u)
Definition: config.h:106
VOID NTAPI READ_PORT_BUFFER_USHORT(IN PUSHORT Port, OUT PUSHORT Buffer, IN ULONG Count)
Definition: portio.c:36
unsigned short USHORT
Definition: pedump.c:61
static const ULONG BaseArray[]
Definition: hwide.c:41
unsigned short * PUSHORT
Definition: retypes.h:2

Definition at line 36 of file hwide.c.

◆ AtaReadPort

#define AtaReadPort (   Channel,
  Port 
)    READ_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port)))

Definition at line 29 of file hwide.c.

◆ AtaWriteBuffer

#define AtaWriteBuffer (   Channel,
  Buffer,
  Count 
)
Value:
(PUSHORT)(Buffer), (Count)/sizeof(USHORT))
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
Definition: bufpool.h:45
#define UlongToPtr(u)
Definition: config.h:106
unsigned short USHORT
Definition: pedump.c:61
#define IDX_IO1_o_Data
Definition: hwide.h:53
static const ULONG BaseArray[]
Definition: hwide.c:41
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI WRITE_PORT_BUFFER_USHORT(IN PUSHORT Port, IN PUSHORT Buffer, IN ULONG Count)
Definition: portio.c:87

Definition at line 32 of file hwide.c.

◆ AtaWritePort

#define AtaWritePort (   Channel,
  Port,
  Data 
)    WRITE_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port)), (Data))

Definition at line 26 of file hwide.c.

◆ MAX_CHANNELS

#define MAX_CHANNELS   RTL_NUMBER_OF(BaseArray)

Definition at line 52 of file hwide.c.

◆ MAX_DEVICES

#define MAX_DEVICES   2 /* Master/Slave */

Definition at line 53 of file hwide.c.

◆ TAG_ATA_DEVICE

#define TAG_ATA_DEVICE   'DatA'

Definition at line 22 of file hwide.c.

Function Documentation

◆ AtaAtapiReadLogicalSectorsLBA()

BOOLEAN AtaAtapiReadLogicalSectorsLBA ( IN OUT PDEVICE_UNIT  DeviceUnit,
IN ULONGLONG  SectorNumber,
IN ULONG  SectorCount,
OUT PVOID  Buffer 
)

Definition at line 187 of file hwide.c.

192 {
193  UCHAR RetryCount;
195 
196  if (DeviceUnit == NULL || SectorCount == 0)
197  return FALSE;
198 
199  if (DeviceUnit->Flags & ATA_DEVICE_ATAPI)
200  {
201  if ((DeviceUnit->Flags & ATA_DEVICE_NO_MEDIA) || (DeviceUnit->Flags & ATA_DEVICE_NOT_READY))
202  {
203  /* Retry 4 times */
204  for (RetryCount = 0; RetryCount < 4; ++RetryCount)
205  {
206  /* Make the device ready */
207  if (AtapiReadyCheck(DeviceUnit))
208  break;
209  }
210  if (RetryCount >= 4)
211  {
212  ERR("AtaAtapiReadLogicalSectorsLBA(): Device not ready.\n");
213  return FALSE;
214  }
215  }
216  if (SectorNumber + SectorCount > DeviceUnit->TotalSectors + 1)
217  {
218  ERR("AtaAtapiReadLogicalSectorsLBA(): Attempt to read more than there is to read.\n");
219  return FALSE;
220  }
221 
222  while (SectorCount > 0)
223  {
224  /* Read a single sector */
225  Success = AtapiReadLogicalSectorLBA(DeviceUnit, SectorNumber, Buffer);
226  if (!Success)
227  return FALSE;
228 
229  --SectorCount;
230  ++SectorNumber;
231  Buffer = (PVOID)((ULONG_PTR)Buffer + DeviceUnit->SectorSize);
232  }
233  }
234  else
235  {
236  /* Retry 3 times */
237  for (RetryCount = 0; RetryCount < 3; ++RetryCount)
238  {
239  /* Read a multiple sectors */
240  Success = AtaReadLogicalSectorsLBA(DeviceUnit, SectorNumber, SectorCount, Buffer);
241  if (Success)
242  return TRUE;
243  }
244  return FALSE;
245  }
246 
247  return TRUE;
248 }
#define TRUE
Definition: types.h:120
static BOOLEAN AtapiReadLogicalSectorLBA(IN PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, OUT PVOID Buffer)
Definition: hwide.c:423
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ATA_DEVICE_NOT_READY
Definition: hwide.h:305
#define FALSE
Definition: types.h:117
#define ATA_DEVICE_NO_MEDIA
Definition: hwide.h:304
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONG SectorCount
Definition: part_xbox.c:31
static BOOLEAN AtaReadLogicalSectorsLBA(IN PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
Definition: hwide.c:252
#define ERR(fmt,...)
Definition: debug.h:110
#define ATA_DEVICE_ATAPI
Definition: hwide.h:303
static BOOLEAN AtapiReadyCheck(IN OUT PDEVICE_UNIT DeviceUnit)
Definition: hwide.c:554

Referenced by Pc98DiskReadLogicalSectorsLBA(), and XboxDiskReadLogicalSectors().

◆ AtaFree()

VOID AtaFree ( VOID  )

Definition at line 166 of file hwide.c.

167 {
168  UCHAR i;
169 
170  for (i = 0; i < RTL_NUMBER_OF(Units); ++i)
171  {
172  if (Units[i])
174  }
175 }
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
static PDEVICE_UNIT Units[MAX_CHANNELS *MAX_DEVICES]
Definition: hwide.c:55
unsigned char UCHAR
Definition: xmlstorage.h:181
#define TAG_ATA_DEVICE
Definition: hwide.c:22
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by Pc98DiskPrepareForReactOS(), and XboxDiskInit().

◆ AtaGetDevice()

PDEVICE_UNIT AtaGetDevice ( IN UCHAR  UnitNumber)

Definition at line 178 of file hwide.c.

179 {
180  if (UnitNumber < RTL_NUMBER_OF(Units))
181  return Units[UnitNumber];
182  else
183  return NULL;
184 }
static PDEVICE_UNIT Units[MAX_CHANNELS *MAX_DEVICES]
Definition: hwide.c:55
smooth NULL
Definition: ftsmooth.c:416
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12

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

◆ AtaHardReset()

static VOID AtaHardReset ( IN UCHAR  Channel)
static

Definition at line 722 of file hwide.c.

723 {
724  TRACE("AtaHardReset(Controller %d)\n", Channel);
725 
727  StallExecutionProcessor(100000);
731 }
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define IDX_IO2_o_Control
Definition: hwide.h:62
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define IDE_DC_REENABLE_CONTROLLER
Definition: hwide.h:142
#define TRACE(s)
Definition: solgame.cpp:4
#define AtaWritePort(Channel, Port, Data)
Definition: hwide.c:26
static BOOLEAN WaitForBusy(IN UCHAR Channel, IN ULONG Timeout)
Definition: hwide.c:704
#define IDE_DC_RESET_CONTROLLER
Definition: hwide.h:139

Referenced by IdentifyDevice().

◆ AtaInit()

BOOLEAN AtaInit ( OUT PUCHAR  DetectedCount)

Definition at line 139 of file hwide.c.

140 {
141  UCHAR Channel, DeviceNumber;
142  PDEVICE_UNIT DeviceUnit = NULL;
143 
144  TRACE("AtaInit()\n");
145 
146  *DetectedCount = 0;
147 
148  RtlZeroMemory(&Units, sizeof(Units));
149 
150  /* Detect and enumerate ATA/ATAPI devices */
151  for (Channel = 0; Channel < MAX_CHANNELS; ++Channel)
152  {
154  {
155  if (IdentifyDevice(Channel, DeviceNumber, &DeviceUnit))
156  {
157  Units[(*DetectedCount)++] = DeviceUnit;
158  }
159  }
160  }
161 
162  return (*DetectedCount > 0);
163 }
static PDEVICE_UNIT Units[MAX_CHANNELS *MAX_DEVICES]
Definition: hwide.c:55
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
static BOOLEAN IdentifyDevice(IN UCHAR Channel, IN UCHAR DeviceNumber, OUT PDEVICE_UNIT *DeviceUnit)
Definition: hwide.c:750
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MAX_CHANNELS
Definition: hwide.c:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
#define MAX_DEVICES
Definition: hwide.c:53

Referenced by Pc98InitializeBootDevices(), and XboxDiskInit().

◆ AtapiCapacityDetect()

static VOID AtapiCapacityDetect ( IN PDEVICE_UNIT  DeviceUnit,
OUT PULONGLONG  TotalSectors,
OUT PULONG  SectorSize 
)
static

Definition at line 474 of file hwide.c.

478 {
479  UCHAR AtapiPacket[16];
480  UCHAR AtapiCapacity[8];
481 
482  /* Send the SCSI READ CAPACITY(10) command */
483  RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket));
484  AtapiPacket[0] = SCSIOP_READ_CAPACITY;
485  if (AtaSendAtapiPacket(DeviceUnit->Channel, AtapiPacket, ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), 8))
486  {
487  AtaReadBuffer(DeviceUnit->Channel, &AtapiCapacity, 8);
488 
489  *TotalSectors = (AtapiCapacity[0] << 24) | (AtapiCapacity[1] << 16) |
490  (AtapiCapacity[2] << 8) | AtapiCapacity[3];
491 
492  *SectorSize = (AtapiCapacity[4] << 24) | (AtapiCapacity[5] << 16) |
493  (AtapiCapacity[6] << 8) | AtapiCapacity[7];
494 
495  /* If device reports a non-zero block length, reset to defaults (we use READ command instead of READ CD) */
496  if (*SectorSize != 0)
497  *SectorSize = 2048;
498  }
499  else
500  {
501  *TotalSectors = 0;
502  *SectorSize = 0;
503 
504  AtapiPrintSenseData(DeviceUnit);
505  }
506 }
static BOOLEAN AtaSendAtapiPacket(IN UCHAR Channel, IN PUCHAR AtapiPacket, IN UCHAR PacketSize, IN USHORT ByteCount)
Definition: hwide.c:376
#define ATAPI_PACKET_SIZE(IdentifyData)
Definition: hwide.c:23
static VOID AtapiPrintSenseData(IN PDEVICE_UNIT DeviceUnit)
Definition: hwide.c:539
#define AtaReadBuffer(Channel, Buffer, Count)
Definition: hwide.c:36
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ ULONG SectorSize
Definition: halfuncs.h:291

Referenced by AtapiReadyCheck(), and IdentifyDevice().

◆ AtapiPrintSenseData()

static VOID AtapiPrintSenseData ( IN PDEVICE_UNIT  DeviceUnit)
static

Definition at line 539 of file hwide.c.

540 {
541  SENSE_DATA SenseData;
542 
543  if (AtapiRequestSense(DeviceUnit, &SenseData))
544  {
545  ERR("SK 0x%x, ASC 0x%x, ASCQ 0x%x\n",
546  SenseData.SenseKey,
547  SenseData.AdditionalSenseCode,
548  SenseData.AdditionalSenseCodeQualifier);
549  }
550 }
UCHAR SenseKey
Definition: cdrw_hw.h:1167
static BOOLEAN AtapiRequestSense(IN PDEVICE_UNIT DeviceUnit, OUT PSENSE_DATA SenseData)
Definition: hwide.c:510
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
#define ERR(fmt,...)
Definition: debug.h:110
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175

Referenced by AtapiCapacityDetect(), AtapiReadLogicalSectorLBA(), and AtapiReadyCheck().

◆ AtapiReadLogicalSectorLBA()

static BOOLEAN AtapiReadLogicalSectorLBA ( IN PDEVICE_UNIT  DeviceUnit,
IN ULONGLONG  SectorNumber,
OUT PVOID  Buffer 
)
static

Definition at line 423 of file hwide.c.

427 {
428  UCHAR AtapiPacket[16];
431 
432  /* Select the drive */
433  SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber);
434  if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT))
435  {
436  ERR("AtapiReadLogicalSectorLBA() failed. Device is busy!\n");
437  return FALSE;
438  }
439 
440  /* Disable interrupts */
443 
444  /* Send the SCSI READ command */
445  RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket));
446  AtapiPacket[0] = SCSIOP_READ;
447  AtapiPacket[2] = (SectorNumber >> 24) & 0xFF;
448  AtapiPacket[3] = (SectorNumber >> 16) & 0xFF;
449  AtapiPacket[4] = (SectorNumber >> 8) & 0xFF;
450  AtapiPacket[5] = SectorNumber & 0xFF;
451  AtapiPacket[8] = 1;
452  Success = AtaSendAtapiPacket(DeviceUnit->Channel,
453  AtapiPacket,
454  ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData),
455  DeviceUnit->SectorSize);
456  if (!Success)
457  {
458  ERR("AtapiReadLogicalSectorLBA() failed. A read error occurred.\n");
459  AtapiPrintSenseData(DeviceUnit);
460  return FALSE;
461  }
462 
463  DataSize = (AtaReadPort(DeviceUnit->Channel, IDX_ATAPI_IO1_i_ByteCountHigh) << 8) |
464  AtaReadPort(DeviceUnit->Channel, IDX_ATAPI_IO1_i_ByteCountLow);
465 
466  /* Transfer the data block */
467  AtaReadBuffer(DeviceUnit->Channel, Buffer, DataSize);
468 
469  return TRUE;
470 }
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
static BOOLEAN AtaSendAtapiPacket(IN UCHAR Channel, IN PUCHAR AtapiPacket, IN UCHAR PacketSize, IN USHORT ByteCount)
Definition: hwide.c:376
#define IDX_IO2_o_Control
Definition: hwide.h:62
#define TRUE
Definition: types.h:120
#define IDX_ATAPI_IO1_i_ByteCountHigh
Definition: hwide.h:92
#define ATAPI_PACKET_SIZE(IdentifyData)
Definition: hwide.c:23
static VOID AtapiPrintSenseData(IN PDEVICE_UNIT DeviceUnit)
Definition: hwide.c:539
#define AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define FALSE
Definition: types.h:117
#define SCSIOP_READ
Definition: cdrw_hw.h:905
unsigned char BOOLEAN
#define AtaReadBuffer(Channel, Buffer, Count)
Definition: hwide.c:36
Definition: bufpool.h:45
#define AtaWritePort(Channel, Port, Data)
Definition: hwide.c:26
static VOID SelectDevice(IN UCHAR Channel, IN UCHAR DeviceNumber)
Definition: hwide.c:735
unsigned char UCHAR
Definition: xmlstorage.h:181
static BOOLEAN WaitForBusy(IN UCHAR Channel, IN ULONG Timeout)
Definition: hwide.c:704
#define ERR(fmt,...)
Definition: debug.h:110
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
unsigned short USHORT
Definition: pedump.c:61
#define IDX_ATAPI_IO1_i_ByteCountLow
Definition: hwide.h:91
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751

Referenced by AtaAtapiReadLogicalSectorsLBA().

◆ AtapiReadyCheck()

static BOOLEAN AtapiReadyCheck ( IN OUT PDEVICE_UNIT  DeviceUnit)
static

Definition at line 554 of file hwide.c.

555 {
556  UCHAR AtapiPacket[16];
558  SENSE_DATA SenseData;
560 
561  /* Select the drive */
562  SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber);
563  if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT))
564  return FALSE;
565 
566  /* Send the SCSI TEST UNIT READY command */
567  RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket));
568  AtapiPacket[0] = SCSIOP_TEST_UNIT_READY;
569  AtaSendAtapiPacket(DeviceUnit->Channel,
570  AtapiPacket,
571  ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData),
572  0);
573 
574  if (!AtapiRequestSense(DeviceUnit, &SenseData))
575  return FALSE;
576 
577  AtaReadBuffer(DeviceUnit->Channel, &SenseData, SENSE_BUFFER_SIZE);
578  TRACE("SK 0x%x, ASC 0x%x, ASCQ 0x%x\n",
579  SenseData.SenseKey,
580  SenseData.AdditionalSenseCode,
581  SenseData.AdditionalSenseCodeQualifier);
582 
583  if (SenseData.SenseKey == SCSI_SENSE_NOT_READY)
584  {
586  {
587  switch (SenseData.AdditionalSenseCodeQualifier)
588  {
590  /* Wait until the CD is spun up */
592  return FALSE;
593 
595  /* The drive needs to be spun up, send the SCSI READ TOC command */
596  RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket));
597  AtapiPacket[0] = SCSIOP_READ_TOC;
598  AtapiPacket[7] = (MAXIMUM_CDROM_SIZE << 8) & 0xFF;
599  AtapiPacket[8] = MAXIMUM_CDROM_SIZE & 0xFF;
600  AtapiPacket[9] = READ_TOC_FORMAT_SESSION << 6;
601  Success = AtaSendAtapiPacket(DeviceUnit->Channel,
602  AtapiPacket,
603  ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData),
605  if (!Success)
606  {
607  AtapiPrintSenseData(DeviceUnit);
608  return FALSE;
609  }
610 
611  AtaReadBuffer(DeviceUnit->Channel, &DummyData, MAXIMUM_CDROM_SIZE);
612  /* fall through */
613 
614  default:
615  DeviceUnit->Flags &= ~ATA_DEVICE_NOT_READY;
616  return FALSE;
617 
618  }
619  }
621  {
622  DeviceUnit->Flags |= ATA_DEVICE_NO_MEDIA;
623  return FALSE;
624  }
625  }
626  else
627  {
628  DeviceUnit->Flags &= ~ATA_DEVICE_NOT_READY;
629  }
630 
631  if (DeviceUnit->Flags & ATA_DEVICE_NO_MEDIA)
632  {
633  /* Detect a medium's capacity */
634  AtapiCapacityDetect(DeviceUnit, &DeviceUnit->TotalSectors, &DeviceUnit->SectorSize);
635 
636  /* If nothing was returned, reset to defaults */
637  if (DeviceUnit->SectorSize == 0)
638  DeviceUnit->SectorSize = 2048;
639  if (DeviceUnit->TotalSectors == 0)
640  DeviceUnit->TotalSectors = 0xFFFFFFFF;
641 
642  DeviceUnit->Flags &= ~ATA_DEVICE_NO_MEDIA;
643  }
644 
645  return TRUE;
646 }
#define SCSIOP_READ_TOC
Definition: cdrw_hw.h:927
UCHAR SenseKey
Definition: cdrw_hw.h:1167
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
ULONG DummyData
Definition: cmdata.c:18
static BOOLEAN AtaSendAtapiPacket(IN UCHAR Channel, IN PUCHAR AtapiPacket, IN UCHAR PacketSize, IN USHORT ByteCount)
Definition: hwide.c:376
#define TRUE
Definition: types.h:120
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define ATAPI_PACKET_SIZE(IdentifyData)
Definition: hwide.c:23
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
static BOOLEAN AtapiRequestSense(IN PDEVICE_UNIT DeviceUnit, OUT PSENSE_DATA SenseData)
Definition: hwide.c:510
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define ATA_DEVICE_NOT_READY
Definition: hwide.h:305
static VOID AtapiPrintSenseData(IN PDEVICE_UNIT DeviceUnit)
Definition: hwide.c:539
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define FALSE
Definition: types.h:117
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define ATA_DEVICE_NO_MEDIA
Definition: hwide.h:304
unsigned char BOOLEAN
#define AtaReadBuffer(Channel, Buffer, Count)
Definition: hwide.c:36
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
#define TRACE(s)
Definition: solgame.cpp:4
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
static VOID AtapiCapacityDetect(IN PDEVICE_UNIT DeviceUnit, OUT PULONGLONG TotalSectors, OUT PULONG SectorSize)
Definition: hwide.c:474
#define READ_TOC_FORMAT_SESSION
Definition: scsi.h:178
static VOID SelectDevice(IN UCHAR Channel, IN UCHAR DeviceNumber)
Definition: hwide.c:735
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MAXIMUM_CDROM_SIZE
Definition: hwide.h:288
static BOOLEAN WaitForBusy(IN UCHAR Channel, IN ULONG Timeout)
Definition: hwide.c:704
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175

Referenced by AtaAtapiReadLogicalSectorsLBA().

◆ AtapiRequestSense()

static BOOLEAN AtapiRequestSense ( IN PDEVICE_UNIT  DeviceUnit,
OUT PSENSE_DATA  SenseData 
)
static

Definition at line 510 of file hwide.c.

513 {
514  UCHAR AtapiPacket[16];
516 
517  RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket));
518  RtlZeroMemory(SenseData, sizeof(SENSE_DATA));
519  AtapiPacket[0] = SCSIOP_REQUEST_SENSE;
520  AtapiPacket[4] = SENSE_BUFFER_SIZE;
521  Success = AtaSendAtapiPacket(DeviceUnit->Channel,
522  AtapiPacket,
523  ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData),
525  if (Success)
526  {
527  AtaReadBuffer(DeviceUnit->Channel, SenseData, SENSE_BUFFER_SIZE);
528  return TRUE;
529  }
530  else
531  {
532  ERR("Cannot read the sense data.\n");
533  return FALSE;
534  }
535 }
static BOOLEAN AtaSendAtapiPacket(IN UCHAR Channel, IN PUCHAR AtapiPacket, IN UCHAR PacketSize, IN USHORT ByteCount)
Definition: hwide.c:376
#define TRUE
Definition: types.h:120
#define ATAPI_PACKET_SIZE(IdentifyData)
Definition: hwide.c:23
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define AtaReadBuffer(Channel, Buffer, Count)
Definition: hwide.c:36
unsigned char UCHAR
Definition: xmlstorage.h:181
#define ERR(fmt,...)
Definition: debug.h:110
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870

Referenced by AtapiPrintSenseData(), AtapiReadyCheck(), and IdentifyDevice().

◆ AtaReadLogicalSectorsLBA()

static BOOLEAN AtaReadLogicalSectorsLBA ( IN PDEVICE_UNIT  DeviceUnit,
IN ULONGLONG  SectorNumber,
IN ULONG  SectorCount,
OUT PVOID  Buffer 
)
static

Definition at line 252 of file hwide.c.

257 {
258  UCHAR Command;
259  ULONG ChsTemp;
260  USHORT Cylinder;
261  UCHAR Head;
262  UCHAR Sector;
263  ULONG BlockCount;
264  ULONG RemainingBlockCount;
265  ULONGLONG Lba;
266  BOOLEAN UseLBA48;
267 
268  UseLBA48 = (DeviceUnit->Flags & ATA_DEVICE_LBA48) &&
269  (((SectorNumber + SectorCount) >= UINT64_C(0x0FFFFF80)) || SectorCount > 256);
270 
271  while (SectorCount > 0)
272  {
273  /* Prevent sector count overflow, divide it into maximum possible chunks and loop each one */
274  if (UseLBA48)
275  BlockCount = min(SectorCount, USHRT_MAX);
276  else
277  BlockCount = min(SectorCount, UCHAR_MAX);
278 
279  /* Convert LBA into a format CHS if needed */
280  if (DeviceUnit->Flags & ATA_DEVICE_CHS)
281  {
282  ChsTemp = DeviceUnit->IdentifyData.SectorsPerTrack * DeviceUnit->IdentifyData.NumberOfHeads;
283  if (ChsTemp)
284  {
285  Cylinder = SectorNumber / ChsTemp;
286  Head = (SectorNumber % ChsTemp) / DeviceUnit->IdentifyData.SectorsPerTrack;
287  Sector = (SectorNumber % DeviceUnit->IdentifyData.SectorsPerTrack) + 1;
288  }
289  else
290  {
291  Cylinder = 0;
292  Head = 0;
293  Sector = 1;
294  }
295  Lba = (Sector & 0xFF) | ((Cylinder & 0xFFFFF) << 8) | ((Head & 0x0F) << 24);
296  }
297  else
298  {
299  Lba = SectorNumber;
300  }
301 
302  /* Select the drive */
303  SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber);
304  if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT))
305  {
306  ERR("AtaReadLogicalSectorsLBA() failed. Device is busy.\n");
307  return FALSE;
308  }
309 
310  /* Disable interrupts */
313 
314  if (UseLBA48)
315  {
316  /* FIFO */
317  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, 0);
318  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, ATA_PIO);
319  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, (BlockCount >> 8) & 0xFF);
320  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, BlockCount & 0xFF);
321  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, (Lba >> 24) & 0xFF);
322  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, Lba & 0xFF);
323  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 32) & 0xFF);
324  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 8) & 0xFF);
325  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 40) & 0xFF);
326  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 16) & 0xFF);
327  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_DriveSelect,
328  IDE_USE_LBA | (DeviceUnit->DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1));
330  }
331  else
332  {
333  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, ATA_PIO);
334  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, BlockCount & 0xFF);
335  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, Lba & 0xFF);
336  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 8) & 0xFF);
337  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 16) & 0xFF);
338  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_DriveSelect,
339  ((Lba >> 24) & 0x0F) |
340  (DeviceUnit->Flags & ATA_DEVICE_CHS ? 0x00 : IDE_USE_LBA) |
341  (DeviceUnit->DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1));
343  }
344 
345  /* Send read command */
346  AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Command, Command);
348 
349  for (RemainingBlockCount = BlockCount; RemainingBlockCount > 0; --RemainingBlockCount)
350  {
351  /* Wait for ready to transfer data block */
352  if (!WaitForFlags(DeviceUnit->Channel, IDE_STATUS_DRQ,
354  {
355  ERR("AtaReadLogicalSectorsLBA() failed. Status: 0x%02x, Error: 0x%02x\n",
356  AtaReadPort(DeviceUnit->Channel, IDX_IO1_i_Status),
357  AtaReadPort(DeviceUnit->Channel, IDX_IO1_i_Error));
358  return FALSE;
359  }
360 
361  /* Transfer the data block */
362  AtaReadBuffer(DeviceUnit->Channel, Buffer, DeviceUnit->SectorSize);
363 
364  Buffer = (PVOID)((ULONG_PTR)Buffer + DeviceUnit->SectorSize);
365  }
366 
367  SectorNumber += BlockCount;
368  SectorCount -= BlockCount;
369  }
370 
371  return TRUE;
372 }
#define IDX_IO1_o_DriveSelect
Definition: hwide.h:59
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define IDX_IO2_o_Control
Definition: hwide.h:62
#define TRUE
Definition: types.h:120
#define ATA_PIO
Definition: hwide.h:161
#define IDE_COMMAND_READ
Definition: atapi.h:104
Definition: shell.h:41
#define ATA_DEVICE_CHS
Definition: hwide.h:308
#define ATA_DEVICE_LBA48
Definition: hwide.h:306
#define IDE_COMMAND_READ_EXT
Definition: ata.h:261
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define USHRT_MAX
Definition: limits.h:38
#define UINT64_C(val)
Definition: freeldr.h:23
#define AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define IDX_IO1_o_Feature
Definition: hwide.h:54
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define IDE_USE_LBA
Definition: hwide.h:133
#define AtaReadBuffer(Channel, Buffer, Count)
Definition: hwide.c:36
Definition: bufpool.h:45
#define IDX_IO1_o_CylinderHigh
Definition: hwide.h:58
void * PVOID
Definition: retypes.h:9
#define IDX_IO1_o_BlockNumber
Definition: hwide.h:56
struct Command Command
uint64_t ULONGLONG
Definition: typedefs.h:67
#define AtaWritePort(Channel, Port, Data)
Definition: hwide.c:26
static VOID SelectDevice(IN UCHAR Channel, IN UCHAR DeviceNumber)
Definition: hwide.c:735
unsigned char UCHAR
Definition: xmlstorage.h:181
static BOOLEAN WaitForBusy(IN UCHAR Channel, IN ULONG Timeout)
Definition: hwide.c:704
ULONG SectorCount
Definition: part_xbox.c:31
#define IDX_IO1_o_CylinderLow
Definition: hwide.h:57
#define ERR(fmt,...)
Definition: debug.h:110
#define IDE_DRIVE_SELECT_1
Definition: hwide.h:130
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
#define IDX_IO1_o_BlockCount
Definition: hwide.h:55
#define IDE_DRIVE_1
Definition: hwide.h:128
unsigned short USHORT
Definition: pedump.c:61
#define UCHAR_MAX
Definition: limits.h:25
#define IDX_IO1_o_Command
Definition: hwide.h:60
#define min(a, b)
Definition: monoChain.cc:55
#define IDX_IO1_i_Error
Definition: hwide.h:42
unsigned int ULONG
Definition: retypes.h:1
#define IDE_DRIVE_2
Definition: hwide.h:129
static BOOLEAN WaitForFlags(IN UCHAR Channel, IN UCHAR Flags, IN UCHAR ExpectedValue, IN ULONG Timeout)
Definition: hwide.c:650
#define IDE_STATUS_DRQ
Definition: hwide.h:113
#define IDX_IO1_i_Status
Definition: hwide.h:48
#define IDE_DRIVE_SELECT_2
Definition: hwide.h:131

Referenced by AtaAtapiReadLogicalSectorsLBA().

◆ AtaSendAtapiPacket()

static BOOLEAN AtaSendAtapiPacket ( IN UCHAR  Channel,
IN PUCHAR  AtapiPacket,
IN UCHAR  PacketSize,
IN USHORT  ByteCount 
)
static

Definition at line 376 of file hwide.c.

381 {
382  /*
383  * REQUEST SENSE is used by driver to clear the ATAPI 'Bus reset' indication.
384  * TEST UNIT READY doesn't require space for returned data.
385  */
386  UCHAR ExpectedFlagsMask = (AtapiPacket[0] == SCSIOP_REQUEST_SENSE) ?
388  UCHAR ExpectedFlags = ((AtapiPacket[0] == SCSIOP_TEST_UNIT_READY) ||
389  (AtapiPacket[0] == SCSIOP_REQUEST_SENSE)) ?
391 
392  /* PIO mode */
394 
395  /* Maximum byte count that is to be transferred */
397  AtaWritePort(Channel, IDX_ATAPI_IO1_o_ByteCountHigh, (ByteCount >> 8) & 0xFF);
398 
399  /* Prepare to transfer a device command via a command packet */
403  {
404  ERR("AtaSendAtapiPacket(0x%x) failed. A device error occurred Status: 0x%02x, Error: 0x%02x\n",
405  AtapiPacket[0], AtaReadPort(Channel, IDX_ATAPI_IO1_i_Status), AtaReadPort(Channel, IDX_ATAPI_IO1_i_Error));
406  return FALSE;
407  }
408 
409  /* Command packet transfer */
410  AtaWriteBuffer(Channel, AtapiPacket, PacketSize);
411  if (!WaitForFlags(Channel, ExpectedFlagsMask, ExpectedFlags, ATA_STATUS_TIMEOUT))
412  {
413  TRACE("AtaSendAtapiPacket(0x%x) failed. An execution error occurred Status: 0x%02x, Error: 0x%02x\n",
414  AtapiPacket[0], AtaReadPort(Channel, IDX_ATAPI_IO1_i_Status), AtaReadPort(Channel, IDX_ATAPI_IO1_i_Error));
415  return FALSE;
416  }
417 
418  return TRUE;
419 }
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define TRUE
Definition: types.h:120
#define ATA_PIO
Definition: hwide.h:161
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define IDX_ATAPI_IO1_o_ByteCountHigh
Definition: hwide.h:101
#define IDX_ATAPI_IO1_o_Command
Definition: hwide.h:103
#define AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define FALSE
Definition: types.h:117
#define IDX_ATAPI_IO1_o_Feature
Definition: hwide.h:97
#define TRACE(s)
Definition: solgame.cpp:4
#define IDX_ATAPI_IO1_i_Error
Definition: hwide.h:88
#define AtaWritePort(Channel, Port, Data)
Definition: hwide.c:26
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IDX_ATAPI_IO1_o_ByteCountLow
Definition: hwide.h:100
#define AtaWriteBuffer(Channel, Buffer, Count)
Definition: hwide.c:32
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1081
#define ERR(fmt,...)
Definition: debug.h:110
#define IDX_ATAPI_IO1_i_Status
Definition: hwide.h:94
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
#define IDE_STATUS_DRDY
Definition: hwide.h:117
static BOOLEAN WaitForFlagsOr(IN UCHAR Channel, IN UCHAR FirstValue, IN UCHAR SecondValue, IN ULONG Timeout)
Definition: hwide.c:677
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
static BOOLEAN WaitForFlags(IN UCHAR Channel, IN UCHAR Flags, IN UCHAR ExpectedValue, IN ULONG Timeout)
Definition: hwide.c:650
#define IDE_STATUS_DRQ
Definition: hwide.h:113

Referenced by AtapiCapacityDetect(), AtapiReadLogicalSectorLBA(), AtapiReadyCheck(), and AtapiRequestSense().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( DISK  )

◆ IdentifyDevice()

static BOOLEAN IdentifyDevice ( IN UCHAR  Channel,
IN UCHAR  DeviceNumber,
OUT PDEVICE_UNIT DeviceUnit 
)
static

Definition at line 750 of file hwide.c.

754 {
755  UCHAR SignatureLow, SignatureHigh, SignatureCount, SignatureNumber;
756  UCHAR Command;
758  SENSE_DATA SenseData;
759  ULONG i;
761  ULONGLONG TotalSectors;
762  USHORT Flags = 0;
763 
764  TRACE("IdentifyDevice() Channel = %x, Device = %x, BaseIoAddress = 0x%x\n",
765  Channel, DeviceNumber, BaseArray[Channel]);
766 
767  /* Look at controller */
768  SelectDevice(Channel, DeviceNumber);
770  AtaWritePort(Channel, IDX_IO1_o_BlockNumber, 0x55);
771  AtaWritePort(Channel, IDX_IO1_o_BlockNumber, 0x55);
773  if (AtaReadPort(Channel, IDX_IO1_i_BlockNumber) != 0x55)
774  goto Failure;
775 
776  /* Reset the controller */
777  AtaHardReset(Channel);
778 
779  /* Select the drive */
780  SelectDevice(Channel, DeviceNumber);
781  if (!WaitForBusy(Channel, ATA_STATUS_TIMEOUT))
782  goto Failure;
783 
784  /* Signature check */
785  SignatureLow = AtaReadPort(Channel, IDX_IO1_i_CylinderLow);
786  SignatureHigh = AtaReadPort(Channel, IDX_IO1_i_CylinderHigh);
787  SignatureCount = AtaReadPort(Channel, IDX_IO1_i_BlockCount);
788  SignatureNumber = AtaReadPort(Channel, IDX_IO1_i_BlockNumber);
789  TRACE("IdentifyDevice(): SL = 0x%x, SH = 0x%x, SC = 0x%x, SN = 0x%x\n",
790  SignatureLow, SignatureHigh, SignatureCount, SignatureNumber);
791  if (SignatureLow == 0x00 && SignatureHigh == 0x00 &&
792  SignatureCount == 0x01 && SignatureNumber == 0x01)
793  {
794  TRACE("IdentifyDevice(): Found PATA device at %d:%d\n", Channel, DeviceNumber);
796  }
797  else if (SignatureLow == ATAPI_MAGIC_LSB &&
798  SignatureHigh == ATAPI_MAGIC_MSB)
799  {
800  TRACE("IdentifyDevice(): Found ATAPI device at %d:%d\n", Channel, DeviceNumber);
803  }
804  else
805  {
806  goto Failure;
807  }
808 
809  /* Disable interrupts */
812 
813  /* Send the identify command */
817  {
818  ERR("IdentifyDevice(): Identify command failed.\n");
819  goto Failure;
820  }
821 
822  /* Receive parameter information from the device */
823  AtaReadBuffer(Channel, &Id, IDENTIFY_DATA_SIZE);
824 
825  /* Swap byte order of the ASCII data */
826  for (i = 0; i < RTL_NUMBER_OF(Id.SerialNumber); ++i)
827  Id.SerialNumber[i] = RtlUshortByteSwap(Id.SerialNumber[i]);
828 
829  for (i = 0; i < RTL_NUMBER_OF(Id.FirmwareRevision); ++i)
830  Id.FirmwareRevision[i] = RtlUshortByteSwap(Id.FirmwareRevision[i]);
831 
832  for (i = 0; i < RTL_NUMBER_OF(Id.ModelNumber); ++i)
833  Id.ModelNumber[i] = RtlUshortByteSwap(Id.ModelNumber[i]);
834 
835  TRACE("S/N %.*s\n", sizeof(Id.SerialNumber), Id.SerialNumber);
836  TRACE("FR %.*s\n", sizeof(Id.FirmwareRevision), Id.FirmwareRevision);
837  TRACE("MN %.*s\n", sizeof(Id.ModelNumber), Id.ModelNumber);
838 
839  /* Allocate a new device unit structure */
840  *DeviceUnit = FrLdrTempAlloc(sizeof(DEVICE_UNIT), TAG_ATA_DEVICE);
841  if (*DeviceUnit == NULL)
842  {
843  ERR("Failed to allocate device unit!\n");
844  return FALSE;
845  }
846 
847  RtlZeroMemory(*DeviceUnit, sizeof(DEVICE_UNIT));
848  (*DeviceUnit)->Channel = Channel;
849  (*DeviceUnit)->DeviceNumber = DeviceNumber;
850  (*DeviceUnit)->IdentifyData = Id;
851 
852  if (Flags & ATA_DEVICE_ATAPI)
853  {
854  /* Clear the ATAPI 'Bus reset' indication */
855  for (i = 0; i < 10; ++i)
856  {
857  AtapiRequestSense(*DeviceUnit, &SenseData);
859  }
860 
861  /* Detect a medium's capacity */
862  AtapiCapacityDetect(*DeviceUnit, &TotalSectors, &SectorSize);
863  if (SectorSize == 0 || TotalSectors == 0)
864  {
865  /* It's ok and can be used to show alert like "Please insert the CD" */
866  TRACE("No media found.\n");
868  }
869  }
870  else
871  {
872  if (Id.SupportLba || (Id.MajorRevision && Id.UserAddressableSectors))
873  {
874  if (Id.FeaturesSupport.Address48)
875  {
876  TRACE("Using LBA48 addressing mode.\n");
878  TotalSectors = Id.UserAddressableSectors48;
879  }
880  else
881  {
882  TRACE("Using LBA28 addressing mode.\n");
884  TotalSectors = Id.UserAddressableSectors;
885  }
886 
887  /* LBA ATA drives always have a sector size of 512 */
888  SectorSize = 512;
889  }
890  else
891  {
892  TRACE("Using CHS addressing mode.\n");
894 
895  if (Id.UnformattedBytesPerSector == 0)
896  {
897  SectorSize = 512;
898  }
899  else
900  {
901  for (i = 1 << 15; i > 0; i >>= 1)
902  {
903  if ((Id.UnformattedBytesPerSector & i) != 0)
904  {
905  SectorSize = i;
906  break;
907  }
908  }
909  }
910  TotalSectors = Id.NumberOfCylinders * Id.NumberOfHeads * Id.SectorsPerTrack;
911  }
912  }
913  TRACE("Sector size %d ; Total sectors %I64d\n", SectorSize, TotalSectors);
914 
915  (*DeviceUnit)->Flags = Flags;
916  (*DeviceUnit)->SectorSize = SectorSize;
917  (*DeviceUnit)->TotalSectors = TotalSectors;
918  if (Flags & ATA_DEVICE_ATAPI)
919  {
920  (*DeviceUnit)->Cylinders = 0xFFFFFFFF;
921  (*DeviceUnit)->Heads = 0xFFFFFFFF;
922  (*DeviceUnit)->Sectors = 0xFFFFFFFF;
923  }
924  else
925  {
926  (*DeviceUnit)->Cylinders = Id.NumberOfCylinders;
927  (*DeviceUnit)->Heads = Id.NumberOfHeads;
928  (*DeviceUnit)->Sectors = Id.SectorsPerTrack;
929  }
930 
931 #if DBG
933 #endif
934 
935  TRACE("IdentifyDevice() done.\n");
936  return TRUE;
937 
938 Failure:
939  TRACE("IdentifyDevice() done. No device present at %d:%d\n", Channel, DeviceNumber);
940  return FALSE;
941 }
#define IDENTIFY_DATA_SIZE
Definition: hwide.h:284
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define ATAPI_MAGIC_MSB
Definition: hwide.h:287
#define IDX_IO2_o_Control
Definition: hwide.h:62
#define ATAPI_MAGIC_LSB
Definition: hwide.h:286
#define TRUE
Definition: types.h:120
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3199
#define ATA_DEVICE_LBA
Definition: hwide.h:307
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
Definition: shell.h:41
#define ATA_DEVICE_CHS
Definition: hwide.h:308
#define ATA_DEVICE_LBA48
Definition: hwide.h:306
static BOOLEAN AtapiRequestSense(IN PDEVICE_UNIT DeviceUnit, OUT PSENSE_DATA SenseData)
Definition: hwide.c:510
DWORD Id
#define ATA_DEVICE_NOT_READY
Definition: hwide.h:305
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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 AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define FALSE
Definition: types.h:117
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
#define ATA_DEVICE_NO_MEDIA
Definition: hwide.h:304
smooth NULL
Definition: ftsmooth.c:416
#define AtaReadBuffer(Channel, Buffer, Count)
Definition: hwide.c:36
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define TRACE(s)
Definition: solgame.cpp:4
#define IDX_IO1_o_BlockNumber
Definition: hwide.h:56
struct Command Command
uint64_t ULONGLONG
Definition: typedefs.h:67
static VOID AtapiCapacityDetect(IN PDEVICE_UNIT DeviceUnit, OUT PULONGLONG TotalSectors, OUT PULONG SectorSize)
Definition: hwide.c:474
#define IDX_IO1_i_BlockCount
Definition: hwide.h:43
#define IDX_IO1_i_CylinderLow
Definition: hwide.h:45
#define AtaWritePort(Channel, Port, Data)
Definition: hwide.c:26
static VOID SelectDevice(IN UCHAR Channel, IN UCHAR DeviceNumber)
Definition: hwide.c:735
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IDX_IO1_i_BlockNumber
Definition: hwide.h:44
static BOOLEAN WaitForBusy(IN UCHAR Channel, IN ULONG Timeout)
Definition: hwide.c:704
#define TAG_ATA_DEVICE
Definition: hwide.c:22
#define ERR(fmt,...)
Definition: debug.h:110
#define ATA_DEVICE_ATAPI
Definition: hwide.h:303
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
unsigned short USHORT
Definition: pedump.c:61
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define IDX_IO1_o_Command
Definition: hwide.h:60
#define DbgDumpBuffer(mask, buf, len)
Definition: debug.h:119
static const ULONG BaseArray[]
Definition: hwide.c:41
#define DPRINT_DISK
Definition: debug.h:29
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static BOOLEAN WaitForFlags(IN UCHAR Channel, IN UCHAR Flags, IN UCHAR ExpectedValue, IN ULONG Timeout)
Definition: hwide.c:650
_In_ ULONG SectorSize
Definition: halfuncs.h:291
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
#define IDE_STATUS_DRQ
Definition: hwide.h:113
static VOID AtaHardReset(IN UCHAR Channel)
Definition: hwide.c:722
#define IDX_IO1_i_CylinderHigh
Definition: hwide.h:46

Referenced by AtaInit().

◆ SelectDevice()

static VOID SelectDevice ( IN UCHAR  Channel,
IN UCHAR  DeviceNumber 
)
static

Definition at line 735 of file hwide.c.

736 {
737 #if defined(SARCH_PC98)
738  /* Select IDE Channel */
739  WRITE_PORT_UCHAR((PUCHAR)IDE_IO_o_BankSelect, Channel);
741 #endif
742 
746 }
#define IDX_IO1_o_DriveSelect
Definition: hwide.h:59
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
unsigned char * PUCHAR
Definition: retypes.h:3
#define AtaWritePort(Channel, Port, Data)
Definition: hwide.c:26
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:20
#define IDE_DRIVE_SELECT_1
Definition: hwide.h:130
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
#define IDE_DRIVE_SELECT_2
Definition: hwide.h:131

Referenced by AtapiReadLogicalSectorLBA(), AtapiReadyCheck(), AtaReadLogicalSectorsLBA(), and IdentifyDevice().

◆ WaitForBusy()

static BOOLEAN WaitForBusy ( IN UCHAR  Channel,
IN ULONG  Timeout 
)
static

Definition at line 704 of file hwide.c.

707 {
708  ASSERT(Timeout != 0);
709 
710  while (Timeout--)
711  {
713 
714  if ((AtaReadPort(Channel, IDX_IO1_i_Status) & IDE_STATUS_BUSY) == 0)
715  return TRUE;
716  }
717  return FALSE;
718 }
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define TRUE
Definition: types.h:120
#define AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define FALSE
Definition: types.h:117
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IDE_STATUS_BUSY
Definition: hwide.h:119
static ULONG Timeout
Definition: ping.c:61
#define IDX_IO1_i_Status
Definition: hwide.h:48

Referenced by AtaHardReset(), AtapiReadLogicalSectorLBA(), AtapiReadyCheck(), AtaReadLogicalSectorsLBA(), IdentifyDevice(), WaitForFlags(), and WaitForFlagsOr().

◆ WaitForFlags()

static BOOLEAN WaitForFlags ( IN UCHAR  Channel,
IN UCHAR  Flags,
IN UCHAR  ExpectedValue,
IN ULONG  Timeout 
)
static

Definition at line 650 of file hwide.c.

655 {
656  UCHAR Status;
657 
658  ASSERT(Timeout != 0);
659 
661 
662  while (Timeout--)
663  {
665 
666  Status = AtaReadPort(Channel, IDX_IO1_i_Status);
667  if (Status & IDE_STATUS_ERROR)
668  return FALSE;
669  else if ((Status & Flags) == ExpectedValue)
670  return TRUE;
671  }
672  return FALSE;
673 }
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define TRUE
Definition: types.h:120
#define IDE_STATUS_ERROR
Definition: hwide.h:110
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define FALSE
Definition: types.h:117
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
static BOOLEAN WaitForBusy(IN UCHAR Channel, IN ULONG Timeout)
Definition: hwide.c:704
static ULONG Timeout
Definition: ping.c:61
#define IDX_IO1_i_Status
Definition: hwide.h:48

Referenced by AtaReadLogicalSectorsLBA(), AtaSendAtapiPacket(), and IdentifyDevice().

◆ WaitForFlagsOr()

static BOOLEAN WaitForFlagsOr ( IN UCHAR  Channel,
IN UCHAR  FirstValue,
IN UCHAR  SecondValue,
IN ULONG  Timeout 
)
static

Definition at line 677 of file hwide.c.

682 {
683  UCHAR Status;
684 
685  ASSERT(Timeout != 0);
686 
688 
689  while (Timeout--)
690  {
692 
693  Status = AtaReadPort(Channel, IDX_IO1_i_Status);
694  if (Status & IDE_STATUS_ERROR)
695  return FALSE;
696  else if ((Status & FirstValue) || (Status & SecondValue))
697  return TRUE;
698  }
699  return FALSE;
700 }
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define TRUE
Definition: types.h:120
#define IDE_STATUS_ERROR
Definition: hwide.h:110
#define AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#define FALSE
Definition: types.h:117
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
static BOOLEAN WaitForBusy(IN UCHAR Channel, IN ULONG Timeout)
Definition: hwide.c:704
static ULONG Timeout
Definition: ping.c:61
#define IDX_IO1_i_Status
Definition: hwide.h:48

Referenced by AtaSendAtapiPacket().

Variable Documentation

◆ BaseArray

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

Definition at line 41 of file hwide.c.

Referenced by IdentifyDevice(), KdDebuggerInitialize0(), KdPortInitializeEx(), KdpPortInitialize(), and otv_MarkBasePos_validate().

◆ Units