Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * advanced host controller interface (sata)
3
 * © 2007  coraid, inc
4
 */
5
 
6
/* ata errors */
7
enum {
8
	Emed	= 1<<0,		/* media error */
9
	Enm	= 1<<1,		/* no media */
10
	Eabrt	= 1<<2,		/* abort */
11
	Emcr	= 1<<3,		/* media change request */
12
	Eidnf	= 1<<4,		/* no user-accessible address */
13
	Emc	= 1<<5,		/* media change */
14
	Eunc	= 1<<6,		/* data error */
15
	Ewp	= 1<<6,		/* write protect */
16
	Eicrc	= 1<<7,		/* interface crc error */
17
 
18
	Efatal	= Eidnf|Eicrc,	/* must sw reset */
19
};
20
 
21
/* ata status */
22
enum {
23
	ASerr	= 1<<0,		/* error */
24
	ASdrq	= 1<<3,		/* request */
25
	ASdf	= 1<<5,		/* fault */
26
	ASdrdy	= 1<<6,		/* ready */
27
	ASbsy	= 1<<7,		/* busy */
28
 
29
	ASobs	= 1<<1|1<<2|1<<4,
30
};
31
 
32
/* pci configuration */
33
enum {
34
	Abar	= 5,
35
};
36
 
37
/*
38
 * ahci memory configuration
39
 *
40
 * 0000-0023	generic host control
41
 * 0024-009f	reserved
42
 * 00a0-00ff	vendor specific.
43
 * 0100-017f	port 0
44
 * ...
45
 * 1080-1100	port 31
46
 */
47
 
48
/* cap bits: supported features */
49
enum {
50
	Hs64a	= 1<<31,	/* 64-bit addressing */
51
	Hsncq	= 1<<30,	/* ncq */
52
	Hssntf	= 1<<29,	/* snotification reg. */
53
	Hsmps	= 1<<28,	/* mech pres switch */
54
	Hsss	= 1<<27,	/* staggered spinup */
55
	Hsalp	= 1<<26,	/* aggressive link pm */
56
	Hsal	= 1<<25,	/* activity led */
57
	Hsclo	= 1<<24,	/* command-list override */
58
	Hiss	= 1<<20,	/* for interface speed */
59
//	Hsnzo	= 1<<19,
60
	Hsam	= 1<<18,	/* ahci-mode only */
61
	Hspm	= 1<<17,	/* port multiplier */
62
//	Hfbss	= 1<<16,
63
	Hpmb	= 1<<15,	/* multiple-block pio */
64
	Hssc	= 1<<14,	/* slumber state */
65
	Hpsc	= 1<<13,	/* partial-slumber state */
66
	Hncs	= 1<<8,		/* n command slots */
67
	Hcccs	= 1<<7,		/* coal */
68
	Hems	= 1<<6,		/* enclosure mgmt. */
69
	Hsxs	= 1<<5,		/* external sata */
70
	Hnp	= 1<<0,		/* n ports */
71
};
72
 
73
/* ghc bits */
74
enum {
75
	Hae	= 1<<31,	/* enable ahci */
76
	Hie	= 1<<1,		/* " interrupts */
77
	Hhr	= 1<<0,		/* hba reset */
78
};
79
 
80
typedef struct {
81
	ulong	cap;
82
	ulong	ghc;
83
	ulong	isr;
84
	ulong	pi;		/* ports implemented */
85
	ulong	ver;
86
	ulong	ccc;		/* coaleasing control */
87
	ulong	cccports;
88
	ulong	emloc;
89
	ulong	emctl;
90
} Ahba;
91
 
