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