aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/ata.h
blob: fcb891ed15880e3d486235de024593aef4604fa5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/*-
 * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer,
 *    without modification, immediately at the beginning of the file.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD$
 */

#ifndef _SYS_ATA_H_
#define _SYS_ATA_H_

#include <sys/ioccom.h>

#define ATAPI_PSIZE_12			0	/* 12 bytes */
#define ATAPI_PSIZE_16			1	/* 16 bytes */

#define ATAPI_DRQT_MPROC		0	/* cpu	  3 ms delay */
#define ATAPI_DRQT_INTR			1	/* intr	 10 ms delay */
#define ATAPI_DRQT_ACCEL		2	/* accel 50 us delay */

#define ATAPI_TYPE_DIRECT		0	/* disk/floppy */
#define ATAPI_TYPE_TAPE			1	/* streaming tape */
#define ATAPI_TYPE_CDROM		5	/* CD-ROM device */
#define ATAPI_TYPE_OPTICAL		7	/* optical disk */

#define ATA_PROTO_ATA			0
#define ATA_PROTO_ATAPI			1

#define ATA_BT_SINGLEPORTSECTOR		1	/* 1 port, 1 sector buffer */
#define ATA_BT_DUALPORTMULTI		2	/* 2 port, mult sector buffer */
#define ATA_BT_DUALPORTMULTICACHE	3	/* above plus track cache */

#define ATA_FLAG_54_58			1	/* words 54-58 valid */
#define ATA_FLAG_64_70			2	/* words 64-70 valid */
#define ATA_FLAG_88			4	/* word 88 valid */

/* ATA/ATAPI device parameter information */
struct ata_params {

#if BYTE_ORDER == LITTLE_ENDIAN
/*000*/	u_int16_t	packet_size	:2;	/* packet command size */

    	u_int16_t	incomplete	:1;
    	u_int16_t			:2;
    	u_int16_t	drq_type	:2;	/* DRQ type */

    	u_int16_t	removable	:1;	/* device is removable */
    	u_int16_t	type		:5;	/* device type */

    	u_int16_t			:2;
    	u_int16_t	cmd_protocol	:1;	/* command protocol */
#else
    	u_int16_t	cmd_protocol	:1;	/* command protocol */
    	u_int16_t			:2;

    	u_int16_t	type		:5;	/* device type */
    	u_int16_t	removable	:1;	/* device is removable */

    	u_int16_t	drq_type	:2;	/* DRQ type */
    	u_int16_t			:2;
    	u_int16_t	incomplete	:1;

