1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2004-2005 HighPoint Technologies, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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. 15 * 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 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #ifndef _ATAPI_H_ 32 #define _ATAPI_H_ 33 34 #pragma pack(1) 35 36 /*************************************************************************** 37 * IDE IO Register File 38 ***************************************************************************/ 39 40 /* 41 * IDE IO Port definition 42 */ 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; 52 53 54 /* 55 * IDE status definitions 56 */ 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 */ 66 67 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 */ 76 77 78 #define LBA_MODE 0x40 79 80 /* 81 * IDE command definitions 82 */ 83 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 */ 97 98 #define IDE_COMMAND_FLUSH_CACHE 0xE7 99 #define IDE_COMMAND_STANDBY_IMMEDIATE 0xE0 100 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 */ 105 #endif 106 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 */ 110 #endif 111 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 118 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 131 132 /* 133 * IDE_COMMAND_SET_FEATURES 134 */ 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 */ 140 141 /* 142 * S.M.A.R.T. commands 143 */ 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 156 157 /*************************************************************************** 158 * IDE Control Register File 159 ***************************************************************************/ 160 161 typedef struct _IDE_REGISTERS_2 { 162 UCHAR AlternateStatus; /* RW: device control port */ 163 } IDE_REGISTERS_2, *PIDE_REGISTERS_2; 164 165 166 /* 167 * IDE drive control definitions 168 */ 169 #define IDE_DC_DISABLE_INTERRUPTS 0x02 170 #define IDE_DC_RESET_CONTROLLER 0x04 171 #define IDE_DC_REENABLE_CONTROLLER 0x00 172 173 /*************************************************************************** 174 * MSNS: Removable device 175 ***************************************************************************/ 176 /* 177 * Media syatus 178 */ 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 184 185 /* 186 * IDENTIFY data 187 */ 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 */ 246 247 } IDENTIFY_DATA, *PIDENTIFY_DATA; 248 249 typedef struct _CONFIGURATION_IDENTIFY_DATA { 250 USHORT Revision; 251 USHORT MWDMAModeSupported; 252 USHORT UDMAModeSupported; 253 ULONG MaximumLbaLow; 254 ULONG MaximumLbaHigh; 255 USHORT CommandSupport; 256 USHORT Reserved[247]; 257 UCHAR Signature; /* 0xA5 */ 258 UCHAR CheckSum; 259 } 260 CONFIGURATION_IDENTIFY_DATA, *PCONFIGURATION_IDENTIFY_DATA; 261 262 /* */ 263 /* Identify data without the Reserved4. */ 264 /* */ 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 */ 301 UCHAR Reserved4; 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; 313 314 #define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA2) 315 316 /* */ 317 /* IDENTIFY DMA timing cycle modes. */ 318 /* */ 319 320 #define IDENTIFY_DMA_CYCLES_MODE_0 0x00 321 #define IDENTIFY_DMA_CYCLES_MODE_1 0x01 322 #define IDENTIFY_DMA_CYCLES_MODE_2 0x02 323 324 /* 325 * Mode definitions 326 */ 327 typedef enum _DISK_MODE 328 { 329 IDE_PIO_0 = 0, 330 IDE_PIO_1, 331 IDE_PIO_2, 332 IDE_PIO_3, 333 IDE_PIO_4, 334 IDE_MWDMA_0, 335 IDE_MWDMA_1, 336 IDE_MWDMA_2, 337 IDE_UDMA_0, 338 IDE_UDMA_1, 339 IDE_UDMA_2, 340 IDE_UDMA_3, 341 IDE_UDMA_4, 342 IDE_UDMA_5, 343 IDE_UDMA_6, 344 IDE_UDMA_7, 345 } DISK_MODE; 346 347 /*************************************************************************** 348 * IDE Macro 349 ***************************************************************************/ 350 #ifndef MAX_LBA_T 351 #define MAX_LBA_T ((LBA_T)-1) 352 #endif 353 354 #define SECTOR_TO_BYTE_SHIFT 9 355 #define SECTOR_TO_BYTE(x) ((ULONG)(x) << SECTOR_TO_BYTE_SHIFT) 356 357 #define mGetStatus(IOPort2) (UCHAR)InPort(&IOPort2->AlternateStatus) 358 #define mUnitControl(IOPort2, Value) OutPort(&IOPort2->AlternateStatus,(UCHAR)(Value)) 359 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));\ 376 } while (0) 377 #else 378 #define mSelectUnit(IOPort,UnitId) OutPort(&IOPort->DriveSelect, (UCHAR)(UnitId)) 379 #endif 380 #define mGetUnitNumber(IOPort) InPort(&IOPort->DriveSelect) 381 #define mIssueCommand(IOPort,Cmd) OutPort(&IOPort->Command, (UCHAR)(Cmd)) 382 383 /* 384 * WDC old disk, don't care right now 385 */ 386 #define WDC_MW1_FIX_FLAG_OFFSET 129 387 #define WDC_MW1_FIX_FLAG_VALUE 0x00005555 388 389 #pragma pack() 390 #endif 391