| Commit | Line | Data |
|---|---|---|
| 258223a3 MD |
1 | /* |
| 2 | * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> | |
| 3 | * | |
| 4 | * Permission to use, copy, modify, and distribute this software for any | |
| 5 | * purpose with or without fee is hereby granted, provided that the above | |
| 6 | * copyright notice and this permission notice appear in all copies. | |
| 7 | * | |
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | * | |
| 16 | * $OpenBSD: atascsi.h,v 1.33 2009/02/16 21:19:06 miod Exp $ | |
| 17 | */ | |
| 18 | ||
| 19 | struct atascsi; | |
| 20 | struct scsi_link; | |
| 21 | ||
| 22 | /* | |
| 23 | * ATA commands | |
| 24 | */ | |
| 25 | ||
| 3209f581 | 26 | #define ATA_C_SATA_FEATURE_ENA 0x10 |
| 258223a3 MD |
27 | #define ATA_C_READDMA_EXT 0x25 |
| 28 | #define ATA_C_READ_LOG_EXT 0x2f | |
| 29 | #define ATA_C_WRITEDMA_EXT 0x35 | |
| 30 | #define ATA_C_READ_FPDMA 0x60 | |
| 31 | #define ATA_C_WRITE_FPDMA 0x61 | |
| 3209f581 | 32 | #define ATA_C_SATA_FEATURE_DIS 0x90 |
| 258223a3 | 33 | #define ATA_C_PACKET 0xa0 |
| fd8bd957 | 34 | #define ATA_C_ATAPI_IDENTIFY 0xa1 |
| 258223a3 MD |
35 | #define ATA_C_READDMA 0xc8 |
| 36 | #define ATA_C_WRITEDMA 0xca | |
| 1980eff3 MD |
37 | #define ATA_C_READ_PM 0xe4 |
| 38 | #define ATA_C_WRITE_PM 0xe8 | |
| 258223a3 MD |
39 | #define ATA_C_FLUSH_CACHE 0xe7 |
| 40 | #define ATA_C_FLUSH_CACHE_EXT 0xea /* lba48 */ | |
| 41 | #define ATA_C_IDENTIFY 0xec | |
| 42 | #define ATA_C_SET_FEATURES 0xef | |
| 43 | #define ATA_C_SEC_FREEZE_LOCK 0xf5 | |
| 44 | ||
| 45 | /* | |
| 3209f581 MD |
46 | * ATA SATA FEATURES subcommands |
| 47 | */ | |
| 48 | #define ATA_SATAFT_NONZDMA 0x01 /* DMA non-zero buffer offset */ | |
| 49 | #define ATA_SATAFT_DMAAAOPT 0x02 /* DMA AA optimization */ | |
| 50 | #define ATA_SATAFT_DEVIPS 0x03 /* Device-initiated pwr state*/ | |
| 51 | #define ATA_SATAFT_INORDER 0x04 /* in-order data delivery */ | |
| 52 | #define ATA_SATAFT_ASYNCNOTIFY 0x05 /* Async notification */ | |
| 53 | ||
| 54 | /* | |
| 258223a3 MD |
55 | * ATA SET FEATURES subcommands |
| 56 | */ | |
| 57 | #define ATA_SF_WRITECACHE_EN 0x02 | |
| 58 | #define ATA_SF_LOOKAHEAD_EN 0xaa | |
| 59 | ||
| 60 | struct ata_identify { | |
| 61 | u_int16_t config; /* 0 */ | |
| 62 | u_int16_t ncyls; /* 1 */ | |
| 63 | u_int16_t reserved1; /* 2 */ | |
| 64 | u_int16_t nheads; /* 3 */ | |
| 65 | u_int16_t track_size; /* 4 */ | |
| 66 | u_int16_t sector_size; /* 5 */ | |
| 67 | u_int16_t nsectors; /* 6 */ | |
| 68 | u_int16_t reserved2[3]; /* 7 vendor unique */ | |
| 69 | u_int8_t serial[20]; /* 10 */ | |
| 70 | u_int16_t buffer_type; /* 20 */ | |
| 71 | u_int16_t buffer_size; /* 21 */ | |
| 72 | u_int16_t ecc; /* 22 */ | |
| 73 | u_int8_t firmware[8]; /* 23 */ | |
| 74 | u_int8_t model[40]; /* 27 */ | |
| 75 | u_int16_t multi; /* 47 */ | |
| 76 | u_int16_t dwcap; /* 48 */ | |
| 77 | u_int16_t cap; /* 49 */ | |
| 78 | u_int16_t reserved3; /* 50 */ | |
| 79 | u_int16_t piomode; /* 51 */ | |
| 80 | u_int16_t dmamode; /* 52 */ | |
| 81 | u_int16_t validinfo; /* 53 */ | |
| 82 | u_int16_t curcyls; /* 54 */ | |
| 83 | u_int16_t curheads; /* 55 */ | |
| 84 | u_int16_t cursectrk; /* 56 */ | |
| 85 | u_int16_t curseccp[2]; /* 57 */ | |
| 86 | u_int16_t mult2; /* 59 */ | |
| 87 | u_int16_t addrsec[2]; /* 60 */ | |
| 88 | u_int16_t worddma; /* 62 */ | |
| 89 | u_int16_t dworddma; /* 63 */ | |
| 90 | u_int16_t advpiomode; /* 64 */ | |
| 91 | u_int16_t minmwdma; /* 65 */ | |
| 92 | u_int16_t recmwdma; /* 66 */ | |
| 93 | u_int16_t minpio; /* 67 */ | |
| 94 | u_int16_t minpioflow; /* 68 */ | |
| 95 | u_int16_t reserved4[2]; /* 69 */ | |
| 96 | u_int16_t typtime[2]; /* 71 */ | |
| 97 | u_int16_t reserved5[2]; /* 73 */ | |
| 98 | u_int16_t qdepth; /* 75 */ | |
| 99 | u_int16_t satacap; /* 76 */ | |
| 100 | u_int16_t reserved6; /* 77 */ | |
| 101 | u_int16_t satafsup; /* 78 */ | |
| 102 | u_int16_t satafen; /* 79 */ | |
| 103 | u_int16_t majver; /* 80 */ | |
| 104 | u_int16_t minver; /* 81 */ | |
| 105 | u_int16_t cmdset82; /* 82 */ | |
| 106 | u_int16_t cmdset83; /* 83 */ | |
| 107 | u_int16_t cmdset84; /* 84 */ | |
| 108 | u_int16_t features85; /* 85 */ | |
| 109 | u_int16_t features86; /* 86 */ | |
| 110 | u_int16_t features87; /* 87 */ | |
| 111 | #define ATA_ID_F87_WWN (1<<8) | |
| 112 | u_int16_t ultradma; /* 88 */ | |
| 113 | u_int16_t erasetime; /* 89 */ | |
| 114 | u_int16_t erasetimex; /* 90 */ | |
| 115 | u_int16_t apm; /* 91 */ | |
| 116 | u_int16_t masterpw; /* 92 */ | |
| 117 | u_int16_t hwreset; /* 93 */ | |
| 118 | u_int16_t acoustic; /* 94 */ | |
| 119 | u_int16_t stream_min; /* 95 */ | |
| 120 | u_int16_t stream_xfer_d; /* 96 */ | |
| 121 | u_int16_t stream_lat; /* 97 */ | |
| 122 | u_int16_t streamperf[2]; /* 98 */ | |
| 123 | u_int16_t addrsecxt[4]; /* 100 */ | |
| 124 | u_int16_t stream_xfer_p; /* 104 */ | |
| 125 | u_int16_t padding1; /* 105 */ | |
| 126 | u_int16_t phys_sect_sz; /* 106 */ | |
| 127 | u_int16_t seek_delay; /* 107 */ | |
| 128 | u_int16_t naa_ieee_oui; /* 108 */ | |
| 129 | u_int16_t ieee_oui_uid; /* 109 */ | |
| 130 | u_int16_t uid_mid; /* 110 */ | |
| 131 | u_int16_t uid_low; /* 111 */ | |
| 132 | u_int16_t resv_wwn[4]; /* 112 */ | |
| 133 | u_int16_t incits; /* 116 */ | |
| 134 | u_int16_t words_lsec[2]; /* 117 */ | |
| 135 | u_int16_t cmdset119; /* 119 */ | |
| 136 | u_int16_t features120; /* 120 */ | |
| 137 | u_int16_t padding2[6]; | |
| 138 | u_int16_t rmsn; /* 127 */ | |
| 139 | u_int16_t securestatus; /* 128 */ | |
| fd8bd957 MD |
140 | #define ATA_SECURE_LOCKED (1<<2) |
| 141 | #define ATA_SECURE_FROZEN (1<<3) | |
| 258223a3 MD |
142 | u_int16_t vendor[31]; /* 129 */ |
| 143 | u_int16_t padding3[16]; /* 160 */ | |
| 144 | u_int16_t curmedser[30]; /* 176 */ | |
| 145 | u_int16_t sctsupport; /* 206 */ | |
| 146 | u_int16_t padding4[48]; /* 207 */ | |
| 147 | u_int16_t integrity; /* 255 */ | |
| 148 | } __packed; | |
| 149 | ||
| 150 | /* | |
| 151 | * IDENTIFY DEVICE data | |
| 152 | */ | |
| 669fbbf7 | 153 | #define ATA_IDENTIFY_SECURITY (1 << 1) |
| 258223a3 MD |
154 | #define ATA_IDENTIFY_WRITECACHE (1 << 5) |
| 155 | #define ATA_IDENTIFY_LOOKAHEAD (1 << 6) | |
| 156 | ||
| 157 | /* | |
| 158 | * Frame Information Structures | |
| 159 | */ | |
| 160 | ||
| 161 | #define ATA_FIS_LENGTH 20 | |
| 162 | ||
| 163 | struct ata_fis_h2d { | |
| 164 | u_int8_t type; | |
| 165 | #define ATA_FIS_TYPE_H2D 0x27 | |
| 166 | u_int8_t flags; | |
| 167 | #define ATA_H2D_FLAGS_CMD (1<<7) | |
| 168 | u_int8_t command; | |
| 169 | u_int8_t features; | |
| 170 | #define ATA_H2D_FEATURES_DMA (1<<0) | |
| 171 | #define ATA_H2D_FEATURES_DIR (1<<2) | |
| 172 | #define ATA_H2D_FEATURES_DIR_READ (1<<2) | |
| 173 | #define ATA_H2D_FEATURES_DIR_WRITE (0<<2) | |
| 174 | ||
| 175 | u_int8_t lba_low; | |
| 176 | u_int8_t lba_mid; | |
| 177 | u_int8_t lba_high; | |
| 178 | u_int8_t device; | |
| 179 | #define ATA_H2D_DEVICE_LBA 0x40 | |
| 180 | ||
| 181 | u_int8_t lba_low_exp; | |
| 182 | u_int8_t lba_mid_exp; | |
| 183 | u_int8_t lba_high_exp; | |
| 184 | u_int8_t features_exp; | |
| 185 | ||
| 186 | u_int8_t sector_count; | |
| 187 | u_int8_t sector_count_exp; | |
| 188 | u_int8_t reserved0; | |
| 189 | u_int8_t control; | |
| cec85a37 | 190 | #define ATA_FIS_CONTROL_SRST 0x04 |
| 1980eff3 | 191 | #define ATA_FIS_CONTROL_4BIT 0x08 |
| 258223a3 MD |
192 | |
| 193 | u_int8_t reserved1; | |
| 194 | u_int8_t reserved2; | |
| 195 | u_int8_t reserved3; | |
| 196 | u_int8_t reserved4; | |
| 197 | } __packed; | |
| 198 | ||
| 199 | struct ata_fis_d2h { | |
| 200 | u_int8_t type; | |
| 201 | #define ATA_FIS_TYPE_D2H 0x34 | |
| 202 | u_int8_t flags; | |
| 203 | #define ATA_D2H_FLAGS_INTR (1<<6) | |
| 204 | u_int8_t status; | |
| 205 | u_int8_t error; | |
| 206 | ||
| 207 | u_int8_t lba_low; | |
| 208 | u_int8_t lba_mid; | |
| 209 | u_int8_t lba_high; | |
| 210 | u_int8_t device; | |
| 211 | ||
| 212 | u_int8_t lba_low_exp; | |
| 213 | u_int8_t lba_mid_exp; | |
| 214 | u_int8_t lba_high_exp; | |
| 215 | u_int8_t reserved0; | |
| 216 | ||
| 217 | u_int8_t sector_count; | |
| 218 | u_int8_t sector_count_exp; | |
| 219 | u_int8_t reserved1; | |
| 220 | u_int8_t reserved2; | |
| 221 | ||
| 222 | u_int8_t reserved3; | |
| 223 | u_int8_t reserved4; | |
| 224 | u_int8_t reserved5; | |
| 225 | u_int8_t reserved6; | |
| 226 | } __packed; | |
| 227 | ||
| 228 | /* | |
| 229 | * SATA log page 10h - | |
| 230 | * looks like a D2H FIS, with errored tag number in first byte. | |
| 231 | */ | |
| 232 | struct ata_log_page_10h { | |
| 233 | struct ata_fis_d2h err_regs; | |
| 234 | #define ATA_LOG_10H_TYPE_NOTQUEUED 0x80 | |
| 235 | #define ATA_LOG_10H_TYPE_TAG_MASK 0x1f | |
| 236 | u_int8_t reserved[256 - sizeof(struct ata_fis_d2h)]; | |
| 237 | u_int8_t vendor_specific[255]; | |
| 238 | u_int8_t checksum; | |
| 239 | } __packed; | |
| 240 | ||
| 241 | /* | |
| 242 | * SATA registers | |
| 243 | */ | |
| 244 | ||
| 245 | #define SATA_SStatus_DET 0x00f | |
| 246 | #define SATA_SStatus_DET_NODEV 0x000 | |
| 247 | #define SATA_SStatus_DET_NOPHY 0x001 | |
| 248 | #define SATA_SStatus_DET_DEV 0x003 | |
| 249 | #define SATA_SStatus_DET_OFFLINE 0x008 | |
| 250 | ||
| 251 | #define SATA_SStatus_SPD 0x0f0 | |
| 252 | #define SATA_SStatus_SPD_NONE 0x000 | |
| 253 | #define SATA_SStatus_SPD_1_5 0x010 | |
| 254 | #define SATA_SStatus_SPD_3_0 0x020 | |
| 255 | ||
| 256 | #define SATA_SStatus_IPM 0xf00 | |
| 257 | #define SATA_SStatus_IPM_NODEV 0x000 | |
| 258 | #define SATA_SStatus_IPM_ACTIVE 0x100 | |
| 259 | #define SATA_SStatus_IPM_PARTIAL 0x200 | |
| 260 | #define SATA_SStatus_IPM_SLUMBER 0x600 | |
| 261 | ||
| 262 | #define SATA_SIGNATURE_PORT_MULTIPLIER 0x96690101 | |
| 263 | #define SATA_SIGNATURE_ATAPI 0xeb140101 | |
| 264 | #define SATA_SIGNATURE_DISK 0x00000101 | |
| 265 | ||
| 266 | /* | |
| 267 | * ATA interface | |
| 268 | */ | |
| 269 | ||
| 1980eff3 MD |
270 | struct ahci_port; |
| 271 | ||
| 258223a3 | 272 | struct ata_port { |
| 1980eff3 MD |
273 | struct ata_identify at_identify; /* only if ATA_PORT_T_DISK */ |
| 274 | struct ahci_port *at_ahci_port; | |
| 275 | int at_type; | |
| 258223a3 MD |
276 | #define ATA_PORT_T_NONE 0 |
| 277 | #define ATA_PORT_T_DISK 1 | |
| 278 | #define ATA_PORT_T_ATAPI 2 | |
| 1980eff3 MD |
279 | #define ATA_PORT_T_PM 3 |
| 280 | int at_features; | |
| 281 | #define ATA_PORT_F_WCACHE (1 << 0) | |
| 282 | #define ATA_PORT_F_RAHEAD (1 << 1) | |
| 283 | #define ATA_PORT_F_FRZLCK (1 << 2) | |
| 3209f581 | 284 | #define ATA_PORT_F_RESCAN (1 << 3) /* re-check on bus scan */ |
| 1980eff3 | 285 | int at_probe; |
| 3209f581 MD |
286 | #define ATA_PROBE_NEED_INIT 0 |
| 287 | #define ATA_PROBE_NEED_HARD_RESET 1 | |
| 288 | #define ATA_PROBE_NEED_SOFT_RESET 2 | |
| 289 | #define ATA_PROBE_NEED_IDENT 3 | |
| 290 | #define ATA_PROBE_GOOD 4 | |
| 1980eff3 MD |
291 | #define ATA_PROBE_FAILED 7 |
| 292 | int at_ncqdepth; | |
| 293 | u_int64_t at_capacity; /* only if ATA_PORT_T_DISK */ | |
| 294 | int at_target; /* port multiplier port */ | |
| 295 | char at_name[16]; | |
| 258223a3 MD |
296 | }; |
| 297 | ||
| 298 | struct ata_xfer { | |
| 299 | struct ata_fis_h2d *fis; | |
| 300 | struct ata_fis_d2h rfis; | |
| 301 | u_int8_t *packetcmd; | |
| 302 | u_int8_t tag; | |
| 303 | ||
| 304 | void *data; | |
| 305 | size_t datalen; | |
| 306 | size_t resid; | |
| 307 | ||
| 308 | void (*complete)(struct ata_xfer *); | |
| 309 | u_int timeout; | |
| 310 | ||
| 311 | int flags; | |
| 312 | #define ATA_F_READ (1<<0) | |
| 313 | #define ATA_F_WRITE (1<<1) | |
| 314 | #define ATA_F_NOWAIT (1<<2) | |
| 315 | #define ATA_F_POLL (1<<3) | |
| 316 | #define ATA_F_PIO (1<<4) | |
| 317 | #define ATA_F_PACKET (1<<5) | |
| 318 | #define ATA_F_NCQ (1<<6) | |
| 319 | #define ATA_F_TIMEOUT_RUNNING (1<<7) | |
| 3209f581 | 320 | #define ATA_F_TIMEOUT_DESIRED (1<<8) |
| f4553de1 | 321 | #define ATA_F_TIMEOUT_EXPIRED (1<<9) |
| 12feb904 MD |
322 | #define ATA_F_AUTOSENSE (1<<10) |
| 323 | #define ATA_F_EXCLUSIVE (1<<11) | |
| 1067474a | 324 | #define ATA_FMT_FLAGS "\020" \ |
| 12feb904 MD |
325 | "\014EXCLUSIVE" \ |
| 326 | "\013AUTOSENSE" \ | |
| 1067474a MD |
327 | "\012EXPIRED" \ |
| 328 | "\011DESIRED" "\010TRUNNING" \ | |
| 329 | "\007NCQ" "\006PACKET" \ | |
| 258223a3 MD |
330 | "\005PIO" "\004POLL" "\003NOWAIT" \ |
| 331 | "\002WRITE" "\001READ" | |
| 332 | ||
| 333 | volatile int state; | |
| 334 | #define ATA_S_SETUP 0 | |
| 335 | #define ATA_S_PENDING 1 | |
| 336 | #define ATA_S_COMPLETE 2 | |
| 337 | #define ATA_S_ERROR 3 | |
| 338 | #define ATA_S_TIMEOUT 4 | |
| 339 | #define ATA_S_ONCHIP 5 | |
| 340 | #define ATA_S_PUT 6 | |
| 341 | ||
| 342 | void *atascsi_private; | |
| 1980eff3 | 343 | struct ata_port *at; /* NULL if direct-attached */ |
| 258223a3 MD |
344 | }; |
| 345 |