	u_int16_t	packet_size	:2;	/* packet command size */
#endif

/*001*/	u_int16_t	cylinders;		/* # of cylinders */
	u_int16_t	reserved2;
/*003*/	u_int16_t	heads;			/* # heads */
	u_int16_t	obsolete4;
	u_int16_t	obsolete5;
/*006*/	u_int16_t	sectors;		/* # sectors/track */
/*007*/	u_int16_t	vendor7[3];
/*010*/	u_int8_t	serial[20];		/* serial number */
	u_int16_t	retired20;
	u_int16_t	retired21;
	u_int16_t	obsolete22;
/*023*/	u_int8_t	revision[8];		/* firmware revision */
/*027*/	u_int8_t	model[40];		/* model name */

#if BYTE_ORDER == LITTLE_ENDIAN
/*047*/	u_int16_t	sectors_intr:8;		/* sectors per interrupt */
	u_int16_t	:8;
#else
	u_int16_t	:8;
	u_int16_t	sectors_intr:8;		/* sectors per interrupt */
#endif

/*048*/	u_int16_t	usedmovsd;		/* double word read/write? */

#if BYTE_ORDER == LITTLE_ENDIAN
/*049*/	u_int16_t	retired49:8;
	u_int16_t	support_dma	:1;	/* DMA supported */
	u_int16_t	support_lba	:1;	/* LBA supported */
	u_int16_t	disable_iordy	:1;	/* IORDY may be disabled */
	u_int16_t	support_iordy	:1;	/* IORDY supported */
	u_int16_t	softreset	:1;	/* needs softreset when busy */
	u_int16_t	stdby_ovlap	:1;	/* standby/overlap supported */
	u_int16_t	support_queueing:1;	/* supports queuing overlap */
	u_int16_t	support_idma	:1;	/* interleaved DMA supported */

/*050*/	u_int16_t	device_stdby_min:1;
	u_int16_t	:13;
	u_int16_t	capability_one:1;
	u_int16_t	capability_zero:1;

/*051*/	u_int16_t	vendor51:8;
	u_int16_t	retired_piomode:8;	/* PIO modes 0-2 */
/*052*/	u_int16_t	vendor52:8;
	u_int16_t	retired_dmamode:8;	/* DMA modes, not ATA-3 */
#else
	u_int16_t	support_idma	:1;	/* interleaved DMA supported */
	u_int16_t	support_queueing:1;	/* supports queuing overlap */
	u_int16_t	stdby_ovlap	:1;	/* standby/overlap supported */
	u_int16_t	softreset	:1;	/* needs softreset when busy */
	u_int16_t	support_iordy	:1;	/* IORDY supported */
	u_int16_t	disable_iordy	:1;	/* IORDY may be disabled */
	u_int16_t	support_lba	:1;	/* LBA supported */
	u_int16_t	support_dma	:1;	/* DMA supported */
	u_int16_t	retired49:8;

	u_int16_t	capability_zero:1;
	u_int16_t	capability_one:1;
	u_int16_t	:13;
	u_int16_t	device_stdby_min:1;

	u_int16_t	retired_piomode:8;	/* PIO modes 0-2 */
	u_int16_t	vendor51:8;
	u_int16_t	retired_dmamode:8;	/* DMA modes, not ATA-3 */
	u_int16_t	vendor52:8;
#endif

/*053*/	u_int16_t	atavalid;		/* fields valid */

	u_int16_t	obsolete54[5];

#if BYTE_ORDER == LITTLE_ENDIAN
/*059*/	u_int16_t	multi_count:8;
	u_int16_t	multi_valid:1;
	u_int16_t	:7;
#else
	u_int16_t	:7;
	u_int16_t	multi_valid:1;
	u_int16_t	multi_count:8;
#endif

/*060*/	u_int16_t	lba_size_1;
	u_int16_t	lba_size_2;
	u_int16_t	obsolete62;
/*063*/	u_int16_t	mwdmamodes;		/* multiword DMA modes */ 
/*064*/	u_int16_t	apiomodes;		/* advanced PIO modes */ 

/*065*/	u_int16_t	mwdmamin;		/* min. M/W DMA time/word ns */
/*066*/	u_int16_t	mwdmarec;		/* rec. M/W DMA time ns */
/*067*/	u_int16_t	pioblind;		/* min. PIO cycle w/o flow */
/*068*/	u_int16_t	pioiordy;		/* min. PIO cycle IORDY flow */
	u_int16_t	reserved69;
	u_int16_t	reserved70;
/*071*/	u_int16_t	rlsovlap;		/* rel time (us) for overlap */
/*072*/	u_int16_t	rlsservice;		/* rel time (us) for service */
	u_int16_t	reserved73;
	u_int16_t	reserved74;

#if BYTE_ORDER == LITTLE_ENDIAN
/*075*/	u_int16_t	queuelen:5;
	u_int16_t	:11;
#else
	u_int16_t	:11;
	u_int16_t	queuelen:5;
#endif

