2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 /***************************************************************************
37 * IDE IO Register File
38 ***************************************************************************/
41 * IDE IO Port definition
43 typedef struct _IDE_REGISTERS_1 {
44 USHORT Data; /* RW: Data port feature register */
45 UCHAR BlockCount; /* RW: Sector count */
46 UCHAR BlockNumber; /* RW: Sector number & LBA 0-7 */
47 UCHAR CylinderLow; /* RW: Cylinder low & LBA 8-15 */
48 UCHAR CylinderHigh; /* RW: Cylinder hign & LBA 16-23 */
49 UCHAR DriveSelect; /* RW: Drive/head & LBA 24-27 */
50 UCHAR Command; /* RO: Status WR:Command */
51 } IDE_REGISTERS_1, *PIDE_REGISTERS_1;
55 * IDE status definitions
57 #define IDE_STATUS_ERROR 0x01 /* Error Occurred in Execution */
58 #define IDE_STATUS_INDEX 0x02 /* is vendor specific */
59 #define IDE_STATUS_CORRECTED_ERROR 0x04 /* Corrected Data */
60 #define IDE_STATUS_DRQ 0x08 /* Ready to transfer data */
61 #define IDE_STATUS_DSC 0x10 /* not defined in ATA-2 */
62 #define IDE_STATUS_DWF 0x20 /* Device Fault has been detected */
63 #define IDE_STATUS_DRDY 0x40 /* Device Ready to accept command */
64 #define IDE_STATUS_IDLE 0x50 /* Device is OK */
65 #define IDE_STATUS_BUSY 0x80 /* Device Busy, must wait */
68 #define IDE_ERROR_BAD_BLOCK 0x80 /* Reserved now */
69 #define IDE_ERROR_DATA_ERROR 0x40 /* Uncorreectable Data Error */
70 #define IDE_ERROR_MEDIA_CHANGE 0x20 /* Media Changed */
71 #define IDE_ERROR_ID_NOT_FOUND 0x10 /* ID Not Found */
72 #define IDE_ERROR_MEDIA_CHANGE_REQ 0x08 /* Media Change Requested */
73 #define IDE_ERROR_COMMAND_ABORTED 0x04 /* Aborted Command */
74 #define IDE_ERROR_TRACK0_NOT_FOUND 0x02 /* Track 0 Not Found */
75 #define IDE_ERROR_ADDRESS_NOT_FOUND 0x01 /* Address Mark Not Found */
81 * IDE command definitions
84 #define IDE_COMMAND_RECALIBRATE 0x10 /* Recalibrate */
85 #define IDE_COMMAND_READ 0x20 /* Read Sectors with retry */
86 #define IDE_COMMAND_WRITE 0x30 /* Write Sectors with retry */
87 #define IDE_COMMAND_VERIFY 0x40 /* Read Verify Sectors with Retry */
88 #define IDE_COMMAND_SEEK 0x70 /* Seek */
89 #define IDE_COMMAND_SET_DRIVE_PARAMETER 0x91 /* Initialize Device Parmeters */
90 #define IDE_COMMAND_GET_MEDIA_STATUS 0xDA
91 #define IDE_COMMAND_DOOR_LOCK 0xDE /* Door Lock */
92 #define IDE_COMMAND_DOOR_UNLOCK 0xDF /* Door Unlock */
93 #define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF /* Set Features */
94 #define IDE_COMMAND_IDENTIFY 0xEC /* Identify Device */
95 #define IDE_COMMAND_MEDIA_EJECT 0xED
96 #define IDE_COMMAND_SET_FEATURES 0xEF /* IDE set features command */
98 #define IDE_COMMAND_FLUSH_CACHE 0xE7
99 #define IDE_COMMAND_STANDBY_IMMEDIATE 0xE0
101 #ifndef NOT_SUPPORT_MULTIPLE
102 #define IDE_COMMAND_READ_MULTIPLE 0xC4 /* Read Multiple */
103 #define IDE_COMMAND_WRITE_MULTIPLE 0xC5 /* Write Multiple */
104 #define IDE_COMMAND_SET_MULTIPLE 0xC6 /* Set Multiple Mode */
107 #ifndef NOT_SUPPORT_DMA
108 #define IDE_COMMAND_DMA_READ 0xc8 /* IDE DMA read command */
109 #define IDE_COMMAND_DMA_WRITE 0xca /* IDE DMA write command */
112 #define IDE_COMMAND_READ_DMA_QUEUE 0xc7 /* IDE read DMA queue command */
113 #define IDE_COMMAND_WRITE_DMA_QUEUE 0xcc /* IDE write DMA queue command */
114 #define IDE_COMMAND_SERVICE 0xA2 /* IDE service command command */
115 #define IDE_COMMAND_NOP 0x00 /* IDE NOP command */
116 #define IDE_STATUS_SRV 0x10
117 #define IDE_RELEASE_BUS 4
119 /*#define IDE_COMMAND_FLUSH_CACHE_EXT */
120 #define IDE_COMMAND_READ_DMA_EXT 0x25
121 #define IDE_COMMAND_READ_QUEUE_EXT 0x26
122 #define IDE_COMMAND_READ_MULTIPLE_EXT 0x29
123 #define IDE_COMMAND_READ_MAX_ADDR 0x27
124 #define IDE_COMMAND_READ_EXT 0x24
125 #define IDE_COMMAND_VERIFY_EXT 0x42
126 #define IDE_COMMAND_SET_MULTIPLE_EXT 0x37
127 #define IDE_COMMAND_WRITE_DMA_EXT 0x35
128 #define IDE_COMMAND_WRITE_QUEUE_EXT 0x36
129 #define IDE_COMMAND_WRITE_EXT 0x34
130 #define IDE_COMMAND_WRITE_MULTIPLE_EXT 0x39
133 * IDE_COMMAND_SET_FEATURES
135 #define FT_USE_ULTRA 0x40 /* Set feature for Ultra DMA */
136 #define FT_USE_MWDMA 0x20 /* Set feature for MW DMA */
137 #define FT_USE_SWDMA 0x10 /* Set feature for SW DMA */
138 #define FT_USE_PIO 0x8 /* Set feature for PIO */
139 #define FT_DISABLE_IORDY 0x10 /* Set feature for disabling IORDY */
142 * S.M.A.R.T. commands
144 #define IDE_COMMAND_SMART 0xB0
145 #define SMART_READ_VALUES 0xd0
146 #define SMART_READ_THRESHOLDS 0xd1
147 #define SMART_AUTOSAVE 0xd2
148 #define SMART_SAVE 0xd3
149 #define SMART_IMMEDIATE_OFFLINE 0xd4
150 #define SMART_READ_LOG_SECTOR 0xd5
151 #define SMART_WRITE_LOG_SECTOR 0xd6
152 #define SMART_ENABLE 0xd8
153 #define SMART_DISABLE 0xd9
154 #define SMART_STATUS 0xda
155 #define SMART_AUTO_OFFLINE 0xdb
157 /***************************************************************************
158 * IDE Control Register File
159 ***************************************************************************/
161 typedef struct _IDE_REGISTERS_2 {
162 UCHAR AlternateStatus; /* RW: device control port */
163 } IDE_REGISTERS_2, *PIDE_REGISTERS_2;
167 * IDE drive control definitions
169 #define IDE_DC_DISABLE_INTERRUPTS 0x02
170 #define IDE_DC_RESET_CONTROLLER 0x04
171 #define IDE_DC_REENABLE_CONTROLLER 0x00
173 /***************************************************************************
174 * MSNS: Removable device
175 ***************************************************************************/
179 #define MSNS_NO_MEDIA 2
180 #define MSNS_MEDIA_CHANGE_REQUEST 8
181 #define MSNS_MIDIA_CHANGE 0x20
182 #define MSNS_WRITE_PROTECT 0x40
183 #define MSNS_READ_PROTECT 0x80
188 typedef struct _IDENTIFY_DATA {
189 USHORT GeneralConfiguration; /* 00 00 */
190 USHORT NumberOfCylinders; /* 02 1 */
191 USHORT Reserved1; /* 04 2 */
192 USHORT NumberOfHeads; /* 06 3 */
193 USHORT UnformattedBytesPerTrack; /* 08 4 */
194 USHORT UnformattedBytesPerSector; /* 0A 5 */
195 USHORT SectorsPerTrack; /* 0C 6 */
196 USHORT VendorUnique1[3]; /* 0E 7-9 */
197 USHORT SerialNumber[10]; /* 14 10-19 */
198 USHORT BufferType; /* 28 20 */
199 USHORT BufferSectorSize; /* 2A 21 */
200 USHORT NumberOfEccBytes; /* 2C 22 */
201 USHORT FirmwareRevision[4]; /* 2E 23-26 */
202 USHORT ModelNumber[20]; /* 36 27-46 */
203 UCHAR MaximumBlockTransfer; /* 5E 47 */
204 UCHAR VendorUnique2; /* 5F */
205 USHORT DoubleWordIo; /* 60 48 */
206 USHORT Capabilities; /* 62 49 */
207 USHORT Reserved2; /* 64 50 */
208 UCHAR VendorUnique3; /* 66 51 */
209 UCHAR PioCycleTimingMode; /* 67 */
210 UCHAR VendorUnique4; /* 68 52 */
211 UCHAR DmaCycleTimingMode; /* 69 */
212 USHORT TranslationFieldsValid; /* 6A 53 */
213 USHORT NumberOfCurrentCylinders; /* 6C 54 */
214 USHORT NumberOfCurrentHeads; /* 6E 55 */
215 USHORT CurrentSectorsPerTrack; /* 70 56 */
216 ULONG CurrentSectorCapacity; /* 72 57-58 */
217 USHORT CurrentMultiSectorSetting; /* 76 59 */
218 ULONG UserAddressableSectors; /* 78 60-61 */
219 UCHAR SingleWordDMASupport; /* 7C 62 */
220 UCHAR SingleWordDMAActive; /* 7D */
221 UCHAR MultiWordDMASupport; /* 7E 63 */
222 UCHAR MultiWordDMAActive; /* 7F */
223 UCHAR AdvancedPIOModes; /* 80 64 */
224 UCHAR Reserved4; /* 81 */
225 USHORT MinimumMWXferCycleTime; /* 82 65 */
226 USHORT RecommendedMWXferCycleTime; /* 84 66 */
227 USHORT MinimumPIOCycleTime; /* 86 67 */
228 USHORT MinimumPIOCycleTimeIORDY; /* 88 68 */
229 USHORT Reserved5[2]; /* 8A 69-70 */
230 USHORT ReleaseTimeOverlapped; /* 8E 71 */
231 USHORT ReleaseTimeServiceCommand; /* 90 72 */
232 USHORT MajorRevision; /* 92 73 */
233 USHORT MinorRevision; /* 94 74 */
234 USHORT MaxQueueDepth; /* 96 75 */
235 USHORT SataCapability; /* 76 */
236 USHORT Reserved6[9]; /* 98 77-85 */
237 USHORT CommandSupport; /* 86 */
238 USHORT CommandEnable; /* 87 */
239 USHORT UtralDmaMode; /* 88 */
240 USHORT Reserved7[11]; /* 89-99 */
241 ULONG Lba48BitLow; /* 101-100 */
242 ULONG Lba48BitHigh; /* 103-102 */
243 USHORT Reserved8[23]; /* 104-126 */
244 USHORT SpecialFunctionsEnabled; /* 127 */
245 USHORT Reserved9[128]; /* 128-255 */
247 } IDENTIFY_DATA, *PIDENTIFY_DATA;
249 typedef struct _CONFIGURATION_IDENTIFY_DATA {
251 USHORT MWDMAModeSupported;
252 USHORT UDMAModeSupported;
254 ULONG MaximumLbaHigh;
255 USHORT CommandSupport;
256 USHORT Reserved[247];
257 UCHAR Signature; /* 0xA5 */
260 CONFIGURATION_IDENTIFY_DATA, *PCONFIGURATION_IDENTIFY_DATA;
263 /* Identify data without the Reserved4. */
265 typedef struct _IDENTIFY_DATA2 {
266 USHORT GeneralConfiguration; /* 00 00 */
267 USHORT NumberOfCylinders; /* 02 1 */
268 USHORT Reserved1; /* 04 2 */
269 USHORT NumberOfHeads; /* 06 3 */
270 USHORT UnformattedBytesPerTrack; /* 08 4 */
271 USHORT UnformattedBytesPerSector; /* 0A 5 */
272 USHORT SectorsPerTrack; /* 0C 6 */
273 USHORT VendorUnique1[3]; /* 0E 7-9 */
274 USHORT SerialNumber[10]; /* 14 10-19 */
275 USHORT BufferType; /* 28 20 */
276 USHORT BufferSectorSize; /* 2A 21 */
277 USHORT NumberOfEccBytes; /* 2C 22 */
278 USHORT FirmwareRevision[4]; /* 2E 23-26 */
279 USHORT ModelNumber[20]; /* 36 27-46 */
280 UCHAR MaximumBlockTransfer; /* 5E 47 */
281 UCHAR VendorUnique2; /* 5F */
282 USHORT DoubleWordIo; /* 60 48 */
283 USHORT Capabilities; /* 62 49 */
284 USHORT Reserved2; /* 64 50 */
285 UCHAR VendorUnique3; /* 66 51 */
286 UCHAR PioCycleTimingMode; /* 67 */
287 UCHAR VendorUnique4; /* 68 52 */
288 UCHAR DmaCycleTimingMode; /* 69 */
289 USHORT TranslationFieldsValid; /* 6A 53 */
290 USHORT NumberOfCurrentCylinders; /* 6C 54 */
291 USHORT NumberOfCurrentHeads; /* 6E 55 */
292 USHORT CurrentSectorsPerTrack; /* 70 56 */
293 ULONG CurrentSectorCapacity; /* 72 57-58 */
294 USHORT CurrentMultiSectorSetting; /* 59 */
295 ULONG UserAddressableSectors; /* 60-61 */
296 UCHAR SingleWordDMASupport; /* 62 */
297 UCHAR SingleWordDMAActive;
298 UCHAR MultiWordDMASupport; /* 63 */
299 UCHAR MultiWordDMAActive;
300 UCHAR AdvancedPIOModes; /* 64 */
302 USHORT MinimumMWXferCycleTime; /* 65 */
303 USHORT RecommendedMWXferCycleTime; /* 66 */
304 USHORT MinimumPIOCycleTime; /* 67 */
305 USHORT MinimumPIOCycleTimeIORDY; /* 68 */
306 USHORT Reserved5[2]; /* 69-70 */
307 USHORT ReleaseTimeOverlapped; /* 71 */
308 USHORT ReleaseTimeServiceCommand; /* 72 */
309 USHORT MajorRevision; /* 73 */
310 USHORT MinorRevision; /* 74 */
311 /* USHORT Reserved6[14]; // 75-88 */
312 } IDENTIFY_DATA2, *PIDENTIFY_DATA2;
314 #define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA2)
317 /* IDENTIFY DMA timing cycle modes. */
320 #define IDENTIFY_DMA_CYCLES_MODE_0 0x00
321 #define IDENTIFY_DMA_CYCLES_MODE_1 0x01
322 #define IDENTIFY_DMA_CYCLES_MODE_2 0x02
327 typedef enum _DISK_MODE
347 /***************************************************************************
349 ***************************************************************************/
351 #define MAX_LBA_T ((LBA_T)-1)
354 #define SECTOR_TO_BYTE_SHIFT 9
355 #define SECTOR_TO_BYTE(x) ((ULONG)(x) << SECTOR_TO_BYTE_SHIFT)
357 #define mGetStatus(IOPort2) (UCHAR)InPort(&IOPort2->AlternateStatus)
358 #define mUnitControl(IOPort2, Value) OutPort(&IOPort2->AlternateStatus,(UCHAR)(Value))
360 #define mGetErrorCode(IOPort) (UCHAR)InPort((PUCHAR)&IOPort->Data+1)
361 #define mSetFeaturePort(IOPort,x) OutPort((PUCHAR)&IOPort->Data+1, x)
362 #define mSetBlockCount(IOPort,x) OutPort(&IOPort->BlockCount, x)
363 #define mGetBlockCount(IOPort) (UCHAR)InPort(&IOPort->BlockCount)
364 #define mGetInterruptReason(IOPort) (UCHAR)InPort(&IOPort->BlockCount)
365 #define mSetBlockNumber(IOPort,x) OutPort(&IOPort->BlockNumber, x)
366 #define mGetBlockNumber(IOPort) (UCHAR)InPort((PUCHAR)&IOPort->BlockNumber)
367 #define mGetByteLow(IOPort) (UCHAR)InPort(&IOPort->CylinderLow)
368 #define mSetCylinderLow(IOPort,x) OutPort(&IOPort->CylinderLow, x)
369 #define mGetByteHigh(IOPort) (UCHAR)InPort(&IOPort->CylinderHigh)
370 #define mSetCylinderHigh(IOPort,x) OutPort(&IOPort->CylinderHigh, x)
371 #define mGetBaseStatus(IOPort) (UCHAR)InPort(&IOPort->Command)
372 #ifdef SUPPORT_HPT601
373 #define mSelectUnit(IOPort,UnitId) do {\
374 OutPort(&IOPort->DriveSelect, (UCHAR)(UnitId));\
375 OutPort(&IOPort->DriveSelect, (UCHAR)(UnitId));\
378 #define mSelectUnit(IOPort,UnitId) OutPort(&IOPort->DriveSelect, (UCHAR)(UnitId))
380 #define mGetUnitNumber(IOPort) InPort(&IOPort->DriveSelect)
381 #define mIssueCommand(IOPort,Cmd) OutPort(&IOPort->Command, (UCHAR)(Cmd))
384 * WDC old disk, don't care right now
386 #define WDC_MW1_FIX_FLAG_OFFSET 129
387 #define WDC_MW1_FIX_FLAG_VALUE 0x00005555