ReactOS 0.4.15-dev-7924-g5949c20
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))
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
static const ULONG BaseArray[]
Definition: hwide.c:41
#define IDX_IO1_i_Data
Definition: hwide.h:41
int Count
Definition: noreturn.cpp:7
unsigned short USHORT
Definition: pedump.c:61
uint16_t * PUSHORT
Definition: typedefs.h:56

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))
VOID NTAPI WRITE_PORT_BUFFER_USHORT(IN PUSHORT Port, IN PUSHORT Buffer, IN ULONG Count)
Definition: portio.c:87
#define IDX_IO1_o_Data
Definition: hwide.h:53

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}
unsigned char BOOLEAN
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ Success
Definition: eventcreate.c:712
static BOOLEAN AtapiReadyCheck(IN OUT PDEVICE_UNIT DeviceUnit)
Definition: hwide.c:554
static BOOLEAN AtapiReadLogicalSectorLBA(IN PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, OUT PVOID Buffer)
Definition: hwide.c:423
static BOOLEAN AtaReadLogicalSectorsLBA(IN PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
Definition: hwide.c:252
#define ATA_DEVICE_NOT_READY
Definition: hwide.h:305
#define ATA_DEVICE_ATAPI
Definition: hwide.h:303
#define ATA_DEVICE_NO_MEDIA
Definition: hwide.h:304
ULONG SectorCount
Definition: part_xbox.c:31
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char UCHAR
Definition: xmlstorage.h:181

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}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197
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 TAG_ATA_DEVICE
Definition: hwide.c:22
static PDEVICE_UNIT Units[MAX_CHANNELS *MAX_DEVICES]
Definition: hwide.c:55