92
enum {
93
	Acpds	= 1<<31,	/* cold port detect status */
94
	Atfes	= 1<<30,	/* task file error status */
95
	Ahbfs	= 1<<29,	/* hba fatal */
96
	Ahbds	= 1<<28,	/* hba error (parity error) */
97
	Aifs	= 1<<27,	/* interface fatal  §6.1.2 */
98
	Ainfs	= 1<<26,	/* interface error (recovered) */
99
	Aofs	= 1<<24,	/* too many bytes from disk */
100
	Aipms	= 1<<23,	/* incorrect prt mul status */
101
	Aprcs	= 1<<22,	/* PhyRdy change status Pxserr.diag.n */
102
	Adpms	= 1<<7,		/* mechanical presence status */
103
	Apcs 	= 1<<6,		/* port connect  diag.x */
104
	Adps 	= 1<<5,		/* descriptor processed */
105
	Aufs 	= 1<<4,		/* unknown fis diag.f */
106
	Asdbs	= 1<<3,		/* set device bits fis received w/ i bit set */
107
	Adss	= 1<<2,		/* dma setup */
108
	Apio	= 1<<1,		/* pio setup fis */
109
	Adhrs	= 1<<0,		/* device to host register fis */
110
 
111
	IEM	= Acpds|Atfes|Ahbds|Ahbfs|Ahbds|Aifs|Ainfs|Aprcs|Apcs|Adps|
112
			Aufs|Asdbs|Adss|Adhrs,
113
	Ifatal	= Atfes|Ahbfs|Ahbds|Aifs,
114
};
115
 
116
/* serror bits */
117
enum {
118
	SerrX	= 1<<26,	/* exchanged */
119
	SerrF	= 1<<25,	/* unknown fis */
120
	SerrT	= 1<<24,	/* transition error */
121
	SerrS	= 1<<23,	/* link sequence */
122
	SerrH	= 1<<22,	/* handshake */
123
	SerrC	= 1<<21,	/* crc */
124
	SerrD	= 1<<20,	/* not used by ahci */
125
	SerrB	= 1<<19,	/* 10-tp-8 decode */
126
	SerrW	= 1<<18,	/* comm wake */
127
	SerrI	= 1<<17,	/* phy internal */
128
	SerrN	= 1<<16,	/* phyrdy change */
129
 
130
	ErrE	= 1<<11,	/* internal */
131
	ErrP	= 1<<10,	/* ata protocol violation */
132
	ErrC	= 1<<9,		/* communication */
133
	ErrT	= 1<<8,		/* transient */
134
	ErrM	= 1<<1,		/* recoverd comm */
135
	ErrI	= 1<<0,		/* recovered data integrety */
136
 
137
	ErrAll	= ErrE|ErrP|ErrC|ErrT|ErrM|ErrI,
138
	SerrAll	= SerrX|SerrF|SerrT|SerrS|SerrH|SerrC|SerrD|SerrB|SerrW|
139
			SerrI|SerrN|ErrAll,
140
	SerrBad	= 0x7f<<19,
141
};
142
 
143
/* cmd register bits */
144
enum {
145
	Aicc	= 1<<28,	/* interface communcations control. 4 bits */
146
	Aasp	= 1<<27,	/* aggressive slumber & partial sleep */
147
	Aalpe 	= 1<<26,	/* aggressive link pm enable */
148
	Adlae	= 1<<25,	/* drive led on atapi */
149
	Aatapi	= 1<<24,	/* device is atapi */
150
	Aesp	= 1<<21,	/* external sata port */
151
	Acpd	= 1<<20,	/* cold presence detect */
152
	Ampsp	= 1<<19,	/* mechanical pres. */
153
	Ahpcp	= 1<<18,	/* hot plug capable */
154
	Apma	= 1<<17,	/* pm attached */
155
	Acps	= 1<<16,	/* cold presence state */
156
	Acr	= 1<<15,	/* cmdlist running */
157
	Afr	= 1<<14,	/* fis running */
158
	Ampss	= 1<<13,	/* mechanical presence switch state */
159
	Accs	= 1<<8,		/* current command slot 12:08 */
160
	Afre	= 1<<4,		/* fis enable receive */
161
	Aclo	= 1<<3,		/* command list override */
162
	Apod	= 1<<2,		/* power on dev (requires cold-pres. detect) */
163
	Asud	= 1<<1,		/* spin-up device;  requires ss capability */
164
	Ast	= 1<<0,		/* start */
165
 
166
	Arun	= Ast|Acr|Afre|Afr,
167
};
168
 