	u_int16_t	reserved76;
	u_int16_t	reserved77;
	u_int16_t	reserved78;
	u_int16_t	reserved79;
/*080*/	u_int16_t	version_major;
/*081*/	u_int16_t	version_minor;
	struct {
#if BYTE_ORDER == LITTLE_ENDIAN
/*082/085*/ u_int16_t	smart:1;
	    u_int16_t	security:1;
	    u_int16_t	removable:1;
	    u_int16_t	power_mngt:1;
	    u_int16_t	packet:1;
	    u_int16_t	write_cache:1;
	    u_int16_t	look_ahead:1;
	    u_int16_t	release_irq:1;
	    u_int16_t	service_irq:1;
	    u_int16_t	reset:1;
	    u_int16_t	protected:1;
	    u_int16_t	:1;
	    u_int16_t	write_buffer:1;
	    u_int16_t	read_buffer:1;
	    u_int16_t	nop:1;
	    u_int16_t	:1;

/*083/086*/ u_int16_t	microcode:1;
	    u_int16_t	queued:1;
	    u_int16_t	cfa:1;
	    u_int16_t	apm:1;
	    u_int16_t	notify:1;
	    u_int16_t	standby:1;
	    u_int16_t	spinup:1;
	    u_int16_t	:1;
	    u_int16_t	max_security:1;
	    u_int16_t	auto_acoustic:1;
	    u_int16_t	address48:1;
	    u_int16_t	config_overlay:1;
	    u_int16_t	flush_cache:1;
	    u_int16_t	flush_cache48:1;
	    u_int16_t	support_one:1;
	    u_int16_t	support_zero:1;

/*084/087*/ u_int16_t	smart_error_log:1;
	    u_int16_t	smart_self_test:1;
	    u_int16_t	media_serial_no:1;
	    u_int16_t	media_card_pass:1;
	    u_int16_t	streaming:1;
	    u_int16_t	logging:1;
	    u_int16_t	:8;
	    u_int16_t	extended_one:1;
	    u_int16_t	extended_zero:1;
#else
	    u_int16_t	:1;
	    u_int16_t	nop:1;
	    u_int16_t	read_buffer:1;
	    u_int16_t	write_buffer:1;
	    u_int16_t	:1;
	    u_int16_t	protected:1;
	    u_int16_t	reset:1;
	    u_int16_t	service_irq:1;
	    u_int16_t	release_irq:1;
	    u_int16_t	look_ahead:1;
	    u_int16_t	write_cache:1;
	    u_int16_t	packet:1;
	    u_int16_t	power_mngt:1;
	    u_int16_t	removable:1;
	    u_int16_t	security:1;
	    u_int16_t	smart:1;

	    u_int16_t	support_zero:1;
	    u_int16_t	support_one:1;
	    u_int16_t	flush_cache48:1;
	    u_int16_t	flush_cache:1;
	    u_int16_t	config_overlay:1;
	    u_int16_t	address48:1;
	    u_int16_t	auto_acoustic:1;
	    u_int16_t	max_security:1;
	    u_int16_t	:1;
	    u_int16_t	spinup:1;
	    u_int16_t	standby:1;
	    u_int16_t	notify:1;
	    u_int16_t	apm:1;
	    u_int16_t	cfa:1;
	    u_int16_t	queued:1;
	    u_int16_t	microcode:1;

	    u_int16_t	extended_zero:1;
	    u_int16_t	extended_one:1;
	    u_int16_t	:8;
	    u_int16_t	logging:1;
	    u_int16_t	streaming:1;
	    u_int16_t	media_card_pass:1;
	    u_int16_t	media_serial_no:1;
	    u_int16_t	smart_self_test:1;
	    u_int16_t	smart_error_log:1;
#endif
	} support, enabled;

/*088*/	u_int16_t	udmamodes;		/* UltraDMA modes */
/*089*/	u_int16_t	erase_time;
/*090*/	u_int16_t	enhanced_erase_time;
/*091*/	u_int16_t	apm_value;
/*092*/	u_int16_t	master_passwd_revision;

#if BYTE_ORDER == LITTLE_ENDIAN
/*093*/	u_int16_t	hwres_master	:8;
	u_int16_t	hwres_slave	:5;
	u_int16_t	hwres_cblid	:1;
	u_int16_t	hwres_valid:2;

/*094*/	u_int16_t	current_acoustic:8;
	u_int16_t	vendor_acoustic:8;
#else
	u_int16_t	hwres_valid:2;
	u_int16_t	hwres_cblid	:1;
	u_int16_t	hwres_slave	:5;
	u_int16_t	hwres_master	:8;

