xref: /plan9-contrib/sys/src/9/pc/sdmv50xx.c (revision 84363d68e61d22383c764147f662f7d876924159)
1 /*
2  * Marvell 88SX[56]0[48][01] fileserver Serial ATA (SATA) driver
3  *
4  * See MV-S101357-00 Rev B Marvell PCI/PCI-X to 8-Port/4-Port
5  * SATA Host Controller, ATA-5 ANSI NCITS 340-2000.
6  *
7  * This is a heavily-modified version (by Coraid) of a heavily-modified
8  * version (from The Labs) of a driver written by Coraid, Inc.
9  * The original copyright notice appears at the end of this file.
10  */
11 
12 #include "u.h"
13 #include "../port/lib.h"
14 #include "mem.h"
15 #include "dat.h"
16 #include "fns.h"
17 #include "io.h"
18 #include "../port/error.h"
19 
20 #include	"../port/sd.h"
21 
22 #define dprint if(!0){}else iprint
23 #define idprint if(!0){}else iprint
24 #define ioprint if(!0){}else iprint
25 
26 enum{
27 	NCtlr		= 4,
28 	NCtlrdrv	= 8,
29 	NDrive		= NCtlr*NCtlrdrv,
30 
31 	Read 		= 0,
32 	Write,
33 };
34 
35 enum {
36 	SrbRing = 32,
37 
38 	/* Addresses of ATA register */
39 	ARcmd		= 027,
40 	ARdev		= 026,
41 	ARerr		= 021,
42 	ARfea		= 021,
43 	ARlba2		= 025,
44 	ARlba1		= 024,
45 	ARlba0		= 023,
46 	ARseccnt	= 022,
47 	ARstat		= 027,
48 
49 	ATAerr		= (1<<0),
50 	ATAdrq		= (1<<3),
51 	ATAdf 		= (1<<5),
52 	ATAdrdy 	= (1<<6),
53 	ATAbusy 	= (1<<7),
54 	ATAabort	= (1<<2),
55 	ATAobs		= (1<<1 | 1<<2 | 1<<4),
56 	ATAeIEN		= (1<<1),
57 	ATAsrst		= (1<<2),
58 	ATAhob		= (1<<7),
59 	ATAbad		= (ATAbusy|ATAdf|ATAdrq|ATAerr),
60 
61 	SFdone 		= (1<<0),
62 	SFerror 	= (1<<1),
63 
64 	SRBident 	= 0,
65 	SRBread,
66 	SRBwrite,
67 	SRBsmart,
68 
69 	SRBnodata = 0,
70 	SRBdatain,
71 	SRBdataout,
72 
73 	RQread		= 1,		/* data coming IN from device */
74 
75 	PRDeot		= (1<<15),
76 
77 	/* EDMA interrupt error cause register */
78 
79 	ePrtDataErr	= (1<<0),
80 	ePrtPRDErr	= (1<<1),
81 	eDevErr		= (1<<2),
82 	eDevDis		= (1<<3),
83 	eDevCon		= (1<<4),
84 	eOverrun	= (1<<5),
85 	eUnderrun	= (1<<6),
86 	eSelfDis	= (1<<8),
87 	ePrtCRQBErr	= (1<<9),
88 	ePrtCRPBErr	= (1<<10),
89 	ePrtIntErr	= (1<<11),
90 	eIORdyErr	= (1<<12),
91 
92 	/* flags for sata 2 version */
93 	eSelfDis2	= (1<<7),
94 	SerrInt		= (1<<5),
95 
96 	/* EDMA Command Register */
97 
98 	eEnEDMA	= (1<<0),
99 	eDsEDMA 	= (1<<1),
100 	eAtaRst 	= (1<<2),
101 
102 	/* Interrupt mask for errors we care about */
103 	IEM		= (eDevDis | eDevCon | eSelfDis),
104 	IEM2		= (eDevDis | eDevCon | eSelfDis2),
105 
106 	/* drive states */
107 	Dnull 		= 0,
108 	Dnew,
109 	Dready,
110 	Derror,
111 	Dmissing,
112 	Dreset,
113 	Dlast,
114 
115 	/* drive flags */
116 	Dext	 	= (1<<0),	/* use ext commands */
117 	Dpio		= (1<<1),	/* doing pio */
118 	Dwanted		= (1<<2),	/* someone wants an srb entry */
119 	Dedma		= (1<<3),	/* device in edma mode */
120 	Dpiowant	= (1<<4),	/* some wants to use the pio mode */
121 
122 	/* phyerrata magic crap */
123 	Mpreamp	= 0x7e0,
124 	Dpreamp	= 0x720,
125 
126 	REV60X1B2	= 0x7,
127 	REV60X1C0	= 0x9,
128 
129 };
130 
131 static char* diskstates[Dlast] = {
132 	"null",
133 	"new",
134 	"ready",
135 	"error",
136 	"missing",
137 	"reset",
138 };
139 
140 extern SDifc sdmv50xxifc;
141 
142 typedef struct Arb Arb;
143 typedef struct Bridge Bridge;
144 typedef struct Chip Chip;
145 typedef struct Ctlr Ctlr;
146 typedef struct Drive Drive;
147 typedef struct Edma Edma;
148 typedef struct Prd Prd;
149 typedef struct Rx Rx;
150 typedef struct Srb Srb;
151 typedef struct Tx Tx;
152 
153 /*
154  * there are 4 drives per chip.  thus an 8-port
155  * card has two chips.
156  */
157 struct Chip
158 {
159 	Arb	*arb;
160 	Edma	*edma;
161 };
162 
163 enum{
164 	DMautoneg,
165 	DMsatai,
166 	DMsataii,
167 };
168 
169 struct Drive
170 {
171 	Lock;
172 
173 	Ctlr	*ctlr;
174 	SDunit	*unit;
175 	char	name[10];
176 	ulong	magic;
177 
178 	Bridge	*bridge;
179 	Edma	*edma;
180 	Chip	*chip;
181 	int	chipx;
182 
183 	int	mediachange;
184 	int	state;
185 	int	flag;
186 	uvlong	sectors;
187 	ulong	pm2;		/* phymode 2 init state */
188 	ulong	intick;		/* check for hung western digital drives. */
189 	int	wait;
190 	int	mode;		/* DMautoneg, satai or sataii. */
191 
192 	char	serial[20+1];
193 	char	firmware[8+1];
194 	char	model[40+1];
195 
196 	ushort	info[256];
197 
198 	Srb	*srb[SrbRing-1];
199 	int	nsrb;
200 	Prd	*prd;
201 	Tx	*tx;
202 	Rx	*rx;
203 
204 	Srb	*srbhead;
205 	Srb	*srbtail;
206 	int	driveno;	/* ctlr*NCtlrdrv + unit */
207 };
208 
209 struct Ctlr
210 {
211 	Lock;
212 
213 	int	irq;
214 	int	tbdf;
215 	int	rid;
216 	ulong	magic;
217 	int	enabled;
218 	int	type;
219 	SDev	*sdev;
220 	Pcidev	*pcidev;
221 
222 	uchar	*mmio;
223 	ulong	*lmmio;
224 	Chip	chip[2];
225 	int	nchip;
226 	Drive	drive[NCtlrdrv];
227 	int	ndrive;
228 };
229 
230 struct Srb			/* request buffer */
231 {
232 	Lock;
233 	Rendez;
234 	Srb	*next;
235 
236 	Drive	*drive;
237 	uvlong	blockno;
238 	int	count;
239 	int	req;
240 	int	flag;
241 	uchar	*data;
242 
243 	uchar	cmd;
244 	uchar	lba[6];
245 	uchar	sectors;
246 	int	sta;
247 	int	err;
248 };
249 
250 /*
251  * Memory-mapped I/O registers in many forms.
252  */
253 struct Bridge			/* memory-mapped per-Drive registers */
254 {
255 	ulong	status;
256 	ulong	serror;
257 	ulong	sctrl;
258 	ulong	phyctrl;
259 	ulong	phymode3;
260 	ulong	phymode4;
261 	uchar	fill0[0x14];
262 	ulong	phymode1;
263 	ulong	phymode2;
264 	char	fill1[8];
265 	ulong	ctrl;
266 	char	fill2[0x34];
267 	ulong	phymode;
268 	char	fill3[0x88];
269 };				/* length must be 0x100 */
270 
271 struct Arb			/* memory-mapped per-Chip registers */
272 {
273 	ulong	config;		/* satahc configuration register (sata2 only) */
274 	ulong	rqop;		/* request queue out-pointer */
275 	ulong	rqip;		/* response queue in pointer */
276 	ulong	ict;		/* inerrupt caolescing threshold */
277 	ulong	itt;		/* interrupt timer threshold */
278 	ulong	ic;		/* interrupt cause */
279 	ulong	btc;		/* bridges test control */
280 	ulong	bts;		/* bridges test status */
281 	ulong	bpc;		/* bridges pin configuration */
282 	char	fill1[0xdc];
283 	Bridge	bridge[4];
284 };
285 
286 struct Edma			/* memory-mapped per-Drive DMA-related registers */
287 {
288 	ulong	config;		/* configuration register */
289 	ulong	timer;
290 	ulong	iec;		/* interrupt error cause */
291 	ulong	iem;		/* interrupt error mask */
292 
293 	ulong	txbasehi;		/* request queue base address high */
294 	ulong	txi;		/* request queue in pointer */
295 	ulong	txo;		/* request queue out pointer */
296 
297 	ulong	rxbasehi;		/* response queue base address high */
298 	ulong	rxi;		/* response queue in pointer */
299 	ulong	rxo;		/* response queue out pointer */
300 
301 	ulong	ctl;		/* command register */
302 	ulong	testctl;		/* test control */
303 	ulong	status;
304 	ulong	iordyto;		/* IORDY timeout */
305 	char	fill[0x18];
306 	ulong	sataconfig;	/* sata 2 */
307 	char	fill[0xac];
308 	ushort	pio;		/* data register */
309 	char	pad0[2];
310 	uchar	err;		/* features and error */
311 	char	pad1[3];
312 	uchar	seccnt;		/* sector count */
313 	char	pad2[3];
314 	uchar	lba0;
315 	char	pad3[3];
316 	uchar	lba1;
317 	char	pad4[3];
318 	uchar	lba2;
319 	char	pad5[3];
320 	uchar	lba3;
321 	char	pad6[3];
322 	uchar	cmdstat;		/* cmd/status */
323 	char	pad7[3];
324 	uchar	altstat;		/* alternate status */
325 	uchar	fill2[0x1df];
326 	Bridge	port;
327 	char	fill3[0x1c00];	/* pad to 0x2000 bytes */
328 };
329 
330 /*
331  * Memory structures shared with card.
332  */
333 struct Prd			/* physical region descriptor */
334 {
335 	ulong	pa;		/* byte address of physical memory */
336 	ushort	count;		/* byte count (bit0 must be 0) */
337 	ushort	flag;
338 	ulong	zero;		/* high long of 64 bit address */
339 	ulong	reserved;
340 };
341 
342 struct Tx				/* command request block */
343 {
344 	ulong	prdpa;		/* physical region descriptor table structures */
345 	ulong	zero;		/* must be zero (high long of prd address) */
346 	ushort	flag;		/* control flags */
347 	ushort	regs[11];
348 };
349 
350 struct Rx				/* command response block */
351 {
352 	ushort	cid;		/* cID of response */
353 	uchar	cEdmaSts;	/* EDMA status */
354 	uchar	cDevSts;		/* status from disk */
355 	ulong	ts;		/* time stamp */
356 };
357 
358 static Drive 	*mvsatadrive[NDrive];
359 static int		nmvsatadrive;
360 
361 /*
362  * Little-endian parsing for drive data.
363  */
364 static ushort
365 lhgets(void *p)
366 {
367 	uchar *a = p;
368 	return ((ushort) a[1] << 8) | a[0];
369 }
370 
371 static ulong
372 lhgetl(void *p)
373 {
374 	uchar *a = p;
375 	return ((ulong) lhgets(a+2) << 16) | lhgets(a);
376 }
377 
378 static uvlong
379 lhgetv(void *p)
380 {
381 	uchar *a = p;
382 	return ((uvlong) lhgetl(a+4) << 32) | lhgetl(a);
383 }
384 
385 static void
386 idmove(char *p, ushort *a, int n)
387 {
388 	char *op;
389 	int i;
390 
391 	op = p;
392 	for(i=0; i<n/2; i++){
393 		*p++ = a[i]>>8;
394 		*p++ = a[i];
395 	}
396 	while(p>op && *--p == ' ')
397 		*p = 0;
398 }
399 
400 /*
401  * Request buffers.
402  */
403 struct
404 {
405 	Lock;
406 	Srb *freechain;
407 	int nalloc;
408 } srblist;
409 
410 static Srb*
411 allocsrb(void)
412 {
413 	Srb *p;
414 
415 	ilock(&srblist);
416 	if((p = srblist.freechain) == nil){
417 		srblist.nalloc++;
418 		iunlock(&srblist);
419 		p = smalloc(sizeof *p);
420 	}else{
421 		srblist.freechain = p->next;
422 		iunlock(&srblist);
423 	}
424 	return p;
425 }
426 
427 static void
428 freesrb(Srb *p)
429 {
430 	ilock(&srblist);
431 	p->next = srblist.freechain;
432 	srblist.freechain = p;
433 	iunlock(&srblist);
434 }
435 
436 /*
437  * Wait for a byte to be a particular value.
438  */
439 static int
440 satawait(uchar *p, uchar mask, uchar v, int ms)
441 {
442 	int i;
443 
444 	for(i=0; i<ms && (*p & mask) != v; i++)
445 		microdelay(1000);
446 	return (*p & mask) == v;
447 }
448 
449 /*
450  * Drive initialization
451  */
452 /* unmask in the pci registers err done */
453 static void
454 unmask(ulong *mmio, int port, int coal)
455 {
456 	port &= 7;
457 	if(coal)
458 		coal = 1;
459 	if (port < 4)
460 		mmio[0x1d64/4] |= (3 << (((port&3)*2)) | (coal<<8));
461 	else
462 		mmio[0x1d64/4] |= (3 << (((port&3)*2+9)) | (coal<<17));
463 }
464 
465 static void
466 mask(ulong *mmio, int port, int coal)
467 {
468 	port &= 7;
469 	if(coal)
470 		coal = 1;
471 	if (port < 4)
472 		mmio[0x1d64/4] &= ~(3 << (((port&3)*2)) | (coal<<8));
473 	else
474 		mmio[0x1d64/4] &= ~(3 << (((port&3)*2+9)) | (coal<<17));
475 }
476 
477 /* I give up, marvell.  You win. */
478 static void
479 phyerrata(Drive *d)
480 {
481 	ulong n, m;
482 	enum { BadAutoCal = 0xf << 26, };
483 
484 	if (d->ctlr->type == 1)
485 		return;
486 	microdelay(200);
487 	n = d->bridge->phymode2;
488 	while ((n & BadAutoCal) == BadAutoCal) {
489 		dprint("%s: badautocal\n", d->unit->name);
490 		n &= ~(1<<16);
491 		n |= (1<<31);
492 		d->bridge->phymode2 = n;
493 		microdelay(200);
494 		d->bridge->phymode2 &= ~((1<<16) | (1<<31));
495 		microdelay(200);
496 		n = d->bridge->phymode2;
497 	}
498 	n &= ~(1<<31);
499 	d->bridge->phymode2 = n;
500 	microdelay(200);
501 
502 	/* abra cadabra!  (random magic) */
503 	m = d->bridge->phymode3;
504 	m &= ~0x7f800000;
505 	m |= 0x2a800000;
506 	d->bridge->phymode3 = m;
507 
508 	/* fix phy mode 4 */
509 	m = d->bridge->phymode3;
510 	n = d->bridge->phymode4;
511 	n &= ~(1<<1);
512 	n |= 1;
513 	switch(d->ctlr->rid){
514 	case REV60X1B2:
515 	default:
516 		d->bridge->phymode4 = n;
517 		d->bridge->phymode3 = m;
518 		break;
519 	case REV60X1C0:
520 		d->bridge->phymode4 = n;
521 		break;
522 	}
523 
524 	/* revert values of pre-emphasis and signal amps to the saved ones */
525 	n = d->bridge->phymode2;
526 	n &= ~Mpreamp;
527 	n |= d->pm2;
528 	n &= ~(1<<16);
529 	d->bridge->phymode2 = n;
530 }
531 
532 static void
533 edmacleanout(Drive *d)
534 {
535 	int i;
536 	Srb *srb;
537 
538 	for(i=0; i<nelem(d->srb); i++){
539 		if(srb = d->srb[i]){
540 			d->srb[i] = nil;
541 			d->nsrb--;
542 			srb->flag |= SFerror|SFdone;
543 			wakeup(srb);
544 		}
545 	}
546 	while(srb = d->srbhead){
547 		d->srbhead = srb->next;
548 		srb->flag |= SFerror|SFdone;
549 		wakeup(srb);
550 	}
551 }
552 
553 static void
554 resetdisk(Drive *d)
555 {
556 	ulong n;
557 
558 	d->sectors = 0;
559 	d->unit->sectors = 0;
560 	if (d->ctlr->type == 2) {
561 		/*
562 		 * without bit 8 we can boot without disks, but
563 		 * inserted disks will never appear.  :-X
564 		 */
565 		n = d->edma->sataconfig;
566 		n &= 0xff;
567 		n |= 0x9b1100;
568 		d->edma->sataconfig = n;
569 		n = d->edma->sataconfig;	/* flush */
570 		USED(n);
571 	}
572 	d->edma->ctl = eDsEDMA;
573 	microdelay(1);
574 	d->edma->ctl = eAtaRst;
575 	microdelay(25);
576 	d->edma->ctl = 0;
577 	if (satawait((uchar *)&d->edma->ctl, eEnEDMA, 0, 3*1000) == 0)
578 		print("%s: eEnEDMA never cleared on reset\n", d->unit->name);
579 	edmacleanout(d);
580 	phyerrata(d);
581 	d->bridge->sctrl = 0x301 | (d->mode << 4);
582 	d->state = Dmissing;
583 }
584 
585 static void
586 edmainit(Drive *d)
587 {
588 	int i;
589 
590 	if(d->tx != nil)
591 		return;
592 
593 	d->tx = xspanalloc(32*sizeof(Tx), 1024, 0);
594 	d->rx = xspanalloc(32*sizeof(Rx), 256, 0);
595 	d->prd = xspanalloc(32*sizeof(Prd), 32, 0);
596 	for(i = 0; i < 32; i++)
597 		d->tx[i].prdpa = PADDR(&d->prd[i]);
598 	coherence();
599 }
600 
601 static int
602 configdrive(Ctlr *ctlr, Drive *d, SDunit *unit)
603 {
604 	dprint("%s: configdrive\n", unit->name);
605 	if(d->driveno < 0)
606 		panic("mv50xx: configdrive: unset driveno\n");
607 	d->unit = unit;
608 	edmainit(d);
609 	d->mode = DMsatai;
610 	if(d->ctlr->type == 1){
611 		d->edma->iem = IEM;
612 		d->bridge = &d->chip->arb->bridge[d->chipx];
613 	}else{
614 		d->edma->iem = IEM2;
615 		d->bridge = &d->chip->edma[d->chipx].port;
616 		d->edma->iem = ~(1<<6);
617 		d->pm2 = Dpreamp;
618 		if(d->ctlr->lmmio[0x180d8/4] & 1)
619 			d->pm2 = d->bridge->phymode2 & Mpreamp;
620 	}
621 	resetdisk(d);
622 	unmask(ctlr->lmmio, d->driveno, 0);
623 	delay(100);
624 	if(d->bridge->status){
625 		dprint("%s: configdrive: found drive %lx\n", unit->name, d->bridge->status);
626 		return 0;
627 	}
628 	return -1;
629 }
630 
631 static int
632 enabledrive(Drive *d)
633 {
634 	Edma *edma;
635 
636 	dprint("%s: enabledrive..", d->unit->name);
637 
638 	if((d->bridge->status & 0xf) != 3){
639 		dprint("%s: not present\n", d->unit->name);
640 		d->state = Dmissing;
641 		return -1;
642 	}
643 	edma = d->edma;
644 	if(satawait(&edma->cmdstat, ATAbusy, 0, 5*1000) == 0){
645 		dprint("%s: busy timeout\n", d->unit->name);
646 		d->state = Dmissing;
647 		return -1;
648 	}
649 	edma->iec = 0;
650 	d->chip->arb->ic &= ~(0x101 << d->chipx);
651 	edma->config = 0x51f;
652 	if (d->ctlr->type == 2)
653 		edma->config |= 7<<11;
654 	edma->txi = PADDR(d->tx);
655 	edma->txo = (ulong)d->tx & 0x3e0;
656 	edma->rxi = (ulong)d->rx & 0xf8;
657 	edma->rxo = PADDR(d->rx);
658 	edma->ctl |= 1;		/* enable dma */
659 
660 	if(d->bridge->status = 0x113){
661 		dprint("%s: new\n", d->unit->name);
662 		d->state = Dnew;
663 	}else
664 		print("%s: status not forced (should be okay)\n", d->unit->name);
665 	return 0;
666 }
667 
668 static void
669 disabledrive(Drive *d)
670 {
671 	int i;
672 	ulong *r;
673 
674 	dprint("%s: disabledrive\n", d->unit->name);
675 
676 	if(d->tx == nil)	/* never enabled */
677 		return;
678 
679 	d->edma->ctl = 0;
680 	d->edma->iem = 0;
681 
682 	r = (ulong*)(d->ctlr->mmio + 0x1d64);
683 	i = d->chipx;
684 	if(d->chipx < 4)
685 		*r &= ~(3 << (i*2));
686 	else
687 		*r |= ~(3 << (i*2+9));
688 }
689 
690 static int
691 setudmamode(Drive *d, uchar mode)
692 {
693 	Edma *edma;
694 
695 	dprint("%s: setudmamode %d\n", d->unit->name, mode);
696 
697 	edma = d->edma;
698 	if (edma == nil) {
699 		iprint("setudamode(m%d): zero d->edma\m", d->driveno);
700 		return 0;
701 	}
702 	if(satawait(&edma->cmdstat, ~ATAobs, ATAdrdy, 9*1000) == 0){
703 		iprint("%s: cmdstat 0x%.2ux ready timeout\n", d->unit->name, edma->cmdstat);
704 		return 0;
705 	}
706 	edma->altstat = ATAeIEN;
707 	edma->err = 3;
708 	edma->seccnt = 0x40 | mode;
709 	edma->cmdstat = 0xef;
710 	microdelay(1);
711 	if(satawait(&edma->cmdstat, ATAbusy, 0, 5*1000) == 0){
712 		iprint("%s: cmdstat 0x%.2ux busy timeout\n", d->unit->name, edma->cmdstat);
713 		return 0;
714 	}
715 	return 1;
716 }
717 
718 static int
719 identifydrive(Drive *d)
720 {
721 	int i;
722 	ushort *id;
723 	Edma *edma;
724 	SDunit *unit;
725 
726 	dprint("%s: identifydrive\n", d->unit->name);
727 
728 	if(setudmamode(d, 5) == 0)	/* do all SATA support 5? */
729 		goto Error;
730 
731 	id = d->info;
732 	memset(d->info, 0, sizeof d->info);
733 	edma = d->edma;
734 	if(satawait(&edma->cmdstat, ~ATAobs, ATAdrdy, 5*1000) == 0)
735 		goto Error;
736 
737 	edma->altstat = ATAeIEN;	/* no interrupts */
738 	edma->cmdstat = 0xec;
739 	microdelay(1);
740 	if(satawait(&edma->cmdstat, ATAbusy, 0, 5*1000) == 0)
741 		goto Error;
742 	for(i = 0; i < 256; i++)
743 		id[i] = edma->pio;
744 	if(edma->cmdstat & ATAbad)
745 		goto Error;
746 	i = lhgets(id+83) | lhgets(id+86);
747 	if(i & (1<<10)){
748 		d->flag |= Dext;
749 		d->sectors = lhgetv(id+100);
750 	}else{
751 		d->flag &= ~Dext;
752 		d->sectors = lhgetl(id+60);
753 	}
754 	idmove(d->serial, id+10, 20);
755 	idmove(d->firmware, id+23, 8);
756 	idmove(d->model, id+27, 40);
757 
758 	unit = d->unit;
759 	memset(unit->inquiry, 0, sizeof unit->inquiry);
760 	unit->inquiry[2] = 2;
761 	unit->inquiry[3] = 2;
762 	unit->inquiry[4] = sizeof(unit->inquiry)-4;
763 	idmove((char*)unit->inquiry+8, id+27, 40);
764 
765 	if(enabledrive(d) == 0) {
766 		d->state = Dready;
767 		d->mediachange = 1;
768 		idprint("%s: LLBA %lld sectors\n", d->unit->name, d->sectors);
769 	} else
770 		d->state = Derror;
771 	if(d->state == Dready)
772 		return 0;
773 	return -1;
774 Error:
775 	dprint("error...");
776 	d->state = Derror;
777 	return -1;
778 }
779 
780 /* p. 163:
781 	M	recovered error
782 	P	protocol error
783 	N	PhyRdy change
784 	W	CommWake
785 	B	8-to-10 encoding error
786 	D	disparity error
787 	C	crc error
788 	H	handshake error
789 	S	link sequence error
790 	T	transport state transition error
791 	F	unrecognized fis type
792 	X	device changed
793 */
794 
795 static char stab[] = {
796 [1]	'M',
797 [10]	'P',
798 [16]	'N',
799 [18]	'W', 'B', 'D', 'C', 'H', 'S', 'T', 'F', 'X'
800 };
801 static ulong sbad = (7<<20)|(3<<23);
802 
803 static void
804 serrdecode(ulong r, char *s, char *e)
805 {
806 	int i;
807 
808 	e -= 3;
809 	for(i = 0; i < nelem(stab) && s < e; i++){
810 		if((r&(1<<i)) && stab[i]){
811 			*s++ = stab[i];
812 			if(sbad&(1<<i))
813 				*s++ = '*';
814 		}
815 	}
816 	*s = 0;
817 }
818 
819 char *iectab[] = {
820 	"ePrtDataErr",
821 	"ePrtPRDErr",
822 	"eDevErr",
823 	"eDevDis",
824 	"eDevCon",
825 	"SerrInt",
826 	"eUnderrun",
827 	"eSelfDis2",
828 	"eSelfDis",
829 	"ePrtCRQBErr",
830 	"ePrtCRPBErr",
831 	"ePrtIntErr",
832 	"eIORdyErr",
833 };
834 
835 static char*
836 iecdecode(ulong cause)
837 {
838 	int i;
839 
840 	for(i = 0; i < nelem(iectab); i++)
841 		if(cause&(1<<i))
842 			return iectab[i];
843 	return "";
844 }
845 
846 enum{
847 	Cerror = ePrtDataErr|ePrtPRDErr|eDevErr|eSelfDis2|ePrtCRPBErr|ePrtIntErr,
848 };
849 
850 static void
851 updatedrive(Drive *d)
852 {
853 	int x;
854 	ulong cause;
855 	Edma *edma;
856 	char buf[32+4+1];
857 
858 	edma = d->edma;
859 	if((edma->ctl&eEnEDMA) == 0){
860 		/* FEr SATA#4 40xx */
861 		x = d->edma->cmdstat;
862 		USED(x);
863 	}
864 	cause = edma->iec;
865 	if(cause == 0)
866 		return;
867 	dprint("%s: cause %08ulx [%s]\n", d->unit->name, cause, iecdecode(cause));
868 	if(cause & eDevCon)
869 		d->state = Dnew;
870 	if(cause&eDevDis && d->state == Dready)
871 		iprint("%s: pulled: st=%08ulx\n", d->unit->name, cause);
872 	switch(d->ctlr->type){
873 	case 1:
874 		if(cause&eSelfDis)
875 			d->state = Derror;
876 		break;
877 	case 2:
878 		if(cause&Cerror)
879 			d->state = Derror;
880 		if(cause&SerrInt){
881 			serrdecode(d->bridge->serror, buf, buf+sizeof buf);
882 			dprint("%s: serror %08ulx [%s]\n", d->unit->name, (ulong)d->bridge->serror, buf);
883 			d->bridge->serror = d->bridge->serror;
884 		}
885 	}
886 	edma->iec = ~cause;
887 }
888 
889 /*
890  * Requests
891  */
892 static Srb*
893 srbrw(int req, Drive *d, uchar *data, uint sectors, uvlong lba)
894 {
895 	int i;
896 	Srb *srb;
897 	static uchar cmd[2][2] = { 0xC8, 0x25, 0xCA, 0x35 };
898 
899 	srb = allocsrb();
900 	srb->req = req;
901 	srb->drive = d;
902 	srb->blockno = lba;
903 	srb->sectors = sectors;
904 	srb->count = sectors*512;
905 	srb->flag = 0;
906 	srb->data = data;
907 
908 	for(i=0; i<6; i++)
909 		srb->lba[i] = lba >> (8*i);
910 	srb->cmd = cmd[srb->req!=SRBread][(d->flag&Dext)!=0];
911 	return srb;
912 }
913 
914 static uintptr
915 advance(uintptr pa, int shift)
916 {
917 	int n, mask;
918 
919 	mask = 0x1F<<shift;
920 	n = (pa & mask) + (1<<shift);
921 	return (pa & ~mask) | (n & mask);
922 }
923 
924 #define CMD(r, v) (((r)<<8) | ((v)&0xFF))
925 static void
926 mvsatarequest(ushort *cmd, Srb *srb, int ext)
927 {
928 	*cmd++ = CMD(ARseccnt, 0);
929 	*cmd++ = CMD(ARseccnt, srb->sectors);
930 	*cmd++ = CMD(ARfea, 0);
931 	if(ext){
932 		*cmd++ = CMD(ARlba0, srb->lba[3]);
933 		*cmd++ = CMD(ARlba0, srb->lba[0]);
934 		*cmd++ = CMD(ARlba1, srb->lba[4]);
935 		*cmd++ = CMD(ARlba1, srb->lba[1]);
936 		*cmd++ = CMD(ARlba2, srb->lba[5]);
937 		*cmd++ = CMD(ARlba2, srb->lba[2]);
938 		*cmd++ = CMD(ARdev, 0xe0);
939 	}else{
940 		*cmd++ = CMD(ARlba0, srb->lba[0]);
941 		*cmd++ = CMD(ARlba1, srb->lba[1]);
942 		*cmd++ = CMD(ARlba2, srb->lba[2]);
943 		*cmd++ = CMD(ARdev, srb->lba[3] | 0xe0);
944 	}
945 	*cmd = CMD(ARcmd, srb->cmd) | (1<<15);
946 }
947 
948 static void
949 startsrb(Drive *d, Srb *srb)
950 {
951 	int i;
952 	Edma *edma;
953 	Prd *prd;
954 	Tx *tx;
955 
956 	if(d->nsrb >= nelem(d->srb)){
957 		srb->next = nil;
958 		if(d->srbhead)
959 			d->srbtail->next = srb;
960 		else
961 			d->srbhead = srb;
962 		d->srbtail = srb;
963 		return;
964 	}
965 
966 	d->nsrb++;
967 	for(i=0; i<nelem(d->srb); i++)
968 		if(d->srb[i] == nil)
969 			break;
970 	if(i == nelem(d->srb))
971 		panic("sdmv50xx: no free srbs");
972 	d->intick = MACHP(0)->ticks;
973 	d->srb[i] = srb;
974 	edma = d->edma;
975 	tx = (Tx*)KADDR(edma->txi);
976 	tx->flag = (i<<1) | (srb->req == SRBread);
977 	prd = KADDR(tx->prdpa);
978 	prd->pa = PADDR(srb->data);
979 	prd->count = srb->count;
980 	prd->flag = PRDeot;
981 	mvsatarequest(tx->regs, srb, d->flag&Dext);
982 	coherence();
983 	edma->txi = advance(edma->txi, 5);
984 	d->intick = MACHP(0)->ticks;
985 }
986 
987 enum{
988 	Rpidx	= 0x1f<<3,
989 };
990 
991 static void
992 completesrb(Drive *d)
993 {
994 	Edma *edma;
995 	Rx *rx;
996 	Srb *srb;
997 
998 	edma = d->edma;
999 	if((edma->ctl & eEnEDMA) == 0)
1000 		return;
1001 
1002 	while((edma->rxo&Rpidx) != (edma->rxi&Rpidx)){
1003 		rx = (Rx*)KADDR(edma->rxo);
1004 		if(srb = d->srb[rx->cid]){
1005 			d->srb[rx->cid] = nil;
1006 			d->nsrb--;
1007 			if(rx->cDevSts & ATAbad)
1008 				srb->flag |= SFerror;
1009 			if (rx->cEdmaSts)
1010 				iprint("cEdmaSts: %02ux\n", rx->cEdmaSts);
1011 			srb->sta = rx->cDevSts;
1012 			srb->flag |= SFdone;
1013 			wakeup(srb);
1014 		}else
1015 			iprint("srb missing\n");
1016 		edma->rxo = advance(edma->rxo, 3);
1017 		if(srb = d->srbhead){
1018 			d->srbhead = srb->next;
1019 			startsrb(d, srb);
1020 		}
1021 	}
1022 }
1023 
1024 static int
1025 srbdone(void *v)
1026 {
1027 	Srb *srb;
1028 
1029 	srb = v;
1030 	return srb->flag & SFdone;
1031 }
1032 
1033 /*
1034  * Interrupts
1035  */
1036 static void
1037 mv50interrupt(Ureg*, void *a)
1038 {
1039 	int i;
1040 	ulong cause;
1041 	Ctlr *ctlr;
1042 	Drive *drive;
1043 
1044 	ctlr = a;
1045 	ilock(ctlr);
1046 	cause = ctlr->lmmio[0x1d60/4];
1047 //	dprint("sd%c: mv50interrupt: 0x%lux\n", ctlr->sdev->idno, cause);
1048 	for(i=0; i<ctlr->ndrive; i++)
1049 		if(cause & (3<<(i*2+i/4))){
1050 			drive = &ctlr->drive[i];
1051 			if(drive->edma == 0)
1052 				continue;	/* not ready yet. */
1053 			ilock(drive);
1054 			updatedrive(drive);
1055 			while(ctlr->chip[i/4].arb->ic & (0x0101 << (i%4))){
1056 				ctlr->chip[i/4].arb->ic = ~(0x101 << (i%4));
1057 				completesrb(drive);
1058 			}
1059 			iunlock(drive);
1060 		}
1061 	iunlock(ctlr);
1062 }
1063 
1064 enum{
1065 	Nms		= 256,
1066 	Midwait		= 16*1024/Nms-1,
1067 	Mphywait	= 512/Nms-1,
1068 };
1069 
1070 static void
1071 westerndigitalhung(Drive *d)
1072 {
1073 	Edma *e;
1074 
1075 	e = d->edma;
1076 	if(d->srb
1077 	&& TK2MS(MACHP(0)->ticks-d->intick) > 5*1000
1078 	&& (e->rxo&Rpidx) == (e->rxi&Rpidx)){
1079 		dprint("westerndigital drive hung; resetting\n");
1080 		d->state = Dreset;
1081 	}
1082 }
1083 
1084 static void
1085 checkdrive(Drive *d, int i)
1086 {
1087 	static ulong s, olds[NCtlr*NCtlrdrv];
1088 	char *name;
1089 
1090 	ilock(d);
1091 	name = d->unit->name;
1092 	s = d->bridge->status;
1093 	if(s != olds[i]){
1094 		dprint("%s: status: %08lx -> %08lx: %s\n", name, olds[i], s, diskstates[d->state]);
1095 		olds[i] = s;
1096 	}
1097 	/* westerndigitalhung(d); */
1098 	switch(d->state){
1099 	case Dnew:
1100 	case Dmissing:
1101 		switch(s){
1102 		case 0x000:
1103 			break;
1104 		default:
1105 			dprint("%s: unknown state %8lx\n", name, s);
1106 		case 0x100:
1107 			if(++d->wait&Mphywait)
1108 				break;
1109 		reset:	d->mode ^= 1;
1110 			dprint("%s: reset; new mode %d\n", name, d->mode);
1111 			resetdisk(d);
1112 			break;
1113 		case 0x123:
1114 		case 0x113:
1115 			s = d->edma->cmdstat;
1116 			if(s == 0x7f || (s&~ATAobs) != ATAdrdy){
1117 				if((++d->wait&Midwait) == 0)
1118 					goto reset;
1119 			}else if(identifydrive(d) == -1)
1120 				goto reset;
1121 		}
1122 		break;
1123 	case Dready:
1124 		if(s != 0)
1125 			break;
1126 		iprint("%s: pulled: st=%08ulx\n", name, s);	/* never happens */
1127 	case Dreset:
1128 	case Derror:
1129 		dprint("%s reset: mode %d\n", name, d->mode);
1130 		resetdisk(d);
1131 		break;
1132 	}
1133 	iunlock(d);
1134 }
1135 
1136 static void
1137 satakproc(void*)
1138 {
1139 	int i;
1140 
1141 	while(waserror())
1142 		;
1143 
1144 	for(;;){
1145 		tsleep(&up->sleep, return0, 0, Nms);
1146 		for(i = 0; i < nmvsatadrive; i++)
1147 			checkdrive(mvsatadrive[i], i);
1148 	}
1149 }
1150 
1151 /*
1152  * Device discovery
1153  */
1154 static SDev*
1155 mv50pnp(void)
1156 {
1157 	int i, nunit;
1158 	uchar *base;
1159 	ulong io, n, *mem;
1160 	Ctlr *ctlr;
1161 	Pcidev *p;
1162 	SDev *head, *tail, *sdev;
1163 	Drive *d;
1164 	static int ctlrno, done;
1165 
1166 	dprint("mv50pnp\n");
1167 	if(done++)
1168 		return nil;
1169 
1170 	p = nil;
1171 	head = nil;
1172 	tail = nil;
1173 	while((p = pcimatch(p, 0x11ab, 0)) != nil){
1174 		switch(p->did){
1175 		case 0x5040:
1176 		case 0x5041:
1177 		case 0x5080:
1178 		case 0x5081:
1179 		case 0x6041:
1180 		case 0x6081:
1181 			break;
1182 		default:
1183 			print("mv50pnp: unknown did %ux ignored\n", (ushort)p->did);
1184 			continue;
1185 		}
1186 		if (ctlrno >= NCtlr) {
1187 			print("mv50pnp: too many controllers\n");
1188 			break;
1189 		}
1190 		nunit = (p->did&0xf0) >> 4;
1191 		print("Marvell 88SX%ux: %d SATA-%s ports with%s flash\n",
1192 			(ushort)p->did, nunit,
1193 			((p->did&0xf000)==0x6000? "II": "I"),
1194 			(p->did&1? "": "out"));
1195 		if((sdev = malloc(sizeof(SDev))) == nil)
1196 			continue;
1197 		if((ctlr = malloc(sizeof(Ctlr))) == nil){
1198 			free(sdev);
1199 			continue;
1200 		}
1201 		memset(sdev, 0, sizeof *sdev);
1202 		memset(ctlr, 0, sizeof *ctlr);
1203 
1204 		io = p->mem[0].bar & ~0x0F;
1205 		mem = (ulong*)vmap(io, p->mem[0].size);
1206 		if(mem == 0){
1207 			print("sdmv50xx: address 0x%luX in use\n", io);
1208 			free(sdev);
1209 			free(ctlr);
1210 			continue;
1211 		}
1212 		ctlr->rid = p->rid;
1213 
1214 		/* avert thine eyes!  (what does this do?) */
1215 		mem[0x104f0/4] = 0;
1216 		ctlr->type = (p->did >> 12) & 3;
1217 		if(ctlr->type == 1){
1218 			n = mem[0xc00/4];
1219 			n &= ~(3<<4);
1220 			mem[0xc00/4] = n;
1221 		}
1222 
1223 		sdev->ifc = &sdmv50xxifc;
1224 		sdev->ctlr = ctlr;
1225 		sdev->nunit = nunit;
1226 		sdev->idno = 'E';
1227 		ctlr->sdev = sdev;
1228 		ctlr->irq = p->intl;
1229 		ctlr->tbdf = p->tbdf;
1230 		ctlr->pcidev = p;
1231 		ctlr->lmmio = mem;
1232 		ctlr->mmio = (uchar*)mem;
1233 		ctlr->nchip = (nunit+3)/4;
1234 		ctlr->ndrive = nunit;
1235 		ctlr->enabled = 0;
1236 		for(i = 0; i < ctlr->nchip; i++){
1237 			base = ctlr->mmio+0x20000+0x10000*i;
1238 			ctlr->chip[i].arb = (Arb*)base;
1239 			ctlr->chip[i].edma = (Edma*)(base + 0x2000);
1240 		}
1241 		for (i = 0; i < nunit; i++) {
1242 			d = &ctlr->drive[i];
1243 			d->sectors = 0;
1244 			d->ctlr = ctlr;
1245 			d->driveno = ctlrno*NCtlrdrv + i;
1246 			d->chipx = i%4;
1247 			d->chip = &ctlr->chip[i/4];
1248 			d->edma = &d->chip->edma[d->chipx];
1249 			mvsatadrive[d->driveno] = d;
1250 		}
1251 		nmvsatadrive += nunit;
1252 		ctlrno++;
1253 		if(head)
1254 			tail->next = sdev;
1255 		else
1256 			head = sdev;
1257 		tail = sdev;
1258 	}
1259 	return head;
1260 }
1261 
1262 /*
1263  * Enable the controller.  Each disk has its own interrupt mask,
1264  * and those get enabled as the disks are brought online.
1265  */
1266 static int
1267 mv50enable(SDev *sdev)
1268 {
1269 	char name[32];
1270 	Ctlr *ctlr;
1271 
1272 	dprint("sd%c: enable\n", sdev->idno);
1273 
1274 	ctlr = sdev->ctlr;
1275 	if (ctlr->enabled)
1276 		return 1;
1277 	snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
1278 	intrenable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
1279 	ctlr->enabled = 1;
1280 	return 1;
1281 }
1282 
1283 /*
1284  * Disable the controller.
1285  */
1286 static int
1287 mv50disable(SDev *sdev)
1288 {
1289 	char name[32];
1290 	int i;
1291 	Ctlr *ctlr;
1292 	Drive *drive;
1293 
1294 	dprint("sd%c: disable\n", sdev->idno);
1295 
1296 	ctlr = sdev->ctlr;
1297 	ilock(ctlr);
1298 	for(i=0; i<ctlr->sdev->nunit; i++){
1299 		drive = &ctlr->drive[i];
1300 		ilock(drive);
1301 		disabledrive(drive);
1302 		iunlock(drive);
1303 	}
1304 	iunlock(ctlr);
1305 	snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
1306 	intrdisable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
1307 	return 0;
1308 }
1309 
1310 /*
1311  * Clean up all disk structures.  Already disabled.
1312  * Could keep count of number of allocated controllers
1313  * and free the srblist when it drops to zero.
1314  */
1315 static void
1316 mv50clear(SDev *sdev)
1317 {
1318 	int i;
1319 	Ctlr *ctlr;
1320 	Drive *d;
1321 
1322 	dprint("sd%c: clear\n", sdev->idno);
1323 
1324 	ctlr = sdev->ctlr;
1325 	for(i=0; i<ctlr->ndrive; i++){
1326 		d = &ctlr->drive[i];
1327 		free(d->tx);
1328 		free(d->rx);
1329 		free(d->prd);
1330 	}
1331 	free(ctlr);
1332 }
1333 
1334 /*
1335  * Check that there is a disk or at least a hot swap bay in the drive.
1336  */
1337 static int
1338 mv50verify(SDunit *unit)
1339 {
1340 	Ctlr *ctlr;
1341 	Drive *drive;
1342 	int i;
1343 
1344 	dprint("%s: verify\n", unit->name);
1345 	ctlr = unit->dev->ctlr;
1346 	drive = &ctlr->drive[unit->subno];
1347 	ilock(ctlr);
1348 	ilock(drive);
1349 	i = configdrive(ctlr, drive, unit);
1350 	iunlock(drive);
1351 	iunlock(ctlr);
1352 
1353 	/*
1354 	 * If ctlr->type == 1, then the drives spin up whenever
1355 	 * the controller feels like it; if ctlr->type != 1, then
1356 	 * they spin up as a result of configdrive.
1357 	 *
1358 	 * If there is a drive in the slot, give it 1.5s to spin up
1359 	 * before returning.  There is a noticeable drag on the
1360 	 * power supply when spinning up fifteen drives
1361 	 * all at once (like in the Coraid enclosures).
1362 	 */
1363 	if(ctlr->type != 1 && i == 0){
1364 		if(!waserror()){
1365 			tsleep(&up->sleep, return0, 0, 1500);
1366 			poperror();
1367 		}
1368 	}
1369 	return 1;
1370 }
1371 
1372 /*
1373  * Check whether the disk is online.
1374  */
1375 static int
1376 mv50online(SDunit *unit)
1377 {
1378 	Ctlr *ctlr;
1379 	Drive *d;
1380 	int r, s0;
1381 	static int once;
1382 
1383 	if(once++ == 0)
1384 		kproc("mvsata", satakproc, 0);
1385 
1386 	ctlr = unit->dev->ctlr;
1387 	d = &ctlr->drive[unit->subno];
1388 	r = 0;
1389 	ilock(d);
1390 	s0 = d->state;
1391 	USED(s0);
1392 	if(d->state == Dnew)
1393 		identifydrive(d);
1394 	if(d->mediachange){
1395 		idprint("%s: online: %s -> %s\n", unit->name, diskstates[s0], diskstates[d->state]);
1396 		r = 2;
1397 		unit->sectors = d->sectors;
1398 		unit->secsize = 512;
1399 		d->mediachange = 0;
1400 	} else if(d->state == Dready)
1401 		r = 1;
1402 	iunlock(d);
1403 	return r;
1404 }
1405 
1406 /*
1407  * Register dumps
1408  */
1409 typedef struct Regs Regs;
1410 struct Regs
1411 {
1412 	ulong offset;
1413 	char *name;
1414 };
1415 
1416 static Regs regsctlr[] =
1417 {
1418 	0x0C28, "pci serr# mask",
1419 	0x1D40, "pci err addr low",
1420 	0x1D44, "pci err addr hi",
1421 	0x1D48, "pci err attr",
1422 	0x1D50, "pci err cmd",
1423 	0x1D58, "pci intr cause",
1424 	0x1D5C, "pci mask cause",
1425 	0x1D60, "device micr",
1426 	0x1D64, "device mimr",
1427 };
1428 
1429 static Regs regsarb[] =
1430 {
1431 	0x0004,	"arb rqop",
1432 	0x0008,	"arb rqip",
1433 	0x000C,	"arb ict",
1434 	0x0010,	"arb itt",
1435 	0x0014,	"arb ic",
1436 	0x0018,	"arb btc",
1437 	0x001C,	"arb bts",
1438 	0x0020,	"arb bpc",
1439 };
1440 
1441 static Regs regsbridge[] =
1442 {
1443 	0x0000,	"bridge status",
1444 	0x0004,	"bridge serror",
1445 	0x0008,	"bridge sctrl",
1446 	0x000C,	"bridge phyctrl",
1447 	0x003C,	"bridge ctrl",
1448 	0x0074,	"bridge phymode",
1449 };
1450 
1451 static Regs regsedma[] =
1452 {
1453 	0x0000,	"edma config",
1454 	0x0004,	"edma timer",
1455 	0x0008,	"edma iec",
1456 	0x000C,	"edma iem",
1457 	0x0010,	"edma txbasehi",
1458 	0x0014,	"edma txi",
1459 	0x0018,	"edma txo",
1460 	0x001C,	"edma rxbasehi",
1461 	0x0020,	"edma rxi",
1462 	0x0024,	"edma rxo",
1463 	0x0028,	"edma c",
1464 	0x002C,	"edma tc",
1465 	0x0030,	"edma status",
1466 	0x0034,	"edma iordyto",
1467 /*	0x0100,	"edma pio",
1468 	0x0104,	"edma err",
1469 	0x0108,	"edma sectors",
1470 	0x010C,	"edma lba0",
1471 	0x0110,	"edma lba1",
1472 	0x0114,	"edma lba2",
1473 	0x0118,	"edma lba3",
1474 	0x011C,	"edma cmdstat",
1475 	0x0120,	"edma altstat",
1476 */
1477 };
1478 
1479 static char*
1480 rdregs(char *p, char *e, void *base, Regs *r, int n, char *prefix)
1481 {
1482 	int i;
1483 
1484 	for(i=0; i<n; i++)
1485 		p = seprint(p, e, "%s%s%-19s %.8ux\n",
1486 			prefix ? prefix : "", prefix ? ": " : "",
1487 			r[i].name, *(ulong *)((uchar*)base+r[i].offset));
1488 	return p;
1489 }
1490 
1491 static char*
1492 rdinfo(char *p, char *e, ushort *info)
1493 {
1494 	int i;
1495 
1496 	p = seprint(p, e, "info");
1497 	for(i=0; i<256; i++){
1498 		p = seprint(p, e, "%s%.4ux%s",
1499 			i%8==0 ? "\t" : "",
1500 			info[i],
1501 			i%8==7 ? "\n" : "");
1502 	}
1503 	return p;
1504 }
1505 
1506 static int
1507 mv50rctl(SDunit *unit, char *p, int l)
1508 {
1509 	char *e, *op;
1510 	Ctlr *ctlr;
1511 	Drive *drive;
1512 
1513 	if((ctlr = unit->dev->ctlr) == nil)
1514 		return 0;
1515 	drive = &ctlr->drive[unit->subno];
1516 
1517 	e = p+l;
1518 	op = p;
1519 	if(drive->state == Dready){
1520 		p = seprint(p, e, "model    %s\n", drive->model);
1521 		p = seprint(p, e, "serial   %s\n", drive->serial);
1522 		p = seprint(p, e, "firmware %s\n", drive->firmware);
1523 	}else
1524 		p = seprint(p, e, "no disk present\n");
1525 	p = seprint(p, e, "geometry %llud 512\n", drive->sectors);
1526 	p = rdinfo(p, e, drive->info);
1527 
1528 	p = rdregs(p, e, drive->chip->arb, regsarb, nelem(regsarb), nil);
1529 	p = rdregs(p, e, drive->bridge, regsbridge, nelem(regsbridge), nil);
1530 	p = rdregs(p, e, drive->edma, regsedma, nelem(regsedma), nil);
1531 
1532 	return p-op;
1533 }
1534 
1535 static int
1536 mv50wctl(SDunit *unit, Cmdbuf *cb)
1537 {
1538 	Ctlr *ctlr;
1539 	Drive *drive;
1540 
1541 	USED(unit);
1542 	if(strcmp(cb->f[0], "reset") == 0){
1543 		ctlr = unit->dev->ctlr;
1544 		drive = &ctlr->drive[unit->subno];
1545 		ilock(drive);
1546 		drive->state = Dreset;
1547 		iunlock(drive);
1548 		return 0;
1549 	}
1550 	cmderror(cb, Ebadctl);
1551 	return -1;
1552 }
1553 
1554 static char*
1555 mv50rtopctl(SDev *sdev, char *p, char *e)
1556 {
1557 	char name[10];
1558 	Ctlr *ctlr;
1559 
1560 	ctlr = sdev->ctlr;
1561 	if(ctlr == nil)
1562 		return p;
1563 
1564 	snprint(name, sizeof name, "sd%c", sdev->idno);
1565 	p = rdregs(p, e, ctlr->mmio, regsctlr, nelem(regsctlr), name);
1566 	/* info for first disk */
1567 	p = rdregs(p, e, ctlr->chip[0].arb, regsarb, nelem(regsarb), name);
1568 	p = rdregs(p, e, &ctlr->chip[0].arb->bridge[0], regsbridge, nelem(regsbridge), name);
1569 	p = rdregs(p, e, &ctlr->chip[0].edma[0], regsedma, nelem(regsedma), name);
1570 
1571 	return p;
1572 }
1573 
1574 static int
1575 waitready(Drive *d)
1576 {
1577 	ulong s, i;
1578 
1579 	for(i = 0; i < 120; i++){
1580 		ilock(d);
1581 		s = d->bridge->status;
1582 		iunlock(d);
1583 		if(s == 0)
1584 			return SDeio;
1585 		if (d->state == Dready)
1586 			return SDok;
1587 		if ((i+1)%60 == 0){
1588 			ilock(d);
1589 			resetdisk(d);
1590 			iunlock(d);
1591 		}
1592 		if(!waserror()){
1593 			tsleep(&up->sleep, return0, 0, 1000);
1594 			poperror();
1595 		}
1596 	}
1597 	print("%s: not responding after 2 minutes\n", d->unit->name);
1598 	return SDeio;
1599 }
1600 
1601 static int
1602 mv50rio(SDreq *r)
1603 {
1604 	int count, max, n, status, try, flag;
1605 	uchar *cmd, *data;
1606 	uvlong lba;
1607 	Ctlr *ctlr;
1608 	Drive *drive;
1609 	SDunit *unit;
1610 	Srb *srb;
1611 
1612 	unit = r->unit;
1613 	ctlr = unit->dev->ctlr;
1614 	drive = &ctlr->drive[unit->subno];
1615 	cmd = r->cmd;
1616 
1617 	if((status = sdfakescsi(r, drive->info, sizeof drive->info)) != SDnostatus){
1618 		/* XXX check for SDcheck here */
1619 		r->status = status;
1620 		return status;
1621 	}
1622 
1623 	switch(cmd[0]){
1624 	case 0x28:	/* read */
1625 	case 0x2A:	/* write */
1626 		break;
1627 	default:
1628 		iprint("%s: bad cmd 0x%.2ux\n", drive->unit->name, cmd[0]);
1629 		r->status = SDcheck;
1630 		return SDcheck;
1631 	}
1632 
1633 	lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
1634 	count = (cmd[7]<<8)|cmd[8];
1635 	if(r->data == nil)
1636 		return SDok;
1637 	if(r->dlen < count*unit->secsize)
1638 		count = r->dlen/unit->secsize;
1639 
1640 	try = 0;
1641 retry:
1642 	if(waitready(drive) != SDok)
1643 		return SDeio;
1644 	/*
1645 	 * Could arrange here to have an Srb always outstanding:
1646 	 *
1647 	 *	lsrb = nil;
1648 	 *	while(count > 0 || lsrb != nil){
1649 	 *		srb = nil;
1650 	 *		if(count > 0){
1651 	 *			srb = issue next srb;
1652 	 *		}
1653 	 *		if(lsrb){
1654 	 *			sleep on lsrb and handle it
1655 	 *		}
1656 	 *	}
1657 	 *
1658 	 * On the disks I tried, this didn't help.  If anything,
1659 	 * it's a little slower.		-rsc
1660 	 */
1661 	data = r->data;
1662 	while(count > 0){
1663 		/*
1664 		 * Max is 128 sectors (64kB) because prd->count is 16 bits.
1665 		 */
1666 		max = 128;
1667 		n = count;
1668 		if(n > max)
1669 			n = max;
1670 		if((drive->edma->ctl&eEnEDMA) == 0)
1671 			goto tryagain;
1672 		srb = srbrw(cmd[0]==0x28 ? SRBread : SRBwrite, drive, data, n, lba);
1673 		ilock(drive);
1674 		startsrb(drive, srb);
1675 		iunlock(drive);
1676 
1677 		/* Don't let user interrupt DMA. */
1678 		while(waserror())
1679 			;
1680 		sleep(srb, srbdone, srb);
1681 		poperror();
1682 
1683 		flag = srb->flag;
1684 		freesrb(srb);
1685 		if(flag == 0){
1686 tryagain:
1687 			if(++try == 10){
1688 				print("%s: bad disk\n", drive->unit->name);
1689 				return SDeio;
1690 			}
1691 			dprint("%s: retry\n", drive->unit->name);
1692 			if(!waserror()){
1693 				tsleep(&up->sleep, return0, 0, 1000);
1694 				poperror();
1695 			}
1696 			goto retry;
1697 		}
1698 		if(flag & SFerror){
1699 			print("%s: i/o error\n", drive->unit->name);
1700 			return SDeio;
1701 		}
1702 		count -= n;
1703 		lba += n;
1704 		data += n*unit->secsize;
1705 	}
1706 	r->rlen = data - (uchar*)r->data;
1707 	return SDok;
1708 }
1709 
1710 SDifc sdmv50xxifc = {
1711 	"mv50xx",			/* name */
1712 
1713 	mv50pnp,			/* pnp */
1714 	nil,				/* legacy */
1715 	mv50enable,			/* enable */
1716 	mv50disable,			/* disable */
1717 
1718 	mv50verify,			/* verify */
1719 	mv50online,			/* online */
1720 	mv50rio,				/* rio */
1721 	mv50rctl,			/* rctl */
1722 	mv50wctl,			/* wctl */
1723 
1724 	scsibio,			/* bio */
1725 	nil,				/* probe */
1726 	mv50clear,			/* clear */
1727 	mv50rtopctl,			/* rtopctl */
1728 };
1729 
1730 /*
1731  * The original driver on which this one is based came with the
1732  * following notice:
1733  *
1734  * Copyright 2005
1735  * Coraid, Inc.
1736  *
1737  * This software is provided `as-is,' without any express or implied
1738  * warranty.  In no event will the author be held liable for any damages
1739  * arising from the use of this software.
1740  *
1741  * Permission is granted to anyone to use this software for any purpose,
1742  * including commercial applications, and to alter it and redistribute it
1743  * freely, subject to the following restrictions:
1744  *
1745  * 1.  The origin of this software must not be misrepresented; you must
1746  * not claim that you wrote the original software.  If you use this
1747  * software in a product, an acknowledgment in the product documentation
1748  * would be appreciated but is not required.
1749  *
1750  * 2.  Altered source versions must be plainly marked as such, and must
1751  * not be misrepresented as being the original software.
1752  *
1753  * 3.  This notice may not be removed or altered from any source
1754  * distribution.
1755  */
1756