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 /////////////////////////////////////////////////////////////////////////////////////////////
27 /////////////////////////////////////////////////////////////////////////////////////////////
29 BOOLEAN
DiskResetController(ULONG DriveNumber
)
34 DPRINTM(DPRINT_DISK
, "DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber
);
36 // BIOS Int 13h, function 0 - Reset disk system
38 // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
41 // CF clear if successful
44 RegsIn
.b
.dl
= DriveNumber
;
46 // Reset the disk controller
47 Int386(0x13, &RegsIn
, &RegsOut
);
49 return INT386_SUCCESS(RegsOut
);
52 BOOLEAN
DiskInt13ExtensionsSupported(ULONG DriveNumber
)
54 static ULONG LastDriveNumber
= 0xffffffff;
55 static BOOLEAN LastSupported
;
59 DPRINTM(DPRINT_DISK
, "PcDiskInt13ExtensionsSupported()\n");
61 if (DriveNumber
== LastDriveNumber
)
63 DPRINTM(DPRINT_DISK
, "Using cached value %s for drive 0x%x\n", LastSupported
? "TRUE" : "FALSE", DriveNumber
);
67 // Some BIOSes report that extended disk access functions are not supported
68 // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
69 // with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
70 // we can assume that all El Torito capable BIOSes support INT 13 extensions.
71 // We simply detect whether we're booting from CD by checking whether the drive
72 // number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
73 if (DriveNumber
>= 0x8A)
79 LastDriveNumber
= DriveNumber
;
81 // IBM/MS INT 13 Extensions - INSTALLATION CHECK
84 // DL = drive (80h-FFh)
86 // CF set on error (extensions not supported)
87 // AH = 01h (invalid function)
88 // CF clear if successful
89 // BX = AA55h if installed
90 // AH = major version of extensions
92 // 20h = 2.0 / EDD-1.0
93 // 21h = 2.1 / EDD-1.1
96 // CX = API subset support bitmap
97 // DH = extension version (v2.0+ ??? -- not present in 1.x)
99 // Bitfields for IBM/MS INT 13 Extensions API support bitmap
100 // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
101 // Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
102 // Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
103 // extended drive parameter table is valid
104 // Bits 3-15 reserved
106 RegsIn
.w
.bx
= 0x55AA;
107 RegsIn
.b
.dl
= DriveNumber
;
109 // Reset the disk controller
110 Int386(0x13, &RegsIn
, &RegsOut
);
112 if (!INT386_SUCCESS(RegsOut
))
114 // CF set on error (extensions not supported)
115 LastSupported
= FALSE
;
119 if (RegsOut
.w
.bx
!= 0xAA55)
121 // BX = AA55h if installed
122 LastSupported
= FALSE
;
126 if (!(RegsOut
.w
.cx
& 0x0001))
128 // CX = API subset support bitmap
129 // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
130 DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut
.w
.cx
, DriveNumber
);
131 LastSupported
= FALSE
;
135 LastSupported
= TRUE
;
139 VOID
DiskStopFloppyMotor(VOID
)
141 WRITE_PORT_UCHAR((PUCHAR
)0x3F2, 0);
144 BOOLEAN
DiskGetExtendedDriveParameters(ULONG DriveNumber
, PVOID Buffer
, USHORT BufferSize
)
148 PUSHORT Ptr
= (PUSHORT
)(BIOSCALLBUFFER
);
150 DPRINTM(DPRINT_DISK
, "DiskGetExtendedDriveParameters()\n");
152 if (!DiskInt13ExtensionsSupported(DriveNumber
))
155 // Initialize transfer buffer
158 // BIOS Int 13h, function 48h - Get drive parameters
160 // DL = drive (bit 7 set for hard disk)
161 // DS:SI = result buffer
165 // CF clear if successful
167 // DS:SI -> result buffer
169 RegsIn
.b
.dl
= DriveNumber
;
170 RegsIn
.x
.ds
= BIOSCALLBUFSEGMENT
; // DS:SI -> result buffer
171 RegsIn
.w
.si
= BIOSCALLBUFOFFSET
;
173 // Get drive parameters
174 Int386(0x13, &RegsIn
, &RegsOut
);
176 if (!INT386_SUCCESS(RegsOut
))
181 memcpy(Buffer
, Ptr
, BufferSize
);
184 DPRINTM(DPRINT_DISK
, "size of buffer: %x\n", Ptr
[0]);
185 DPRINTM(DPRINT_DISK
, "information flags: %x\n", Ptr
[1]);
186 DPRINTM(DPRINT_DISK
, "number of physical cylinders on drive: %u\n", *(PULONG
)&Ptr
[2]);
187 DPRINTM(DPRINT_DISK
, "number of physical heads on drive: %u\n", *(PULONG
)&Ptr
[4]);
188 DPRINTM(DPRINT_DISK
, "number of physical sectors per track: %u\n", *(PULONG
)&Ptr
[6]);
189 DPRINTM(DPRINT_DISK
, "total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr
[8]);
190 DPRINTM(DPRINT_DISK
, "bytes per sector: %u\n", Ptr
[12]);
193 DPRINTM(DPRINT_DISK
, "EED configuration parameters: %x:%x\n", Ptr
[13], Ptr
[14]);
194 if (Ptr
[13] != 0xffff && Ptr
[14] != 0xffff)
196 PUCHAR SpecPtr
= (PUCHAR
)(ULONG_PTR
)((Ptr
[13] << 4) + Ptr
[14]);
197 DPRINTM(DPRINT_DISK
, "SpecPtr: %x\n", SpecPtr
);
198 DPRINTM(DPRINT_DISK
, "physical I/O port base address: %x\n", *(PUSHORT
)&SpecPtr
[0]);
199 DPRINTM(DPRINT_DISK
, "disk-drive control port address: %x\n", *(PUSHORT
)&SpecPtr
[2]);
200 DPRINTM(DPRINT_DISK
, "drive flags: %x\n", SpecPtr
[4]);
201 DPRINTM(DPRINT_DISK
, "proprietary information: %x\n", SpecPtr
[5]);
202 DPRINTM(DPRINT_DISK
, "IRQ for drive: %u\n", SpecPtr
[6]);
203 DPRINTM(DPRINT_DISK
, "sector count for multi-sector transfers: %u\n", SpecPtr
[7]);
204 DPRINTM(DPRINT_DISK
, "DMA control: %x\n", SpecPtr
[8]);
205 DPRINTM(DPRINT_DISK
, "programmed I/O control: %x\n", SpecPtr
[9]);
206 DPRINTM(DPRINT_DISK
, "drive options: %x\n", *(PUSHORT
)&SpecPtr
[10]);
211 DPRINTM(DPRINT_DISK
, "signature: %x\n", Ptr
[15]);