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