◆ 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}

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
731}
#define ATA_STATUS_TIMEOUT
Definition: hwide.c:24
#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
#define IDE_DC_REENABLE_CONTROLLER
Definition: hwide.h:142
#define IDX_IO2_o_Control
Definition: hwide.h:62
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
#define TRACE(s)
Definition: solgame.cpp:4

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}
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
static BOOLEAN IdentifyDevice(IN UCHAR Channel, IN UCHAR DeviceNumber, OUT PDEVICE_UNIT *DeviceUnit)
Definition: hwide.c:750
#define MAX_DEVICES
Definition: hwide.c:53
#define MAX_CHANNELS
Definition: hwide.c:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

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}
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
#define AtaReadBuffer(Channel, Buffer, Count)
Definition: hwide.c:36
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
_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,
549 }
550}
static BOOLEAN AtapiRequestSense(IN PDEVICE_UNIT DeviceUnit, OUT PSENSE_DATA SenseData)
Definition: hwide.c:510
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
UCHAR SenseKey
Definition: cdrw_hw.h:1167

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}
#define SCSIOP_READ
Definition: cdrw_hw.h:905
static VOID SelectDevice(IN UCHAR Channel, IN UCHAR DeviceNumber)
Definition: hwide.c:735
#define AtaReadPort(Channel, Port)
Definition: hwide.c:29
#define IDX_ATAPI_IO1_i_ByteCountHigh
Definition: hwide.h:92
#define IDX_ATAPI_IO1_i_ByteCountLow
Definition: hwide.h:91
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755

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,
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 SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define SCSIOP_READ_TOC
Definition: cdrw_hw.h:927
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#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
ULONG DummyData
Definition: cmdata.c:18
static VOID AtapiCapacityDetect(IN PDEVICE_UNIT DeviceUnit, OUT PULONGLONG TotalSectors, OUT PULONG SectorSize)
Definition: hwide.c:474
#define MAXIMUM_CDROM_SIZE
Definition: hwide.h:288
#define READ_TOC_FORMAT_SESSION
Definition: scsi.h:178

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}
#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{
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 IDE_COMMAND_READ_EXT
Definition: ata.h:261
#define IDE_COMMAND_READ
Definition: atapi.h:104
#define UINT64_C(val)
Definition: freeldr.h:23
static BOOLEAN WaitForFlags(IN UCHAR Channel, IN UCHAR Flags, IN UCHAR ExpectedValue, IN ULONG Timeout)
Definition: hwide.c:650
#define IDX_IO1_o_BlockNumber
Definition: hwide.h:56
#define IDX_IO1_o_CylinderHigh
Definition: hwide.h:58
#define IDE_USE_LBA
Definition: hwide.h:133
#define IDE_DRIVE_SELECT_1
Definition: hwide.h:130
#define IDX_IO1_o_Feature
Definition: hwide.h:54
#define IDX_IO1_i_Status
Definition: hwide.h:48
#define IDE_STATUS_DRQ
Definition: hwide.h:113
#define ATA_PIO
Definition: hwide.h:161
#define IDE_DRIVE_1
Definition: hwide.h:128
#define ATA_DEVICE_CHS
Definition: hwide.h:308
#define IDE_DRIVE_SELECT_2
Definition: hwide.h:131
#define IDX_IO1_o_DriveSelect
Definition: hwide.h:59
#define IDX_IO1_o_Command
Definition: hwide.h:60
#define ATA_DEVICE_LBA48
Definition: hwide.h:306
#define IDX_IO1_i_Error
Definition: hwide.h:42
#define IDE_DRIVE_2
Definition: hwide.h:129
#define IDX_IO1_o_BlockCount
Definition: hwide.h:55
#define IDX_IO1_o_CylinderLow
Definition: hwide.h:57
#define UCHAR_MAX
Definition: limits.h:25
#define USHRT_MAX
Definition: limits.h:38
#define min(a, b)
Definition: monoChain.cc:55
Definition: shell.h:41
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67

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 */
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}
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
#define AtaWriteBuffer(Channel, Buffer, Count)
Definition: hwide.c:32
static BOOLEAN WaitForFlagsOr(IN UCHAR Channel, IN UCHAR FirstValue, IN UCHAR SecondValue, IN ULONG Timeout)
Definition: hwide.c:677
#define IDX_ATAPI_IO1_o_Command
Definition: hwide.h:103
#define IDE_STATUS_DRDY
Definition: hwide.h:117
#define IDX_ATAPI_IO1_o_ByteCountHigh
Definition: hwide.h:101
#define IDX_ATAPI_IO1_o_ByteCountLow
Definition: hwide.h:100
#define IDX_ATAPI_IO1_i_Status
Definition: hwide.h:94
#define IDX_ATAPI_IO1_o_Feature
Definition: hwide.h:97
#define IDX_ATAPI_IO1_i_Error
Definition: hwide.h:88
_In_ USHORT PacketSize
Definition: iofuncs.h:1058
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099

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;
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 */
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
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;
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
938Failure:
939 TRACE("IdentifyDevice() done. No device present at %d:%d\n", Channel, DeviceNumber);
940 return FALSE;
941}
DWORD Id
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define DbgDumpBuffer(mask, buf, len)
Definition: debug.h:119
#define DPRINT_DISK
Definition: debug.h:29
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
static VOID AtaHardReset(IN UCHAR Channel)
Definition: hwide.c:722
#define ATA_DEVICE_LBA
Definition: hwide.h:307
#define ATAPI_MAGIC_MSB
Definition: hwide.h:287
#define IDENTIFY_DATA_SIZE
Definition: hwide.h:284
#define IDX_IO1_i_BlockNumber
Definition: hwide.h:44
#define IDX_IO1_i_CylinderLow
Definition: hwide.h:45
#define IDX_IO1_i_BlockCount
Definition: hwide.h:43
#define IDX_IO1_i_CylinderHigh
Definition: hwide.h:46
#define ATAPI_MAGIC_LSB
Definition: hwide.h:286
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3197

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 WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
unsigned char * PUCHAR
Definition: typedefs.h:53

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}
#define IDE_STATUS_BUSY
Definition: hwide.h:119
#define ASSERT(a)
Definition: mode.c:44
static ULONG Timeout
Definition: ping.c:61

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{
657
658 ASSERT(Timeout != 0);
659
661
662 while (Timeout--)
663 {
665
668 return FALSE;
669 else if ((Status & Flags) == ExpectedValue)
670 return TRUE;
671 }
672 return FALSE;
673}
Status
Definition: gdiplustypes.h:25
#define IDE_STATUS_ERROR
Definition: hwide.h:110

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{
684
685 ASSERT(Timeout != 0);
686
688
689 while (Timeout--)
690 {
692
695 return FALSE;
696 else if ((Status & FirstValue) || (Status & SecondValue))
697 return TRUE;
698 }
699 return FALSE;
700}

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