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