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)
419 REGS RegsIn, RegsOut;
423 RtlZeroMemory(&DiskDrive->ExtGeometry,
sizeof(DiskDrive->ExtGeometry));
425 &DiskDrive->ExtGeometry,
426 sizeof(DiskDrive->ExtGeometry));
429 TRACE(
"DiskGetExtendedDriveParameters(0x%x) returned:\n"
432 "Sects/Track: 0x%x\n"
433 "Total Sects: 0x%llx\n"
434 "Bytes/Sect : 0x%x\n",
436 DiskDrive->ExtGeometry.Cylinders,
437 DiskDrive->ExtGeometry.Heads,
438 DiskDrive->ExtGeometry.SectorsPerTrack,
439 DiskDrive->ExtGeometry.Sectors,
440 DiskDrive->ExtGeometry.BytesPerSector);
444 RtlZeroMemory(&DiskDrive->Geometry,
sizeof(DiskDrive->Geometry));
466 RegsIn.
b.
dl = DriveNumber;
467 RegsIn.
w.
es = 0x0000;
468 RegsIn.
w.
di = 0x0000;
471 Int386(0x13, &RegsIn, &RegsOut);
480 Cylinders = (RegsOut.
b.
cl & 0xC0) << 2;
481 Cylinders += RegsOut.
b.
ch;
483 DiskDrive->Geometry.Cylinders = Cylinders;
484 DiskDrive->Geometry.Heads = RegsOut.
b.
dh + 1;
485 DiskDrive->Geometry.SectorsPerTrack = RegsOut.
b.
cl & 0x3F;
486 DiskDrive->Geometry.BytesPerSector = 512;
488 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
489 DiskDrive->Geometry.Heads *
490 DiskDrive->Geometry.SectorsPerTrack;
492 TRACE(
"Regular Int13h(0x%x) returned:\n"
495 "Sects/Track: 0x%x\n"
496 "Total Sects: 0x%llx\n"
497 "Bytes/Sect : 0x%x\n",
499 DiskDrive->Geometry.Cylinders,
500 DiskDrive->Geometry.Heads,
501 DiskDrive->Geometry.SectorsPerTrack,
502 DiskDrive->Geometry.Sectors,
503 DiskDrive->Geometry.BytesPerSector);
526 "DriveNumber: 0x%x\n"
528 "Int13ExtensionsSupported = %s\n",
530 DiskDrive->IsRemovable ?
"TRUE" :
"FALSE",
531 DiskDrive->Int13ExtensionsSupported ?
"TRUE" :
"FALSE");
540#ifdef CACHE_MULTI_DRIVES
549 if (!DiskDrive->Initialized)
558 DiskDrive->Initialized |= 0x80;
561 DiskDrive->Initialized =
TRUE;
563 else if (DiskDrive->Initialized & 0x80)
569 DiskDrive->Initialized =
FALSE;
577 ASSERT((0 <= DriveNumber) && (DriveNumber <= 0xFF));
611 REGS RegsIn, RegsOut;
616 Packet->PacketSize =
sizeof(*Packet);
621 Packet->LBAStartBlock = SectorNumber;
634 RegsIn.
b.
dl = DriveNumber;
639 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
647 Int386(0x13, &RegsIn, &RegsOut);
659 DiskError(
"Disk Read Failed in LBA mode", RegsOut.
b.
ah);
660 ERR(
"Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
675 UCHAR PhysicalSector;
679 ULONG NumberOfSectorsToRead;
680 REGS RegsIn, RegsOut;
683 DriveGeometry = DiskDrive->Geometry;
698 if (PhysicalSector > 1)
709 if ((PhysicalHead >= DriveGeometry.
Heads) ||
710 (PhysicalTrack >= DriveGeometry.
Cylinders) ||
711 ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.
SectorsPerTrack + 1)) ||
714 DiskError(
"Disk read exceeds drive geometry limits.", 0);
737 RegsIn.
b.
al = (
UCHAR)NumberOfSectorsToRead;
738 RegsIn.
b.
ch = (PhysicalTrack & 0xFF);
739 RegsIn.
b.
cl = (
UCHAR)(PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
740 RegsIn.
b.
dh = PhysicalHead;
741 RegsIn.
b.
dl = DriveNumber;
746 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
748 Int386(0x13, &RegsIn, &RegsOut);
762 DiskError(
"Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.
b.
ah);
763 ERR(
"Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
779 SectorNumber += NumberOfSectorsToRead;
794 TRACE(
"PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u Buffer: 0x%x\n",
807 TRACE(
"--> Using LBA\n");
813 TRACE(
"--> Using CHS\n");
818#if defined(__i386__) || defined(_M_AMD64)
830 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
_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)
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)
static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
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