110#ifdef CACHE_MULTI_DRIVES
120#ifdef CACHE_MULTI_DRIVES
141 case 0x00:
return "No error";
142 case 0x01:
return "Bad command passed to driver";
143 case 0x02:
return "Address mark not found or bad sector";
144 case 0x03:
return "Diskette write protect error";
145 case 0x04:
return "Sector not found";
146 case 0x05:
return "Fixed disk reset failed";
147 case 0x06:
return "Diskette changed or removed";
148 case 0x07:
return "Bad fixed disk parameter table";
149 case 0x08:
return "DMA overrun";
150 case 0x09:
return "DMA access across 64k boundary";
151 case 0x0A:
return "Bad fixed disk sector flag";
152 case 0x0B:
return "Bad fixed disk cylinder";
153 case 0x0C:
return "Unsupported track/invalid media";
154 case 0x0D:
return "Invalid number of sectors on fixed disk format";
155 case 0x0E:
return "Fixed disk controlled data address mark detected";
156 case 0x0F:
return "Fixed disk DMA arbitration level out of range";
157 case 0x10:
return "ECC/CRC error on disk read";
158 case 0x11:
return "Recoverable fixed disk data error, data fixed by ECC";
159 case 0x20:
return "Controller error (NEC for floppies)";
160 case 0x40:
return "Seek failure";
161 case 0x80:
return "Time out, drive not ready";
162 case 0xAA:
return "Fixed disk drive not ready";
163 case 0xBB:
return "Fixed disk undefined error";
164 case 0xCC:
return "Fixed disk write fault on selected drive";
165 case 0xE0:
return "Fixed disk status error/Error reg = 0";
166 case 0xFF:
return "Sense operation failed";
168 default:
return "Unknown error code";
176 REGS RegsIn, RegsOut;
178 WARN(
"DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
190 RegsIn.
b.
dl = DriveNumber;
193 Int386(0x13, &RegsIn, &RegsOut);
206 if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
216 REGS RegsIn, RegsOut;
226 if (DriveNumber >= 0x8A)
256 RegsIn.
w.
bx = 0x55AA;
257 RegsIn.
b.
dl = DriveNumber;
260 Int386(0x13, &RegsIn, &RegsOut);
267 if (RegsOut.
w.
bx != 0xAA55)
274 TRACE(
"Drive 0x%x: INT 13h Extended version: 0x%02x, API bitmap: 0x%04x\n",
275 DriveNumber, RegsOut.
b.
ah, RegsOut.
w.
cx);
277 if (!(RegsOut.
w.
cx & 0x0001))
283 WARN(
"Drive 0x%x: Suspicious API subset support bitmap 0x%04x\n",
284 DriveNumber, RegsOut.
w.
cx);
299 REGS RegsIn, RegsOut;
301 TRACE(
"DiskGetExtendedDriveParameters(0x%x)\n", DriveNumber);
303 if (!DiskDrive->Int13ExtensionsSupported || (
BufferSize <
sizeof(*
Ptr)))
328 RegsIn.
b.
dl = DriveNumber;
333 Int386(0x13, &RegsIn, &RegsOut);
340 TRACE(
"Size of buffer: 0x%x\n",
Ptr->Size);
341 TRACE(
"Information flags: 0x%x\n",
Ptr->Flags);
342 TRACE(
"Number of physical cylinders on drive: %u\n",
Ptr->Cylinders);
343 TRACE(
"Number of physical heads on drive: %u\n",
Ptr->Heads);
344 TRACE(
"Number of physical sectors per track: %u\n",
Ptr->SectorsPerTrack);
345 TRACE(
"Total number of sectors on drive: %I64u\n",
Ptr->Sectors);
346 TRACE(
"Bytes per sector: %u\n",
Ptr->BytesPerSector);
347 if (
Ptr->Size >= 0x1E)
352 TRACE(
"EDD configuration parameters (DPTE): %x:%x\n", Seg,
Off);
356 if (
Ptr->PDPTE != 0xFFFFFFFF &&
Ptr->PDPTE != 0)
359 TRACE(
"SpecPtr: 0x%x\n", SpecPtr);
360 TRACE(
"Physical I/O port base address: 0x%x\n", *(
PUSHORT)&SpecPtr[0]);
361 TRACE(
"Disk-drive control port address: 0x%x\n", *(
PUSHORT)&SpecPtr[2]);
362 TRACE(
"Head register upper nibble: 0x%x\n", SpecPtr[4]);
363 TRACE(
"BIOS Vendor-specific: 0x%x\n", SpecPtr[5]);
364 TRACE(
"IRQ for drive: %u\n", SpecPtr[6]);
365 TRACE(
"Sector count for multi-sector transfers: %u\n", SpecPtr[7]);
366 TRACE(
"DMA control: 0x%x\n", SpecPtr[8]);
367 TRACE(
"Programmed I/O control: 0x%x\n", SpecPtr[9]);
371 if (
Ptr->Size >= 0x42)
398 REGS RegsIn, RegsOut;
402 RtlZeroMemory(&DiskDrive->ExtGeometry,
sizeof(DiskDrive->ExtGeometry));
404 &DiskDrive->ExtGeometry,
405 sizeof(DiskDrive->ExtGeometry));
408 TRACE(
"DiskGetExtendedDriveParameters(0x%x) returned:\n"
411 "Sects/Track: 0x%x\n"
412 "Total Sects: 0x%llx\n"
413 "Bytes/Sect : 0x%x\n",
415 DiskDrive->ExtGeometry.Cylinders,
416 DiskDrive->ExtGeometry.Heads,
417 DiskDrive->ExtGeometry.SectorsPerTrack,
418 DiskDrive->ExtGeometry.Sectors,
419 DiskDrive->ExtGeometry.BytesPerSector);
423 RtlZeroMemory(&DiskDrive->Geometry,
sizeof(DiskDrive->Geometry));
445 RegsIn.
b.
dl = DriveNumber;
446 RegsIn.
w.
es = 0x0000;
447 RegsIn.
w.
di = 0x0000;
450 Int386(0x13, &RegsIn, &RegsOut);
459 Cylinders = (RegsOut.
b.
cl & 0xC0) << 2;
460 Cylinders += RegsOut.
b.
ch;
462 DiskDrive->Geometry.Cylinders = Cylinders;
463 DiskDrive->Geometry.Heads = RegsOut.
b.
dh + 1;
464 DiskDrive->Geometry.SectorsPerTrack = RegsOut.
b.
cl & 0x3F;
465 DiskDrive->Geometry.BytesPerSector = 512;
467 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
468 DiskDrive->Geometry.Heads *
469 DiskDrive->Geometry.SectorsPerTrack;
471 TRACE(
"Regular Int13h(0x%x) returned:\n"
474 "Sects/Track: 0x%x\n"
475 "Total Sects: 0x%llx\n"
476 "Bytes/Sect : 0x%x\n",
478 DiskDrive->Geometry.Cylinders,
479 DiskDrive->Geometry.Heads,
480 DiskDrive->Geometry.SectorsPerTrack,
481 DiskDrive->Geometry.Sectors,
482 DiskDrive->Geometry.BytesPerSector);
505 "DriveNumber: 0x%x\n"
507 "Int13ExtensionsSupported = %s\n",
509 DiskDrive->IsRemovable ?
"TRUE" :
"FALSE",
510 DiskDrive->Int13ExtensionsSupported ?
"TRUE" :
"FALSE");
519#ifdef CACHE_MULTI_DRIVES
528 if (!DiskDrive->Initialized)
537 DiskDrive->Initialized |= 0x80;
540 DiskDrive->Initialized =
TRUE;
542 else if (DiskDrive->Initialized & 0x80)
548 DiskDrive->Initialized =
FALSE;
556 ASSERT((0 <= DriveNumber) && (DriveNumber <= 0xFF));
590 REGS RegsIn, RegsOut;
595 Packet->PacketSize =
sizeof(*Packet);
600 Packet->LBAStartBlock = SectorNumber;
613 RegsIn.
b.
dl = DriveNumber;
618 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
626 Int386(0x13, &RegsIn, &RegsOut);
638 DiskError(
"Disk Read Failed in LBA mode", RegsOut.
b.
ah);
639 ERR(
"Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
654 UCHAR PhysicalSector;
658 ULONG NumberOfSectorsToRead;
659 REGS RegsIn, RegsOut;
662 DriveGeometry = DiskDrive->Geometry;
677 if (PhysicalSector > 1)
688 if ((PhysicalHead >= DriveGeometry.
Heads) ||
689 (PhysicalTrack >= DriveGeometry.
Cylinders) ||
690 ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.
SectorsPerTrack + 1)) ||
693 DiskError(
"Disk read exceeds drive geometry limits.", 0);
716 RegsIn.
b.
al = (
UCHAR)NumberOfSectorsToRead;
717 RegsIn.
b.
ch = (PhysicalTrack & 0xFF);
718 RegsIn.
b.
cl = (
UCHAR)(PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
719 RegsIn.
b.
dh = PhysicalHead;
720 RegsIn.
b.
dl = DriveNumber;
725 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
727 Int386(0x13, &RegsIn, &RegsOut);
741 DiskError(
"Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.
b.
ah);
742 ERR(
"Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
758 SectorNumber += NumberOfSectorsToRead;
773 TRACE(
"PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u Buffer: 0x%x\n",
786 TRACE(
"--> Using LBA\n");
792 TRACE(
"--> Using CHS\n");
797#if defined(__i386__) || defined(_M_AMD64)
809 TRACE(
"PcDiskGetDriveGeometry(0x%x)\n", DriveNumber);
VOID DiskError(_In_ PCSTR ErrorString, _In_ ULONG ErrorCode)
#define DBG_DEFAULT_CHANNEL(ch)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
_In_ NDIS_ERROR_CODE ErrorCode
VOID __cdecl DiskStopFloppyMotor(VOID)
#define WRITE_PORT_UCHAR(p, d)
#define INT386_SUCCESS(regs)
int __cdecl Int386(int ivec, REGS *in, REGS *out)
static BOOLEAN DiskInt13ExtensionsSupported(IN UCHAR DriveNumber)
BOOLEAN DiskResetController(UCHAR DriveNumber)
PCSTR DiskGetErrorCodeString(_In_ ULONG ErrorCode)
struct _EXTENDED_GEOMETRY EXTENDED_GEOMETRY
struct _EXTENDED_GEOMETRY * PEXTENDED_GEOMETRY
static BOOLEAN PcDiskReadLogicalSectorsLBA(IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
static BOOLEAN DiskGetExtendedDriveParameters(_In_ UCHAR DriveNumber, _In_ PPC_DISK_DRIVE DiskDrive, _Out_ PVOID Buffer, _In_ USHORT BufferSize)
static BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber)
struct _PC_DISK_DRIVE PC_DISK_DRIVE
static USHORT LastDriveNumber
static BOOLEAN PcDiskReadLogicalSectorsCHS(IN UCHAR DriveNumber, IN PPC_DISK_DRIVE DiskDrive, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
static PC_DISK_DRIVE PcDiskDrive
struct I386_DISK_ADDRESS_PACKET * PI386_DISK_ADDRESS_PACKET
BOOLEAN PcDiskReadLogicalSectors(IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
struct I386_CDROM_SPEC_PACKET * PI386_CDROM_SPEC_PACKET
struct _PC_DISK_DRIVE * PPC_DISK_DRIVE
static BOOLEAN InitDriveGeometry(IN UCHAR DriveNumber, IN PPC_DISK_DRIVE DiskDrive)
CONFIGURATION_TYPE DiskGetConfigType(_In_ UCHAR DriveNumber)
static PPC_DISK_DRIVE PcDiskDriveNumberToDrive(IN UCHAR DriveNumber)
static BOOLEAN PcDiskDriveInit(IN UCHAR DriveNumber, IN OUT PPC_DISK_DRIVE DiskDrive)
ULONG PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
BOOLEAN PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
enum _CONFIGURATION_TYPE CONFIGURATION_TYPE
USHORT TransferBufferSegment
USHORT TransferBufferOffset
ULONG BytesPerSector
Number of bytes per sector.
ULONG Cylinders
Number of cylinders on the disk.
ULONGLONG Sectors
Total number of disk sectors/LBA blocks.
ULONG SectorsPerTrack
Number of sectors per track.
ULONG Heads
Number of heads on the disk.
EXTENDED_GEOMETRY ExtGeometry
BOOLEAN Int13ExtensionsSupported
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
#define BIOSCALLBUFSEGMENT
#define BIOSCALLBUFOFFSET