	u_int16_t	vendor_acoustic:8;
	u_int16_t	current_acoustic:8;
#endif

/*095*/	u_int16_t	stream_min_req_size;
/*096*/	u_int16_t	stream_transfer_time;
/*097*/	u_int16_t	stream_access_latency;
/*098*/	u_int32_t	stream_granularity;
/*100*/	u_int16_t	lba_size48_1;
	u_int16_t	lba_size48_2;
	u_int16_t	lba_size48_3;
	u_int16_t	lba_size48_4;
	u_int16_t	reserved104[23];
/*127*/	u_int16_t	removable_status;
/*128*/	u_int16_t	security_status;
	u_int16_t	reserved129[31];
/*160*/	u_int16_t	cfa_powermode1;
	u_int16_t	reserved161[14];
/*176*/	u_int16_t	media_serial[30];
	u_int16_t	reserved206[49];
/*255*/	u_int16_t	integrity;
};

#define ATA_MODE_MASK		0x0f
#define ATA_DMA_MASK		0xf0
#define ATA_PIO			0x00
#define ATA_PIO0		0x08
#define ATA_PIO1		0x09
#define ATA_PIO2		0x0a
#define ATA_PIO3		0x0b
#define ATA_PIO4		0x0c
#define ATA_DMA			0x10
#define ATA_WDMA		0x20
#define ATA_WDMA2		0x22
#define ATA_UDMA		0x40
#define ATA_UDMA2		0x42
#define ATA_UDMA4		0x44
#define ATA_UDMA5		0x45
#define ATA_UDMA6		0x46

struct ata_cmd {
    int				channel;
    int				device;
    int				cmd;
#define ATAGPARM		1
#define ATAGMODE		2
#define ATASMODE		3
#define ATAREINIT		4
#define ATAATTACH		5
#define ATADETACH		6
#define ATAPICMD		7
#define ATARAIDREBUILD		8
#define ATARAIDCREATE		9
#define ATARAIDDELETE		10
#define ATARAIDSTATUS		11
#define ATAENCSTAT		12

    union {
	struct {
	    int			mode[2];
	} mode;
	struct {
	    int			type[2];
	    char		name[2][32];
	    struct ata_params	params[2];
	} param;
	struct raid_setup {
	    int			type;
#define	AR_RAID0			1
#define	AR_RAID1			2
#define	AR_SPAN				4

	    int			total_disks;
	    int			disks[16];
	    int			interleave;
	    int			unit;
	} raid_setup;
	struct raid_status {
	    int			type;
	    int			total_disks;
	    int			disks[16];
	    int			interleave;
	    int			status;
#define	AR_READY			1
#define	AR_DEGRADED			2
#define	AR_REBUILDING			4

	    int			progress;
	} raid_status;
	struct {
	    int			fan;
	    int			temp;
	    int			v05;
	    int			v12;
	} enclosure;
	struct {
	    char		ccb[16];
	    caddr_t		data;
	    int			count;
	    int			flags;
#define ATAPI_CMD_CTRL			0x00
#define ATAPI_CMD_READ			0x01
#define ATAPI_CMD_WRITE			0x02

	    int			timeout;
	    int			error;
	    char		sense_data[18];
	} atapi;
    } u;
};

#define IOCATA			_IOWR('a',  1, struct ata_cmd)

#endif /* _SYS_ATA_H_ */