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