169
/* ctl register bits */
170
enum {
171
	Aipm	= 1<<8,		/* interface power mgmt. 3=off */
172
	Aspd	= 1<<4,
173
	Adet	= 1<<0,		/* device detection */
174
};
175
 
176
#define	sstatus	scr0
177
#define	sctl	scr2
178
#define	serror	scr1
179
#define	sactive	scr3
180
 
181
typedef struct {
182
	ulong	list;		/* PxCLB must be 1kb aligned. */
183
	ulong	listhi;
184
	ulong	fis;		/* 256-byte aligned */
185
	ulong	fishi;
186
	ulong	isr;
187
	ulong	ie;		/* interrupt enable */
188
	ulong	cmd;
189
	ulong	res1;
190
	ulong	task;
191
	ulong	sig;
192
	ulong	scr0;
193
	ulong	scr2;
194
	ulong	scr1;
195
	ulong	scr3;
196
	ulong	ci;		/* command issue */
197
	ulong	ntf;
198
	uchar	res2[8];
199
	ulong	vendor;
200
} Aport;
201
 
202
enum {
203
	/*
204
	 * Aport sstatus bits (actually states):
205
	 * 11-8 interface power management
206
	 *  7-4 current interface speed (generation #)
207
	 *  3-0 device detection
208
	 */
209
	Intslumber	= 0x600,
210
	Intpartpwr	= 0x200,
211
	Intactive	= 0x100,
212
	Intpm		= 0xf00,
213
 
214
	Devphyoffline	= 4,
215
	Devphycomm	= 2,		/* phy communication established */
216
	Devpresent	= 1,
217
	Devdet		= Devpresent | Devphycomm | Devphyoffline,
218
};
219
 
220
/* in host's memory; not memory mapped */
221
typedef struct {
222
	uchar	*base;
223
	uchar	*d;
224
	uchar	*p;
225
	uchar	*r;
226
	uchar	*u;
227
	ulong	*devicebits;
228
} Afis;
229
 
230
enum {
231
	Lprdtl	= 1<<16,	/* physical region descriptor table len */
232
	Lpmp	= 1<<12,	/* port multiplier port */
233
	Lclear	= 1<<10,	/* clear busy on R_OK */
234
	Lbist	= 1<<9,
235
	Lreset	= 1<<8,
236
	Lpref	= 1<<7,		/* prefetchable */
237
	Lwrite	= 1<<6,
238
	Latapi	= 1<<5,
239
	Lcfl	= 1<<0,		/* command fis length in double words */
240
};
241
 
242
/* in hosts memory; memory mapped */
243
typedef struct {
244
	ulong	flags;
245
	ulong	len;
246
	ulong	ctab;
247
	ulong	ctabhi;
248
	uchar	reserved[16];
249
} Alist;
250
 
251
typedef struct {
252
	ulong	dba;
253
	ulong	dbahi;
254
	ulong	pad;
255
	ulong	count;
256
} Aprdt;
257
 
258
typedef struct {
259
	uchar	cfis[0x40];
260
	uchar	atapi[0x10];
261
	uchar	pad[0x30];
262
	Aprdt	prdt;
263
} Actab;
264
 
265
enum {
266
	Ferror	= 1,
267
	Fdone	= 2,
268
};
269
 
270
enum {
271
	Dllba 	= 1,
272
	Dsmart	= 1<<1,
273
	Dpower	= 1<<2,
274
	Dnop	= 1<<3,
275
	Datapi	= 1<<4,
276
	Datapi16= 1<<5,
277
};
278
 
279
typedef struct {
280
	QLock;
281
	Rendez;
282
	uchar	flag;
283
	uchar	feat;
284
	uchar	smart;
285
	Afis	fis;
286
	Alist	*list;
287
	Actab	*ctab;
288
} Aportm;
289
 
290
typedef struct {
291
	Aport	*p;
292
	Aportm	*pm;
293
} Aportc;