xref: /openbsd/sys/dev/ata/atascsi.h (revision 404b540a)
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