94#ifdef CACHE_MULTI_DRIVES
104#ifdef CACHE_MULTI_DRIVES
132 case 0x00:
return "no error";
133 case 0x01:
return "bad command passed to driver";
134 case 0x02:
return "address mark not found or bad sector";
135 case 0x03:
return "diskette write protect error";
136 case 0x04:
return "sector not found";
137 case 0x05:
return "fixed disk reset failed";
138 case 0x06:
return "diskette changed or removed";
139 case 0x07:
return "bad fixed disk parameter table";
140 case 0x08:
return "DMA overrun";
141 case 0x09:
return "DMA access across 64k boundary";
142 case 0x0A:
return "bad fixed disk sector flag";
143 case 0x0B:
return "bad fixed disk cylinder";
144 case 0x0C:
return "unsupported track/invalid media";
145 case 0x0D:
return "invalid number of sectors on fixed disk format";
146 case 0x0E:
return "fixed disk controlled data address mark detected";
147 case 0x0F:
return "fixed disk DMA arbitration level out of range";
148 case 0x10:
return "ECC/CRC error on disk read";
149 case 0x11:
return "recoverable fixed disk data error, data fixed by ECC";
150 case 0x20:
return "controller error (NEC for floppies)";
151 case 0x40:
return "seek failure";
152 case 0x80:
return "time out, drive not ready";
153 case 0xAA:
return "fixed disk drive not ready";
154 case 0xBB:
return "fixed disk undefined error";
155 case 0xCC:
return "fixed disk write fault on selected drive";
156 case 0xE0:
return "fixed disk status error/Error reg = 0";
157 case 0xFF:
return "sense operation failed";
159 default:
return "unknown error code";
165 CHAR ErrorCodeString[200];
170 sprintf(ErrorCodeString,
"%s\n\nError Code: 0x%lx\nError: %s",
173 ERR(
"%s\n", ErrorCodeString);
182 REGS RegsIn, RegsOut;
184 WARN(
"DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
196 RegsIn.
b.
dl = DriveNumber;
199 Int386(0x13, &RegsIn, &RegsOut);
212 if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
222 REGS RegsIn, RegsOut;
232 if (DriveNumber >= 0x8A)
262 RegsIn.
w.
bx = 0x55AA;
263 RegsIn.
b.
dl = DriveNumber;
266 Int386(0x13, &RegsIn, &RegsOut);
273 if (RegsOut.
w.
bx != 0xAA55)
279 if (!(RegsOut.
w.
cx & 0x0001))
285 WARN(
"Suspicious API subset support bitmap 0x%x on device 0x%lx\n",
286 RegsOut.
w.
cx, DriveNumber);
300 REGS RegsIn, RegsOut;
303 TRACE(
"DiskGetExtendedDriveParameters(0x%x)\n", DriveNumber);
305 if (!DiskDrive->Int13ExtensionsSupported)
324 RegsIn.
b.
dl = DriveNumber;
329 Int386(0x13, &RegsIn, &RegsOut);
336 TRACE(
"size of buffer: %x\n",
Ptr[0]);
337 TRACE(
"information flags: %x\n",
Ptr[1]);
338 TRACE(
"number of physical cylinders on drive: %u\n", *(
PULONG)&
Ptr[2]);
339 TRACE(
"number of physical heads on drive: %u\n", *(
PULONG)&
Ptr[4]);
340 TRACE(
"number of physical sectors per track: %u\n", *(
PULONG)&
Ptr[6]);
341 TRACE(
"total number of sectors on drive: %I64u\n", *(
unsigned long long*)&
Ptr[8]);
342 TRACE(
"bytes per sector: %u\n",
Ptr[12]);
345 TRACE(
"EED configuration parameters: %x:%x\n",
Ptr[13],
Ptr[14]);
346 if (
Ptr[13] != 0xffff &&
Ptr[14] != 0xffff)
349 TRACE(
"SpecPtr: %x\n", SpecPtr);
350 TRACE(
"physical I/O port base address: %x\n", *(
PUSHORT)&SpecPtr[0]);
351 TRACE(
"disk-drive control port address: %x\n", *(
PUSHORT)&SpecPtr[2]);
352 TRACE(
"drive flags: %x\n", SpecPtr[4]);
353 TRACE(
"proprietary information: %x\n", SpecPtr[5]);
354 TRACE(
"IRQ for drive: %u\n", SpecPtr[6]);
355 TRACE(
"sector count for multi-sector transfers: %u\n", SpecPtr[7]);
356 TRACE(
"DMA control: %x\n", SpecPtr[8]);
357 TRACE(
"programmed I/O control: %x\n", SpecPtr[9]);
376 REGS RegsIn, RegsOut;
380 DiskDrive->ExtGeometry.Size =
sizeof(DiskDrive->ExtGeometry);
382 &DiskDrive->ExtGeometry,
383 DiskDrive->ExtGeometry.Size);
387 RtlZeroMemory(&DiskDrive->ExtGeometry,
sizeof(DiskDrive->ExtGeometry));
391 TRACE(
"DiskGetExtendedDriveParameters(0x%x) returned:\n"
394 "Sects/Track: 0x%x\n"
395 "Bytes/Sect : 0x%x\n",
397 DiskDrive->ExtGeometry.Cylinders,
398 DiskDrive->ExtGeometry.Heads,
399 DiskDrive->ExtGeometry.SectorsPerTrack,
400 DiskDrive->ExtGeometry.BytesPerSector);
404 RtlZeroMemory(&DiskDrive->Geometry,
sizeof(DiskDrive->Geometry));
426 RegsIn.
b.
dl = DriveNumber;
427 RegsIn.
w.
es = 0x0000;
428 RegsIn.
w.
di = 0x0000;
431 Int386(0x13, &RegsIn, &RegsOut);
440 Cylinders = (RegsOut.
b.
cl & 0xC0) << 2;
441 Cylinders += RegsOut.
b.
ch;
443 DiskDrive->Geometry.Cylinders = Cylinders;
444 DiskDrive->Geometry.Heads = RegsOut.
b.
dh + 1;
445 DiskDrive->Geometry.Sectors = RegsOut.
b.
cl & 0x3F;
446 DiskDrive->Geometry.BytesPerSector = 512;
448 TRACE(
"Regular Int13h(0x%x) returned:\n"
451 "Sects/Track: 0x%x (original 0x%x)\n"
452 "Bytes/Sect : 0x%x\n",
454 DiskDrive->Geometry.Cylinders,
455 DiskDrive->Geometry.Heads,
456 DiskDrive->Geometry.Sectors, RegsOut.
b.
cl,
457 DiskDrive->Geometry.BytesPerSector);
480 "DriveNumber: 0x%x\n"
482 "Int13ExtensionsSupported = %s\n",
484 DiskDrive->IsRemovable ?
"TRUE" :
"FALSE",
485 DiskDrive->Int13ExtensionsSupported ?
"TRUE" :
"FALSE");
494#ifdef CACHE_MULTI_DRIVES
503 if (!DiskDrive->Initialized)
512 DiskDrive->Initialized |= 0x80;
515 DiskDrive->Initialized =
TRUE;
517 else if (DiskDrive->Initialized & 0x80)
523 DiskDrive->Initialized =
FALSE;
531 ASSERT((0 <= DriveNumber) && (DriveNumber <= 0xFF));
564 REGS RegsIn, RegsOut;
570 Packet->PacketSize =
sizeof(*Packet);
576 Packet->LBAStartBlock = SectorNumber;
589 RegsIn.
b.
dl = DriveNumber;
594 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
596 Int386(0x13, &RegsIn, &RegsOut);
604 else if (RegsOut.
b.
ah == 0x11)
617 DiskError(
"Disk Read Failed in LBA mode", RegsOut.
b.
ah);
618 ERR(
"Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
633 UCHAR PhysicalSector;
637 ULONG NumberOfSectorsToRead;
638 REGS RegsIn, RegsOut;
641 DriveGeometry = DiskDrive->Geometry;
642 if (DriveGeometry.
Sectors == 0 || DriveGeometry.
Heads == 0)
651 PhysicalSector = 1 + (
UCHAR)(SectorNumber % DriveGeometry.
Sectors);
652 PhysicalHead = (
UCHAR)((SectorNumber / DriveGeometry.
Sectors) % DriveGeometry.
Heads);
653 PhysicalTrack = (
ULONG)((SectorNumber / DriveGeometry.
Sectors) / DriveGeometry.
Heads);
656 if (PhysicalSector > 1)
659 NumberOfSectorsToRead = (DriveGeometry.
Sectors - (PhysicalSector - 1));
666 NumberOfSectorsToRead = DriveGeometry.
Sectors;
672 if ((PhysicalHead >= DriveGeometry.
Heads) ||
673 (PhysicalTrack >= DriveGeometry.
Cylinders) ||
674 ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.
Sectors + 1)) ||
675 (PhysicalSector > DriveGeometry.
Sectors))
677 DiskError(
"Disk read exceeds drive geometry limits.", 0);
700 RegsIn.
b.
al = (
UCHAR)NumberOfSectorsToRead;
701 RegsIn.
b.
ch = (PhysicalTrack & 0xFF);
702 RegsIn.
b.
cl = (
UCHAR)(PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
703 RegsIn.
b.
dh = PhysicalHead;
704 RegsIn.
b.
dl = DriveNumber;
709 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
711 Int386(0x13, &RegsIn, &RegsOut);
719 else if (RegsOut.
b.
ah == 0x11)
734 DiskError(
"Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.
b.
ah);
735 ERR(
"Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
751 SectorNumber += NumberOfSectorsToRead;
766 TRACE(
"PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n",
779 TRACE(
"--> Using LBA\n");
785 TRACE(
"--> Using CHS\n");
790#if defined(__i386__) || defined(_M_AMD64)
802 TRACE(
"PcDiskGetDriveGeometry(0x%x)\n", DriveNumber);
#define DBG_DEFAULT_CHANNEL(ch)
_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)
static PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
static BOOLEAN PcDiskReadLogicalSectorsLBA(IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
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 BOOLEAN DiskGetExtendedDriveParameters(IN UCHAR DriveNumber, IN PPC_DISK_DRIVE DiskDrive, OUT PVOID Buffer, IN USHORT BufferSize)
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
EXTENDED_GEOMETRY ExtGeometry
BOOLEAN Int13ExtensionsSupported
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
VOID UiMessageBox(PCSTR Format,...)
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
#define BIOSCALLBUFSEGMENT
#define BIOSCALLBUFOFFSET