3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 DBG_DEFAULT_CHANNEL(DISK
);
27 /////////////////////////////////////////////////////////////////////////////////////////////
29 /////////////////////////////////////////////////////////////////////////////////////////////
31 BOOLEAN
DiskResetController(UCHAR DriveNumber
)
36 WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber
);
38 // BIOS Int 13h, function 0 - Reset disk system
40 // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
43 // CF clear if successful
46 RegsIn
.b
.dl
= DriveNumber
;
48 // Reset the disk controller
49 Int386(0x13, &RegsIn
, &RegsOut
);
51 return INT386_SUCCESS(RegsOut
);
54 BOOLEAN
DiskInt13ExtensionsSupported(UCHAR DriveNumber
)
56 static UCHAR LastDriveNumber
= 0xff;
57 static BOOLEAN LastSupported
;
61 TRACE("PcDiskInt13ExtensionsSupported()\n");
63 if (DriveNumber
== LastDriveNumber
)
65 TRACE("Using cached value %s for drive 0x%x\n", LastSupported
? "TRUE" : "FALSE", DriveNumber
);
69 // Some BIOSes report that extended disk access functions are not supported
70 // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
71 // with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
72 // we can assume that all El Torito capable BIOSes support INT 13 extensions.
73 // We simply detect whether we're booting from CD by checking whether the drive
74 // number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
75 if (DriveNumber
>= 0x8A)
81 LastDriveNumber
= DriveNumber
;
83 // IBM/MS INT 13 Extensions - INSTALLATION CHECK
86 // DL = drive (80h-FFh)
88 // CF set on error (extensions not supported)
89 // AH = 01h (invalid function)
90 // CF clear if successful
91 // BX = AA55h if installed
92 // AH = major version of extensions
94 // 20h = 2.0 / EDD-1.0
95 // 21h = 2.1 / EDD-1.1
98 // CX = API subset support bitmap
99 // DH = extension version (v2.0+ ??? -- not present in 1.x)
101 // Bitfields for IBM/MS INT 13 Extensions API support bitmap
102 // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
103 // Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
104 // Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
105 // extended drive parameter table is valid
106 // Bits 3-15 reserved
108 RegsIn
.w
.bx
= 0x55AA;
109 RegsIn
.b
.dl
= DriveNumber
;
111 // Reset the disk controller
112 Int386(0x13, &RegsIn
, &RegsOut
);
114 if (!INT386_SUCCESS(RegsOut
))
116 // CF set on error (extensions not supported)
117 LastSupported
= FALSE
;
121 if (RegsOut
.w
.bx
!= 0xAA55)
123 // BX = AA55h if installed
124 LastSupported
= FALSE
;
128 if (!(RegsOut
.w
.cx
& 0x0001))
130 // CX = API subset support bitmap
131 // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
132 DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut
.w
.cx
, DriveNumber
);
133 LastSupported
= FALSE
;
137 LastSupported
= TRUE
;
141 VOID
DiskStopFloppyMotor(VOID
)
143 WRITE_PORT_UCHAR((PUCHAR
)0x3F2, 0);
146 BOOLEAN
DiskGetExtendedDriveParameters(UCHAR DriveNumber
, PVOID Buffer
, USHORT BufferSize
)
150 PUSHORT Ptr
= (PUSHORT
)(BIOSCALLBUFFER
);
152 TRACE("DiskGetExtendedDriveParameters()\n");
154 if (!DiskInt13ExtensionsSupported(DriveNumber
))
157 // Initialize transfer buffer
160 // BIOS Int 13h, function 48h - Get drive parameters
162 // DL = drive (bit 7 set for hard disk)
163 // DS:SI = result buffer
167 // CF clear if successful
169 // DS:SI -> result buffer
171 RegsIn
.b
.dl
= DriveNumber
;
172 RegsIn
.x
.ds
= BIOSCALLBUFSEGMENT
; // DS:SI -> result buffer
173 RegsIn
.w
.si
= BIOSCALLBUFOFFSET
;
175 // Get drive parameters
176 Int386(0x13, &RegsIn
, &RegsOut
);
178 if (!INT386_SUCCESS(RegsOut
))
183 memcpy(Buffer
, Ptr
, BufferSize
);
186 TRACE("size of buffer: %x\n", Ptr
[0]);
187 TRACE("information flags: %x\n", Ptr
[1]);
188 TRACE("number of physical cylinders on drive: %u\n", *(PULONG
)&Ptr
[2]);
189 TRACE("number of physical heads on drive: %u\n", *(PULONG
)&Ptr
[4]);
190 TRACE("number of physical sectors per track: %u\n", *(PULONG
)&Ptr
[6]);
191 TRACE("total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr
[8]);
192 TRACE("bytes per sector: %u\n", Ptr
[12]);
195 TRACE("EED configuration parameters: %x:%x\n", Ptr
[13], Ptr
[14]);
196 if (Ptr
[13] != 0xffff && Ptr
[14] != 0xffff)
198 PUCHAR SpecPtr
= (PUCHAR
)(ULONG_PTR
)((Ptr
[13] << 4) + Ptr
[14]);
199 TRACE("SpecPtr: %x\n", SpecPtr
);
200 TRACE("physical I/O port base address: %x\n", *(PUSHORT
)&SpecPtr
[0]);
201 TRACE("disk-drive control port address: %x\n", *(PUSHORT
)&SpecPtr
[2]);
202 TRACE("drive flags: %x\n", SpecPtr
[4]);
203 TRACE("proprietary information: %x\n", SpecPtr
[5]);
204 TRACE("IRQ for drive: %u\n", SpecPtr
[6]);
205 TRACE("sector count for multi-sector transfers: %u\n", SpecPtr
[7]);
206 TRACE("DMA control: %x\n", SpecPtr
[8]);
207 TRACE("programmed I/O control: %x\n", SpecPtr
[9]);
208 TRACE("drive options: %x\n", *(PUSHORT
)&SpecPtr
[10]);
213 TRACE("signature: %x\n", Ptr
[15]);