110#ifdef CACHE_MULTI_DRIVES
120#ifdef CACHE_MULTI_DRIVES
148 case 0x00:
return "no error";
149 case 0x01:
return "bad command passed to driver";
150 case 0x02:
return "address mark not found or bad sector";
151 case 0x03:
return "diskette write protect error";
152 case 0x04:
return "sector not found";
153 case 0x05:
return "fixed disk reset failed";
154 case 0x06:
return "diskette changed or removed";
155 case 0x07:
return "bad fixed disk parameter table";
156 case 0x08:
return "DMA overrun";
157 case 0x09:
return "DMA access across 64k boundary";
158 case 0x0A:
return "bad fixed disk sector flag";
159 case 0x0B:
return "bad fixed disk cylinder";
160 case 0x0C:
return "unsupported track/invalid media";
161 case 0x0D:
return "invalid number of sectors on fixed disk format";
162 case 0x0E:
return "fixed disk controlled data address mark detected";
163 case 0x0F:
return "fixed disk DMA arbitration level out of range";
164 case 0x10:
return "ECC/CRC error on disk read";
165 case 0x11:
return "recoverable fixed disk data error, data fixed by ECC";
166 case 0x20:
return "controller error (NEC for floppies)";
167 case 0x40:
return "seek failure";
168 case 0x80:
return "time out, drive not ready";
169 case 0xAA:
return "fixed disk drive not ready";
170 case 0xBB:
return "fixed disk undefined error";
171 case 0xCC:
return "fixed disk write fault on selected drive";
172 case 0xE0:
return "fixed disk status error/Error reg = 0";
173 case 0xFF:
return "sense operation failed";
175 default:
return "unknown error code";
181 CHAR ErrorCodeString[200];
186 sprintf(ErrorCodeString,
"%s\n\nError Code: 0x%lx\nError: %s",
189 ERR(
"%s\n", ErrorCodeString);
197 REGS RegsIn, RegsOut;
199 WARN(
"DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
211 RegsIn.
b.
dl = DriveNumber;
214 Int386(0x13, &RegsIn, &RegsOut);
227 if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
237 REGS RegsIn, RegsOut;
247 if (DriveNumber >= 0x8A)
277 RegsIn.
w.
bx = 0x55AA;
278 RegsIn.
b.
dl = DriveNumber;
281 Int386(0x13, &RegsIn, &RegsOut);
288 if (RegsOut.
w.
bx != 0xAA55)
295 TRACE(
"Drive 0x%x: INT 13h Extended version: 0x%02x, API bitmap: 0x%04x\n",
296 DriveNumber, RegsOut.
b.
ah, RegsOut.
w.
cx);
298 if (!(RegsOut.
w.
cx & 0x0001))
304 WARN(
"Drive 0x%x: Suspicious API subset support bitmap 0x%04x\n",
305 DriveNumber, RegsOut.
w.
cx);
320 REGS RegsIn, RegsOut;
322 TRACE(
"DiskGetExtendedDriveParameters(0x%x)\n", DriveNumber);
324 if (!DiskDrive->Int13ExtensionsSupported || (
BufferSize <
sizeof(*
Ptr)))
349 RegsIn.
b.
dl = DriveNumber;
354 Int386(0x13, &RegsIn, &RegsOut);
361 TRACE(
"Size of buffer: 0x%x\n",
Ptr->Size);
362 TRACE(
"Information flags: 0x%x\n",
Ptr->Flags);
363 TRACE(
"Number of physical cylinders on drive: %u\n",
Ptr->Cylinders);
364 TRACE(
"Number of physical heads on drive: %u\n",
Ptr->Heads);
365 TRACE(
"Number of physical sectors per track: %u\n",
Ptr->SectorsPerTrack);
366 TRACE(
"Total number of sectors on drive: %I64u\n",
Ptr->Sectors);
367 TRACE(
"Bytes per sector: %u\n",
Ptr->BytesPerSector);
368 if (
Ptr->Size >= 0x1E)
373 TRACE(
"EDD configuration parameters (DPTE): %x:%x\n", Seg, Off);
377 if (
Ptr->PDPTE != 0xFFFFFFFF &&
Ptr->PDPTE != 0)
380 TRACE(
"SpecPtr: 0x%x\n", SpecPtr);
381 TRACE(
"Physical I/O port base address: 0x%x\n", *(
PUSHORT)&SpecPtr[0]);
382 TRACE(
"Disk-drive control port address: 0x%x\n", *(
PUSHORT)&SpecPtr[2]);
383 TRACE(
"Head register upper nibble: 0x%x\n", SpecPtr[4]);
384 TRACE(
"BIOS Vendor-specific: 0x%x\n", SpecPtr[5]);
385 TRACE(
"IRQ for drive: %u\n", SpecPtr[6]);
386 TRACE(
"Sector count for multi-sector transfers: %u\n", SpecPtr[7]);
387 TRACE(
"DMA control: 0x%x\n", SpecPtr[8]);
388 TRACE(
"Programmed I/O control: 0x%x\n", SpecPtr[9]);
392 if (
Ptr->Size >= 0x42)
407 REGS RegsIn, RegsOut;
411 RtlZeroMemory(&DiskDrive->ExtGeometry,
sizeof(DiskDrive->ExtGeometry));
413 &DiskDrive->ExtGeometry,
414 sizeof(DiskDrive->ExtGeometry));
417 TRACE(
"DiskGetExtendedDriveParameters(0x%x) returned:\n"
420 "Sects/Track: 0x%x\n"
421 "Total Sects: 0x%llx\n"
422 "Bytes/Sect : 0x%x\n",
424 DiskDrive->ExtGeometry.Cylinders,
425 DiskDrive->ExtGeometry.Heads,
426 DiskDrive->ExtGeometry.SectorsPerTrack,
427 DiskDrive->ExtGeometry.Sectors,
428 DiskDrive->ExtGeometry.BytesPerSector);
432 RtlZeroMemory(&DiskDrive->Geometry,
sizeof(DiskDrive->Geometry));
454 RegsIn.
b.
dl = DriveNumber;
455 RegsIn.
w.
es = 0x0000;
456 RegsIn.
w.
di = 0x0000;
459 Int386(0x13, &RegsIn, &RegsOut);
468 Cylinders = (RegsOut.
b.
cl & 0xC0) << 2;
469 Cylinders += RegsOut.
b.
ch;
471 DiskDrive->Geometry.Cylinders = Cylinders;
472 DiskDrive->Geometry.Heads = RegsOut.
b.
dh + 1;
473 DiskDrive->Geometry.SectorsPerTrack = RegsOut.
b.
cl & 0x3F;
474 DiskDrive->Geometry.BytesPerSector = 512;
476 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
477 DiskDrive->Geometry.Heads *
478 DiskDrive->Geometry.SectorsPerTrack;
480 TRACE(
"Regular Int13h(0x%x) returned:\n"
483 "Sects/Track: 0x%x\n"
484 "Total Sects: 0x%llx\n"
485 "Bytes/Sect : 0x%x\n",
487 DiskDrive->Geometry.Cylinders,
488 DiskDrive->Geometry.Heads,
489 DiskDrive->Geometry.SectorsPerTrack,
490 DiskDrive->Geometry.Sectors,
491 DiskDrive->Geometry.BytesPerSector);
514 "DriveNumber: 0x%x\n"
516 "Int13ExtensionsSupported = %s\n",
518 DiskDrive->IsRemovable ?
"TRUE" :
"FALSE",
519 DiskDrive->Int13ExtensionsSupported ?
"TRUE" :
"FALSE");
528#ifdef CACHE_MULTI_DRIVES
537 if (!DiskDrive->Initialized)
546 DiskDrive->Initialized |= 0x80;
549 DiskDrive->Initialized =
TRUE;
551 else if (DiskDrive->Initialized & 0x80)
557 DiskDrive->Initialized =
FALSE;
565 ASSERT((0 <= DriveNumber) && (DriveNumber <= 0xFF));
599 REGS RegsIn, RegsOut;
604 Packet->PacketSize =
sizeof(*Packet);
609 Packet->LBAStartBlock = SectorNumber;
622 RegsIn.
b.
dl = DriveNumber;
627 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
635 Int386(0x13, &RegsIn, &RegsOut);
647 DiskError(
"Disk Read Failed in LBA mode", RegsOut.
b.
ah);
648 ERR(
"Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
663 UCHAR PhysicalSector;
667 ULONG NumberOfSectorsToRead;
668 REGS RegsIn, RegsOut;
671 DriveGeometry = DiskDrive->Geometry;
686 if (PhysicalSector > 1)
697 if ((PhysicalHead >= DriveGeometry.
Heads) ||
698 (PhysicalTrack >= DriveGeometry.
Cylinders) ||
699 ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.
SectorsPerTrack + 1)) ||
702 DiskError(
"Disk read exceeds drive geometry limits.", 0);
725 RegsIn.
b.
al = (
UCHAR)NumberOfSectorsToRead;
726 RegsIn.
b.
ch = (PhysicalTrack & 0xFF);
727 RegsIn.
b.
cl = (
UCHAR)(PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
728 RegsIn.
b.
dh = PhysicalHead;
729 RegsIn.
b.
dl = DriveNumber;
734 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
736 Int386(0x13, &RegsIn, &RegsOut);
750 DiskError(
"Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.
b.
ah);
751 ERR(
"Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
767 SectorNumber += NumberOfSectorsToRead;
782 TRACE(
"PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u Buffer: 0x%x\n",
795 TRACE(
"--> Using LBA\n");
801 TRACE(
"--> Using CHS\n");
806#if defined(__i386__) || defined(_M_AMD64)
818 TRACE(
"PcDiskGetDriveGeometry(0x%x)\n", DriveNumber);
#define DBG_DEFAULT_CHANNEL(ch)
VOID UiMessageBox(_In_ PCSTR Format,...)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
#define sprintf(buf, format,...)
_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)
struct _EXTENDED_GEOMETRY EXTENDED_GEOMETRY
static PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
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
LONG DiskReportError(BOOLEAN bShowError)
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)
static PPC_DISK_DRIVE PcDiskDriveNumberToDrive(IN UCHAR DriveNumber)
static BOOLEAN PcDiskDriveInit(IN UCHAR DriveNumber, IN OUT PPC_DISK_DRIVE DiskDrive)
ULONG PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
BOOLEAN PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
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