2 * Marvell 88SX[56]0[48][01] Serial ATA (SATA) driver
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.
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.
13 #include "../port/lib.h"
18 #include "../port/error.h"
19 #include "../port/sd.h"
22 #define dprint(...) // print(__VA_ARGS__)
23 #define idprint(...) print(__VA_ARGS__)
24 #define Ticks MACHP(0)->ticks
29 NDrive = NCtlr*NCtlrdrv,
33 /* Addresses of ATA register */
50 ATAobs = 1<<1 | 1<<2 | 1<<4,
52 ATAbad = ATAbusy|ATAdf|ATAdrq|ATAerr,
59 /* EDMA interrupt error cause register */
73 /* flags for sata 2 version */
77 /* EDMA Command Register */
82 /* Interrupt mask for errors we care about */
83 IEM = eDevDis | eDevCon | eSelfDis,
84 IEM2 = eDevDis | eDevCon | eSelfDis2,
93 /* general mmio registers */
111 typedef struct Arb Arb;
112 typedef struct Bridge Bridge;
113 typedef struct Chip Chip;
114 typedef struct Ctlr Ctlr;
115 typedef struct Drive Drive;
116 typedef struct Edma Edma;
117 typedef struct Prd Prd;
118 typedef struct Rx Rx;
119 typedef struct Srb Srb;
120 typedef struct Tx Tx;
123 * there are 4 drives per chip. thus an 8-port
124 * card has two chips.
150 ulong pm2; /* phymode 2 init state */
151 ulong intick; /* check for hung drives. */
153 int mode; /* DMautoneg, satai or sataii. */
170 int driveno; /* ctlr*NCtlrdrv + unit */
190 Drive drive[NCtlrdrv];
194 struct Srb /* request buffer */
215 * Memory-mapped I/O registers in many forms.
217 struct Bridge /* memory-mapped per-drive registers */
233 }; /* must be 0x100 hex in length */
235 struct Arb /* memory-mapped per-chip registers */
237 ulong config; /* satahc configuration register (sata2 only) */
238 ulong rqop; /* request queue out-pointer */
239 ulong rqip; /* response queue in pointer */
240 ulong ict; /* inerrupt caolescing threshold */
241 ulong itt; /* interrupt timer threshold */
242 ulong ic; /* interrupt cause */
243 ulong btc; /* bridges test control */
244 ulong bts; /* bridges test status */
245 ulong bpc; /* bridges pin configuration */
250 struct Edma /* memory-mapped per-drive DMA-related registers */
252 ulong config; /* configuration register */
254 ulong iec; /* interrupt error cause */
255 ulong iem; /* interrupt error mask */
257 ulong txbasehi; /* request queue base address high */
258 ulong txi; /* request queue in pointer */
259 ulong txo; /* request queue out pointer */
261 ulong rxbasehi; /* response queue base address high */
262 ulong rxi; /* response queue in pointer */
263 ulong rxo; /* response queue out pointer */
265 ulong ctl; /* command register */
266 ulong testctl; /* test control */
268 ulong iordyto; /* IORDY timeout */
270 ulong sataconfig; /* sata 2 */
272 ushort pio; /* data register */
274 uchar err; /* features and error */
276 uchar seccnt; /* sector count */
286 uchar cmdstat; /* cmd/status */
288 uchar altstat; /* alternate status */
291 char fill3[0x1c00]; /* pad to 0x2000 bytes */
295 * Memory structures shared with card.
297 struct Prd /* physical region descriptor */
299 ulong pa; /* byte address of physical memory */
300 ushort count; /* byte count (bit0 must be 0) */
302 ulong zero; /* high long of 64 bit address */
306 struct Tx /* command request block */
308 ulong prdpa; /* physical region descriptor table structures */
309 ulong zero; /* must be zero (high long of prd address) */
310 ushort flag; /* control flags */
314 struct Rx /* command response block */
316 ushort cid; /* cID of response */
317 uchar cEdmaSts; /* EDMA status */
318 uchar cDevSts; /* status from disk */
319 ulong ts; /* time stamp */
322 static Ctlr *mvsatactlr[NCtlr];
323 static Drive *mvsatadrive[NDrive];
324 static int nmvsatadrive;
325 static char *diskstates[Dlast] = {
334 extern SDifc sdmv50xxifc;
352 if((p = srblist.freechain) == nil){
355 p = smalloc(sizeof *p);
357 srblist.freechain = p->next;
367 p->next = srblist.freechain;
368 srblist.freechain = p;
373 satawait(uchar *p, uchar mask, uchar v, int ms)
377 for(i=0; i<ms && (*p & mask) != v; i++)
379 return (*p & mask) == v;
382 /* unmask in the pci registers err done */
384 portswitch(ulong *mmio, int port, uint coal, uint on)
388 m = 3<<(port&3)*2 | coal<<8;
392 mmio[Portswtch] |= m;
394 mmio[Portswtch] &= m;
401 return d->unit->name;
405 /* I give up, marvell. You win. */
410 enum { BadAutoCal = 0xf << 26, };
412 if(d->ctlr->type == 1){
413 /* set phyctrl bits [0:1] to 01 per MV-S102013-00 Rev C. */
414 n = d->bridge->phyctrl;
416 d->bridge->phyctrl = n | 1;
420 n = d->bridge->phymode2;
421 while ((n & BadAutoCal) == BadAutoCal) {
422 dprint("%s: badautocal\n", dnam(d));
425 d->bridge->phymode2 = n;
427 d->bridge->phymode2 &= ~(1<<16 | 1<<31);
429 n = d->bridge->phymode2;
432 d->bridge->phymode2 = n;
435 /* abra cadabra! (random magic) */
436 m = d->bridge->phymode3;
439 d->bridge->phymode3 = m;
442 m = d->bridge->phymode3;
443 n = d->bridge->phymode4;
446 switch(d->ctlr->rid){
449 d->bridge->phymode4 = n;
450 d->bridge->phymode3 = m;
453 d->bridge->phymode4 = n;
457 /* revert values of pre-emphasis and signal amps to the saved ones */
458 n = d->bridge->phymode2;
462 d->bridge->phymode2 = n;
466 edmacleanout(Drive *d)
471 for(i=0; i<nelem(d->srb); i++){
475 srb->flag |= SFerror|SFdone;
479 while(srb = d->srbhead){
480 d->srbhead = srb->next;
481 srb->flag |= SFerror|SFdone;
487 edmadisable(Drive *d, int reset)
492 if(!reset && (e->ctl & eEnEDMA) == 0)
500 if (satawait((uchar *)&e->ctl, eEnEDMA, 0, 3*1000) == 0){
501 print("%s: eEnEDMA never cleared on reset\n", dnam(d));
514 d->unit->sectors = 0;
515 if (d->ctlr->type == 2) {
517 * without bit 8 we can boot without disks, but
518 * inserted disks will never appear. :-X
520 n = d->edma->sataconfig;
523 d->edma->sataconfig = n;
524 n = d->edma->sataconfig; /* flush */
527 if(edmadisable(d, 1) == -1){
530 d->bridge->sctrl = 0x301 | d->mode<<4;
542 d->tx = xspanalloc(32*sizeof(Tx), 1024, 0);
543 d->rx = xspanalloc(32*sizeof(Rx), 256, 0);
544 d->prd = xspanalloc(32*sizeof(Prd), 32, 0);
545 for(i = 0; i < 32; i++)
546 d->tx[i].prdpa = PCIWADDR(&d->prd[i]);
551 configdrive(Ctlr *ctlr, Drive *d, SDunit *unit)
553 dprint("%s: configdrive\n", unit->name);
556 portswitch(ctlr->lmmio, d->driveno, 0, 1);
558 if(d->bridge->status){
559 dprint("%s: configdrive: found drive %lux\n", unit->name, d->bridge->status);
570 dprint("%s: enabledrive..", dnam(d));
572 if((d->bridge->status & 0xf) != 3){
573 dprint("%s: not present\n", dnam(d));
577 if(satawait(&edma->cmdstat, ATAbusy, 0, 5*1000) == 0){
578 dprint("%s: busy timeout\n", dnam(d));
582 d->chip->arb->ic &= ~(0x101 << d->chipx);
583 edma->config = 0x51f;
584 if (d->ctlr->type == 2)
585 edma->config |= 7<<11;
586 edma->txi = PCIWADDR(d->tx);
587 edma->txo = (ulong)d->tx & 0x3e0;
588 edma->rxi = (ulong)d->rx & 0xf8;
589 edma->rxo = PCIWADDR(d->rx);
590 edma->ctl |= 1; /* enable dma */
595 enabledrive(Drive *d)
597 dprint("%s: enabledrive..", dnam(d));
598 if(edmaenable(d) == 0){
599 switch(d->bridge->status){
607 print("mv50: enable reset\n");
613 disabledrive(Drive *d)
615 if(d->tx == nil) /* never enabled */
619 portswitch(d->ctlr->lmmio, d->driveno, 0, 0);
623 setudmamode(Drive *d, uchar mode)
627 dprint("%s: setudmamode %d\n", dnam(d), mode);
630 iprint("setudamode(m%d): zero d->edma\m", d->driveno);
633 if(satawait(&edma->cmdstat, ~ATAobs, ATAdrdy, 250) == 0){
634 iprint("%s: cmdstat 0x%.2ux ready timeout\n", dnam(d), edma->cmdstat);
637 edma->altstat = ATAeIEN;
639 edma->seccnt = 0x40 | mode;
640 edma->cmdstat = 0xef;
642 if(satawait(&edma->cmdstat, ATAbusy, 0, 5*1000) == 0){
643 iprint("%s: cmdstat 0x%.2ux busy timeout\n", dnam(d), edma->cmdstat);
650 identifydrive(Drive *d)
658 dprint("%s: identifydrive\n", dnam(d));
659 setfissig(d, 0); /* BOTCH; need to find and set signature */
660 if(setudmamode(d, 5) == 0) /* BOTCH; run after identify */
664 memset(d->info, 0, sizeof d->info);
666 if(satawait(&edma->cmdstat, ~ATAobs, ATAdrdy, 5*1000) == 0)
669 edma->altstat = ATAeIEN; /* no interrupts */
670 edma->cmdstat = 0xec;
672 if(satawait(&edma->cmdstat, ATAbusy, 0, 5*1000) == 0)
674 for(i = 0; i < 256; i++)
676 if(edma->cmdstat & ATAbad)
678 d->sectors = idfeat(d, id);
679 d->secsize = idss(d, id);
680 idmove(d->serial, id+10, 20);
681 idmove(d->firmware, id+23, 8);
682 idmove(d->model, id+27, 40);
683 d->wwn = idwwn(d, id);
686 memset(u->inquiry, 0, sizeof u->inquiry);
689 u->inquiry[4] = sizeof u->inquiry - 4;
690 idmove((char*)u->inquiry+8, id+27, 40);
692 if(enabledrive(d) == 0) {
698 idprint("%s: %sLBA %llud sectors\n", dnam(d), s, d->sectors);
701 if(d->state == Dready)
716 * B 8-to-10 encoding error
720 * S link sequence error
721 * T transport state transition error
722 * F unrecognized fis type
726 static char stab[] = {
730 [18] 'W', 'B', 'D', 'C', 'H', 'S', 'T', 'F', 'X'
732 static ulong sbad = 7<<20 | 3<<23;
735 serrdecode(ulong r, char *s, char *e)
740 for(i = 0; i < nelem(stab) && s < e; i++)
741 if(r & 1<<i && stab[i]){
749 static char *iectab[] = {
766 iecdecode(ulong cause)
770 for(i = 0; i < nelem(iectab); i++)
777 Cerror1 = ePrtDataErr|ePrtPRDErr|eOverrun|ePrtCRQBErr|ePrtCRPBErr|ePrtIntErr,
778 Cerror2 = ePrtDataErr|ePrtPRDErr|ePrtCRQBErr|
779 ePrtCRPBErr|ePrtIntErr|eDevErr|eSelfDis2,
783 updatedrive(Drive *d)
791 if((edma->ctl & eEnEDMA) == 0){
792 /* FEr SATA#4 40xx */
793 x = d->edma->cmdstat;
799 dprint("%s: cause %.8lux [%s]\n", dnam(d), cause, iecdecode(cause));
802 if(cause & eDevDis && d->state == Dready)
803 iprint("%s: pulled: st=%.8lux\n", dnam(d), cause);
804 switch(d->ctlr->type){
806 if(cause & eUnderrun){
807 /* FEr SATA#5 50xx for revs A0, B0 */
812 dprint("%s: underrun\n", dnam(d));
815 if(cause & (eDevErr | eSelfDis)){
817 * FEr SATA#7 60xx for refs A0, B0
818 * check for IRC error. we only check the
819 * ABORT flag as we don't get the upper nibble
822 if(edma->altstat & ATAerr && edma->err & ATAabort)
834 serrdecode(d->bridge->serror, buf, buf+sizeof buf);
835 dprint("%s: serror %.8lux [%s]\n", dnam(d), d->bridge->serror, buf);
836 d->bridge->serror = ~0; /*d->bridge->serror;*/
847 srbrw(int rw, Drive *d, uchar *data, uint sectors, uvlong lba)
851 static uchar cmd[2][2] = { 0xC8, 0x25, 0xCA, 0x35 };
857 srb->sectors = sectors;
858 srb->count = sectors * d->secsize;
863 srb->lba[i] = lba >> 8*i;
864 srb->cmd = cmd[srb->req!=SDread][(d->feat&Dllba)!=0];
868 #define CMD(r, v) (((r)<<8) | (v))
870 mvsatarequest(ushort *cmd, Srb *srb, int llba)
872 *cmd++ = CMD(ARseccnt, 0);
873 *cmd++ = CMD(ARseccnt, srb->sectors);
874 *cmd++ = CMD(ARfea, 0);
876 *cmd++ = CMD(ARlba0, srb->lba[3]);
877 *cmd++ = CMD(ARlba0, srb->lba[0]);
878 *cmd++ = CMD(ARlba1, srb->lba[4]);
879 *cmd++ = CMD(ARlba1, srb->lba[1]);
880 *cmd++ = CMD(ARlba2, srb->lba[5]);
881 *cmd++ = CMD(ARlba2, srb->lba[2]);
882 *cmd++ = CMD(ARdev, 0xe0);
884 *cmd++ = CMD(ARlba0, srb->lba[0]);
885 *cmd++ = CMD(ARlba1, srb->lba[1]);
886 *cmd++ = CMD(ARlba2, srb->lba[2]);
887 *cmd++ = CMD(ARdev, srb->lba[3] | 0xe0);
889 *cmd = CMD(ARcmd, srb->cmd) | 1<<15;
893 advance(uintptr pa, int shift)
898 n = (pa & mask) + (1<<shift);
899 return (pa & ~mask) | (n & mask);
903 startsrb(Drive *d, Srb *srb)
910 if(d->nsrb >= nelem(d->srb)){
913 d->srbtail->next = srb;
921 for(i=0; i<nelem(d->srb); i++)
924 if(i == nelem(d->srb))
925 panic("sdmv50xx: no free srbs");
929 tx = (Tx*)KADDR(edma->txi);
930 tx->flag = i<<1 | (srb->req == SDread);
931 prd = KADDR(tx->prdpa);
932 prd->pa = PCIWADDR(srb->data);
933 prd->count = srb->count;
935 mvsatarequest(tx->regs, srb, d->feat&Dllba);
937 edma->txi = advance(edma->txi, 5);
946 completesrb(Drive *d)
953 if((edma->ctl & eEnEDMA) == 0)
956 while((edma->rxo&Rpidx) != (edma->rxi&Rpidx)){
957 rx = (Rx*)KADDR(edma->rxo);
958 if(srb = d->srb[rx->cid]){
959 d->srb[rx->cid] = nil;
961 if(rx->cDevSts & ATAbad)
962 srb->flag |= SFerror;
964 iprint("cEdmaSts: %02ux\n", rx->cEdmaSts);
965 srb->sta = rx->cDevSts;
969 iprint("srb missing\n");
970 edma->rxo = advance(edma->rxo, 3);
971 if(srb = d->srbhead){
972 d->srbhead = srb->next;
984 return srb->flag & SFdone;
991 mv50interrupt(Ureg*, void *v)
1002 cause = ctlr->lmmio[0x1d60/4];
1003 // dprint("sd%c: mv50interrupt: %.8lux\n", ctlr->sdev->idno, cause);
1004 for(i=0; cause && i<ctlr->ndrive; i++)
1005 if(cause & (3<<(i*2+i/4))){
1006 drive = &ctlr->drive[i];
1007 if(drive->edma == 0)
1008 continue; /* not ready yet. */
1012 a = ctlr->chip[i/4].arb;
1017 if(TK2MS(Ticks - tk0) > 3000){
1018 print("%s: irq wedge\n", dnam(drive));
1019 drive->state = Dreset;
1030 Midwait = 16*1024/Nms - 1,
1031 Mphywait = 512/Nms - 1,
1041 && TK2MS(Ticks - d->intick) > 5*1000
1042 && (e->rxo&Rpidx) == (e->rxi&Rpidx)){
1043 print("%s: drive hung; resetting\n", dnam(d));
1049 checkdrive(Drive *d, int i)
1051 static ulong s, olds[NCtlr*NCtlrdrv];
1054 s = d->bridge->status;
1056 dprint("%s: status: %.8lux -> %.8lux: %s\n", dnam(d), olds[i], s, diskstates[d->state]);
1067 dprint("%s: unknown state %.8lux\n", dnam(d), s);
1069 if(++d->wait&Mphywait)
1071 reset: d->mode ^= 1;
1072 dprint("%s: reset; new mode %d\n", dnam(d), d->mode);
1077 s = d->edma->cmdstat;
1078 if(s == 0x7f || (s&~ATAobs) != ATAdrdy){
1079 if((++d->wait&Midwait) == 0)
1081 }else if(identifydrive(d) == -1)
1088 iprint("%s: pulled: st=%.8lux\n", dnam(d), s); /* never happens */
1091 dprint("%s reset: mode %d\n", dnam(d), d->mode);
1106 tsleep(&up->sleep, return0, 0, Nms);
1107 for(i = 0; i < nmvsatadrive; i++)
1108 checkdrive(mvsatadrive[i], i);
1117 if(d->ctlr->type == 1){
1119 d->bridge = &d->chip->arb->bridge[d->chipx];
1121 d->edma->iem = IEM2;
1122 d->bridge = &d->chip->edma[d->chipx].port;
1123 // d->edma->iem = ~(1<<6);
1125 if(d->ctlr->lmmio[0x180d8/4] & 1)
1126 d->pm2 = d->bridge->phymode2 & Mpreamp;
1139 SDev *head, *tail, *sdev;
1140 static int ctlrno, done;
1148 while((p = pcimatch(p, 0x11ab, 0)) != nil){
1149 if(p->ccrb != Pcibcstore || p->ccru + p->ccrp || p->did&0x0f00)
1160 print("mv50pnp: unknown did %ux ignored\n", (ushort)p->did);
1163 if (ctlrno >= NCtlr) {
1164 print("mv50pnp: too many controllers\n");
1167 nunit = (p->did&0xf0) >> 4;
1168 print("#S/sd%c: Marvell 88sx%ux: %d sata-%s ports with%s flash\n",
1169 'E' + ctlrno, (ushort)p->did, nunit,
1170 ((p->did&0xf000)==0x6000? "II": "I"),
1171 (p->did&1? "": "out"));
1172 if((sdev = malloc(sizeof *sdev)) == nil)
1174 if((ctlr = malloc(sizeof *ctlr)) == nil){
1178 io = p->mem[0].bar & ~0x0F;
1179 mem = (ulong*)vmap(io, p->mem[0].size);
1181 print("sdmv50xx: address 0x%luX in use\n", io);
1188 /* avert thine eyes! (what does this do?) */
1190 ctlr->type = (p->did >> 12) & 3;
1191 if(ctlr->type == 1){
1197 sdev->ifc = &sdmv50xxifc;
1199 sdev->nunit = nunit;
1202 ctlr->irq = p->intl;
1203 ctlr->tbdf = p->tbdf;
1206 ctlr->mmio = (uchar*)mem;
1207 ctlr->nchip = (nunit+3)/4;
1208 ctlr->ndrive = nunit;
1210 for(i = 0; i < ctlr->nchip; i++){
1211 base = ctlr->mmio+0x20000+0x10000*i;
1212 ctlr->chip[i].arb = (Arb*)base;
1213 ctlr->chip[i].edma = (Edma*)(base + 0x2000);
1215 for (i = 0; i < nunit; i++) {
1216 d = &ctlr->drive[i];
1217 snprint(d->name, sizeof d->name, "mv50%d.%d", ctlrno, i);
1220 d->driveno = ctlrno*NCtlrdrv + i;
1222 d->chip = &ctlr->chip[i/4];
1223 d->edma = &d->chip->edma[d->chipx];
1224 mvsatadrive[d->driveno] = d;
1227 mvsatactlr[ctlrno] = ctlr;
1228 nmvsatadrive += nunit;
1240 mv50enable(SDev *sdev)
1245 dprint("sd%c: enable\n", sdev->idno);
1251 kproc("mvsata", satakproc, 0);
1252 snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
1253 intrenable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
1258 mv50disable(SDev *sdev)
1265 dprint("sd%c: disable\n", sdev->idno);
1269 for(i=0; i<ctlr->sdev->nunit; i++){
1270 drive = &ctlr->drive[i];
1272 disabledrive(drive);
1276 snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
1277 intrdisable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
1282 * Check that there is a disk or at least a hot swap bay in the drive.
1285 mv50verify(SDunit *unit)
1291 dprint("%s: verify\n", unit->name);
1292 ctlr = unit->dev->ctlr;
1293 drive = &ctlr->drive[unit->subno];
1296 i = configdrive(ctlr, drive, unit);
1301 * If ctlr->type == 1, then the drives spin up whenever
1302 * the controller feels like it; if ctlr->type == 2, then
1303 * they spin up as a result of configdrive.
1305 * If there is a drive in the slot, give it 1.4s to spin up
1306 * before returning. There is a noticeable drag on the
1307 * power supply when spinning up fifteen drives
1308 * all at once (like in the Coraid enclosures).
1310 if(ctlr->type == 2 && i == 0)
1312 tsleep(&up->sleep, return0, 0, 1400);
1319 * Check whether the disk is online.
1322 mv50online(SDunit *unit)
1329 ctlr = unit->dev->ctlr;
1330 d = &ctlr->drive[unit->subno];
1335 if(d->state == Dnew)
1338 idprint("%s: online: %s -> %s\n", unit->name, diskstates[s0], diskstates[d->state]);
1340 unit->sectors = d->sectors;
1341 unit->secsize = d->secsize;
1343 } else if(d->state == Dready)
1352 typedef struct Regs Regs;
1359 static Regs regsctlr[] =
1361 0x0C28, "pci serr# mask",
1362 0x1D40, "pci err addr low",
1363 0x1D44, "pci err addr hi",
1364 0x1D48, "pci err attr",
1365 0x1D50, "pci err cmd",
1366 0x1D58, "pci intr cause",
1367 0x1D5C, "pci mask cause",
1368 0x1D60, "device micr",
1369 0x1D64, "device mimr",
1372 static Regs regsarb[] =
1384 static Regs regsbridge[] =
1386 0x0000, "bridge status",
1387 0x0004, "bridge serror",
1388 0x0008, "bridge sctrl",
1389 0x000C, "bridge phyctrl",
1390 0x003C, "bridge ctrl",
1391 0x0074, "bridge phymode",
1394 static Regs regsedma[] =
1396 0x0000, "edma config",
1397 0x0004, "edma timer",
1400 0x0010, "edma txbasehi",
1403 0x001C, "edma rxbasehi",
1408 0x0030, "edma status",
1409 0x0034, "edma iordyto",
1410 /* 0x0100, "edma pio",
1412 0x0108, "edma sectors",
1413 0x010C, "edma lba0",
1414 0x0110, "edma lba1",
1415 0x0114, "edma lba2",
1416 0x0118, "edma lba3",
1417 0x011C, "edma cmdstat",
1418 0x0120, "edma altstat",
1423 rdregs(char *p, char *e, void *base, Regs *r, int n, char *prefix)
1428 p = seprint(p, e, "%s%s%-19s %.8ux\n",
1429 prefix ? prefix : "", prefix ? ": " : "",
1430 r[i].name, *(u32int*)((uchar*)base+r[i].offset));
1435 mv50rctl(SDunit *unit, char *p, int l)
1441 if((ctlr = unit->dev->ctlr) == nil)
1443 drive = &ctlr->drive[unit->subno];
1447 if(drive->state == Dready){
1448 p = seprint(p, e, "model %s\n", drive->model);
1449 p = seprint(p, e, "serial %s\n", drive->serial);
1450 p = seprint(p, e, "firmware %s\n", drive->firmware);
1451 p = seprint(p, e, "wwn\t%llux\n", drive->wwn);
1452 p = seprint(p, e, "flag\t");
1453 p = pflag(p, e, drive);
1455 p = seprint(p, e, "no disk present\n");
1456 p = seprint(p, e, "geometry %llud %ud\n", drive->sectors, drive->secsize);
1457 p = rdregs(p, e, drive->bridge, regsbridge, nelem(regsbridge), nil);
1459 p = rdregs(p, e, drive->chip->arb, regsarb, nelem(regsarb), nil);
1460 p = rdregs(p, e, drive->bridge, regsbridge, nelem(regsbridge), nil);
1461 p = rdregs(p, e, drive->edma, regsedma, nelem(regsedma), nil);
1467 mv50wctl(SDunit *unit, Cmdbuf *cb)
1472 if(strcmp(cb->f[0], "reset") == 0){
1473 ctlr = unit->dev->ctlr;
1474 drive = &ctlr->drive[unit->subno];
1476 drive->state = Dreset;
1480 cmderror(cb, Ebadctl);
1489 for(i = 0; i < 120; i++){
1491 s = d->bridge->status;
1495 if(d->state == Dready)
1503 tsleep(&up->sleep, return0, 0, 1000);
1507 print("%s: not responding; error\n", dnam(d));
1512 mv50bio(SDunit *u, int /*lun*/, int write, void *a, long count, uvlong lba)
1520 ctlr = u->dev->ctlr;
1521 d = ctlr->drive + u->subno;
1525 if(waitready(d) != SDok)
1529 * Max is 128 sectors (64kB) because prd->count is 16 bits.
1535 if((d->edma->ctl&eEnEDMA) == 0 && edmaenable(d) == -1){
1539 srb = srbrw(write, d, data, n, lba);
1545 sleep(srb, srbdone, srb);
1551 tryagain: if(++try == 10){
1552 print("%s: bad disk\n", dnam(d));
1555 dprint("%s: retry\n", dnam(d));
1559 print("%s: i/o error\n", dnam(d));
1564 data += n*u->secsize;
1566 return data - (uchar*)a;
1572 int count, n, status, rw;
1579 ctlr = unit->dev->ctlr;
1580 d = &ctlr->drive[unit->subno];
1582 if((status = sdfakescsi(r)) != SDnostatus)
1583 return r->status = status;
1584 if((status = sdfakescsirw(r, &lba, &count, &rw)) == SDcheck)
1586 n = mv50bio(r->unit, r->lun, rw, r->data, count, lba);
1594 mkrfis(SDreq *r, Drive *d, Edma *e)
1601 if((d->feat & Dllba) && (r->ataproto & P28) == 0){
1602 u[Frerror] = e->err;
1603 u[Fsc8] = e->seccnt;
1605 u[Flba24] = e->lba0;
1607 u[Flba32] = e->lba1;
1609 u[Flba40] = e->lba2;
1610 u[Flba16] = e->lba2;
1612 u[Fstatus] = e->cmdstat;
1614 u[Frerror] = e->err;
1618 u[Flba16] = e->lba2;
1620 u[Fstatus] = e->cmdstat;
1625 piocmd(SDreq *r, Drive *d)
1628 int n, nsec, i, err;
1634 if(waitready(d) != SDok)
1638 nsec = r->dlen / u->secsize;
1639 if(r->dlen < nsec*u->secsize)
1640 nsec = r->dlen/u->secsize;
1642 error("can't do more than 256 sectors");
1646 if(edmadisable(d, 0) == -1) {
1648 error("can't disable edma");
1650 n = satawait(&e->cmdstat, ATAdrdy|ATAbusy, ATAdrdy, 3*1000);
1652 print("piocmd: notready %.2ux\n", e->cmdstat);
1654 return sdsetsense(r, SDcheck, 4, 8, 0);
1657 if(r->ataproto & P28){
1658 e->altstat = ATAeIEN;
1663 e->lba2 = c[Flba16];
1665 e->cmdstat = c[Fcmd];
1667 e->altstat = ATAeIEN;
1668 e->seccnt = c[Fsc8];
1671 e->lba0 = c[Flba24];
1673 e->lba1 = c[Flba32];
1675 e->lba1 = c[Flba40];
1676 e->lba2 = c[Flba16];
1678 e->cmdstat = c[Fcmd];
1682 if((r->ataproto & Pdatam) == Pnd)
1683 n = satawait(&e->cmdstat, ATAbusy, 0, 3*1000);
1685 n = satawait(&e->cmdstat, ATAbusy|ATAdrq, ATAdrq, 3*1000);
1686 if(n == 0 || e->cmdstat & ATAerr){
1691 for(; nsec > 0; nsec--)
1692 for (i = 0; i < u->secsize; i += 2) {
1693 n = satawait(&e->cmdstat, ATAbusy|ATAdrq, ATAdrq, 300);
1699 if(r->ataproto & Pout){
1700 n = (ushort)p[i + 1] << 8;
1715 return sdsetsense(r, SDcheck, 4, 8, 0);
1717 return sdsetsense(r, SDok, 0, 0, 0);
1721 * hack to allow udma mode to be set or unset
1722 * via direct ata command. it would be better
1723 * to move the assumptions about dma mode out
1724 * of some of the helper functions.
1732 if(c[Fcmd] == 0xef && c[Ffeat] == 0x03){
1740 fisreqchk(Sfis *f, SDreq *r)
1742 if((r->ataproto & Pprotom) == Ppkt)
1745 * handle oob requests;
1746 * restrict & sanitize commands
1750 if(r->cmd[0] == 0xf0){
1751 sigtofis(f, r->cmd);
1762 badf(SDreq *r, Drive*)
1764 print("badf %.2ux %2ux\n", r->cmd[2], r->ataproto);
1765 return sdsetsense(r, SDcheck, 2, 24, 0);
1769 ataio0(SDreq *r, Drive *d)
1771 int (*f)(SDreq*, Drive*);
1774 switch(r->ataproto & Pprotom){
1795 d = c->drive + u->subno;
1796 if((status = fisreqchk(d, r)) != SDnostatus)
1799 USED(udm); /* botch */
1807 switch(status = ataio0(r, d)){
1809 dprint("%s: status %d\n", dnam(d), status);
1812 dprint("%s: retry\n", dnam(d));
1815 sdsetsense(r, SDok, 0, 0, 0);
1820 return r->status = status;
1824 SDifc sdmv50xxifc = {
1825 "mv50xx", /* name */
1829 mv50enable, /* enable */
1830 mv50disable, /* disable */
1832 mv50verify, /* verify */
1833 mv50online, /* online */
1835 mv50rctl, /* rctl */
1836 mv50wctl, /* wctl */
1847 * The original driver on which this one is based came with the
1853 * This software is provided `as-is,' without any express or implied
1854 * warranty. In no event will the author be held liable for any damages
1855 * arising from the use of this software.
1857 * Permission is granted to anyone to use this software for any purpose,
1858 * including commercial applications, and to alter it and redistribute it
1859 * freely, subject to the following restrictions:
1861 * 1. The origin of this software must not be misrepresented; you must
1862 * not claim that you wrote the original software. If you use this
1863 * software in a product, an acknowledgment in the product documentation
1864 * would be appreciated but is not required.
1866 * 2. Altered source versions must be plainly marked as such, and must
1867 * not be misrepresented as being the original software.
1869 * 3. This notice may not be removed or altered from any source