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