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