Export CONFIG_ options via #version/kconfig
[akaros.git] / kern / drivers / dev / sdiahci.c
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  * ahci serial ata driver
12  * copyright © 2007-8 coraid, inc.
13  */
14
15 #include <vfs.h>
16
17 #include <assert.h>
18 #include <cpio.h>
19 #include <error.h>
20 #include <ip.h>
21 #include <kfs.h>
22 #include <kmalloc.h>
23 #include <kref.h>
24 #include <pmap.h>
25 #include <sd.h>
26 #include <slab.h>
27 #include <smp.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <ahci.h>
32
33 enum {
34         Vatiamd = 0x1002,
35         Vintel = 0x8086,
36         Vmarvell = 0x1b4b,
37 };
38
39 #define iprintd(...)                                                           \
40         do {                                                                       \
41                 if (prid)                                                              \
42                         printd(__VA_ARGS__);                                               \
43         } while (0)
44 #define aprintd(...)                                                           \
45         do {                                                                       \
46                 if (datapi)                                                            \
47                         printd(__VA_ARGS__);                                               \
48         } while (0)
49 #define Tname(c) tname[(c)->type]
50 #define Intel(x) ((x)->pci->ven_id == Vintel)
51
52 enum {
53         NCtlr = 16,
54         NCtlrdrv = 32,
55         NDrive = NCtlr * NCtlrdrv,
56
57         Read = 0,
58         Write,
59
60         Nms = 256, /* ms. between drive checks */
61         Mphywait = 2 * 1024 / Nms - 1,
62         Midwait = 16 * 1024 / Nms - 1,
63         Mcomrwait = 64 * 1024 / Nms - 1,
64
65         Obs = 0xa0, /* obsolete device bits */
66
67         /*
68      * if we get more than this many interrupts per tick for a drive,
69      * either the hardware is broken or we've got a bug in this driver.
70      */
71         Maxintrspertick = 2000, /* was 1000 */
72 };
73
74 /* pci space configuration */
75 enum {
76         Pmap = 0x90,
77         Ppcs = 0x91,
78         Prev = 0xa8,
79 };
80
81 enum {
82         Tesb,
83         Tich,
84         Tsb600,
85         Tunk,
86 };
87
88 static char *tname[] = {
89     "63xxesb", "ich", "sb600", "unknown",
90 };
91
92 enum {
93         Dnull,
94         Dmissing,
95         Dnew,
96         Dready,
97         Derror,
98         Dreset,
99         Doffline,
100         Dportreset,
101         Dlast,
102 };
103
104 static char *diskstates[Dlast] = {
105     "null", "missing", "new", "ready", "error", "reset", "offline", "portreset",
106 };
107
108 enum {
109         DMautoneg,
110         DMsatai,
111         DMsataii,
112         DMsata3,
113 };
114
115 static char *modename[] = {
116     /* used in control messages */
117     "auto", "satai", "sataii", "sata3",
118 };
119 static char *descmode[] = {
120     /*  only printed */
121     "auto", "sata 1", "sata 2", "sata 3",
122 };
123
124 static char *flagname[] = {
125     "llba", "smart", "power", "nop", "atapi", "atapi16",
126 };
127
128 struct drive {
129         spinlock_t Lock;
130
131         struct ctlr *ctlr;
132         struct sdunit *unit;
133         char name[10];
134         void *port;
135         struct aportm portm;
136         struct aportc portc; /* redundant ptr to port and portm */
137
138         unsigned char mediachange;
139         unsigned char state;
140         unsigned char smartrs;
141
142         uint64_t sectors;
143         uint32_t secsize;
144         uint32_t intick; /* start tick of current transfer */
145         uint32_t lastseen;
146         int wait;
147         unsigned char mode; /* DMautoneg, satai or sataii */
148         unsigned char active;
149
150         char serial[20 + 1];
151         char firmware[8 + 1];
152         char model[40 + 1];
153
154         int infosz;
155         uint16_t *info;
156         uint16_t tinyinfo[2]; /* used iff malloc fails */
157
158         int driveno; /* ctlr*NCtlrdrv + unit */
159         /* controller port # != driveno when not all ports are enabled */
160         int portno;
161
162         uint32_t lastintr0;
163         uint32_t intrs;
164 };
165
166 struct ctlr {
167         spinlock_t Lock;
168
169         int type;
170         int enabled;
171         struct sdev *sdev;
172         struct pci_device *pci;
173         void *vector;
174
175         /* virtual register addresses */
176         void *mmio;
177         void *hba;
178
179         /* phyical register address */
180         uintptr_t physio;
181
182         struct drive *rawdrive;
183         struct drive *drive[NCtlrdrv];
184         int ndrive;
185         int mport; /* highest drive # (0-origin) on ich9 at least */
186
187         uint32_t lastintr0;
188         uint32_t intrs; /* not attributable to any drive */
189 };
190
191 struct Asleep {
192         void *p;
193         int i;
194 };
195
196 struct sdifc sdiahciifc; // TODO(afergs): make static???
197
198 static struct ctlr iactlr[NCtlr];
199 static struct sdev sdevs[NCtlr];
200 static int niactlr;
201
202 static struct drive *iadrive[NDrive];
203 static int niadrive;
204
205 /* these are fiddled in iawtopctl() */
206 static int debug;
207 static int prid = 1;
208 static int datapi;
209
210 // TODO: does this get initialized correctly?
211 static char stab[] = {
212         [0]     = 'i', 'm',
213         [8]     = 't', 'c', 'p', 'e',
214         [16]    = 'N', 'I', 'W', 'B', 'D', 'C', 'H', 'S', 'T', 'F', 'X'
215 };
216
217 // AHCI register access helper functions
218 // TODO(afergs): Figure out what the datatype for reg/offset should really be!
219
220 static inline uint32_t ahci_hba_read32(void *base, uint32_t reg)
221 {
222         return read_mmreg32((uintptr_t)base + reg);
223 }
224
225 static inline void ahci_hba_write32(void *base, uint32_t reg, uint32_t val)
226 {
227         write_mmreg32((uintptr_t)base + reg, val);
228 }
229
230 static inline uint32_t ahci_port_read32(void *aport, uint32_t reg)
231 {
232         return read_mmreg32((uintptr_t)aport + reg);
233 }
234
235 static inline void ahci_port_write32(void *aport, uint32_t reg, uint32_t val)
236 {
237         write_mmreg32((uintptr_t)aport + reg, val);
238 }
239
240 static inline uint32_t ahci_list_read32(void *alist, uint32_t reg)
241 {
242         return read_mmreg32((uintptr_t)alist + reg);
243 }
244
245 static inline void ahci_list_write32(void *alist, uint32_t reg, uint32_t val)
246 {
247         write_mmreg32((uintptr_t)alist + reg, val);
248 }
249
250 static inline uint32_t ahci_prdt_read32(void *aprdt, uint32_t reg)
251 {
252         return read_mmreg32((uintptr_t)aprdt + reg);
253 }
254
255 static inline void ahci_prdt_write32(void *aprdt, uint32_t reg, uint32_t val)
256 {
257         write_mmreg32((uintptr_t)aprdt + reg, val);
258 }
259
260 static inline uint8_t ahci_cfis_read8(void *acfis, uint8_t offset)
261 {
262         return read_mmreg8((uintptr_t)acfis + offset);
263 }
264
265 static inline void ahci_cfis_write8(void *acfis, uint8_t offset, uint8_t val)
266 {
267         write_mmreg8((uintptr_t)acfis + offset, val);
268 }
269
270 static uint32_t set_bit32(void *base, uint32_t offset, uint32_t mask)
271 {
272         uint32_t value = read_mmreg32((uintptr_t)base + offset);
273
274         value |= mask;
275         write_mmreg32((uintptr_t)base + offset, value);
276         return value;
277 }
278
279 static uint32_t clear_bit32(void *base, uint32_t offset, uint32_t mask)
280 {
281         uint32_t value = read_mmreg32((uintptr_t)base + offset);
282
283         value &= ~mask;
284         write_mmreg32((uintptr_t)base + offset, value);
285         return value;
286 }
287
288 static uint8_t set_bit8(void *base, uint32_t offset, uint8_t mask)
289 {
290         uint8_t value = read_mmreg8((uintptr_t)base + offset);
291
292         value |= mask;
293         write_mmreg8((uintptr_t)base + offset, value);
294         return value;
295 }
296
297 static uint8_t clear_bit8(void *base, uint32_t offset, uint8_t mask)
298 {
299         uint8_t value = read_mmreg8((uintptr_t)base + offset);
300
301         value &= ~mask;
302         write_mmreg8((uintptr_t)base + offset, value);
303         return value;
304 }
305
306 /* ALL time units in this file are in milliseconds. */
307 static uint32_t ms(void)
308 {
309         return (uint32_t)(epoch_nsec() / 1048576);
310 }
311
312 /* TODO: if we like this, make it useable elsewhere. */
313 static void sdierror(struct cmdbuf *cb, char *fmt, ...)
314 {
315         char *c = kzmalloc(512, MEM_WAIT);
316         va_list ap;
317
318         assert(fmt);
319         va_start(ap, fmt);
320         vsnprintf(c, 512, fmt, ap);
321         va_end(ap);
322         cmderror(cb, c);
323         kfree(c);
324 }
325
326 static void serrstr(uint32_t r, char *s, char *e)
327 {
328         int i;
329
330         e -= 3;
331         for (i = 0; i < ARRAY_SIZE(stab) && s < e; i++)
332                 if (r & (1 << i) && stab[i]) {
333                         *s++ = stab[i];
334                         if (SerrBad & (1 << i))
335                                 *s++ = '*';
336                 }
337         *s = 0;
338 }
339
340 static char ntab[] = "0123456789abcdef";
341
342 static void preg(volatile unsigned char *reg, int n)
343 {
344         int i;
345         char buf[25 * 3 + 1], *e;
346
347         e = buf;
348         for (i = 0; i < n; i++) {
349                 *e++ = ntab[reg[i] >> 4];
350                 *e++ = ntab[reg[i] & 0xf];
351                 *e++ = ' ';
352         }
353         *e++ = '\n';
354         *e = 0;
355         printd(buf);
356 }
357
358 static void dreg(char *s, void *p)
359 {
360         printd("ahci: %stask=%#lx; cmd=%#lx; ci=%#lx; is=%#lx\n", s,
361                ahci_port_read32(p, PORT_TFD), ahci_port_read32(p, PORT_CMD),
362                ahci_port_read32(p, PORT_CI), ahci_port_read32(p, PORT_IS));
363 }
364
365 static void esleep(int ms)
366 {
367         ERRSTACK(1);
368
369         if (waserror()) {
370                 poperror();
371                 return;
372         }
373         kthread_usleep(ms * 1000);
374         poperror();
375 }
376
377 static int ahciclear(void *v)
378 {
379         struct Asleep *s;
380
381         s = v;
382         return (ahci_port_read32(s->p, PORT_CI) & s->i) == 0;
383 }
384
385 static void aesleep(struct aportm *pm, struct Asleep *a, int ms)
386 {
387         ERRSTACK(1);
388
389         if (waserror()) {
390                 poperror();
391                 return;
392         }
393         rendez_sleep_timeout(&pm->Rendez, ahciclear, a, ms * 1000);
394         poperror();
395 }
396
397 static int ahciwait(struct aportc *c, int ms)
398 {
399         struct Asleep as;
400         void *port;
401         uint32_t cmd, tfd;
402
403         port = c->p;
404         cmd = ahci_port_read32(port, PORT_CMD);
405         printd("ahci: %s: CMD=0x%08x\n", __func__, cmd);
406
407         // TODO: Set the correct CI bit for the slot, not always slot 0!
408         ahci_port_write32(port, PORT_CI, 1);
409         as.p = port;
410         as.i = 1;
411         aesleep(c->pm, &as, ms);
412         tfd = ahci_port_read32(port, PORT_TFD);
413         if (((tfd & 0x81) == 0) && // Not busy and not error
414             (ahci_port_read32(port, PORT_CI) == 0))
415                 return 0;
416         dreg("ahci: ahciwait: timeout ", c->p);
417         return -1;
418 }
419
420 /* fill in cfis boilerplate */
421 static void *cfissetup(struct aportc *pc)
422 {
423         void *cfis;
424
425         cfis = pc->pm->ctab; // cfis is the first thing in ctab, same location
426         memset((void *)cfis, 0, 0x20);
427         ahci_cfis_write8(cfis, 0, 0x27); // H2D
428         ahci_cfis_write8(cfis, 1, 0x80); // Transfer due to update to CMD register
429         ahci_cfis_write8(cfis, 7, Obs);
430         return cfis;
431 }
432
433 /* initialize pc's list */
434 static void listsetup(struct aportc *pc, int flags)
435 {
436         void *list;
437
438         list = pc->pm->list;
439         ahci_list_write32(list, ALIST_FLAGS, flags | 5);
440         ahci_list_write32(list, ALIST_LEN, 0);
441         ahci_list_write32(list, ALIST_CTAB, paddr_low32(pc->pm->ctab));
442         ahci_list_write32(list, ALIST_CTABHI, paddr_high32(pc->pm->ctab));
443         printd("ahci: %s: CTAB physical address=0x%08x:0x%08x\n", __func__,
444                paddr_high32(pc->pm->ctab), paddr_low32(pc->pm->ctab));
445 }
446
447 static int nop(struct aportc *pc)
448 {
449         void *cfis;
450
451         if ((pc->pm->feat & Dnop) == 0)
452                 return -1;
453         cfis = cfissetup(pc);
454         ahci_cfis_write8(cfis, 2, 0);
455         listsetup(pc, Lwrite);
456         return ahciwait(pc, 3 * 1000);
457 }
458
459 static int setfeatures(struct aportc *pc, unsigned char f)
460 {
461         void *cfis;
462
463         cfis = cfissetup(pc);
464         ahci_cfis_write8(cfis, 2, 0xef);
465         ahci_cfis_write8(cfis, 3, f);
466         listsetup(pc, Lwrite);
467         return ahciwait(pc, 3 * 1000);
468 }
469
470 static int setudmamode(struct aportc *pc, unsigned char f)
471 {
472         void *cfis;
473
474         printd("ahci: %s: PORT_SIG=0x%08x\n", __func__,
475                ahci_port_read32(pc->p, PORT_SIG));
476         /* hack */
477         if ((ahci_port_read32(pc->p, PORT_SIG) >> 16) == 0xeb14)
478                 return 0;
479         cfis = cfissetup(pc);
480         ahci_cfis_write8(cfis, 2, 0xef);
481         ahci_cfis_write8(cfis, 3, 3);         /* set transfer mode */
482         ahci_cfis_write8(cfis, 12, 0x40 | f); /* sector count */
483         listsetup(pc, Lwrite);
484         return ahciwait(pc, 3 * 1000);
485 }
486
487 static void asleep(int ms)
488 {
489         udelay(ms * 1000);
490 }
491
492 static int ahciportreset(struct aportc *c)
493 {
494         uint32_t cmd, i, scr_ctl;
495         void *port;
496
497         port = c->p;
498         clear_bit32(port, PORT_CMD, Afre | Ast);
499         for (i = 0; i < 500; i += 25) {
500                 if ((ahci_port_read32(port, PORT_CMD) & Acr) == 0)
501                         break;
502                 asleep(25);
503         }
504
505         scr_ctl = ahci_port_read32(port, PORT_SCTL);
506         scr_ctl = 1 | (scr_ctl & ~7);
507         ahci_port_write32(port, PORT_SCTL, scr_ctl);
508         printk("Sleeping one second\n");
509         udelay(1000 * 1000);
510         clear_bit32(port, PORT_SCTL, 7); // TODO: Make sure PxCMD.ST == 0 first?
511         return 0;
512 }
513
514 static int smart(struct aportc *pc, int n)
515 {
516         void *cfis;
517
518         if ((pc->pm->feat & Dsmart) == 0)
519                 return -1;
520         cfis = cfissetup(pc);
521         ahci_cfis_write8(cfis, 2, 0xb0);
522         ahci_cfis_write8(cfis, 3, 0xd8 + n); /* able smart */
523         ahci_cfis_write8(cfis, 5, 0x4f);
524         ahci_cfis_write8(cfis, 6, 0xc2);
525         listsetup(pc, Lwrite);
526         // TODO(afergs): Replace 1|32 with constants
527         if (ahciwait(pc, 1000) == -1 ||
528             ahci_port_read32(pc->p, PORT_TFD) & (1 | 32)) {
529                 printd("ahci: smart fail %#lx\n", ahci_port_read32(pc->p, PORT_TFD));
530                 return -1;
531         }
532         if (n)
533                 return 0;
534         return 1;
535 }
536
537 static int smartrs(struct aportc *pc)
538 {
539         void *cfis;
540         volatile unsigned char *rfis;
541         uint32_t tfd;
542
543         cfis = cfissetup(pc);
544         ahci_cfis_write8(cfis, 2, 0xb0);
545         ahci_cfis_write8(cfis, 3, 0xda); /* return smart status */
546         ahci_cfis_write8(cfis, 5, 0x4f);
547         ahci_cfis_write8(cfis, 6, 0xc2);
548         listsetup(pc, Lwrite);
549
550         rfis = pc->pm->fis.r;
551         tfd = ahci_port_read32(pc->p, PORT_TFD);
552         // TODO(afergs): Replace 1|32 with constants
553         if (ahciwait(pc, 1000) == -1 || tfd & (1 | 32)) {
554                 printd("ahci: smart fail %#lx\n", tfd);
555                 preg(rfis, 20);
556                 return -1;
557         }
558         if (rfis[5] == 0x4f && rfis[6] == 0xc2)
559                 return 1;
560         return 0;
561 }
562
563 static int ahciflushcache(struct aportc *pc)
564 {
565         void *cfis;
566
567         cfis = cfissetup(pc);
568         ahci_cfis_write8(cfis, 2, pc->pm->feat & Dllba ? 0xea : 0xe7);
569         listsetup(pc, Lwrite);
570         if (ahciwait(pc, 60000) == -1 ||
571             ahci_port_read32(pc->p, PORT_TFD) & (1 | 32)) {
572                 printd("ahciflushcache: fail %#lx\n",
573                        ahci_port_read32(pc->p, PORT_TFD));
574                 // preg(pc->m->fis.r, 20);
575                 return -1;
576         }
577         return 0;
578 }
579
580 static uint16_t gbit16(void *a)
581 {
582         unsigned char *i;
583
584         i = a;
585         return i[1] << 8 | i[0];
586 }
587
588 static uint32_t gbit32(void *a)
589 {
590         uint32_t j;
591         unsigned char *i;
592
593         i = a;
594         j = i[3] << 24;
595         j |= i[2] << 16;
596         j |= i[1] << 8;
597         j |= i[0];
598         return j;
599 }
600
601 static uint64_t gbit64(void *a)
602 {
603         unsigned char *i;
604
605         i = a;
606         return (uint64_t)gbit32(i + 4) << 32 | gbit32(a);
607 }
608
609 static int ahciidentify0(struct aportc *pc, void *id, int atapi)
610 {
611         void *cfis, *prdt;
612         static unsigned char tab[] = {
613             0xec, 0xa1,
614         };
615
616         cfis = cfissetup(pc);
617         ahci_cfis_write8(cfis, 2, tab[atapi]);
618         printd("ahci: %s: ATAPI=%d, cfis[2]: 0x%02x\n", __func__, atapi,
619                ahci_cfis_read8(cfis, 2));
620         printd("ahci: %s: CFIS physical address=0x%08x:0x%08x\n", __func__,
621                paddr_high32(cfis), paddr_low32(cfis));
622
623         listsetup(pc, 1 << 16);
624
625         memset(id, 0, 0x200); /* Fill 512 bytes with 0's */
626         prdt = pc->pm->ctab + ACTAB_PRDT;
627         ahci_prdt_write32(prdt, APRDT_DBA, paddr_low32(id));
628         ahci_prdt_write32(prdt, APRDT_DBAHI, paddr_high32(id));
629         ahci_prdt_write32(prdt, APRDT_COUNT, 1 << 31 | (0x200 - 2) | 1);
630         printd("ahci: %s: DBA  physical address=0x%08x:0x%08x\n", __func__,
631                paddr_high32(id), paddr_low32(id));
632
633         return ahciwait(pc, 3 * 1000);
634 }
635
636 static int64_t ahciidentify(struct aportc *pc, uint16_t *id)
637 {
638         int i, sig;
639         int64_t s;
640         struct aportm *pm;
641         int cnt;
642
643         pm = pc->pm;
644         pm->feat = 0;
645         pm->smart = 0;
646         i = 0;
647         sig = ahci_port_read32(pc->p, PORT_SIG) >> 16;
648         if (sig == 0xeb14) {
649                 pm->feat |= Datapi;
650                 i = 1;
651         }
652         if (ahciidentify0(pc, id, i) == -1)
653                 return -1;
654
655 #ifdef DEBUG
656         printd("ahci: %s: ahciidentify0 return dump=\n\t", __func__);
657         for (cnt = 0; cnt < 64; cnt++) {
658                 printd("0x%08x  ", id[cnt]);
659                 if (cnt % 4 == 3 && cnt != 63)
660                         printd("\n\t");
661         }
662         printd("\n");
663 #endif
664
665         i = gbit16(id + 83) | gbit16(id + 86);
666         if (i & (1 << 10)) {
667                 pm->feat |= Dllba;
668                 s = gbit64(id + 100);
669         } else
670                 s = gbit32(id + 60);
671
672         if (pm->feat & Datapi) {
673                 i = gbit16(id + 0);
674                 if (i & 1)
675                         pm->feat |= Datapi16;
676         }
677
678         i = gbit16(id + 83);
679         if ((i >> 14) == 1) {
680                 if (i & (1 << 3))
681                         pm->feat |= Dpower;
682                 i = gbit16(id + 82);
683                 if (i & 1)
684                         pm->feat |= Dsmart;
685                 if (i & (1 << 14))
686                         pm->feat |= Dnop;
687         }
688         return s;
689 }
690
691 #if 0
692 static int
693 ahciquiet(struct aport *a)
694 {
695         uint32_t *p, i;
696
697         p = &a->cmd;
698         *p &= ~Ast;
699         for(i = 0; i < 500; i += 50){
700                 if((*p & Acr) == 0)
701                         goto stop;
702                 asleep(50);
703         }
704         return -1;
705 stop:
706         if((a->task & (ASdrq|ASbsy)) == 0){
707                 *p |= Ast;
708                 return 0;
709         }
710
711         *p |= Aclo;
712         for(i = 0; i < 500; i += 50){
713                 if((*p & Aclo) == 0)
714                         goto stop1;
715                 asleep(50);
716         }
717         return -1;
718 stop1:
719         /* extra check */
720         printd("ahci: clo clear %#lx\n", a->task);
721         if(a->task & ASbsy)
722                 return -1;
723         *p |= Ast;
724         return 0;
725 }
726 #endif
727
728 #if 0
729 static int
730 ahcicomreset(struct aportc *pc)
731 {
732         unsigned char *c;
733
734         printd("ahcicomreset\n");
735         dreg("ahci: comreset ", pc->p);
736         if(ahciquiet(pc->p) == -1){
737                 printd("ahciquiet failed\n");
738                 return -1;
739         }
740         dreg("comreset ", pc->p);
741
742         c = cfissetup(pc);
743         ahci_cfis_write8(cfis, 1, 0);
744         ahci_cfis_write8(cfis, 15, 1<<2);       /* srst */
745         listsetup(pc, Lclear | Lreset);
746         if(ahciwait(pc, 500) == -1){
747                 printd("ahcicomreset: first command failed\n");
748                 return -1;
749         }
750         microdelay(250);
751         dreg("comreset ", pc->p);
752
753         c = cfissetup(pc);
754         ahci_cfis_write8(cfis, 1, 0);
755         listsetup(pc, Lwrite);
756         if (ahciwait(pc, 150) == -1) {
757                 printd("ahcicomreset: second command failed\n");
758                 return -1;
759         }
760         dreg("comreset ", pc->p);
761         return 0;
762 }
763 #endif
764
765 static int ahciidle(void *port)
766 {
767         uint32_t i, r, cmd;
768
769         cmd = ahci_port_read32(port, PORT_CMD);
770         if ((cmd & Arun) == 0)
771                 return 0;
772         cmd &= ~Ast;
773         ahci_port_write32(port, PORT_CMD, cmd);
774
775         r = 0;
776         for (i = 0; i < 500; i += 25) {
777                 if ((ahci_port_read32(port, PORT_CMD) & Acr) == 0)
778                         goto stop;
779                 asleep(25);
780         }
781         r = -1;
782 stop:
783         if ((ahci_port_read32(port, PORT_CMD) & Afre) == 0)
784                 return r;
785
786         clear_bit32(port, PORT_CMD, Afre);
787         for (i = 0; i < 500; i += 25) {
788                 if ((ahci_port_read32(port, PORT_CMD) & Afre) == 0)
789                         return 0;
790                 asleep(25);
791         }
792         return -1;
793 }
794
795 /*
796  * § 6.2.2.1  first part; comreset handled by reset disk.
797  *      - remainder is handled by configdisk.
798  *      - ahcirecover is a quick recovery from a failed command.
799  */
800 static int ahciswreset(struct aportc *pc)
801 {
802         int i;
803
804         i = ahciidle(pc->p);
805
806         set_bit32(pc->p, PORT_CMD, Afre);
807         if (i == -1)
808                 return -1;
809         if (ahci_port_read32(pc->p, PORT_TFD) & (ASdrq | ASbsy))
810                 return -1;
811         return 0;
812 }
813
814 static int ahcirecover(struct aportc *pc)
815 {
816         ahciswreset(pc);
817
818         set_bit32(pc->p, PORT_CMD, Ast);
819         if (setudmamode(pc, 5) == -1)
820                 return -1;
821         return 0;
822 }
823
824 static void *malign(int size, int align)
825 {
826         return kmalloc_align(size, MEM_WAIT, align);
827 }
828
829 static void setupfis(struct afis *f)
830 {
831         f->base = malign(0x100, 0x100); /* magic */
832         f->d = f->base + 0;
833         f->p = f->base + 0x20;
834         f->r = f->base + 0x40;
835         f->u = f->base + 0x60;
836         f->devicebits = (uint32_t *)(f->base + 0x58);
837 }
838
839 static void ahciwakeup(void *port)
840 {
841         uint16_t s;
842         uint32_t sctl;
843
844         s = ahci_port_read32(port, PORT_SSTS);
845         if ((s & Intpm) != Intslumber && (s & Intpm) != Intpartpwr)
846                 return;
847         if ((s & Devdet) != Devpresent) { /* not (device, no phy) */
848                 iprint("ahci: slumbering drive unwakable %#x\n", s);
849                 return;
850         }
851         ahci_port_write32(port, PORT_SCTL, 3 * Aipm | 0 * Aspd | Adet);
852         udelay(1000 * 1000);
853         clear_bit32(port, PORT_SCTL, 7);
854         //      iprint("ahci: wake %#x -> %#x\n", s, p->sstatus);
855 }
856
857 static int ahciconfigdrive(struct drive *d)
858 {
859         char *name;
860         void *hba, *port;
861         struct aportm *pm;
862         uint32_t cap, sstatus;
863
864         hba = d->ctlr->hba;
865         port = d->portc.p;
866         pm = d->portc.pm;
867         if (pm->list == 0) {
868                 setupfis(&pm->fis);
869                 pm->list = malign(ALIST_SIZE, 1024);
870                 pm->ctab = malign(ACTAB_PRDT + APRDT_SIZE, 128);
871         }
872
873         if (d->unit)
874                 name = d->unit->sdperm.name;
875         else
876                 name = NULL;
877         sstatus = ahci_port_read32(port, PORT_SSTS);
878         cap = ahci_hba_read32(hba, HBA_CAP);
879         if (sstatus & (Devphycomm | Devpresent) && cap & Hsss) {
880                 /* device connected & staggered spin-up */
881                 printd("ahci: configdrive: %s: spinning up ... [%#lx]\n", name,
882                        sstatus);
883                 set_bit32(port, PORT_CMD, Apod | Asud);
884                 asleep(1400);
885         }
886
887         ahci_port_write32(port, PORT_SERR, SerrAll);
888
889         ahci_port_write32(port, PORT_CLB, paddr_low32(pm->list));
890         ahci_port_write32(port, PORT_CLBU, paddr_high32(pm->list));
891         printd("ahci: %s: PORT_CLB physical address=0x%08x:0x%08x\n", __func__,
892                paddr_high32(pm->list), paddr_low32(pm->list));
893         ahci_port_write32(port, PORT_FB, paddr_low32(pm->fis.base));
894         ahci_port_write32(port, PORT_FBU, paddr_high32(pm->fis.base));
895         printd("ahci: %s: PORT_FB  physical address=0x%08x:0x%08x\n", __func__,
896                paddr_high32(pm->fis.base), paddr_low32(pm->fis.base));
897
898         set_bit32(port, PORT_CMD, Afre | Ast);
899
900         /* drive coming up in slumbering? */
901         sstatus = ahci_port_read32(port, PORT_SSTS);
902         if ((sstatus & Devdet) == Devpresent &&
903             ((sstatus & Intpm) == Intslumber || (sstatus & Intpm) == Intpartpwr))
904                 ahciwakeup(port);
905
906         /* "disable power management" sequence from book. */
907         ahci_port_write32(port, PORT_SCTL,
908                           (3 * Aipm) | (d->mode * Aspd) | (0 * Adet));
909         clear_bit32(port, PORT_CMD, Aalpe);
910         ahci_port_write32(port, PORT_IE, IEM);
911
912         return 0;
913 }
914
915 static void ahcienable(void *hba)
916 {
917         set_bit32(hba, HBA_GHC, Hie);
918 }
919
920 static void ahcidisable(void *hba)
921 {
922         clear_bit32(hba, HBA_GHC, Hie);
923 }
924
925 static int countbits(uint32_t u)
926 {
927         int n;
928
929         n = 0;
930         for (; u != 0; u >>= 1)
931                 if (u & 1)
932                         n++;
933         return n;
934 }
935
936 static int ahciconf(struct ctlr *ctlr)
937 {
938         void *hba;
939         uint32_t cap;
940
941         hba = ctlr->hba = ctlr->mmio;
942         cap = ahci_hba_read32(hba, HBA_CAP);
943
944         if ((cap & Hsam) == 0)
945                 set_bit32(hba, HBA_GHC, Hae);
946
947         printd("#S/sd%c: type %s port %#p: sss %ld ncs %ld coal %ld "
948                "%ld ports, led %ld clo %ld ems %ld\n",
949                ctlr->sdev->idno, tname[ctlr->type], hba, (cap >> 27) & 1,
950                (cap >> 8) & 0x1f, (cap >> 7) & 1, (cap & 0x1f) + 1, (cap >> 25) & 1,
951                (cap >> 24) & 1, (cap >> 6) & 1);
952         return countbits(ahci_hba_read32(hba, HBA_PI));
953 }
954
955 #if 0
956 static int
957 ahcihbareset(void *hba)
958 {
959         int wait;
960
961         h->ghc |= 1;
962         for(wait = 0; wait < 1000; wait += 100){
963                 if(h->ghc == 0)
964                         return 0;
965                 delay(100);
966         }
967         return -1;
968 }
969 #endif
970
971 static void idmove(char *p, uint16_t *a, int n)
972 {
973         int i;
974         char *op, *e;
975
976         op = p;
977         for (i = 0; i < n / 2; i++) {
978                 *p++ = a[i] >> 8;
979                 *p++ = a[i];
980         }
981         *p = 0;
982         while (p > op && *--p == ' ')
983                 *p = 0;
984         e = p;
985         for (p = op; *p == ' '; p++)
986                 ;
987         memmove(op, p, n - (e - p));
988 }
989
990 static int identify(struct drive *d)
991 {
992         uint16_t *id;
993         int64_t osectors, s;
994         unsigned char oserial[21];
995         struct sdunit *u;
996
997         if (d->info == NULL) {
998                 d->infosz = 512 * sizeof(uint16_t);
999                 d->info = kzmalloc(d->infosz, 0);
1000                 printd("ahci: %s: HBA physical address (hack): 0x%08x:0x%08x\n",
1001                        __func__, paddr_high32(d->info), paddr_low32(d->info));
1002         }
1003         if (d->info == NULL) {
1004                 d->info = d->tinyinfo;
1005                 d->infosz = sizeof d->tinyinfo;
1006         }
1007         id = d->info;
1008         s = ahciidentify(&d->portc, id);
1009         if (s == -1) {
1010                 d->state = Derror;
1011                 return -1;
1012         }
1013         osectors = d->sectors;
1014         memmove(oserial, d->serial, sizeof d->serial);
1015
1016         u = d->unit;
1017         d->sectors = s;
1018         d->secsize = u->secsize;
1019         if (d->secsize == 0)
1020                 d->secsize = 512; /* default */
1021         d->smartrs = 0;
1022
1023         idmove(d->serial, id + 10, 20);
1024         idmove(d->firmware, id + 23, 8);
1025         idmove(d->model, id + 27, 40);
1026
1027         memset(u->inquiry, 0, sizeof u->inquiry);
1028         u->inquiry[2] = 2;
1029         u->inquiry[3] = 2;
1030         u->inquiry[4] = sizeof u->inquiry - 4;
1031         memmove(u->inquiry + 8, d->model, 40);
1032
1033         if (osectors != s || memcmp(oserial, d->serial, sizeof oserial) != 0) {
1034                 d->mediachange = 1;
1035                 u->sectors = 0;
1036         }
1037         return 0;
1038 }
1039
1040 static void clearci(void *p)
1041 {
1042         uint32_t cmd;
1043
1044         cmd = ahci_port_read32(p, PORT_CMD);
1045         if (cmd & Ast) {
1046                 clear_bit32(p, PORT_CMD, Ast);
1047                 set_bit32(p, PORT_CMD, Ast);
1048         }
1049 }
1050
1051 static void updatedrive(struct drive *d)
1052 {
1053         uint32_t cause, serr, task, sstatus, ie, s0, pr, ewake;
1054         char *name;
1055         void *port;
1056         static uint32_t last;
1057
1058         pr = 1;
1059         ewake = 0;
1060         port = d->port;
1061         cause = ahci_port_read32(port, PORT_IS);
1062         serr = ahci_port_read32(port, PORT_SERR);
1063         ahci_port_write32(port, PORT_IS, cause);
1064         name = "??";
1065         if (d->unit && d->unit->sdperm.name)
1066                 name = d->unit->sdperm.name;
1067
1068         if (ahci_port_read32(port, PORT_CI) == 0) {
1069                 d->portm.flag |= Fdone;
1070                 rendez_wakeup(&d->portm.Rendez);
1071                 pr = 0;
1072         } else if (cause & Adps)
1073                 pr = 0;
1074         if (cause & Ifatal) {
1075                 ewake = 1;
1076                 printd("ahci: updatedrive: %s: fatal\n", name);
1077         }
1078         task = ahci_port_read32(port, PORT_TFD);
1079         if (cause & Adhrs) {
1080                 if (task & (1 << 5 | 1)) {
1081                         printd("ahci: %s: Adhrs cause %#lx serr %#lx task %#lx\n", name,
1082                                cause, serr, task);
1083                         d->portm.flag |= Ferror;
1084                         ewake = 1;
1085                 }
1086                 pr = 0;
1087         }
1088         sstatus = ahci_port_read32(port, PORT_SSTS);
1089         if (task & 1 && last != cause)
1090                 printd("%s: err ca %#lx serr %#lx task %#lx sstat %#lx\n", name, cause,
1091                        serr, task, sstatus);
1092         if (pr)
1093                 printd("%s: upd %#lx ta %#lx\n", name, cause, task);
1094
1095         if (cause & (Aprcs | Aifs)) {
1096                 s0 = d->state;
1097                 switch (sstatus & Devdet) {
1098                 case 0: /* no device */
1099                         d->state = Dmissing;
1100                         break;
1101                 case Devpresent: /* device but no phy comm. */
1102                         if ((sstatus & Intpm) == Intslumber ||
1103                             (sstatus & Intpm) == Intpartpwr)
1104                                 d->state = Dnew; /* slumbering */
1105                         else
1106                                 d->state = Derror;
1107                         break;
1108                 case Devpresent | Devphycomm:
1109                         /* power mgnt crap for surprise removal */
1110                         set_bit32(port, PORT_IE, Aprcs | Apcs); /* is this required? */
1111                         d->state = Dreset;
1112                         break;
1113                 case Devphyoffline:
1114                         d->state = Doffline;
1115                         break;
1116                 }
1117                 printd("%s: %s → %s [Apcrs] %#lx\n", name, diskstates[s0],
1118                        diskstates[d->state], sstatus);
1119                 /* print pulled message here. */
1120                 if (s0 == Dready && d->state != Dready)
1121                         iprintd("%s: pulled\n", name); /* wtf? */
1122                 if (d->state != Dready)
1123                         d->portm.flag |= Ferror;
1124                 ewake = 1;
1125         }
1126         ahci_port_write32(port, PORT_SERR, serr);
1127         if (ewake) {
1128                 clearci(port);
1129                 rendez_wakeup(&d->portm.Rendez);
1130         }
1131         last = cause;
1132 }
1133
1134 static void pstatus(struct drive *d, uint32_t s)
1135 {
1136         /*
1137          * s is masked with Devdet.
1138          *
1139          * bogus code because the first interrupt is currently dropped.
1140          * likely my fault.  serror may be cleared at the wrong time.
1141          */
1142         switch (s) {
1143         case 0: /* no device */
1144                 d->state = Dmissing;
1145                 break;
1146         case Devpresent: /* device but no phy. comm. */
1147                 break;
1148         case Devphycomm: /* should this be missing?  need testcase. */
1149                 printd("ahci: pstatus 2\n");
1150         /* fallthrough */
1151         case Devpresent | Devphycomm:
1152                 d->wait = 0;
1153                 d->state = Dnew;
1154                 break;
1155         case Devphyoffline:
1156                 d->state = Doffline;
1157                 break;
1158         case Devphyoffline | Devphycomm: /* does this make sense? */
1159                 d->state = Dnew;
1160                 break;
1161         }
1162 }
1163
1164 static int configdrive(struct drive *d)
1165 {
1166         if (ahciconfigdrive(d) == -1)
1167                 return -1;
1168         spin_lock_irqsave(&d->Lock);
1169         pstatus(d, ahci_port_read32(d->port, PORT_SSTS) & Devdet);
1170         spin_unlock_irqsave(&d->Lock);
1171         return 0;
1172 }
1173
1174 static void setstate(struct drive *d, int state)
1175 {
1176         spin_lock_irqsave(&d->Lock);
1177         d->state = state;
1178         spin_unlock_irqsave(&d->Lock);
1179 }
1180
1181 static void resetdisk(struct drive *d)
1182 {
1183         unsigned int state, det, cmd, stat;
1184         void *port;
1185
1186         port = d->port;
1187         det = ahci_port_read32(port, PORT_SCTL) & 7;
1188         stat = ahci_port_read32(port, PORT_SSTS) & Devdet;
1189         cmd = ahci_port_read32(port, PORT_CMD);
1190         state = (cmd >> 28) & 0xf;
1191         printd("ahci: resetdisk: icc %#x  det %d sdet %d\n", state, det, stat);
1192
1193         spin_lock_irqsave(&d->Lock);
1194         state = d->state;
1195         if (d->state != Dready || d->state != Dnew)
1196                 d->portm.flag |= Ferror;
1197         clearci(port); /* satisfy sleep condition. */
1198         rendez_wakeup(&d->portm.Rendez);
1199         if (stat != (Devpresent | Devphycomm)) {
1200                 /* device absent or phy not communicating */
1201                 d->state = Dportreset;
1202                 spin_unlock_irqsave(&d->Lock);
1203                 return;
1204         }
1205         d->state = Derror;
1206         spin_unlock_irqsave(&d->Lock);
1207
1208         qlock(&d->portm.ql);
1209         if (cmd & Ast && ahciswreset(&d->portc) == -1)
1210                 setstate(d, Dportreset); /* get a bigger stick. */
1211         else {
1212                 setstate(d, Dmissing);
1213                 configdrive(d);
1214         }
1215         printd("ahci: %s: resetdisk: %s → %s\n",
1216                (d->unit ? d->unit->sdperm.name : NULL), diskstates[state],
1217                diskstates[d->state]);
1218         qunlock(&d->portm.ql);
1219 }
1220
1221 static int newdrive(struct drive *d)
1222 {
1223         char *name;
1224         struct aportc *pc;
1225         struct aportm *pm;
1226
1227         pc = &d->portc;
1228         pm = &d->portm;
1229
1230         name = d->unit->sdperm.name;
1231         if (name == 0)
1232                 name = "??";
1233
1234         if (ahci_port_read32(d->port, PORT_TFD) == 0x80)
1235                 return -1;
1236         qlock(&pc->pm->ql);
1237         if (setudmamode(pc, 5) == -1) {
1238                 printd("%s: can't set udma mode\n", name);
1239                 goto lose;
1240         }
1241         if (identify(d) == -1) {
1242                 printd("%s: identify failure\n", name);
1243                 goto lose;
1244         }
1245         if (pm->feat & Dpower && setfeatures(pc, 0x85) == -1) {
1246                 pm->feat &= ~Dpower;
1247                 if (ahcirecover(pc) == -1)
1248                         goto lose;
1249         }
1250         setstate(d, Dready);
1251         qunlock(&pc->pm->ql);
1252
1253         iprintd("%s: %sLBA %llu sectors: %s %s %s %s\n", d->unit->sdperm.name,
1254                 (pm->feat & Dllba ? "L" : ""), d->sectors, d->model, d->firmware,
1255                 d->serial, d->mediachange ? "[mediachange]" : "");
1256         return 0;
1257
1258 lose:
1259         iprintd("%s: can't be initialized\n", d->unit->sdperm.name);
1260         setstate(d, Dnull);
1261         qunlock(&pc->pm->ql);
1262         return -1;
1263 }
1264
1265 static void westerndigitalhung(struct drive *d)
1266 {
1267         uint32_t task, ci;
1268
1269         task = ahci_port_read32(d->port, PORT_TFD);
1270         ci = ahci_port_read32(d->port, PORT_CI);
1271
1272         if ((d->portm.feat & Datapi) == 0 && d->active &&
1273             (ms() - d->intick) > 5000) {
1274                 printd("%s: drive hung; resetting [%#lx] ci %#lx\n",
1275                        d->unit->sdperm.name, task, ci);
1276                 d->state = Dreset;
1277         }
1278 }
1279
1280 static uint16_t olds[NCtlr * NCtlrdrv];
1281
1282 static int doportreset(struct drive *d)
1283 {
1284         int i;
1285
1286         i = -1;
1287         qlock(&d->portm.ql);
1288         if (ahciportreset(&d->portc) == -1)
1289                 printd("ahci: doportreset: fails\n")
1290         else
1291                 i = 0;
1292         qunlock(&d->portm.ql);
1293         printd("ahci: doportreset: portreset → %s  [task %#lx]\n",
1294                diskstates[d->state], ahci_port_read32(d->port, PORT_TFD));
1295         return i;
1296 }
1297
1298 /* drive must be locked */
1299 static void statechange(struct drive *d)
1300 {
1301         switch (d->state) {
1302         case Dnull:
1303         case Doffline:
1304                 if (d->unit->sectors != 0) {
1305                         d->sectors = 0;
1306                         d->mediachange = 1;
1307                 }
1308         /* fallthrough */
1309         case Dready:
1310                 d->wait = 0;
1311                 break;
1312         }
1313 }
1314
1315 static void checkdrive(struct drive *d, int i)
1316 {
1317         uint16_t s;
1318         uint32_t task;
1319         char *name;
1320
1321         if (d == NULL) {
1322                 printd("checkdrive: NULL d\n");
1323                 return;
1324         }
1325         spin_lock_irqsave(&d->Lock);
1326         if (d->unit == NULL || d->port == NULL) {
1327                 if (0)
1328                         printk("checkdrive: nil d->%s\n",
1329                                d->unit == NULL ? "unit" : "port");
1330                 spin_unlock_irqsave(&d->Lock);
1331                 return;
1332         }
1333         name = d->unit->sdperm.name;
1334         s = ahci_port_read32(d->port, PORT_SSTS);
1335         if (s)
1336                 d->lastseen = ms();
1337         if (s != olds[i]) {
1338                 printd("%s: status: %06#x -> %06#x: %s\n", name, olds[i], s,
1339                        diskstates[d->state]);
1340                 olds[i] = s;
1341                 d->wait = 0;
1342         }
1343         westerndigitalhung(d);
1344
1345         switch (d->state) {
1346         case Dnull:
1347         case Dready:
1348                 break;
1349         case Dmissing:
1350         case Dnew:
1351                 switch (s & (Intactive | Devdet)) {
1352                 case Devpresent: /* no device (pm), device but no phy. comm. */
1353                         ahciwakeup(d->port);
1354                 /* fall through */
1355                 case 0: /* no device */
1356                         break;
1357                 default:
1358                         printd("%s: unknown status %06#x\n", name, s);
1359                 /* fall through */
1360                 case Intactive: /* active, no device */
1361                         if (++d->wait & Mphywait)
1362                                 break;
1363                 reset:
1364                         if (++d->mode > DMsataii)
1365                                 d->mode = 0;
1366                         if (d->mode == DMsatai) { /* we tried everything */
1367                                 d->state = Dportreset;
1368                                 goto portreset;
1369                         }
1370                         printd("%s: reset; new mode %s\n", name, modename[d->mode]);
1371                         spin_unlock_irqsave(&d->Lock);
1372                         resetdisk(d);
1373                         spin_lock_irqsave(&d->Lock);
1374                         break;
1375                 case Intactive | Devphycomm | Devpresent:
1376                         task = ahci_port_read32(d->port, PORT_TFD);
1377                         if ((++d->wait & Midwait) == 0) {
1378                                 printd("%s: slow reset %06#x task=%#lx; %d\n", name, s, task,
1379                                        d->wait);
1380                                 goto reset;
1381                         }
1382                         s = (unsigned char)task;
1383                         if (s == 0x7f ||
1384                             ((ahci_port_read32(d->port, PORT_SIG) >> 16) != 0xeb14 &&
1385                              (s & ~0x17) != (1 << 6)))
1386                                 break;
1387                         spin_unlock_irqsave(&d->Lock);
1388                         newdrive(d);
1389                         spin_lock_irqsave(&d->Lock);
1390                         break;
1391                 }
1392                 break;
1393         case Doffline:
1394                 if (d->wait++ & Mcomrwait)
1395                         break;
1396         /* fallthrough */
1397         case Derror:
1398         case Dreset:
1399                 printd("%s: reset [%s]: mode %d; status %06#x\n", name,
1400                        diskstates[d->state], d->mode, s);
1401                 spin_unlock_irqsave(&d->Lock);
1402                 resetdisk(d);
1403                 spin_lock_irqsave(&d->Lock);
1404                 break;
1405         case Dportreset:
1406         portreset:
1407                 if (d->wait++ & 0xff && (s & Intactive) == 0)
1408                         break;
1409                 /* device is active */
1410                 printd("%s: portreset [%s]: mode %d; status %06#x\n", name,
1411                        diskstates[d->state], d->mode, s);
1412                 d->portm.flag |= Ferror;
1413                 clearci(d->port);
1414                 rendez_wakeup(&d->portm.Rendez);
1415                 if ((s & Devdet) == 0) { /* no device */
1416                         d->state = Dmissing;
1417                         break;
1418                 }
1419                 spin_unlock_irqsave(&d->Lock);
1420                 doportreset(d);
1421                 spin_lock_irqsave(&d->Lock);
1422                 break;
1423         }
1424         statechange(d);
1425         spin_unlock_irqsave(&d->Lock);
1426 }
1427
1428 static void satakproc(void *v)
1429 {
1430         int i;
1431         for (;;) {
1432                 kthread_usleep(Nms * 1000);
1433                 for (i = 0; i < niadrive; i++)
1434                         if (iadrive[i] != NULL)
1435                                 checkdrive(iadrive[i], i);
1436         }
1437 }
1438
1439 static void isctlrjabbering(struct ctlr *c, uint32_t cause)
1440 {
1441         uint32_t now;
1442
1443         now = ms();
1444         if (now > c->lastintr0) {
1445                 c->intrs = 0;
1446                 c->lastintr0 = now;
1447         }
1448         if (++c->intrs > Maxintrspertick) {
1449                 iprint("sdiahci: %lu intrs per tick for no serviced "
1450                        "drive; cause %#lx mport %d\n",
1451                        c->intrs, cause, c->mport);
1452                 c->intrs = 0;
1453         }
1454 }
1455
1456 static void isdrivejabbering(struct drive *d)
1457 {
1458         uint32_t now = ms();
1459
1460         if (now > d->lastintr0) {
1461                 d->intrs = 0;
1462                 d->lastintr0 = now;
1463         }
1464         if (++d->intrs > Maxintrspertick) {
1465                 iprint("sdiahci: %lu interrupts per tick for %s\n", d->intrs,
1466                        d->unit->sdperm.name);
1467                 d->intrs = 0;
1468         }
1469 }
1470
1471 static void iainterrupt(struct hw_trapframe *unused_hw_trapframe, void *a)
1472 {
1473         int i;
1474         uint32_t cause, mask, p_is, h_is, pi;
1475         struct ctlr *c;
1476         struct drive *d;
1477
1478         c = a;
1479         spin_lock_irqsave(&c->Lock);
1480         cause = ahci_hba_read32(c->hba, HBA_ISR);
1481         if (cause == 0) {
1482                 isctlrjabbering(c, cause);
1483                 // iprint("sdiahci: interrupt for no drive\n");
1484                 spin_unlock_irqsave(&c->Lock);
1485                 return;
1486         }
1487         for (i = 0; cause && i <= c->mport; i++) {
1488                 mask = 1 << i;
1489                 if ((cause & mask) == 0)
1490                         continue;
1491                 d = c->rawdrive + i;
1492                 spin_lock_irqsave(&d->Lock);
1493                 isdrivejabbering(d);
1494                 p_is = ahci_port_read32(d->port, PORT_IS);
1495                 pi = ahci_hba_read32(c->hba, HBA_PI);
1496                 if (p_is && pi & mask)
1497                         updatedrive(d);
1498                 ahci_hba_write32(c->hba, HBA_ISR, mask);
1499                 spin_unlock_irqsave(&d->Lock);
1500
1501                 cause &= ~mask;
1502         }
1503         if (cause) {
1504                 isctlrjabbering(c, cause);
1505                 iprint("sdiahci: intr cause unserviced: %#lx\n", cause);
1506         }
1507         spin_unlock_irqsave(&c->Lock);
1508 }
1509
1510 /* checkdrive, called from satakproc, will prod the drive while we wait */
1511 static void awaitspinup(struct drive *d)
1512 {
1513         int ms;
1514         uint16_t s;
1515         char *name;
1516
1517         spin_lock_irqsave(&d->Lock);
1518         if (d->unit == NULL || d->port == NULL) {
1519                 panic("awaitspinup: NULL d->unit or d->port");
1520                 spin_unlock_irqsave(&d->Lock);
1521                 return;
1522         }
1523         name = (d->unit ? d->unit->sdperm.name : NULL);
1524         s = ahci_port_read32(d->port, PORT_SSTS);
1525         if (!(s & Devpresent)) { /* never going to be ready */
1526                 printd("awaitspinup: %s absent, not waiting\n", name);
1527                 spin_unlock_irqsave(&d->Lock);
1528                 return;
1529         }
1530
1531         for (ms = 20000; ms > 0; ms -= 50)
1532                 switch (d->state) {
1533                 case Dnull:
1534                         /* absent; done */
1535                         spin_unlock_irqsave(&d->Lock);
1536                         printd("awaitspinup: %s in null state\n", name);
1537                         return;
1538                 case Dready:
1539                 case Dnew:
1540                         if (d->sectors || d->mediachange) {
1541                                 /* ready to use; done */
1542                                 spin_unlock_irqsave(&d->Lock);
1543                                 printd("awaitspinup: %s ready!\n", name);
1544                                 return;
1545                         }
1546                 /* fall through */
1547                 default:
1548                 case Dmissing: /* normal waiting states */
1549                 case Dreset:
1550                 case Doffline: /* transitional states */
1551                 case Derror:
1552                 case Dportreset:
1553                         spin_unlock_irqsave(&d->Lock);
1554                         asleep(50);
1555                         spin_lock_irqsave(&d->Lock);
1556                         break;
1557                 }
1558         printd("awaitspinup: %s didn't spin up after 20 seconds\n", name);
1559         spin_unlock_irqsave(&d->Lock);
1560 }
1561
1562 static int iaverify(struct sdunit *u)
1563 {
1564         struct ctlr *c;
1565         struct drive *d;
1566
1567         c = u->dev->ctlr;
1568         d = c->drive[u->subno];
1569         spin_lock_irqsave(&c->Lock);
1570         spin_lock_irqsave(&d->Lock);
1571         d->unit = u;
1572         spin_unlock_irqsave(&d->Lock);
1573         spin_unlock_irqsave(&c->Lock);
1574         checkdrive(d, d->driveno); /* c->d0 + d->driveno */
1575
1576         /*
1577          * hang around until disks are spun up and thus available as
1578          * nvram, dos file systems, etc.  you wouldn't expect it, but
1579          * the intel 330 ssd takes a while to `spin up'.
1580          */
1581         awaitspinup(d);
1582         return 1;
1583 }
1584
1585 static int iaenable(struct sdev *s)
1586 {
1587         char name[32];
1588         struct ctlr *c;
1589         static int once;
1590
1591         c = s->ctlr;
1592         spin_lock_irqsave(&c->Lock);
1593         if (!c->enabled) {
1594                 if (once == 0) {
1595                         once = 1;
1596                         ktask("ahci", satakproc, 0);
1597                 }
1598                 if (c->ndrive == 0)
1599                         panic("iaenable: zero s->ctlr->ndrive");
1600                 pci_set_bus_master(c->pci);
1601                 snprintf(name, sizeof(name), "%s (%s)", s->name, s->ifc->name);
1602                 /*c->vector = intrenable(c->pci->intl, iainterrupt, c, c->pci->tbdf,
1603                  *name);*/
1604                 /* what do we do about the arg? */
1605                 register_irq(c->pci->irqline, iainterrupt, c, pci_to_tbdf(c->pci));
1606                 /* supposed to squelch leftover interrupts here. */
1607                 ahcienable(c->hba);
1608                 c->enabled = 1;
1609         }
1610         spin_unlock_irqsave(&c->Lock);
1611         return 1;
1612 }
1613
1614 static int iadisable(struct sdev *s)
1615 {
1616         char name[32];
1617         struct ctlr *c;
1618
1619         c = s->ctlr;
1620         spin_lock_irqsave(&c->Lock);
1621         ahcidisable(c->hba);
1622         snprintf(name, sizeof(name), "%s (%s)", s->name, s->ifc->name);
1623         // TODO: what to do here?
1624         // intrdisable(c->vector);
1625         c->enabled = 0;
1626         spin_unlock_irqsave(&c->Lock);
1627         return 1;
1628 }
1629
1630 static int iaonline(struct sdunit *unit)
1631 {
1632         int r;
1633         struct ctlr *c;
1634         struct drive *d;
1635
1636         c = unit->dev->ctlr;
1637         d = c->drive[unit->subno];
1638         r = 0;
1639
1640         if ((d->portm.feat & Datapi) && d->mediachange) {
1641                 r = scsionline(unit);
1642                 if (r > 0)
1643                         d->mediachange = 0;
1644                 return r;
1645         }
1646
1647         spin_lock_irqsave(&d->Lock);
1648         if (d->mediachange) {
1649                 r = 2;
1650                 d->mediachange = 0;
1651                 /* devsd resets this after online is called; why? */
1652                 unit->sectors = d->sectors;
1653                 unit->secsize = 512; /* default size */
1654         } else if (d->state == Dready)
1655                 r = 1;
1656         spin_unlock_irqsave(&d->Lock);
1657         return r;
1658 }
1659
1660 /* returns locked list! */
1661 static void *ahcibuild(struct drive *d, unsigned char *cmd, void *data, int n,
1662                        int64_t lba)
1663 {
1664         void *cfis, *list, *prdt, *ctab;
1665         unsigned char acmd, dir, llba, c7;
1666         struct aportm *pm;
1667         uint32_t flags;
1668         static unsigned char tab[2][2] = {
1669             {0xc8, 0x25}, {0xca, 0x35},
1670         };
1671
1672         pm = &d->portm;
1673         dir = *cmd != 0x28;
1674         llba = pm->feat & Dllba ? 1 : 0;
1675         acmd = tab[dir][llba];
1676         qlock(&pm->ql);
1677         list = pm->list;
1678         ctab = pm->ctab;
1679         cfis = ctab;
1680
1681         ahci_cfis_write8(cfis, 0, 0x27);
1682         ahci_cfis_write8(cfis, 1, 0x80);
1683         ahci_cfis_write8(cfis, 2, acmd);
1684         ahci_cfis_write8(cfis, 3, 0);
1685
1686         ahci_cfis_write8(cfis, 4, lba);       /* sector                 lba low 7:0 */
1687         ahci_cfis_write8(cfis, 5, lba >> 8);  /* cylinder low   lba mid 15:8 */
1688         ahci_cfis_write8(cfis, 6, lba >> 16); /* cylinder hi    lba hi  23:16 */
1689         c7 = Obs | 0x40;                      /* 0x40 == lba */
1690         if (llba == 0)
1691                 c7 |= (lba >> 24) & 7;
1692         ahci_cfis_write8(cfis, 7, c7);
1693
1694         ahci_cfis_write8(cfis, 8, lba >> 24);  /* sector (exp)                  lba     31:24 */
1695         ahci_cfis_write8(cfis, 9, lba >> 32);  /* cylinder low (exp)    lba     39:32 */
1696         ahci_cfis_write8(cfis, 10, lba >> 48); /* cylinder hi (exp)             lba     48:40 */
1697         ahci_cfis_write8(cfis, 11, 0);         /* features (exp); */
1698
1699         ahci_cfis_write8(cfis, 12, n);      /* sector count */
1700         ahci_cfis_write8(cfis, 13, n >> 8); /* sector count (exp) */
1701         ahci_cfis_write8(cfis, 14, 0);      /* r */
1702         ahci_cfis_write8(cfis, 15, 0);      /* control */
1703
1704         ahci_cfis_write8(cfis, 16, 0);
1705         ahci_cfis_write8(cfis, 17, 0);
1706         ahci_cfis_write8(cfis, 18, 0);
1707         ahci_cfis_write8(cfis, 19, 0);
1708
1709         flags = 1 << 16 | Lpref | 0x5; /* Lpref ?? */
1710         if (dir == Write)
1711                 flags |= Lwrite;
1712         ahci_list_write32(list, ALIST_FLAGS, flags);
1713         ahci_list_write32(list, ALIST_LEN, 0);
1714         ahci_list_write32(list, ALIST_CTAB, paddr_low32(ctab));
1715         ahci_list_write32(list, ALIST_CTABHI, paddr_high32(ctab));
1716
1717         prdt = ctab + ACTAB_PRDT;
1718         ahci_prdt_write32(prdt, APRDT_DBA, paddr_low32(data));
1719         ahci_prdt_write32(prdt, APRDT_DBAHI, paddr_high32(data));
1720         if (d->unit == NULL)
1721                 panic("ahcibuild: NULL d->unit");
1722         ahci_prdt_write32(prdt, APRDT_COUNT,
1723                           1 << 31 | (d->unit->secsize * n - 2) | 1);
1724
1725         return list;
1726 }
1727
1728 static void *ahcibuildpkt(struct aportm *pm, struct sdreq *r, void *data, int n)
1729 {
1730         int fill, len, i;
1731         void *cfis, *list, *ctab, *prdt;
1732         uint32_t flags;
1733
1734         qlock(&pm->ql);
1735         list = pm->list;
1736         ctab = pm->ctab;
1737         cfis = ctab;
1738
1739         fill = pm->feat & Datapi16 ? 16 : 12;
1740         if ((len = r->clen) > fill)
1741                 len = fill;
1742         memmove(ctab + ACTAB_ATAPI, r->cmd, len);
1743         memset(ctab + ACTAB_ATAPI + len, 0, fill - len);
1744
1745         ahci_cfis_write8(cfis, 0, 0x27);
1746         ahci_cfis_write8(cfis, 1, 0x80);
1747         ahci_cfis_write8(cfis, 2, 0xa0);
1748         if (n != 0)
1749                 ahci_cfis_write8(cfis, 3, 1); /* dma */
1750         else
1751                 ahci_cfis_write8(cfis, 3, 0); /* features (exp); */
1752
1753         ahci_cfis_write8(cfis, 4, 0);      /* sector                    lba low 7:0 */
1754         ahci_cfis_write8(cfis, 5, n);      /* cylinder low              lba mid 15:8 */
1755         ahci_cfis_write8(cfis, 6, n >> 8); /* cylinder hi               lba hi  23:16 */
1756         ahci_cfis_write8(cfis, 7, Obs);
1757
1758         for (i = 0; i < 12; i++)
1759                 ahci_cfis_write8(cfis, 8 + i, 0);
1760
1761         flags = 1 << 16 | Lpref | Latapi | 0x5;
1762         if (r->write != 0 && data)
1763                 flags |= Lwrite;
1764         ahci_list_write32(list, ALIST_FLAGS, flags);
1765         ahci_list_write32(list, ALIST_LEN, 0);
1766         ahci_list_write32(list, ALIST_CTAB, paddr_low32(ctab));
1767         ahci_list_write32(list, ALIST_CTABHI, paddr_high32(ctab));
1768         printd("ahci: %s: LIST->CTAB physical address=0x%08x:0x%08x\n", __func__,
1769                paddr_high32(ctab), paddr_low32(ctab));
1770
1771         if (data == 0)
1772                 return list;
1773
1774         prdt = ctab + ACTAB_PRDT;
1775         ahci_prdt_write32(prdt, APRDT_DBA, paddr_low32(data));
1776         ahci_prdt_write32(prdt, APRDT_DBAHI, paddr_high32(data));
1777         ahci_prdt_write32(prdt, APRDT_COUNT, 1 << 31 | (n - 2) | 1);
1778         printd("ahci: %s: PRDT->DBA  physical address=0x%08x:0x%08x\n", __func__,
1779                paddr_high32(data), paddr_low32(data));
1780
1781         return list;
1782 }
1783
1784 static int waitready(struct drive *d)
1785 {
1786         uint32_t s, i, delta;
1787
1788         for (i = 0; i < 15000; i += 250) {
1789                 if (d->state == Dreset || d->state == Dportreset || d->state == Dnew)
1790                         return 1;
1791                 delta = ms() - d->lastseen;
1792                 if (d->state == Dnull || delta > 10 * 1000)
1793                         return -1;
1794                 spin_lock_irqsave(&d->Lock);
1795                 s = ahci_port_read32(d->port, PORT_SSTS);
1796                 spin_unlock_irqsave(&d->Lock);
1797                 if ((s & Intpm) == 0 && delta > 1500)
1798                         return -1; /* no detect */
1799                 if (d->state == Dready && (s & Devdet) == (Devphycomm | Devpresent))
1800                         return 0; /* ready, present & phy. comm. */
1801                 esleep(250);
1802         }
1803         printd("%s: not responding; offline\n", d->unit->sdperm.name);
1804         setstate(d, Doffline);
1805         return -1;
1806 }
1807
1808 static int lockready(struct drive *d)
1809 {
1810         int i;
1811
1812         qlock(&d->portm.ql);
1813         while ((i = waitready(d)) == 1) { /* could wait forever? */
1814                 qunlock(&d->portm.ql);
1815                 esleep(1);
1816                 qlock(&d->portm.ql);
1817         }
1818         return i;
1819 }
1820
1821 static int flushcache(struct drive *d)
1822 {
1823         int i;
1824
1825         i = -1;
1826         if (lockready(d) == 0)
1827                 i = ahciflushcache(&d->portc);
1828         qunlock(&d->portm.ql);
1829         return i;
1830 }
1831
1832 static int iariopkt(struct sdreq *r, struct drive *d)
1833 {
1834         ERRSTACK(2);
1835         int n, count, try, max, flag, task, wormwrite;
1836         char *name;
1837         unsigned char *cmd, *data;
1838         void *port;
1839         struct Asleep as;
1840
1841         cmd = r->cmd;
1842         name = d->unit->sdperm.name;
1843         port = d->port;
1844
1845         aprintd("ahci: iariopkt: %04#x %04#x %c %d %p\n", cmd[0], cmd[2],
1846                 "rw"[r->write], r->dlen, r->data);
1847         if (cmd[0] == 0x5a && (cmd[2] & 0x3f) == 0x3f)
1848                 return sdmodesense(r, cmd, d->info, d->infosz);
1849         r->rlen = 0;
1850         count = r->dlen;
1851         max = 65536;
1852
1853         try = 0;
1854 retry:
1855         data = r->data;
1856         n = count;
1857         if (n > max)
1858                 n = max;
1859         ahcibuildpkt(&d->portm, r, data, n);
1860         switch (waitready(d)) {
1861         case -1:
1862                 qunlock(&d->portm.ql);
1863                 return SDeio;
1864         case 1:
1865                 qunlock(&d->portm.ql);
1866                 esleep(1);
1867                 goto retry;
1868         }
1869         /* d->portm qlock held here */
1870
1871         spin_lock_irqsave(&d->Lock);
1872         d->portm.flag = 0;
1873         spin_unlock_irqsave(&d->Lock);
1874         ahci_port_write32(port, PORT_CI, 1);
1875
1876         as.p = port;
1877         as.i = 1;
1878         d->intick = ms();
1879         d->active++;
1880
1881         while (waserror())
1882                 poperror();
1883         /* don't sleep here forever */
1884         rendez_sleep_timeout(&d->portm.Rendez, ahciclear, &as, (3 * 1000) * 1000);
1885         poperror();
1886         if (!ahciclear(&as)) {
1887                 qunlock(&d->portm.ql);
1888                 printd("%s: ahciclear not true after 3 seconds\n", name);
1889                 r->status = SDcheck;
1890                 return SDcheck;
1891         }
1892
1893         d->active--;
1894         spin_lock_irqsave(&d->Lock);
1895         flag = d->portm.flag;
1896         task = ahci_port_read32(port, PORT_TFD);
1897         spin_unlock_irqsave(&d->Lock);
1898
1899         if ((task & (Efatal << 8)) ||
1900             ((task & (ASbsy | ASdrq)) && (d->state == Dready))) {
1901                 ahci_port_write32(port, PORT_CI, 0);
1902                 ahcirecover(&d->portc);
1903                 task = ahci_port_read32(port, PORT_TFD);
1904                 flag &= ~Fdone; /* either an error or do-over */
1905         }
1906         qunlock(&d->portm.ql);
1907         if (flag == 0) {
1908                 if (++try == 10) {
1909                         printd("%s: bad disk\n", name);
1910                         r->status = SDcheck;
1911                         return SDcheck;
1912                 }
1913                 /*
1914                  * write retries cannot succeed on write-once media,
1915                  * so just accept any failure.
1916                  */
1917                 wormwrite = 0;
1918                 switch (d->unit->inquiry[0] & SDinq0periphtype) {
1919                 case SDperworm:
1920                 case SDpercd:
1921                         switch (cmd[0]) {
1922                         case 0x0a: /* write (6?) */
1923                         case 0x2a: /* write (10) */
1924                         case 0x8a: /* int32_t write (16) */
1925                         case 0x2e: /* write and verify (10) */
1926                                 wormwrite = 1;
1927                                 break;
1928                         }
1929                         break;
1930                 }
1931                 if (!wormwrite) {
1932                         printd("%s: retry\n", name);
1933                         goto retry;
1934                 }
1935         }
1936         if (flag & Ferror) {
1937                 if ((task & Eidnf) == 0)
1938                         printd("%s: i/o error task=%#x\n", name, task);
1939                 r->status = SDcheck;
1940                 return SDcheck;
1941         }
1942
1943         data += n;
1944
1945         r->rlen = data - (unsigned char *)r->data;
1946         r->status = SDok;
1947         return SDok;
1948 }
1949
1950 static int iario(struct sdreq *r)
1951 {
1952         ERRSTACK(1);
1953         int i, n, count, try, max, flag, task;
1954         uint64_t lba;
1955         char *name;
1956         unsigned char *cmd, *data;
1957         void *port;
1958         struct Asleep as;
1959         struct ctlr *c;
1960         struct drive *d;
1961         struct sdunit *unit;
1962
1963         unit = r->unit;
1964         c = unit->dev->ctlr;
1965         d = c->drive[unit->subno];
1966         if (d->portm.feat & Datapi)
1967                 return iariopkt(r, d);
1968         cmd = r->cmd;
1969         name = d->unit->sdperm.name;
1970         port = d->port;
1971
1972         if (r->cmd[0] == 0x35 || r->cmd[0] == 0x91) {
1973                 if (flushcache(d) == 0)
1974                         return sdsetsense(r, SDok, 0, 0, 0);
1975                 return sdsetsense(r, SDcheck, 3, 0xc, 2);
1976         }
1977
1978         if ((i = sdfakescsi(r, d->info, d->infosz)) != SDnostatus) {
1979                 r->status = i;
1980                 return i;
1981         }
1982
1983         if (*cmd != 0x28 && *cmd != 0x2a) {
1984                 printd("%s: bad cmd %.2#x\n", name, cmd[0]);
1985                 r->status = SDcheck;
1986                 return SDcheck;
1987         }
1988
1989         // TODO: make cmd bigger to support drives with >= 2 TiB capacity,
1990         // with 32 bits and 512 B blocks only 2^(9+32) = 2 TiB addressable
1991         lba = (uint32_t)(cmd[2] << 24) | cmd[3] << 16 | cmd[4] << 8 | cmd[5];
1992         count = cmd[7] << 8 | cmd[8];
1993         if (r->data == NULL)
1994                 return SDok;
1995         if (r->dlen < count * unit->secsize)
1996                 count = r->dlen / unit->secsize;
1997         max = 128;
1998
1999         try = 0;
2000 retry:
2001         data = r->data;
2002         while (count > 0) {
2003                 n = count;
2004                 if (n > max)
2005                         n = max;
2006                 ahcibuild(d, cmd, data, n, lba);
2007                 switch (waitready(d)) {
2008                 case -1:
2009                         qunlock(&d->portm.ql);
2010                         return SDeio;
2011                 case 1:
2012                         qunlock(&d->portm.ql);
2013                         esleep(1);
2014                         goto retry;
2015                 }
2016                 /* d->portm qlock held here */
2017                 spin_lock_irqsave(&d->Lock);
2018                 d->portm.flag = 0;
2019                 spin_unlock_irqsave(&d->Lock);
2020                 ahci_port_write32(port, PORT_CI, 1);
2021
2022                 as.p = port;
2023                 as.i = 1;
2024                 d->intick = ms();
2025                 d->active++;
2026
2027                 while (waserror())
2028                         poperror();
2029                 /* don't sleep here forever */
2030                 rendez_sleep_timeout(&d->portm.Rendez, ahciclear, &as,
2031                                      (3 * 1000) * 1000);
2032                 poperror();
2033                 if (!ahciclear(&as)) {
2034                         qunlock(&d->portm.ql);
2035                         printd("%s: ahciclear not true after 3 seconds\n", name);
2036                         r->status = SDcheck;
2037                         return SDcheck;
2038                 }
2039
2040                 d->active--;
2041                 spin_lock_irqsave(&d->Lock);
2042                 flag = d->portm.flag;
2043                 task = ahci_port_read32(port, PORT_TFD);
2044                 spin_unlock_irqsave(&d->Lock);
2045
2046                 if ((task & (Efatal << 8)) ||
2047                     ((task & (ASbsy | ASdrq)) && d->state == Dready)) {
2048                         ahci_port_write32(port, PORT_CI, 0);
2049                         ahcirecover(&d->portc);
2050                         task = ahci_port_read32(port, PORT_TFD);
2051                 }
2052                 qunlock(&d->portm.ql);
2053                 if (flag == 0) {
2054                         if (++try == 10) {
2055                                 printd("%s: bad disk\n", name);
2056                                 r->status = SDeio;
2057                                 return SDeio;
2058                         }
2059                         printd("%s: retry blk %lld\n", name, lba);
2060                         goto retry;
2061                 }
2062                 if (flag & Ferror) {
2063                         printk("%s: i/o error task=%#x @%lld\n", name, task, lba);
2064                         r->status = SDeio;
2065                         return SDeio;
2066                 }
2067
2068                 count -= n;
2069                 lba += n;
2070                 data += n * unit->secsize;
2071         }
2072         r->rlen = data - (unsigned char *)r->data;
2073         r->status = SDok;
2074         return SDok;
2075 }
2076
2077 /*
2078  * configure drives 0-5 as ahci sata (c.f. errata).
2079  * what about 6 & 7, as claimed by marvell 0x9123?
2080  */
2081 static int iaahcimode(struct pci_device *p)
2082 {
2083         printd("iaahcimode: %#x %#x %#x\n", pcidev_read8(p, 0x91),
2084                pcidev_read8(p, 92), pcidev_read8(p, 93));
2085         pcidev_write16(p, 0x92, pcidev_read16(p, 0x92) | 0x3f); /* ports 0-5 */
2086         return 0;
2087 }
2088
2089 static void iasetupahci(struct ctlr *c)
2090 {
2091         void *p = c->mmio; /* This is actually a pointer to HBA */
2092         /* disable cmd block decoding. */
2093         pcidev_write16(c->pci, 0x40, pcidev_read16(c->pci, 0x40) & ~(1 << 15));
2094         pcidev_write16(c->pci, 0x42, pcidev_read16(c->pci, 0x42) & ~(1 << 15));
2095
2096         ahci_hba_write32(p, HBA_GHC, 1 << 31); /* enable ahci mode (ghc register) */
2097         ahci_hba_write32(p, HBA_PI,
2098                          (1 << 6) - 1); /* 5 ports. (supposedly ro pi reg.) */
2099
2100         /* enable ahci mode and 6 ports; from ich9 datasheet */
2101         pcidev_write16(c->pci, 0x90, 1 << 6 | 1 << 5);
2102 }
2103
2104 static int didtype(struct pci_device *p)
2105 {
2106         switch (p->ven_id) {
2107         case Vintel:
2108                 if ((p->dev_id & 0xfffc) == 0x2680)
2109                         return Tesb;
2110                 /*
2111                  * 0x27c4 is the intel 82801 in compatibility (not sata) mode.
2112                  */
2113                 if (p->dev_id == 0x1e02 ||            /* c210 */
2114                     p->dev_id == 0x24d1 ||            /* 82801eb/er */
2115                     (p->dev_id & 0xfffb) == 0x27c1 || /* 82801g[bh]m ich7 */
2116                     p->dev_id == 0x2821 ||            /* 82801h[roh] */
2117                     (p->dev_id & 0xfffe) == 0x2824 || /* 82801h[b] */
2118                     (p->dev_id & 0xfeff) == 0x2829 || /* ich8/9m */
2119                     (p->dev_id & 0xfffe) == 0x2922 || /* ich9 */
2120                     p->dev_id == 0x3a02 ||            /* 82801jd/do */
2121                     (p->dev_id & 0xfefe) == 0x3a22 || /* ich10, pch */
2122                     (p->dev_id & 0xfff8) == 0x3b28 || /* pchm */
2123                     p->dev_id == 0x1d02)              /* c600/x79 pch */
2124                         return Tich;
2125                 break;
2126         case Vatiamd:
2127                 if (p->dev_id == 0x4380 || p->dev_id == 0x4390 || p->dev_id == 0x4391) {
2128                         printd("detected sb600 vid %#x did %#x\n", p->ven_id, p->dev_id);
2129                         return Tsb600;
2130                 }
2131                 break;
2132         case Vmarvell:
2133                 if (p->dev_id == 0x9123)
2134                         printk("ahci: marvell sata 3 controller has delusions of something on unit 7\n");
2135                 break;
2136         }
2137         if (p->class == Pcibcstore && p->subclass == Pciscsata && p->progif == 1) {
2138                 printd("ahci: Tunk: vid %#4.4x did %#4.4x\n", p->ven_id, p->dev_id);
2139                 return Tunk;
2140         }
2141         return -1;
2142 }
2143
2144 static int newctlr(struct ctlr *ctlr, struct sdev *sdev, int nunit)
2145 {
2146         int i, n;
2147         struct drive *drive;
2148         uint32_t h_cap, pi;
2149
2150         ctlr->ndrive = sdev->nunit = nunit;
2151         h_cap = ahci_hba_read32(ctlr->hba, HBA_CAP);
2152         printd("ahci: %s: HBA_CAP=0x%08x\n", __func__, h_cap);
2153         ctlr->mport = h_cap & ((1 << 5) - 1);
2154
2155         i = (h_cap >> 20) & ((1 << 4) - 1); /* iss */
2156         printk("#S/sd%c: %s: %#p %s, %d ports, irq %d\n", sdev->idno, Tname(ctlr),
2157                ctlr->physio, descmode[i], nunit, ctlr->pci->irqline);
2158         /* map the drives -- they don't all need to be enabled. */
2159         n = 0;
2160         ctlr->rawdrive = kzmalloc(NCtlrdrv * sizeof(struct drive), 0);
2161         if (ctlr->rawdrive == NULL) {
2162                 printd("ahci: out of memory\n");
2163                 return -1;
2164         }
2165         pi = ahci_hba_read32(ctlr->hba, HBA_PI);
2166         for (i = 0; i < NCtlrdrv; i++) {
2167                 drive = ctlr->rawdrive + i;
2168                 spinlock_init(&drive->Lock);
2169                 drive->portno = i;
2170                 drive->driveno = -1;
2171                 drive->sectors = 0;
2172                 drive->serial[0] = ' ';
2173                 drive->ctlr = ctlr;
2174                 if ((pi & (1 << i)) == 0)
2175                         continue;
2176                 drive->port = ctlr->mmio + 0x80 * i + 0x100;
2177                 drive->portc.p = drive->port;
2178                 drive->portc.pm = &drive->portm;
2179                 qlock_init(&drive->portm.ql);
2180                 rendez_init(&drive->portm.Rendez);
2181                 drive->driveno = n++;
2182                 ctlr->drive[drive->driveno] = drive;
2183                 iadrive[niadrive + drive->driveno] = drive;
2184         }
2185         for (i = 0; i < n; i++)
2186                 if (ahciidle(ctlr->drive[i]->port) == -1) {
2187                         printd("ahci: %s: port %d wedged; abort\n", Tname(ctlr), i);
2188                         return -1;
2189                 }
2190         for (i = 0; i < n; i++) {
2191                 ctlr->drive[i]->mode = DMsatai;
2192                 configdrive(ctlr->drive[i]);
2193         }
2194         return n;
2195 }
2196
2197 static void releasedrive(struct kref *kref)
2198 {
2199         printk("release drive called, but we don't do that yet\n");
2200 }
2201
2202 static struct sdev *iapnp(void)
2203 {
2204         int n, nunit, type;
2205         struct ctlr *c;
2206         struct pci_device *p;
2207         struct sdev *head, *tail, *s;
2208
2209         // TODO: ensure we're only called once.
2210
2211         memset(olds, 0xff, sizeof olds);
2212         p = NULL;
2213         head = tail = NULL;
2214         STAILQ_FOREACH(p, &pci_devices, all_dev) {
2215                 type = didtype(p);
2216                 if (type == -1)
2217                         continue;
2218                 printd("ahci: %s: ven_id=0x%04x, dev_id=0x%04x, didtype=%d\n",
2219                        __func__, p->ven_id, p->dev_id, type);
2220                 if (p->bar[Abar].mmio_base32 == 0)
2221                         continue;
2222                 if (niactlr == NCtlr) {
2223                         printk("ahci: iapnp: %s: too many controllers\n", tname[type]);
2224                         break;
2225                 }
2226                 c = iactlr + niactlr;
2227                 s = sdevs + niactlr;
2228                 memset(c, 0, sizeof *c);
2229                 memset(s, 0, sizeof *s);
2230                 kref_init(&s->r, releasedrive, 1);
2231                 qlock_init(&s->ql);
2232                 qlock_init(&s->unitlock);
2233                 c->physio = p->bar[Abar].mmio_base32 & ~0xf;
2234                 c->mmio = (void *)vmap_pmem_nocache(c->physio, p->bar[Abar].mmio_sz);
2235                 if (c->mmio == 0) {
2236                         printk("ahci: %s: address %#lX in use did=%#x\n", Tname(c),
2237                                c->physio, p->dev_id);
2238                         continue;
2239                 }
2240                 printk("sdiahci %s: Mapped %p/%d to %p\n", tname[type], c->physio,
2241                        p->bar[Abar].mmio_sz, c->mmio);
2242                 c->pci = p;
2243                 c->type = type;
2244
2245                 s->ifc = &sdiahciifc;
2246                 s->idno = 'E' + niactlr;
2247                 s->ctlr = c;
2248                 c->sdev = s;
2249
2250                 if (Intel(c) && p->dev_id != 0x2681)
2251                         iasetupahci(c);
2252                 nunit = ahciconf(c);
2253                 // ahcihbareset((void *)c->mmio);
2254                 if (Intel(c) && iaahcimode(p) == -1)
2255                         break;
2256                 if (nunit < 1) {
2257                         vunmap_vmem((uintptr_t)c->mmio, p->bar[Abar].mmio_sz);
2258                         continue;
2259                 }
2260                 n = newctlr(c, s, nunit);
2261                 if (n < 0)
2262                         continue;
2263                 niadrive += n;
2264                 niactlr++;
2265                 if (head)
2266                         tail->next = s;
2267                 else
2268                         head = s;
2269                 tail = s;
2270         }
2271         return head;
2272 }
2273
2274 static char *smarttab[] = {"unset", "error", "threshold exceeded", "normal"};
2275
2276 static char *pflag(char *s, char *e, unsigned char f)
2277 {
2278         unsigned char i;
2279
2280         for (i = 0; i < 8; i++)
2281                 if (f & (1 << i))
2282                         s = seprintf(s, e, "%s ", flagname[i]);
2283         return seprintf(s, e, "\n");
2284 }
2285
2286 static int iarctl(struct sdunit *u, char *p, int l)
2287 {
2288         char buf[32];
2289         char *e, *op;
2290         void *port;
2291         struct ctlr *c;
2292         struct drive *d;
2293         uint32_t serror, task, cmd, ci, is, sig, sstatus;
2294
2295         c = u->dev->ctlr;
2296         if (c == NULL) {
2297                 printk("iarctl: nil u->dev->ctlr\n");
2298                 return 0;
2299         }
2300         d = c->drive[u->subno];
2301         port = d->port;
2302
2303         e = p + l;
2304         op = p;
2305         if (d->state == Dready) {
2306                 p = seprintf(p, e, "model\t%s\n", d->model);
2307                 p = seprintf(p, e, "serial\t%s\n", d->serial);
2308                 p = seprintf(p, e, "firm\t%s\n", d->firmware);
2309                 if (d->smartrs == 0xff)
2310                         p = seprintf(p, e, "smart\tenable error\n");
2311                 else if (d->smartrs == 0)
2312                         p = seprintf(p, e, "smart\tdisabled\n");
2313                 else
2314                         p = seprintf(p, e, "smart\t%s\n", smarttab[d->portm.smart]);
2315                 p = seprintf(p, e, "flag\t");
2316                 p = pflag(p, e, d->portm.feat);
2317         } else
2318                 p = seprintf(p, e, "no disk present [%s]\n", diskstates[d->state]);
2319         serror = ahci_port_read32(port, PORT_SERR);
2320         task = ahci_port_read32(port, PORT_TFD);
2321         cmd = ahci_port_read32(port, PORT_CMD);
2322         ci = ahci_port_read32(port, PORT_CI);
2323         is = ahci_port_read32(port, PORT_IS);
2324         sig = ahci_port_read32(port, PORT_SIG);
2325         sstatus = ahci_port_read32(port, PORT_SSTS);
2326         serrstr(serror, buf, buf + sizeof(buf) - 1);
2327         p = seprintf(p, e,
2328                      "reg\ttask %#lx cmd %#lx serr %#lx %s ci %#lx is %#lx; sig %#lx sstatus %06#lx\n",
2329                      task, cmd, serror, buf, ci, is, sig, sstatus);
2330         if (d->unit == NULL)
2331                 panic("iarctl: nil d->unit");
2332         p = seprintf(p, e, "geometry %llu %lu\n", d->sectors, d->unit->secsize);
2333         return p - op;
2334 }
2335
2336 static void runflushcache(struct drive *d)
2337 {
2338         int32_t t0;
2339
2340         t0 = ms();
2341         if (flushcache(d) != 0)
2342                 error(EIO, "Flush cache failed");
2343         printd("ahci: flush in %ld ms\n", ms() - t0);
2344 }
2345
2346 static void forcemode(struct drive *d, char *mode)
2347 {
2348         int i;
2349
2350         for (i = 0; i < ARRAY_SIZE(modename); i++)
2351                 if (strcmp(mode, modename[i]) == 0)
2352                         break;
2353         if (i == ARRAY_SIZE(modename))
2354                 i = 0;
2355         spin_lock_irqsave(&d->Lock);
2356         d->mode = i;
2357         spin_unlock_irqsave(&d->Lock);
2358 }
2359
2360 static void runsmartable(struct drive *d, int i)
2361 {
2362         ERRSTACK(1);
2363
2364         if (waserror()) {
2365                 qunlock(&d->portm.ql);
2366                 d->smartrs = 0;
2367                 nexterror();
2368         }
2369         if (lockready(d) == -1)
2370                 error(EIO, "runsmartable: lockready returned -1");
2371         d->smartrs = smart(&d->portc, i);
2372         d->portm.smart = 0;
2373         qunlock(&d->portm.ql);
2374         poperror();
2375 }
2376
2377 static void forcestate(struct drive *d, char *state)
2378 {
2379         int i;
2380
2381         for (i = 0; i < ARRAY_SIZE(diskstates); i++)
2382                 if (strcmp(state, diskstates[i]) == 0)
2383                         break;
2384         if (i == ARRAY_SIZE(diskstates))
2385                 error(EINVAL, "Can't set state to invalid value '%s'", state);
2386         setstate(d, i);
2387 }
2388
2389 /*
2390  * force this driver to notice a change of medium if the hardware doesn't
2391  * report it.
2392  */
2393 static void changemedia(struct sdunit *u)
2394 {
2395         struct ctlr *c;
2396         struct drive *d;
2397
2398         c = u->dev->ctlr;
2399         d = c->drive[u->subno];
2400         spin_lock_irqsave(&d->Lock);
2401         d->mediachange = 1;
2402         u->sectors = 0;
2403         spin_unlock_irqsave(&d->Lock);
2404 }
2405
2406 static int iawctl(struct sdunit *u, struct cmdbuf *cmd)
2407 {
2408         ERRSTACK(1);
2409         char **f;
2410         struct ctlr *c;
2411         struct drive *d;
2412         unsigned int i;
2413
2414         c = u->dev->ctlr;
2415         d = c->drive[u->subno];
2416         f = cmd->f;
2417
2418         if (strcmp(f[0], "change") == 0)
2419                 changemedia(u);
2420         else if (strcmp(f[0], "flushcache") == 0)
2421                 runflushcache(d);
2422         else if (strcmp(f[0], "identify") == 0) {
2423                 i = strtoul(f[1] ? f[1] : "0", 0, 0);
2424                 if (i > 0xff)
2425                         i = 0;
2426                 printd("ahci: %04d %#x\n", i, d->info[i]);
2427         } else if (strcmp(f[0], "mode") == 0)
2428                 forcemode(d, f[1] ? f[1] : "satai");
2429         else if (strcmp(f[0], "nop") == 0) {
2430                 if ((d->portm.feat & Dnop) == 0) {
2431                         sdierror(cmd, "no drive support");
2432                         return -1;
2433                 }
2434                 if (waserror()) {
2435                         qunlock(&d->portm.ql);
2436                         nexterror();
2437                 }
2438                 if (lockready(d) == -1)
2439                         error(EIO, "%s: lockready returned -1", __func__);
2440                 nop(&d->portc);
2441                 qunlock(&d->portm.ql);
2442                 poperror();
2443         } else if (strcmp(f[0], "reset") == 0)
2444                 forcestate(d, "reset");
2445         else if (strcmp(f[0], "smart") == 0) {
2446                 if (d->smartrs == 0)
2447                         sdierror(cmd, "smart not enabled");
2448                 if (waserror()) {
2449                         qunlock(&d->portm.ql);
2450                         d->smartrs = 0;
2451                         nexterror();
2452                 }
2453                 if (lockready(d) == -1)
2454                         error(EIO, "%s: lockready returned -1", __func__);
2455                 d->portm.smart = 2 + smartrs(&d->portc);
2456                 qunlock(&d->portm.ql);
2457                 poperror();
2458         } else if (strcmp(f[0], "smartdisable") == 0)
2459                 runsmartable(d, 1);
2460         else if (strcmp(f[0], "smartenable") == 0)
2461                 runsmartable(d, 0);
2462         else if (strcmp(f[0], "state") == 0)
2463                 forcestate(d, f[1] ? f[1] : "null");
2464         else {
2465                 sdierror(cmd, "%s: unknown control '%s'", __func__, f[0]);
2466                 return -1;
2467         }
2468         return 0;
2469 }
2470
2471 static char *portr(char *p, char *e, unsigned int x)
2472 {
2473         int i, a;
2474
2475         p[0] = 0;
2476         a = -1;
2477         for (i = 0; i < 32; i++) {
2478                 if ((x & (1 << i)) == 0) {
2479                         if (a != -1 && i - 1 != a)
2480                                 p = seprintf(p, e, "-%d", i - 1);
2481                         a = -1;
2482                         continue;
2483                 }
2484                 if (a == -1) {
2485                         if (i > 0)
2486                                 p = seprintf(p, e, ", ");
2487                         p = seprintf(p, e, "%d", a = i);
2488                 }
2489         }
2490         if (a != -1 && i - 1 != a)
2491                 p = seprintf(p, e, "-%d", i - 1);
2492         return p;
2493 }
2494
2495 /* must emit exactly one line per controller (sd(3)) */
2496 static char *iartopctl(struct sdev *sdev, char *p, char *e)
2497 {
2498         uint32_t cap, ghc, isr, pi, ver;
2499         char pr[25];
2500         void *hba;
2501         struct ctlr *ctlr;
2502
2503 #define has(x, str)                                                            \
2504         do {                                                                       \
2505                 if (cap & (x))                                                         \
2506                         p = seprintf(p, e, "%s ", (str));                                  \
2507         } while (0)
2508
2509         ctlr = sdev->ctlr;
2510         hba = ctlr->hba;
2511         p = seprintf(p, e, "sd%c ahci port %#p: ", sdev->idno, ctlr->physio);
2512         cap = ahci_hba_read32(hba, HBA_CAP);
2513         has(Hs64a, "64a");
2514         has(Hsalp, "alp");
2515         has(Hsam, "am");
2516         has(Hsclo, "clo");
2517         has(Hcccs, "coal");
2518         has(Hems, "ems");
2519         has(Hsal, "led");
2520         has(Hsmps, "mps");
2521         has(Hsncq, "ncq");
2522         has(Hssntf, "ntf");
2523         has(Hspm, "pm");
2524         has(Hpsc, "pslum");
2525         has(Hssc, "slum");
2526         has(Hsss, "ss");
2527         has(Hsxs, "sxs");
2528         pi = ahci_hba_read32(hba, HBA_PI);
2529         portr(pr, pr + sizeof(pr), pi);
2530
2531         ghc = ahci_hba_read32(hba, HBA_GHC);
2532         isr = ahci_hba_read32(hba, HBA_ISR);
2533         ver = ahci_hba_read32(hba, HBA_VS);
2534         return seprintf(
2535             p, e, "iss %ld ncs %ld np %ld; ghc %#lx isr %#lx pi %#lx %s ver %#lx\n",
2536             (cap >> 20) & 0xf, (cap >> 8) & 0x1f, 1 + (cap & 0x1f), ghc, isr, pi,
2537             ver);
2538 #undef has
2539 }
2540
2541 static int iawtopctl(struct sdev *sdev, struct cmdbuf *cmd)
2542 {
2543         int *v;
2544         char **f;
2545
2546         f = cmd->f;
2547         v = 0;
2548
2549         if (f[0] == NULL)
2550                 return 0;
2551         if (strcmp(f[0], "debug") == 0)
2552                 v = &debug;
2553         else if (strcmp(f[0], "iprintd") == 0)
2554                 v = &prid;
2555         else if (strcmp(f[0], "aprint") == 0)
2556                 v = &datapi;
2557         else
2558                 sdierror(cmd, "%s: bad control '%s'", __func__, f[0]);
2559
2560         switch (cmd->nf) {
2561         default:
2562                 sdierror(cmd, "%s: %d args, only 1 or 2 allowed", __func__, cmd->nf);
2563         case 1:
2564                 *v ^= 1;
2565                 break;
2566         case 2:
2567                 if (f[1])
2568                         *v = strcmp(f[1], "on") == 0;
2569                 else
2570                         *v ^= 1;
2571                 break;
2572         }
2573         return 0;
2574 }
2575
2576 struct sdifc sdiahciifc = {
2577     "iahci",
2578
2579     iapnp,
2580     NULL, /* legacy */
2581     iaenable,
2582     iadisable,
2583
2584     iaverify,
2585     iaonline,
2586     iario,
2587     iarctl,
2588     iawctl,
2589
2590     scsibio,
2591     NULL, /* probe */
2592     NULL, /* clear */
2593     iartopctl,
2594     iawtopctl,
2595 };