AHCI: Replace MMIO accesses with helper functions
[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         int64_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         lba = cmd[2] << 24 | cmd[3] << 16 | cmd[4] << 8 | cmd[5];
1982         count = cmd[7] << 8 | cmd[8];
1983         if (r->data == NULL)
1984                 return SDok;
1985         if (r->dlen < count * unit->secsize)
1986                 count = r->dlen / unit->secsize;
1987         max = 128;
1988
1989         try = 0;
1990 retry:
1991         data = r->data;
1992         while (count > 0) {
1993                 n = count;
1994                 if (n > max)
1995                         n = max;
1996                 ahcibuild(d, cmd, data, n, lba);
1997                 switch (waitready(d)) {
1998                 case -1:
1999                         qunlock(&d->portm.ql);
2000                         return SDeio;
2001                 case 1:
2002                         qunlock(&d->portm.ql);
2003                         esleep(1);
2004                         goto retry;
2005                 }
2006                 /* d->portm qlock held here */
2007                 spin_lock_irqsave(&d->Lock);
2008                 d->portm.flag = 0;
2009                 spin_unlock_irqsave(&d->Lock);
2010                 ahci_port_write32(port, PORT_CI, 1);
2011
2012                 as.p = port;
2013                 as.i = 1;
2014                 d->intick = ms();
2015                 d->active++;
2016
2017                 while (waserror())
2018                         ;
2019                 /* don't sleep here forever */
2020                 rendez_sleep_timeout(&d->portm.Rendez, ahciclear, &as,
2021                                      (3 * 1000) * 1000);
2022                 poperror();
2023                 if (!ahciclear(&as)) {
2024                         qunlock(&d->portm.ql);
2025                         printd("%s: ahciclear not true after 3 seconds\n", name);
2026                         r->status = SDcheck;
2027                         return SDcheck;
2028                 }
2029
2030                 d->active--;
2031                 spin_lock_irqsave(&d->Lock);
2032                 flag = d->portm.flag;
2033                 task = ahci_port_read32(port, PORT_TFD);
2034                 spin_unlock_irqsave(&d->Lock);
2035
2036                 if ((task & (Efatal << 8)) ||
2037                     ((task & (ASbsy | ASdrq)) && d->state == Dready)) {
2038                         ahci_port_write32(port, PORT_CI, 0);
2039                         ahcirecover(&d->portc);
2040                         task = ahci_port_read32(port, PORT_TFD);
2041                 }
2042                 qunlock(&d->portm.ql);
2043                 if (flag == 0) {
2044                         if (++try == 10) {
2045                                 printd("%s: bad disk\n", name);
2046                                 r->status = SDeio;
2047                                 return SDeio;
2048                         }
2049                         printd("%s: retry blk %lld\n", name, lba);
2050                         goto retry;
2051                 }
2052                 if (flag & Ferror) {
2053                         printk("%s: i/o error task=%#x @%lld\n", name, task, lba);
2054                         r->status = SDeio;
2055                         return SDeio;
2056                 }
2057
2058                 count -= n;
2059                 lba += n;
2060                 data += n * unit->secsize;
2061         }
2062         r->rlen = data - (unsigned char *)r->data;
2063         r->status = SDok;
2064         return SDok;
2065 }
2066
2067 /*
2068  * configure drives 0-5 as ahci sata (c.f. errata).
2069  * what about 6 & 7, as claimed by marvell 0x9123?
2070  */
2071 static int iaahcimode(struct pci_device *p)
2072 {
2073         printd("iaahcimode: %#x %#x %#x\n", pcidev_read8(p, 0x91),
2074                pcidev_read8(p, 92), pcidev_read8(p, 93));
2075         pcidev_write16(p, 0x92, pcidev_read16(p, 0x92) | 0x3f); /* ports 0-5 */
2076         return 0;
2077 }
2078
2079 static void iasetupahci(struct ctlr *c)
2080 {
2081         void *p = c->mmio; /* This is actually a pointer to HBA */
2082         /* disable cmd block decoding. */
2083         pcidev_write16(c->pci, 0x40, pcidev_read16(c->pci, 0x40) & ~(1 << 15));
2084         pcidev_write16(c->pci, 0x42, pcidev_read16(c->pci, 0x42) & ~(1 << 15));
2085
2086         ahci_hba_write32(p, HBA_GHC, 1 << 31); /* enable ahci mode (ghc register) */
2087         ahci_hba_write32(p, HBA_PI,
2088                          (1 << 6) - 1); /* 5 ports. (supposedly ro pi reg.) */
2089
2090         /* enable ahci mode and 6 ports; from ich9 datasheet */
2091         pcidev_write16(c->pci, 0x90, 1 << 6 | 1 << 5);
2092 }
2093
2094 static int didtype(struct pci_device *p)
2095 {
2096         printd("ahci: %s: ven_id=0x%04x, dev_id=0x%04x\n", __func__, p->ven_id,
2097                p->dev_id);
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                         return Tich;
2116                 break;
2117         case Vatiamd:
2118                 if (p->dev_id == 0x4380 || p->dev_id == 0x4390 || p->dev_id == 0x4391) {
2119                         printd("detected sb600 vid %#x did %#x\n", p->ven_id, p->dev_id);
2120                         return Tsb600;
2121                 }
2122                 break;
2123         case Vmarvell:
2124                 if (p->dev_id == 0x9123)
2125                         printk("ahci: marvell sata 3 controller has delusions of something on unit 7\n");
2126                 break;
2127         }
2128         if (p->class == Pcibcstore && p->subclass == Pciscsata && p->progif == 1) {
2129                 printd("ahci: Tunk: vid %#4.4x did %#4.4x\n", p->ven_id, p->dev_id);
2130                 return Tunk;
2131         }
2132         return -1;
2133 }
2134
2135 static int newctlr(struct ctlr *ctlr, struct sdev *sdev, int nunit)
2136 {
2137         int i, n;
2138         struct drive *drive;
2139         uint32_t h_cap, pi;
2140
2141         ctlr->ndrive = sdev->nunit = nunit;
2142         h_cap = ahci_hba_read32(ctlr->hba, HBA_CAP);
2143         printd("ahci: %s: HBA_CAP=0x%08x\n", __func__, h_cap);
2144         ctlr->mport = h_cap & ((1 << 5) - 1);
2145
2146         i = (h_cap >> 20) & ((1 << 4) - 1); /* iss */
2147         printk("#S/sd%c: %s: %#p %s, %d ports, irq %d\n", sdev->idno, Tname(ctlr),
2148                ctlr->physio, descmode[i], nunit, ctlr->pci->irqline);
2149         /* map the drives -- they don't all need to be enabled. */
2150         n = 0;
2151         ctlr->rawdrive = kzmalloc(NCtlrdrv * sizeof(struct drive), 0);
2152         if (ctlr->rawdrive == NULL) {
2153                 printd("ahci: out of memory\n");
2154                 return -1;
2155         }
2156         pi = ahci_hba_read32(ctlr->hba, HBA_PI);
2157         for (i = 0; i < NCtlrdrv; i++) {
2158                 drive = ctlr->rawdrive + i;
2159                 spinlock_init(&drive->Lock);
2160                 drive->portno = i;
2161                 drive->driveno = -1;
2162                 drive->sectors = 0;
2163                 drive->serial[0] = ' ';
2164                 drive->ctlr = ctlr;
2165                 if ((pi & (1 << i)) == 0)
2166                         continue;
2167                 drive->port = ctlr->mmio + 0x80 * i + 0x100;
2168                 drive->portc.p = drive->port;
2169                 drive->portc.pm = &drive->portm;
2170                 qlock_init(&drive->portm.ql);
2171                 rendez_init(&drive->portm.Rendez);
2172                 drive->driveno = n++;
2173                 ctlr->drive[drive->driveno] = drive;
2174                 iadrive[niadrive + drive->driveno] = drive;
2175         }
2176         for (i = 0; i < n; i++)
2177                 if (ahciidle(ctlr->drive[i]->port) == -1) {
2178                         printd("ahci: %s: port %d wedged; abort\n", Tname(ctlr), i);
2179                         return -1;
2180                 }
2181         for (i = 0; i < n; i++) {
2182                 ctlr->drive[i]->mode = DMsatai;
2183                 configdrive(ctlr->drive[i]);
2184         }
2185         return n;
2186 }
2187
2188 static void releasedrive(struct kref *kref)
2189 {
2190         printk("release drive called, but we don't do that yet\n");
2191 }
2192
2193 static struct sdev *iapnp(void)
2194 {
2195         int n, nunit, type;
2196         struct ctlr *c;
2197         struct pci_device *p;
2198         struct sdev *head, *tail, *s;
2199
2200         // TODO: ensure we're only called once.
2201
2202         memset(olds, 0xff, sizeof olds);
2203         p = NULL;
2204         head = tail = NULL;
2205         STAILQ_FOREACH(p, &pci_devices, all_dev) {
2206                 type = didtype(p);
2207                 printd("didtype: %d\n", type);
2208                 if (type == -1)
2209                         continue;
2210                 if (p->bar[Abar].mmio_base32 == 0)
2211                         continue;
2212                 if (niactlr == NCtlr) {
2213                         printk("ahci: iapnp: %s: too many controllers\n", tname[type]);
2214                         break;
2215                 }
2216                 c = iactlr + niactlr;
2217                 s = sdevs + niactlr;
2218                 memset(c, 0, sizeof *c);
2219                 memset(s, 0, sizeof *s);
2220                 kref_init(&s->r, releasedrive, 1);
2221                 qlock_init(&s->ql);
2222                 qlock_init(&s->unitlock);
2223                 c->physio = p->bar[Abar].mmio_base32 & ~0xf;
2224                 c->mmio = (void *)vmap_pmem_nocache(c->physio, p->bar[Abar].mmio_sz);
2225                 if (c->mmio == 0) {
2226                         printk("ahci: %s: address %#lX in use did=%#x\n", Tname(c),
2227                                c->physio, p->dev_id);
2228                         continue;
2229                 }
2230                 printk("sdiahci %s: Mapped %p/%d to %p\n", tname[type], c->physio,
2231                        p->bar[Abar].mmio_sz, c->mmio);
2232                 c->pci = p;
2233                 c->type = type;
2234
2235                 s->ifc = &sdiahciifc;
2236                 s->idno = 'E' + niactlr;
2237                 s->ctlr = c;
2238                 c->sdev = s;
2239
2240                 if (Intel(c) && p->dev_id != 0x2681)
2241                         iasetupahci(c);
2242                 nunit = ahciconf(c);
2243                 // ahcihbareset((void *)c->mmio);
2244                 if (Intel(c) && iaahcimode(p) == -1)
2245                         break;
2246                 if (nunit < 1) {
2247                         vunmap_vmem((uintptr_t)c->mmio, p->bar[Abar].mmio_sz);
2248                         continue;
2249                 }
2250                 n = newctlr(c, s, nunit);
2251                 if (n < 0)
2252                         continue;
2253                 niadrive += n;
2254                 niactlr++;
2255                 if (head)
2256                         tail->next = s;
2257                 else
2258                         head = s;
2259                 tail = s;
2260         }
2261         return head;
2262 }
2263
2264 static char *smarttab[] = {"unset", "error", "threshold exceeded", "normal"};
2265
2266 static char *pflag(char *s, char *e, unsigned char f)
2267 {
2268         unsigned char i;
2269
2270         for (i = 0; i < 8; i++)
2271                 if (f & (1 << i))
2272                         s = seprintf(s, e, "%s ", flagname[i]);
2273         return seprintf(s, e, "\n");
2274 }
2275
2276 static int iarctl(struct sdunit *u, char *p, int l)
2277 {
2278         char buf[32];
2279         char *e, *op;
2280         void *port;
2281         struct ctlr *c;
2282         struct drive *d;
2283         uint32_t serror, task, cmd, ci, is, sig, sstatus;
2284
2285         c = u->dev->ctlr;
2286         if (c == NULL) {
2287                 printk("iarctl: nil u->dev->ctlr\n");
2288                 return 0;
2289         }
2290         d = c->drive[u->subno];
2291         port = d->port;
2292
2293         e = p + l;
2294         op = p;
2295         if (d->state == Dready) {
2296                 p = seprintf(p, e, "model\t%s\n", d->model);
2297                 p = seprintf(p, e, "serial\t%s\n", d->serial);
2298                 p = seprintf(p, e, "firm\t%s\n", d->firmware);
2299                 if (d->smartrs == 0xff)
2300                         p = seprintf(p, e, "smart\tenable error\n");
2301                 else if (d->smartrs == 0)
2302                         p = seprintf(p, e, "smart\tdisabled\n");
2303                 else
2304                         p = seprintf(p, e, "smart\t%s\n", smarttab[d->portm.smart]);
2305                 p = seprintf(p, e, "flag\t");
2306                 p = pflag(p, e, d->portm.feat);
2307         } else
2308                 p = seprintf(p, e, "no disk present [%s]\n", diskstates[d->state]);
2309         serror = ahci_port_read32(port, PORT_SERR);
2310         task = ahci_port_read32(port, PORT_TFD);
2311         cmd = ahci_port_read32(port, PORT_CMD);
2312         ci = ahci_port_read32(port, PORT_CI);
2313         is = ahci_port_read32(port, PORT_IS);
2314         sig = ahci_port_read32(port, PORT_SIG);
2315         sstatus = ahci_port_read32(port, PORT_SSTS);
2316         serrstr(serror, buf, buf + sizeof(buf) - 1);
2317         p = seprintf(p, e,
2318                      "reg\ttask %#lx cmd %#lx serr %#lx %s ci %#lx is %#lx; sig %#lx sstatus %06#lx\n",
2319                      task, cmd, serror, buf, ci, is, sig, sstatus);
2320         if (d->unit == NULL)
2321                 panic("iarctl: nil d->unit");
2322         p = seprintf(p, e, "geometry %llu %lu\n", d->sectors, d->unit->secsize);
2323         return p - op;
2324 }
2325
2326 static void runflushcache(struct drive *d)
2327 {
2328         int32_t t0;
2329
2330         t0 = ms();
2331         if (flushcache(d) != 0)
2332                 error(EIO, "Flush cache failed");
2333         printd("ahci: flush in %ld ms\n", ms() - t0);
2334 }
2335
2336 static void forcemode(struct drive *d, char *mode)
2337 {
2338         int i;
2339
2340         for (i = 0; i < ARRAY_SIZE(modename); i++)
2341                 if (strcmp(mode, modename[i]) == 0)
2342                         break;
2343         if (i == ARRAY_SIZE(modename))
2344                 i = 0;
2345         spin_lock_irqsave(&d->Lock);
2346         d->mode = i;
2347         spin_unlock_irqsave(&d->Lock);
2348 }
2349
2350 static void runsmartable(struct drive *d, int i)
2351 {
2352         ERRSTACK(2);
2353         if (waserror()) {
2354                 qunlock(&d->portm.ql);
2355                 d->smartrs = 0;
2356                 nexterror();
2357         }
2358         if (lockready(d) == -1)
2359                 error(EIO, "runsmartable: lockready returned -1");
2360         d->smartrs = smart(&d->portc, i);
2361         d->portm.smart = 0;
2362         qunlock(&d->portm.ql);
2363         poperror();
2364 }
2365
2366 static void forcestate(struct drive *d, char *state)
2367 {
2368         int i;
2369
2370         for (i = 0; i < ARRAY_SIZE(diskstates); i++)
2371                 if (strcmp(state, diskstates[i]) == 0)
2372                         break;
2373         if (i == ARRAY_SIZE(diskstates))
2374                 error(EINVAL, "Can't set state to invalid value '%s'", state);
2375         setstate(d, i);
2376 }
2377
2378 /*
2379  * force this driver to notice a change of medium if the hardware doesn't
2380  * report it.
2381  */
2382 static void changemedia(struct sdunit *u)
2383 {
2384         struct ctlr *c;
2385         struct drive *d;
2386
2387         c = u->dev->ctlr;
2388         d = c->drive[u->subno];
2389         spin_lock_irqsave(&d->Lock);
2390         d->mediachange = 1;
2391         u->sectors = 0;
2392         spin_unlock_irqsave(&d->Lock);
2393 }
2394
2395 static int iawctl(struct sdunit *u, struct cmdbuf *cmd)
2396 {
2397         ERRSTACK(2);
2398         char **f;
2399         struct ctlr *c;
2400         struct drive *d;
2401         unsigned int i;
2402
2403         c = u->dev->ctlr;
2404         d = c->drive[u->subno];
2405         f = cmd->f;
2406
2407         if (strcmp(f[0], "change") == 0)
2408                 changemedia(u);
2409         else if (strcmp(f[0], "flushcache") == 0)
2410                 runflushcache(d);
2411         else if (strcmp(f[0], "identify") == 0) {
2412                 i = strtoul(f[1] ? f[1] : "0", 0, 0);
2413                 if (i > 0xff)
2414                         i = 0;
2415                 printd("ahci: %04d %#x\n", i, d->info[i]);
2416         } else if (strcmp(f[0], "mode") == 0)
2417                 forcemode(d, f[1] ? f[1] : "satai");
2418         else if (strcmp(f[0], "nop") == 0) {
2419                 if ((d->portm.feat & Dnop) == 0) {
2420                         sdierror(cmd, "no drive support");
2421                         return -1;
2422                 }
2423                 if (waserror()) {
2424                         qunlock(&d->portm.ql);
2425                         nexterror();
2426                 }
2427                 if (lockready(d) == -1)
2428                         error(EIO, "%s: lockready returned -1", __func__);
2429                 nop(&d->portc);
2430                 qunlock(&d->portm.ql);
2431                 poperror();
2432         } else if (strcmp(f[0], "reset") == 0)
2433                 forcestate(d, "reset");
2434         else if (strcmp(f[0], "smart") == 0) {
2435                 if (d->smartrs == 0)
2436                         sdierror(cmd, "smart not enabled");
2437                 if (waserror()) {
2438                         qunlock(&d->portm.ql);
2439                         d->smartrs = 0;
2440                         nexterror();
2441                 }
2442                 if (lockready(d) == -1)
2443                         error(EIO, "%s: lockready returned -1", __func__);
2444                 d->portm.smart = 2 + smartrs(&d->portc);
2445                 qunlock(&d->portm.ql);
2446                 poperror();
2447         } else if (strcmp(f[0], "smartdisable") == 0)
2448                 runsmartable(d, 1);
2449         else if (strcmp(f[0], "smartenable") == 0)
2450                 runsmartable(d, 0);
2451         else if (strcmp(f[0], "state") == 0)
2452                 forcestate(d, f[1] ? f[1] : "null");
2453         else {
2454                 sdierror(cmd, "%s: unknown control '%s'", __func__, f[0]);
2455                 return -1;
2456         }
2457         return 0;
2458 }
2459
2460 static char *portr(char *p, char *e, unsigned int x)
2461 {
2462         int i, a;
2463
2464         p[0] = 0;
2465         a = -1;
2466         for (i = 0; i < 32; i++) {
2467                 if ((x & (1 << i)) == 0) {
2468                         if (a != -1 && i - 1 != a)
2469                                 p = seprintf(p, e, "-%d", i - 1);
2470                         a = -1;
2471                         continue;
2472                 }
2473                 if (a == -1) {
2474                         if (i > 0)
2475                                 p = seprintf(p, e, ", ");
2476                         p = seprintf(p, e, "%d", a = i);
2477                 }
2478         }
2479         if (a != -1 && i - 1 != a)
2480                 p = seprintf(p, e, "-%d", i - 1);
2481         return p;
2482 }
2483
2484 /* must emit exactly one line per controller (sd(3)) */
2485 static char *iartopctl(struct sdev *sdev, char *p, char *e)
2486 {
2487         uint32_t cap, ghc, isr, pi, ver;
2488         char pr[25];
2489         void *hba;
2490         struct ctlr *ctlr;
2491
2492 #define has(x, str)                                                            \
2493         do {                                                                       \
2494                 if (cap & (x))                                                         \
2495                         p = seprintf(p, e, "%s ", (str));                                  \
2496         } while (0)
2497
2498         ctlr = sdev->ctlr;
2499         hba = ctlr->hba;
2500         p = seprintf(p, e, "sd%c ahci port %#p: ", sdev->idno, ctlr->physio);
2501         cap = ahci_hba_read32(hba, HBA_CAP);
2502         has(Hs64a, "64a");
2503         has(Hsalp, "alp");
2504         has(Hsam, "am");
2505         has(Hsclo, "clo");
2506         has(Hcccs, "coal");
2507         has(Hems, "ems");
2508         has(Hsal, "led");
2509         has(Hsmps, "mps");
2510         has(Hsncq, "ncq");
2511         has(Hssntf, "ntf");
2512         has(Hspm, "pm");
2513         has(Hpsc, "pslum");
2514         has(Hssc, "slum");
2515         has(Hsss, "ss");
2516         has(Hsxs, "sxs");
2517         pi = ahci_hba_read32(hba, HBA_PI);
2518         portr(pr, pr + sizeof(pr), pi);
2519
2520         ghc = ahci_hba_read32(hba, HBA_GHC);
2521         isr = ahci_hba_read32(hba, HBA_ISR);
2522         ver = ahci_hba_read32(hba, HBA_VS);
2523         return seprintf(
2524             p, e, "iss %ld ncs %ld np %ld; ghc %#lx isr %#lx pi %#lx %s ver %#lx\n",
2525             (cap >> 20) & 0xf, (cap >> 8) & 0x1f, 1 + (cap & 0x1f), ghc, isr, pi,
2526             ver);
2527 #undef has
2528 }
2529
2530 static int iawtopctl(struct sdev *sdev, struct cmdbuf *cmd)
2531 {
2532         int *v;
2533         char **f;
2534
2535         f = cmd->f;
2536         v = 0;
2537
2538         if (f[0] == NULL)
2539                 return 0;
2540         if (strcmp(f[0], "debug") == 0)
2541                 v = &debug;
2542         else if (strcmp(f[0], "iprintd") == 0)
2543                 v = &prid;
2544         else if (strcmp(f[0], "aprint") == 0)
2545                 v = &datapi;
2546         else
2547                 sdierror(cmd, "%s: bad control '%s'", __func__, f[0]);
2548
2549         switch (cmd->nf) {
2550         default:
2551                 sdierror(cmd, "%s: %d args, only 1 or 2 allowed", __func__, cmd->nf);
2552         case 1:
2553                 *v ^= 1;
2554                 break;
2555         case 2:
2556                 if (f[1])
2557                         *v = strcmp(f[1], "on") == 0;
2558                 else
2559                         *v ^= 1;
2560                 break;
2561         }
2562         return 0;
2563 }
2564
2565 struct sdifc sdiahciifc = {
2566     "iahci",
2567
2568     iapnp,
2569     NULL, /* legacy */
2570     iaenable,
2571     iadisable,
2572
2573     iaverify,
2574     iaonline,
2575     iario,
2576     iarctl,
2577     iawctl,
2578
2579     scsibio,
2580     NULL, /* probe */
2581     NULL, /* clear */
2582     iartopctl,
2583     iawtopctl,
2584 };