1 /* 2 * Mylex MultiMaster (Buslogic BT-*) SCSI Host Adapter 3 * in both 24-bit and 32-bit mode. 4 * 24-bit mode works for Adaptec AHA-154xx series too. 5 * 6 * To do: 7 * allocate more Ccb's as needed, up to NMbox-1; 8 * add nmbox and nccb to Ctlr struct for the above; 9 * 64-bit LUN/explicit wide support necessary? 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 "ureg.h" 19 #include "../port/error.h" 20 21 #include "../port/sd.h" 22 23 #define K2BPA(va, tbdf) PADDR(va) 24 #define BPA2K(pa, tbdf) KADDR(pa) 25 26 extern SDifc sdmylexifc; 27 28 enum { /* registers */ 29 Rcontrol = 0x00, /* WO: control register */ 30 Rstatus = 0x00, /* RO: status register */ 31 Rcpr = 0x01, /* WO: command/parameter register */ 32 Rdatain = 0x01, /* RO: data-in register */ 33 Rinterrupt = 0x02, /* RO: interrupt register */ 34 }; 35 36 enum { /* Rcontrol */ 37 Rsbus = 0x10, /* SCSI Bus Reset */ 38 Rint = 0x20, /* Interrupt Reset */ 39 Rsoft = 0x40, /* Soft Reset */ 40 Rhard = 0x80, /* Hard Reset */ 41 }; 42 43 enum { /* Rstatus */ 44 Cmdinv = 0x01, /* Command Invalid */ 45 Dirrdy = 0x04, /* Data In Register Ready */ 46 Cprbsy = 0x08, /* Command/Parameter Register Busy */ 47 Hardy = 0x10, /* Host Adapter Ready */ 48 Inreq = 0x20, /* Initialisation Required */ 49 Dfail = 0x40, /* Diagnostic Failure */ 50 Dact = 0x80, /* Diagnostic Active */ 51 }; 52 53 enum { /* Rcpr */ 54 Cinitialise = 0x01, /* Initialise Mailbox */ 55 Cstart = 0x02, /* Start Mailbox Command */ 56 Cinquiry = 0x04, /* Adapter Inquiry */ 57 Ceombri = 0x05, /* Enable OMBR Interrupt */ 58 Cinquire = 0x0B, /* Inquire Configuration */ 59 Cextbios = 0x28, /* AHA-1542: extended BIOS info. */ 60 Cmbienable = 0x29, /* AHA-1542: Mailbox interface enable */ 61 Ciem = 0x81, /* Initialise Extended Mailbox */ 62 Ciesi = 0x8D, /* Inquire Extended Setup Information */ 63 Cerrm = 0x8F, /* Enable strict round-robin mode */ 64 Cwide = 0x96, /* Wide CCB */ 65 }; 66 67 enum { /* Rinterrupt */ 68 Imbl = 0x01, /* Incoming Mailbox Loaded */ 69 Mbor = 0x02, /* Mailbox Out Ready */ 70 Cmdc = 0x04, /* Command Complete */ 71 Rsts = 0x08, /* SCSI Reset State */ 72 Intv = 0x80, /* Interrupt Valid */ 73 }; 74 75 typedef struct Mbox24 Mbox24; 76 struct Mbox24 { 77 uchar code; /* action/completion code */ 78 uchar ccb[3]; /* CCB pointer (MSB, ..., LSB) */ 79 }; 80 81 typedef struct Mbox32 Mbox32; 82 struct Mbox32 { 83 uchar ccb[4]; /* CCB pointer (LSB, ..., MSB) */ 84 uchar btstat; /* BT-7[45]7[SD] status */ 85 uchar sdstat; /* SCSI device status */ 86 uchar pad; 87 uchar code; /* action/completion code */ 88 }; 89 90 enum { /* mailbox commands */ 91 Mbfree = 0x00, /* Mailbox not in use */ 92 93 Mbostart = 0x01, /* Start a mailbox command */ 94 Mboabort = 0x02, /* Abort a mailbox command */ 95 96 Mbiok = 0x01, /* CCB completed without error */ 97 Mbiabort = 0x02, /* CCB aborted at request of host */ 98 Mbinx = 0x03, /* Aborted CCB not found */ 99 Mbierror = 0x04, /* CCB completed with error */ 100 }; 101 102 typedef struct Ccb24 Ccb24; 103 typedef struct Ccb32 Ccb32; 104 typedef union Ccb Ccb; 105 106 typedef struct Ccb24 { 107 uchar opcode; /* Operation code */ 108 uchar datadir; /* Data direction control */ 109 uchar cdblen; /* Length of CDB */ 110 uchar senselen; /* Length of sense area */ 111 uchar datalen[3]; /* Data length (MSB, ..., LSB) */ 112 uchar dataptr[3]; /* Data pointer (MSB, ..., LSB) */ 113 uchar linkptr[3]; /* Link pointer (MSB, ..., LSB) */ 114 uchar linkid; /* command linking identifier */ 115 uchar btstat; /* BT-* adapter status */ 116 uchar sdstat; /* SCSI device status */ 117 uchar reserved[2]; /* */ 118 uchar cs[12+0xFF]; /* Command descriptor block + Sense */ 119 120 void* data; /* buffer if address > 24-bits */ 121 122 Rendez; 123 int done; /* command completed */ 124 125 Ccb* ccb; /* link on free list */ 126 } Ccb24; 127 128 129 typedef struct Ccb32 { 130 uchar opcode; /* Operation code */ 131 uchar datadir; /* Data direction control */ 132 uchar cdblen; /* Length of CDB */ 133 uchar senselen; /* Length of sense area */ 134 uchar datalen[4]; /* Data length (LSB, ..., MSB) */ 135 uchar dataptr[4]; /* Data pointer (LSB, ..., MSB) */ 136 uchar reserved[2]; 137 uchar btstat; /* BT-* adapter status */ 138 uchar sdstat; /* SCSI device status */ 139 uchar targetid; /* Target ID */ 140 uchar luntag; /* LUN & tag */ 141 uchar cdb[12]; /* Command descriptor block */ 142 uchar ccbctl; /* CCB control */ 143 uchar linkid; /* command linking identifier */ 144 uchar linkptr[4]; /* Link pointer (LSB, ..., MSB) */ 145 uchar senseptr[4]; /* Sense pointer (LSB, ..., MSB) */ 146 uchar sense[0xFF]; /* Sense bytes */ 147 148 Rendez; 149 int done; /* command completed */ 150 151 Ccb* ccb; /* link on free list */ 152 } Ccb32; 153 154 typedef union Ccb { 155 Ccb24; 156 Ccb32; 157 } Ccb; 158 159 enum { /* opcode */ 160 OInitiator = 0x00, /* initiator CCB */ 161 Ordl = 0x03, /* initiator CCB with 162 * residual data length returned 163 */ 164 }; 165 166 enum { /* datadir */ 167 CCBdatain = 0x08, /* inbound, length is checked */ 168 CCBdataout = 0x10, /* outbound, length is checked */ 169 }; 170 171 enum { /* btstat */ 172 Eok = 0x00, /* normal completion with no errors */ 173 }; 174 175 enum { /* luntag */ 176 TagEnable = 0x20, /* Tag enable */ 177 SQTag = 0x00, /* Simple Queue Tag */ 178 HQTag = 0x40, /* Head of Queue Tag */ 179 OQTag = 0x80, /* Ordered Queue Tag */ 180 }; 181 182 enum { /* CCB control */ 183 NoDisc = 0x08, /* No disconnect */ 184 NoUnd = 0x10, /* No underrrun error report */ 185 NoData = 0x20, /* No data transfer */ 186 NoStat = 0x40, /* No CCB status if zero */ 187 NoIntr = 0x80, /* No Interrupts */ 188 }; 189 190 typedef struct Ctlr Ctlr; 191 struct Ctlr { 192 int port; /* I/O port */ 193 int id; /* adapter SCSI id */ 194 int bus; /* 24 or 32 -bit */ 195 int irq; 196 int wide; 197 Pcidev* pcidev; 198 SDev* sdev; 199 int spurious; 200 201 Lock issuelock; 202 203 Lock ccblock; 204 QLock ccbq; 205 Rendez ccbr; 206 207 Lock mboxlock; 208 void* mb; /* mailbox out + mailbox in */ 209 int mbox; /* current mailbox out index into mb */ 210 int mbix; /* current mailbox in index into mb */ 211 212 Lock cachelock; 213 Ccb* ccb; /* list of free Ccb's */ 214 Ccb** cache; /* last completed Ccb */ 215 }; 216 217 /* 218 * The number of mailboxes should be a multiple of 8 (4 for Mbox32) 219 * to ensure the boundary between the out and in mailboxes doesn't 220 * straddle a cache-line boundary. 221 * The number of Ccb's should be less than the number of mailboxes to 222 * ensure no queueing is necessary on mailbox allocation. 223 */ 224 enum { 225 NMbox = 8*8, /* number of Mbox's */ 226 NCcb = NMbox-1, /* number of Ccb's */ 227 }; 228 229 #define PADDR24(a, n) ((PADDR(a)+(n)) <= (1<<24)) 230 231 static void 232 ccbfree(Ctlr* ctlr, Ccb* ccb) 233 { 234 lock(&ctlr->ccblock); 235 if(ctlr->bus == 24) 236 ((Ccb24*)ccb)->ccb = ctlr->ccb; 237 else 238 ((Ccb32*)ccb)->ccb = ctlr->ccb; 239 if(ctlr->ccb == nil) 240 wakeup(&ctlr->ccbr); 241 ctlr->ccb = ccb; 242 unlock(&ctlr->ccblock); 243 } 244 245 static int 246 ccbavailable(void* a) 247 { 248 return ((Ctlr*)a)->ccb != nil; 249 } 250 251 static Ccb* 252 ccballoc(Ctlr* ctlr) 253 { 254 Ccb *ccb; 255 256 for(;;){ 257 lock(&ctlr->ccblock); 258 if((ccb = ctlr->ccb) != nil){ 259 if(ctlr->bus == 24) 260 ctlr->ccb = ((Ccb24*)ccb)->ccb; 261 else 262 ctlr->ccb = ((Ccb32*)ccb)->ccb; 263 unlock(&ctlr->ccblock); 264 break; 265 } 266 267 unlock(&ctlr->ccblock); 268 qlock(&ctlr->ccbq); 269 if(waserror()){ 270 qunlock(&ctlr->ccbq); 271 continue; 272 } 273 sleep(&ctlr->ccbr, ccbavailable, ctlr); 274 qunlock(&ctlr->ccbq); 275 poperror(); 276 } 277 278 return ccb; 279 } 280 281 static int 282 done24(void* arg) 283 { 284 return ((Ccb24*)arg)->done; 285 } 286 287 static int 288 mylex24rio(SDreq* r) 289 { 290 ulong p; 291 Ctlr *ctlr; 292 Ccb24 *ccb; 293 Mbox24 *mb; 294 uchar *data, lun, *sense; 295 int d, n, btstat, sdstat, target; 296 297 ctlr = r->unit->dev->ctlr; 298 target = r->unit->subno; 299 lun = (r->cmd[1]>>5) & 0x07; 300 301 /* 302 * Ctlr->cache holds the last completed Ccb for this target if it 303 * returned 'check condition'. 304 * If this command is a request-sense and there is valid sense data 305 * from the last completed Ccb, return it immediately. 306 */ 307 lock(&ctlr->cachelock); 308 if((ccb = ctlr->cache[target]) != nil){ 309 ctlr->cache[target] = nil; 310 if(r->cmd[0] == 0x03 311 && ccb->sdstat == SDcheck && lun == ((ccb->cs[1]>>5) & 0x07)){ 312 unlock(&ctlr->cachelock); 313 if(r->dlen){ 314 sense = &ccb->cs[ccb->cdblen]; 315 n = 8+sense[7]; 316 if(n > r->dlen) 317 n = r->dlen; 318 memmove(r->data, sense, n); 319 r->rlen = n; 320 } 321 ccbfree(ctlr, (Ccb*)ccb); 322 return SDok; 323 } 324 } 325 unlock(&ctlr->cachelock); 326 if(ccb == nil) 327 ccb = ccballoc(ctlr); 328 329 /* 330 * Check if the transfer is to memory above the 24-bit limit the 331 * controller can address. If it is, try to allocate a temporary 332 * buffer as a staging area. 333 */ 334 n = r->dlen; 335 if(n && !PADDR24(r->data, n)){ 336 data = mallocz(n, 0); 337 if(data == nil || !PADDR24(data, n)){ 338 if(data != nil){ 339 free(data); 340 ccb->data = nil; 341 } 342 ccbfree(ctlr, (Ccb*)ccb); 343 return SDmalloc; 344 } 345 if(r->write) 346 memmove(data, r->data, n); 347 ccb->data = r->data; 348 } 349 else 350 data = r->data; 351 352 /* 353 * Fill in the ccb. 354 */ 355 ccb->opcode = Ordl; 356 357 ccb->datadir = (target<<5)|lun; 358 if(n == 0) 359 ccb->datadir |= CCBdataout|CCBdatain; 360 else if(!r->write) 361 ccb->datadir |= CCBdatain; 362 else 363 ccb->datadir |= CCBdataout; 364 365 ccb->cdblen = r->clen; 366 ccb->senselen = 0xFF; 367 368 ccb->datalen[0] = n>>16; 369 ccb->datalen[1] = n>>8; 370 ccb->datalen[2] = n; 371 if(data == nil) 372 p = 0; 373 else 374 p = PADDR(data); 375 ccb->dataptr[0] = p>>16; 376 ccb->dataptr[1] = p>>8; 377 ccb->dataptr[2] = p; 378 379 ccb->linkptr[0] = ccb->linkptr[1] = ccb->linkptr[2] = 0; 380 ccb->linkid = 0; 381 ccb->btstat = ccb->sdstat = 0; 382 ccb->reserved[0] = ccb->reserved[1] = 0; 383 384 memmove(ccb->cs, r->cmd, r->clen); 385 386 /* 387 * There's one more mbox than there there is 388 * ccb so there is always one free. 389 */ 390 lock(&ctlr->mboxlock); 391 mb = ctlr->mb; 392 mb += ctlr->mbox; 393 p = PADDR(ccb); 394 mb->ccb[0] = p>>16; 395 mb->ccb[1] = p>>8; 396 mb->ccb[2] = p; 397 mb->code = Mbostart; 398 ctlr->mbox++; 399 if(ctlr->mbox >= NMbox) 400 ctlr->mbox = 0; 401 402 /* 403 * This command does not require Hardy 404 * and doesn't generate a Cmdc interrupt. 405 */ 406 ccb->done = 0; 407 outb(ctlr->port+Rcpr, Cstart); 408 unlock(&ctlr->mboxlock); 409 410 /* 411 * Wait for the request to complete and return the status. 412 * Since the buffer is not reference counted cannot return 413 * until the DMA is done writing into the buffer so the caller 414 * cannot free the buffer prematurely. 415 */ 416 while(waserror()) 417 ; 418 sleep(ccb, done24, ccb); 419 poperror(); 420 421 /* 422 * Save the status and patch up the number of 423 * bytes actually transferred. 424 * There's a firmware bug on some 956C controllers 425 * which causes the return count from a successful 426 * READ CAPACITY not be updated, so fix it here. 427 */ 428 sdstat = ccb->sdstat; 429 btstat = ccb->btstat; 430 431 d = ccb->datalen[0]<<16; 432 d |= ccb->datalen[1]<<8; 433 d |= ccb->datalen[2]; 434 if(ccb->cs[0] == 0x25 && sdstat == SDok) 435 d = 0; 436 n -= d; 437 r->rlen = n; 438 439 /* 440 * Tidy things up if a staging area was used for the data, 441 */ 442 if(ccb->data != nil){ 443 if(sdstat == SDok && btstat == 0 && !r->write) 444 memmove(ccb->data, data, n); 445 free(data); 446 ccb->data = nil; 447 } 448 449 /* 450 * If there was a check-condition, save the 451 * ccb for a possible request-sense command. 452 */ 453 if(sdstat == SDcheck){ 454 if(r->flags & SDnosense){ 455 lock(&ctlr->cachelock); 456 if(ctlr->cache[target]) 457 ccbfree(ctlr, ctlr->cache[target]); 458 ctlr->cache[target] = (Ccb*)ccb; 459 unlock(&ctlr->cachelock); 460 return SDcheck; 461 } 462 sense = &ccb->cs[ccb->cdblen]; 463 n = 8+sense[7]; 464 if(n > sizeof(r->sense)-1) 465 n = sizeof(r->sense)-1; 466 memmove(r->sense, sense, n); 467 r->flags |= SDvalidsense; 468 } 469 ccbfree(ctlr, (Ccb*)ccb); 470 471 if(btstat){ 472 if(btstat == 0x11) 473 return SDtimeout; 474 return SDeio; 475 } 476 return sdstat; 477 } 478 479 static void 480 mylex24interrupt(Ureg*, void* arg) 481 { 482 ulong pa; 483 Ctlr *ctlr; 484 Ccb24 *ccb; 485 Mbox24 *mb, *mbox; 486 int port, rinterrupt, rstatus; 487 488 ctlr = arg; 489 port = ctlr->port; 490 491 /* 492 * Save and clear the interrupt(s). The only 493 * interrupts expected are Cmdc, which is ignored, 494 * and Imbl which means something completed. 495 * There's one spurious interrupt left over from 496 * initialisation, ignore it. 497 */ 498 rinterrupt = inb(port+Rinterrupt); 499 rstatus = inb(port+Rstatus); 500 outb(port+Rcontrol, Rint); 501 if((rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++) 502 print("%s: interrupt 0x%2.2ux\n", 503 ctlr->sdev->name, rinterrupt); 504 if((rinterrupt & Cmdc) && (rstatus & Cmdinv)) 505 print("%s: command invalid\n", ctlr->sdev->name); 506 507 /* 508 * Look for something in the mail. 509 * If there is, save the status, free the mailbox 510 * and wakeup whoever. 511 */ 512 mb = ctlr->mb; 513 for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){ 514 pa = (mbox->ccb[0]<<16)|(mbox->ccb[1]<<8)|mbox->ccb[2]; 515 ccb = BPA2K(pa, BUSUNKNOWN); 516 mbox->code = 0; 517 ccb->done = 1; 518 wakeup(ccb); 519 520 ctlr->mbix++; 521 if(ctlr->mbix >= NMbox+NMbox) 522 ctlr->mbix = NMbox; 523 } 524 } 525 526 static int 527 done32(void* arg) 528 { 529 return ((Ccb32*)arg)->done; 530 } 531 532 static int 533 mylex32rio(SDreq* r) 534 { 535 ulong p; 536 uchar lun; 537 Ctlr *ctlr; 538 Ccb32 *ccb; 539 Mbox32 *mb; 540 int d, n, btstat, sdstat, target; 541 542 ctlr = r->unit->dev->ctlr; 543 target = r->unit->subno; 544 lun = (r->cmd[1]>>5) & 0x07; 545 546 /* 547 * Ctlr->cache holds the last completed Ccb for this target if it 548 * returned 'check condition'. 549 * If this command is a request-sense and there is valid sense data 550 * from the last completed Ccb, return it immediately. 551 */ 552 lock(&ctlr->cachelock); 553 if((ccb = ctlr->cache[target]) != nil){ 554 ctlr->cache[target] = nil; 555 if(r->cmd[0] == 0x03 556 && ccb->sdstat == SDcheck && lun == (ccb->luntag & 0x07)){ 557 unlock(&ctlr->cachelock); 558 if(r->dlen){ 559 n = 8+ccb->sense[7]; 560 if(n > r->dlen) 561 n = r->dlen; 562 memmove(r->data, ccb->sense, n); 563 r->rlen = n; 564 } 565 ccbfree(ctlr, (Ccb*)ccb); 566 return SDok; 567 } 568 } 569 unlock(&ctlr->cachelock); 570 if(ccb == nil) 571 ccb = ccballoc(ctlr); 572 573 /* 574 * Fill in the ccb. 575 */ 576 ccb->opcode = Ordl; 577 578 n = r->dlen; 579 if(n == 0) 580 ccb->datadir = CCBdataout|CCBdatain; 581 else if(!r->write) 582 ccb->datadir = CCBdatain; 583 else 584 ccb->datadir = CCBdataout; 585 586 ccb->cdblen = r->clen; 587 588 ccb->datalen[0] = n; 589 ccb->datalen[1] = n>>8; 590 ccb->datalen[2] = n>>16; 591 ccb->datalen[3] = n>>24; 592 if(r->data == nil) 593 p = 0; 594 else 595 p = PADDR(r->data); 596 ccb->dataptr[0] = p; 597 ccb->dataptr[1] = p>>8; 598 ccb->dataptr[2] = p>>16; 599 ccb->dataptr[3] = p>>24; 600 601 ccb->targetid = target; 602 ccb->luntag = lun; 603 if(r->unit->inquiry[7] & 0x02) 604 if(ctlr->wide) 605 ccb->datadir |= SQTag|TagEnable; 606 else 607 ccb->luntag |= SQTag|TagEnable; 608 memmove(ccb->cdb, r->cmd, r->clen); 609 ccb->btstat = ccb->sdstat = 0; 610 ccb->ccbctl = 0; 611 612 /* 613 * There's one more mbox than there there is 614 * ccb so there is always one free. 615 */ 616 lock(&ctlr->mboxlock); 617 mb = ctlr->mb; 618 mb += ctlr->mbox; 619 p = PADDR(ccb); 620 mb->ccb[0] = p; 621 mb->ccb[1] = p>>8; 622 mb->ccb[2] = p>>16; 623 mb->ccb[3] = p>>24; 624 mb->code = Mbostart; 625 ctlr->mbox++; 626 if(ctlr->mbox >= NMbox) 627 ctlr->mbox = 0; 628 629 /* 630 * This command does not require Hardy 631 * and doesn't generate a Cmdc interrupt. 632 */ 633 ccb->done = 0; 634 outb(ctlr->port+Rcpr, Cstart); 635 unlock(&ctlr->mboxlock); 636 637 /* 638 * Wait for the request to complete and return the status. 639 * Since the buffer is not reference counted cannot return 640 * until the DMA is done writing into the buffer so the caller 641 * cannot free the buffer prematurely. 642 */ 643 while(waserror()) 644 ; 645 sleep(ccb, done32, ccb); 646 poperror(); 647 648 /* 649 * Save the status and patch up the number of 650 * bytes actually transferred. 651 * There's a firmware bug on some 956C controllers 652 * which causes the return count from a successful 653 * READ CAPACITY not to be updated, so fix it here. 654 */ 655 sdstat = ccb->sdstat; 656 btstat = ccb->btstat; 657 658 d = ccb->datalen[0]; 659 d |= (ccb->datalen[1]<<8); 660 d |= (ccb->datalen[2]<<16); 661 d |= (ccb->datalen[3]<<24); 662 if(ccb->cdb[0] == 0x25 && sdstat == SDok) 663 d = 0; 664 n -= d; 665 r->rlen = n; 666 667 /* 668 * If there was a check-condition, save the 669 * ccb for a possible request-sense command. 670 */ 671 if(sdstat == SDcheck){ 672 if(r->flags & SDnosense){ 673 lock(&ctlr->cachelock); 674 if(ctlr->cache[target]) 675 ccbfree(ctlr, ctlr->cache[target]); 676 ctlr->cache[target] = (Ccb*)ccb; 677 unlock(&ctlr->cachelock); 678 return SDcheck; 679 } 680 n = 8+ccb->sense[7]; 681 if(n > sizeof(r->sense)-1) 682 n = sizeof(r->sense)-1; 683 memmove(r->sense, ccb->sense, n); 684 r->flags |= SDvalidsense; 685 } 686 ccbfree(ctlr, (Ccb*)ccb); 687 688 if(btstat){ 689 if(btstat == 0x11) 690 return SDtimeout; 691 return SDeio; 692 } 693 return sdstat; 694 } 695 696 static void 697 mylex32interrupt(Ureg*, void* arg) 698 { 699 ulong pa; 700 Ctlr *ctlr; 701 Ccb32 *ccb; 702 Mbox32 *mb, *mbox; 703 int port, rinterrupt, rstatus; 704 705 ctlr = arg; 706 port = ctlr->port; 707 708 /* 709 * Save and clear the interrupt(s). The only 710 * interrupts expected are Cmdc, which is ignored, 711 * and Imbl which means something completed. 712 * There's one spurious interrupt left over from 713 * initialisation, ignore it. 714 * In order to share PCI IRQs, just ignore spurious interrupts. 715 */ 716 rinterrupt = inb(port+Rinterrupt); 717 rstatus = inb(port+Rstatus); 718 outb(port+Rcontrol, Rint); 719 if(0 && (rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++) 720 print("%s: interrupt 0x%2.2ux\n", 721 ctlr->sdev->name, rinterrupt); 722 if((rinterrupt & Cmdc) && (rstatus & Cmdinv)) 723 print("%s: command invalid\n", ctlr->sdev->name); 724 725 /* 726 * Look for something in the mail. 727 * If there is, free the mailbox and wakeup whoever. 728 */ 729 mb = ctlr->mb; 730 for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){ 731 pa = (mbox->ccb[3]<<24) 732 |(mbox->ccb[2]<<16) 733 |(mbox->ccb[1]<<8) 734 |mbox->ccb[0]; 735 if(ctlr->pcidev) 736 ccb = BPA2K(pa, ctlr->pcidev->tbdf); 737 else 738 ccb = BPA2K(pa, BUSUNKNOWN); 739 mbox->code = 0; 740 ccb->done = 1; 741 wakeup(ccb); 742 743 ctlr->mbix++; 744 if(ctlr->mbix >= NMbox+NMbox) 745 ctlr->mbix = NMbox; 746 } 747 } 748 749 static int 750 mylexrio(SDreq* r) 751 { 752 int subno; 753 Ctlr *ctlr; 754 755 subno = r->unit->subno; 756 ctlr = r->unit->dev->ctlr; 757 if(subno == ctlr->id || (!ctlr->wide && subno >= 8)) 758 r->status = SDtimeout; 759 else if(ctlr->bus == 24) 760 r->status = mylex24rio(r); 761 else 762 r->status = mylex32rio(r); 763 return r->status; 764 } 765 766 /* 767 * Issue a command to a controller. The command and its length is 768 * contained in cmd and cmdlen. If any data is to be 769 * returned, datalen should be non-zero, and the returned data 770 * will be placed in data. 771 * If Cmdc is set, bail out, the invalid command will be handled 772 * when the interrupt is processed. 773 */ 774 static void 775 issueio(int port, uchar* cmd, int cmdlen, uchar* data, int datalen) 776 { 777 int len; 778 779 if(cmd[0] != Cstart && cmd[0] != Ceombri){ 780 while(!(inb(port+Rstatus) & Hardy)) 781 ; 782 } 783 outb(port+Rcpr, cmd[0]); 784 785 len = 1; 786 while(len < cmdlen){ 787 if(!(inb(port+Rstatus) & Cprbsy)){ 788 outb(port+Rcpr, cmd[len]); 789 len++; 790 } 791 if(inb(port+Rinterrupt) & Cmdc) 792 return; 793 } 794 795 if(datalen){ 796 len = 0; 797 while(len < datalen){ 798 if(inb(port+Rstatus) & Dirrdy){ 799 data[len] = inb(port+Rdatain); 800 len++; 801 } 802 if(inb(port+Rinterrupt) & Cmdc) 803 return; 804 } 805 } 806 } 807 808 /* 809 * Issue a command to a controller, wait for it to complete then 810 * try to reset the interrupt. Should only be called at initialisation. 811 */ 812 static int 813 issue(Ctlr* ctlr, uchar* cmd, int cmdlen, uchar* data, int datalen) 814 { 815 int port; 816 uchar rinterrupt, rstatus; 817 static Lock mylexissuelock; 818 819 port = ctlr->port; 820 821 ilock(&ctlr->issuelock); 822 issueio(port, cmd, cmdlen, data, datalen); 823 824 while(!((rinterrupt = inb(port+Rinterrupt)) & Cmdc)) 825 ; 826 827 rstatus = inb(port+Rstatus); 828 outb(port+Rcontrol, Rint); 829 iunlock(&ctlr->issuelock); 830 831 if((rinterrupt & Cmdc) && (rstatus & Cmdinv)) 832 return 0; 833 return 1; 834 } 835 836 static SDev* 837 mylexprobe(int port, int irq) 838 { 839 SDev *sdev; 840 Ctlr *ctlr; 841 uchar cmd[6], data[256]; 842 int clen, dlen, timeo; 843 static int count; 844 845 if(ioalloc(port, 0x3, 0, "mylex") < 0) 846 return nil; 847 ctlr = nil; 848 sdev = nil; 849 /* 850 * Attempt to hard-reset the board and reset 851 * the SCSI bus. If the board state doesn't settle to 852 * idle with mailbox initialisation required, either 853 * it isn't a compatible board or it's broken. 854 * If the controller has SCAM set this can take a while. 855 */ 856 if(getconf("*noscsireset") != nil) 857 outb(port+Rcontrol, Rhard); 858 else 859 outb(port+Rcontrol, Rhard|Rsbus); 860 for(timeo = 0; timeo < 100; timeo++){ 861 if(inb(port+Rstatus) == (Inreq|Hardy)) 862 break; 863 delay(100); 864 } 865 if(inb(port+Rstatus) != (Inreq|Hardy)){ 866 buggery: 867 if(ctlr != nil) 868 free(ctlr); 869 if (sdev != nil) 870 free(sdev); 871 iofree(port); 872 return nil; 873 } 874 875 if((ctlr = malloc(sizeof(Ctlr))) == nil) 876 goto buggery; 877 ctlr->port = port; 878 ctlr->irq = irq; 879 ctlr->bus = 24; 880 ctlr->wide = 0; 881 882 /* 883 * Try to determine if this is a 32-bit MultiMaster controller 884 * by attempting to obtain the extended inquiry information; 885 * this command is not implemented on Adaptec 154xx 886 * controllers. If successful, the first byte of the returned 887 * data is the host adapter bus type, 'E' for 32-bit EISA, 888 * PCI and VLB buses. 889 */ 890 cmd[0] = Ciesi; 891 cmd[1] = 14; 892 clen = 2; 893 dlen = 256; 894 if(issue(ctlr, cmd, clen, data, dlen)){ 895 if(data[0] == 'E') 896 ctlr->bus = 32; 897 ctlr->wide = data[0x0D] & 0x01; 898 /* 899 * devsd doesn't pass us the `spec' argument, so 900 * we'll assume that sd0 goes to the first scsi host 901 * adapter found, etc. 902 */ 903 print("#S/sd%d: mylex SCSI: port 0x%ux: %d-bit, ", 904 count++, ctlr->port, ctlr->bus); 905 if (ctlr->wide) 906 print("wide\n"); 907 else 908 print("narrow\n"); 909 } 910 else{ 911 /* 912 * Inconceivable though it may seem, a hard controller reset 913 * is necessary here to clear out the command queue. Every 914 * board seems to lock-up in a different way if you give an 915 * invalid command and then try to clear out the 916 * command/parameter and/or data-in register. 917 * Soft reset doesn't do the job either. Fortunately no 918 * serious initialisation has been done yet so there's nothing 919 * to tidy up. 920 */ 921 outb(port+Rcontrol, Rhard); 922 for(timeo = 0; timeo < 100; timeo++){ 923 if(inb(port+Rstatus) == (Inreq|Hardy)) 924 break; 925 delay(100); 926 } 927 if(inb(port+Rstatus) != (Inreq|Hardy)) 928 goto buggery; 929 } 930 931 /* 932 * If the BIOS is enabled on the AHA-1542C/CF and BIOS options for 933 * support of drives > 1Gb, dynamic scanning of the SCSI bus or more 934 * than 2 drives under DOS 5.0 are enabled, the BIOS disables 935 * accepting Cmbinit to protect against running with drivers which 936 * don't support those options. In order to unlock the interface it 937 * is necessary to read a lock-code using Cextbios and write it back 938 * using Cmbienable; the lock-code is non-zero. 939 */ 940 cmd[0] = Cinquiry; 941 clen = 1; 942 dlen = 4; 943 if(issue(ctlr, cmd, clen, data, dlen) == 0) 944 goto buggery; 945 if(data[0] >= 0x43){ 946 cmd[0] = Cextbios; 947 clen = 1; 948 dlen = 2; 949 if(issue(ctlr, cmd, clen, data, dlen) == 0) 950 goto buggery; 951 952 /* 953 * Lock-code returned in data[1]. If it's non-zero write 954 * it back along with bit 0 of byte 0 cleared to enable 955 * mailbox initialisation. 956 */ 957 if(data[1]){ 958 cmd[0] = Cmbienable; 959 cmd[1] = 0; 960 cmd[2] = data[1]; 961 clen = 3; 962 if(issue(ctlr, cmd, clen, 0, 0) == 0) 963 goto buggery; 964 } 965 } 966 967 /* 968 * Get the id, DMA and IRQ info from the board. This will 969 * cause an interrupt which will hopefully not cause any 970 * trouble because the interrupt number isn't known yet. 971 * This is necessary as the DMA won't be set up if the 972 * board has the BIOS disabled. 973 * 974 * If the IRQ is already known, this must be a 32-bit PCI 975 * or EISA card, in which case the returned DMA and IRQ can 976 * be ignored. 977 */ 978 cmd[0] = Cinquire; 979 clen = 1; 980 dlen = 3; 981 if(issue(ctlr, cmd, clen, data, dlen) == 0) 982 goto buggery; 983 984 ctlr->id = data[2] & 0x07; 985 if(ctlr->irq < 0){ 986 switch(data[0]){ /* DMA Arbitration Priority */ 987 case 0x80: /* Channel 7 */ 988 outb(0xD6, 0xC3); 989 outb(0xD4, 0x03); 990 break; 991 case 0x40: /* Channel 6 */ 992 outb(0xD6, 0xC2); 993 outb(0xD4, 0x02); 994 break; 995 case 0x20: /* Channel 5 */ 996 outb(0xD6, 0xC1); 997 outb(0xD4, 0x01); 998 break; 999 case 0x01: /* Channel 0 */ 1000 outb(0x0B, 0xC0); 1001 outb(0x0A, 0x00); 1002 break; 1003 default: 1004 if(ctlr->bus == 24) 1005 goto buggery; 1006 break; 1007 } 1008 1009 switch(data[1]){ /* Interrupt Channel */ 1010 case 0x40: 1011 ctlr->irq = 15; 1012 break; 1013 case 0x20: 1014 ctlr->irq = 14; 1015 break; 1016 case 0x08: 1017 ctlr->irq = 12; 1018 break; 1019 case 0x04: 1020 ctlr->irq = 11; 1021 break; 1022 case 0x02: 1023 ctlr->irq = 10; 1024 break; 1025 case 0x01: 1026 ctlr->irq = 9; 1027 break; 1028 default: 1029 goto buggery; 1030 } 1031 } 1032 1033 if((sdev = malloc(sizeof(SDev))) == nil) 1034 goto buggery; 1035 sdev->ifc = &sdmylexifc; 1036 sdev->ctlr = ctlr; 1037 sdev->idno = '0'; 1038 ctlr->sdev = sdev; 1039 if(!ctlr->wide) 1040 sdev->nunit = 8; 1041 else 1042 sdev->nunit = 16; 1043 1044 return sdev; 1045 } 1046 1047 static int mylexport[8] = { 1048 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0x000, 0x000, 1049 }; 1050 1051 static SDev* 1052 mylexpnp(void) 1053 { 1054 Pcidev *p; 1055 Ctlr *ctlr; 1056 ISAConf isa; 1057 int cfg, ctlrno, i, x; 1058 SDev *sdev, *head, *tail; 1059 1060 p = nil; 1061 head = tail = nil; 1062 while(p = pcimatch(p, 0x104B, 0)){ 1063 if((sdev = mylexprobe(p->mem[0].bar & ~0x01, p->intl)) == nil) 1064 continue; 1065 1066 ctlr = sdev->ctlr; 1067 ctlr->pcidev = p; 1068 1069 if(head != nil) 1070 tail->next = sdev; 1071 else 1072 head = sdev; 1073 tail = sdev; 1074 } 1075 1076 if(strncmp(KADDR(0xFFFD9), "EISA", 4) == 0){ 1077 for(cfg = 0x1000; cfg < MaxEISA*0x1000; cfg += 0x1000){ 1078 x = 0; 1079 for(i = 0; i < 4; i++) 1080 x |= inb(cfg+CfgEISA+i)<<(i*8); 1081 if(x != 0x0142B30A && x != 0x0242B30A) 1082 continue; 1083 1084 x = inb(cfg+0xC8C); 1085 if((sdev = mylexprobe(mylexport[x & 0x07], -1)) == nil) 1086 continue; 1087 1088 if(head != nil) 1089 tail->next = sdev; 1090 else 1091 head = sdev; 1092 tail = sdev; 1093 } 1094 } 1095 1096 for(ctlrno = 0; ctlrno < 4; ctlrno++){ 1097 memset(&isa, 0, sizeof(isa)); 1098 if(!isaconfig("scsi", ctlrno, &isa)) 1099 continue; 1100 if(strcmp(isa.type, "aha1542")) 1101 continue; 1102 if((sdev = mylexprobe(isa.port, -1)) == nil) 1103 continue; 1104 1105 if(head != nil) 1106 tail->next = sdev; 1107 else 1108 head = sdev; 1109 tail = sdev; 1110 } 1111 1112 return head; 1113 } 1114 1115 static int 1116 mylex24enable(Ctlr* ctlr) 1117 { 1118 ulong p; 1119 Ccb24 *ccb, *ccbp; 1120 uchar cmd[6], *v; 1121 int len; 1122 1123 len = (sizeof(Mbox24)*NMbox*2)+(sizeof(Ccb24)*NCcb); 1124 v = xspanalloc(len, 32, 0); 1125 1126 if(!PADDR24(ctlr, sizeof(Ctlr)) || !PADDR24(v, len)) 1127 return 0; 1128 1129 ctlr->mb = v; 1130 v += sizeof(Mbox24)*NMbox*2; 1131 1132 ccb = (Ccb24*)v; 1133 for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){ 1134 ccbp->ccb = ctlr->ccb; 1135 ctlr->ccb = (Ccb*)ccbp; 1136 } 1137 1138 /* 1139 * Initialise the software controller and 1140 * set the board scanning the mailboxes. 1141 */ 1142 ctlr->mbix = NMbox; 1143 1144 cmd[0] = Cinitialise; 1145 cmd[1] = NMbox; 1146 p = K2BPA(ctlr->mb, BUSUNKNOWN); 1147 cmd[2] = p>>16; 1148 cmd[3] = p>>8; 1149 cmd[4] = p; 1150 1151 return issue(ctlr, cmd, 5, 0, 0); 1152 } 1153 1154 static int 1155 mylex32enable(Ctlr* ctlr) 1156 { 1157 ulong p; 1158 Ccb32 *ccb, *ccbp; 1159 uchar cmd[6], *v; 1160 1161 v = xspanalloc((sizeof(Mbox32)*NMbox*2)+(sizeof(Ccb32)*NCcb), 32, 0); 1162 1163 ctlr->mb = v; 1164 v += sizeof(Mbox32)*NMbox*2; 1165 1166 ccb = (Ccb32*)v; 1167 for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){ 1168 /* 1169 * Fill in some stuff that doesn't change. 1170 */ 1171 ccbp->senselen = sizeof(ccbp->sense); 1172 p = PADDR(ccbp->sense); 1173 ccbp->senseptr[0] = p; 1174 ccbp->senseptr[1] = p>>8; 1175 ccbp->senseptr[2] = p>>16; 1176 ccbp->senseptr[3] = p>>24; 1177 1178 ccbp->ccb = ctlr->ccb; 1179 ctlr->ccb = (Ccb*)ccbp; 1180 } 1181 1182 /* 1183 * Attempt wide mode setup. 1184 */ 1185 if(ctlr->wide){ 1186 cmd[0] = Cwide; 1187 cmd[1] = 1; 1188 if(!issue(ctlr, cmd, 2, 0, 0)) { 1189 ctlr->wide = 0; 1190 print("mylex32enable: port 0x%ux: scsi wide-mode setup " 1191 "failed on wide host adapter", ctlr->port); 1192 } 1193 } 1194 1195 /* 1196 * Initialise the software controller and 1197 * set the board scanning the mailboxes. 1198 */ 1199 ctlr->mbix = NMbox; 1200 1201 cmd[0] = Ciem; 1202 cmd[1] = NMbox; 1203 if(ctlr->pcidev) 1204 p = K2BPA(ctlr->mb, ctlr->tbdf); 1205 else 1206 p = K2BPA(ctlr->mb, BUSUNKNOWN); 1207 cmd[2] = p; 1208 cmd[3] = p>>8; 1209 cmd[4] = p>>16; 1210 cmd[5] = p>>24; 1211 1212 return issue(ctlr, cmd, 6, 0, 0); 1213 } 1214 1215 static int 1216 mylexenable(SDev* sdev) 1217 { 1218 int tbdf; 1219 Ctlr *ctlr; 1220 void (*interrupt)(Ureg*, void*); 1221 char name[32]; 1222 1223 ctlr = sdev->ctlr; 1224 if(ctlr->cache == nil){ 1225 if((ctlr->cache = malloc(sdev->nunit*sizeof(Ccb*))) == nil) 1226 return 0; 1227 } 1228 1229 tbdf = BUSUNKNOWN; 1230 if(ctlr->bus == 32){ 1231 if(ctlr->pcidev){ 1232 tbdf = ctlr->pcidev->tbdf; 1233 pcisetbme(ctlr->pcidev); 1234 } 1235 if(!mylex32enable(ctlr)) 1236 return 0; 1237 interrupt = mylex32interrupt; 1238 } 1239 else if(mylex24enable(ctlr)) 1240 interrupt = mylex24interrupt; 1241 else 1242 return 0; 1243 1244 snprint(name, sizeof(name), "sd%c (%s)", sdev->idno, sdev->ifc->name); 1245 intrenable(ctlr->irq, interrupt, ctlr, tbdf, name); 1246 1247 return 1; 1248 } 1249 1250 SDifc sdmylexifc = { 1251 "mylex", /* name */ 1252 1253 mylexpnp, /* pnp */ 1254 nil, /* legacy */ 1255 mylexenable, /* enable */ 1256 nil, /* disable */ 1257 1258 scsiverify, /* verify */ 1259 scsionline, /* online */ 1260 mylexrio, /* rio */ 1261 nil, /* rctl */ 1262 nil, /* wctl */ 1263 1264 scsibio, /* bio */ 1265 nil, /* probe */ 1266 nil, /* clear */ 1267 nil, /* rtopctl */ 1268 nil, /* wtopctl */ 1269 }; 1270