1 /*----------------------------------------------------------------*/ 2 /* 3 Qlogic linux driver - work in progress. No Warranty express or implied. 4 Use at your own risk. Support Tort Reform so you won't have to read all 5 these silly disclaimers. 6 7 Copyright 1994, Tom Zerucha. 8 tz@execpc.com 9 10 Additional Code, and much appreciated help by 11 Michael A. Griffith 12 grif@cs.ucr.edu 13 14 Thanks to Eric Youngdale and Dave Hinds for loadable module and PCMCIA 15 help respectively, and for suffering through my foolishness during the 16 debugging process. 17 18 Reference Qlogic FAS408 Technical Manual, 53408-510-00A, May 10, 1994 19 (you can reference it, but it is incomplete and inaccurate in places) 20 21 Version 0.46 1/30/97 - kernel 1.2.0+ 22 23 Functions as standalone, loadable, and PCMCIA driver, the latter from 24 Dave Hinds' PCMCIA package. 25 26 Cleaned up 26/10/2002 by Alan Cox <alan@lxorguk.ukuu.org.uk> as part of the 2.5 27 SCSI driver cleanup and audit. This driver still needs work on the 28 following 29 - Non terminating hardware waits 30 - Some layering violations with its pcmcia stub 31 32 Redistributable under terms of the GNU General Public License 33 34 For the avoidance of doubt the "preferred form" of this code is one which 35 is in an open non patent encumbered format. Where cryptographic key signing 36 forms part of the process of creating an executable the information 37 including keys needed to generate an equivalently functional executable 38 are deemed to be part of the source code. 39 40 */ 41 42 #include <linux/module.h> 43 #include <linux/blkdev.h> /* to get disk capacity */ 44 #include <linux/kernel.h> 45 #include <linux/string.h> 46 #include <linux/init.h> 47 #include <linux/interrupt.h> 48 #include <linux/ioport.h> 49 #include <linux/proc_fs.h> 50 #include <linux/unistd.h> 51 #include <linux/spinlock.h> 52 #include <linux/stat.h> 53 54 #include <asm/io.h> 55 #include <asm/irq.h> 56 #include <asm/dma.h> 57 58 #include "scsi.h" 59 #include <scsi/scsi_host.h> 60 #include "qlogicfas408.h" 61 62 /*----------------------------------------------------------------*/ 63 static int qlcfg5 = (XTALFREQ << 5); /* 15625/512 */ 64 static int qlcfg6 = SYNCXFRPD; 65 static int qlcfg7 = SYNCOFFST; 66 static int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4); 67 static int qlcfg9 = ((XTALFREQ + 4) / 5); 68 static int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4); 69 70 /*----------------------------------------------------------------*/ 71 72 /*----------------------------------------------------------------*/ 73 /* local functions */ 74 /*----------------------------------------------------------------*/ 75 76 /* error recovery - reset everything */ 77 78 static void ql_zap(struct qlogicfas408_priv *priv) 79 { 80 int x; 81 int qbase = priv->qbase; 82 int int_type = priv->int_type; 83 84 x = inb(qbase + 0xd); 85 REG0; 86 outb(3, qbase + 3); /* reset SCSI */ 87 outb(2, qbase + 3); /* reset chip */ 88 if (x & 0x80) 89 REG1; 90 } 91 92 /* 93 * Do a pseudo-dma tranfer 94 */ 95 96 static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, 97 int reqlen) 98 { 99 int j; 100 int qbase = priv->qbase; 101 j = 0; 102 if (phase & 1) { /* in */ 103 #if QL_TURBO_PDMA 104 rtrc(4) 105 /* empty fifo in large chunks */ 106 if (reqlen >= 128 && (inb(qbase + 8) & 2)) { /* full */ 107 insl(qbase + 4, request, 32); 108 reqlen -= 128; 109 request += 128; 110 } 111 while (reqlen >= 84 && !(j & 0xc0)) /* 2/3 */ 112 if ((j = inb(qbase + 8)) & 4) 113 { 114 insl(qbase + 4, request, 21); 115 reqlen -= 84; 116 request += 84; 117 } 118 if (reqlen >= 44 && (inb(qbase + 8) & 8)) { /* 1/3 */ 119 insl(qbase + 4, request, 11); 120 reqlen -= 44; 121 request += 44; 122 } 123 #endif 124 /* until both empty and int (or until reclen is 0) */ 125 rtrc(7) 126 j = 0; 127 while (reqlen && !((j & 0x10) && (j & 0xc0))) 128 { 129 /* while bytes to receive and not empty */ 130 j &= 0xc0; 131 while (reqlen && !((j = inb(qbase + 8)) & 0x10)) 132 { 133 *request++ = inb(qbase + 4); 134 reqlen--; 135 } 136 if (j & 0x10) 137 j = inb(qbase + 8); 138 139 } 140 } else { /* out */ 141 #if QL_TURBO_PDMA 142 rtrc(4) 143 if (reqlen >= 128 && inb(qbase + 8) & 0x10) { /* empty */ 144 outsl(qbase + 4, request, 32); 145 reqlen -= 128; 146 request += 128; 147 } 148 while (reqlen >= 84 && !(j & 0xc0)) /* 1/3 */ 149 if (!((j = inb(qbase + 8)) & 8)) { 150 outsl(qbase + 4, request, 21); 151 reqlen -= 84; 152 request += 84; 153 } 154 if (reqlen >= 40 && !(inb(qbase + 8) & 4)) { /* 2/3 */ 155 outsl(qbase + 4, request, 10); 156 reqlen -= 40; 157 request += 40; 158 } 159 #endif 160 /* until full and int (or until reclen is 0) */ 161 rtrc(7) 162 j = 0; 163 while (reqlen && !((j & 2) && (j & 0xc0))) { 164 /* while bytes to send and not full */ 165 while (reqlen && !((j = inb(qbase + 8)) & 2)) 166 { 167 outb(*request++, qbase + 4); 168 reqlen--; 169 } 170 if (j & 2) 171 j = inb(qbase + 8); 172 } 173 } 174 /* maybe return reqlen */ 175 return inb(qbase + 8) & 0xc0; 176 } 177 178 /* 179 * Wait for interrupt flag (polled - not real hardware interrupt) 180 */ 181 182 static int ql_wai(struct qlogicfas408_priv *priv) 183 { 184 int k; 185 int qbase = priv->qbase; 186 unsigned long i; 187 188 k = 0; 189 i = jiffies + WATCHDOG; 190 while (time_before(jiffies, i) && !priv->qabort && 191 !((k = inb(qbase + 4)) & 0xe0)) { 192 barrier(); 193 cpu_relax(); 194 } 195 if (time_after_eq(jiffies, i)) 196 return (DID_TIME_OUT); 197 if (priv->qabort) 198 return (priv->qabort == 1 ? DID_ABORT : DID_RESET); 199 if (k & 0x60) 200 ql_zap(priv); 201 if (k & 0x20) 202 return (DID_PARITY); 203 if (k & 0x40) 204 return (DID_ERROR); 205 return 0; 206 } 207 208 /* 209 * Initiate scsi command - queueing handler 210 * caller must hold host lock 211 */ 212 213 static void ql_icmd(struct scsi_cmnd *cmd) 214 { 215 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 216 int qbase = priv->qbase; 217 int int_type = priv->int_type; 218 unsigned int i; 219 220 priv->qabort = 0; 221 222 REG0; 223 /* clearing of interrupts and the fifo is needed */ 224 225 inb(qbase + 5); /* clear interrupts */ 226 if (inb(qbase + 5)) /* if still interrupting */ 227 outb(2, qbase + 3); /* reset chip */ 228 else if (inb(qbase + 7) & 0x1f) 229 outb(1, qbase + 3); /* clear fifo */ 230 while (inb(qbase + 5)); /* clear ints */ 231 REG1; 232 outb(1, qbase + 8); /* set for PIO pseudo DMA */ 233 outb(0, qbase + 0xb); /* disable ints */ 234 inb(qbase + 8); /* clear int bits */ 235 REG0; 236 outb(0x40, qbase + 0xb); /* enable features */ 237 238 /* configurables */ 239 outb(qlcfgc, qbase + 0xc); 240 /* config: no reset interrupt, (initiator) bus id */ 241 outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8); 242 outb(qlcfg7, qbase + 7); 243 outb(qlcfg6, qbase + 6); 244 outb(qlcfg5, qbase + 5); /* select timer */ 245 outb(qlcfg9 & 7, qbase + 9); /* prescaler */ 246 /* outb(0x99, qbase + 5); */ 247 outb(scmd_id(cmd), qbase + 4); 248 249 for (i = 0; i < cmd->cmd_len; i++) 250 outb(cmd->cmnd[i], qbase + 2); 251 252 priv->qlcmd = cmd; 253 outb(0x41, qbase + 3); /* select and send command */ 254 } 255 256 /* 257 * Process scsi command - usually after interrupt 258 */ 259 260 static void ql_pcmd(struct scsi_cmnd *cmd) 261 { 262 unsigned int i, j; 263 unsigned long k; 264 unsigned int status; /* scsi returned status */ 265 unsigned int message; /* scsi returned message */ 266 unsigned int phase; /* recorded scsi phase */ 267 unsigned int reqlen; /* total length of transfer */ 268 char *buf; 269 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 270 int qbase = priv->qbase; 271 int int_type = priv->int_type; 272 273 rtrc(1) 274 j = inb(qbase + 6); 275 i = inb(qbase + 5); 276 if (i == 0x20) { 277 set_host_byte(cmd, DID_NO_CONNECT); 278 return; 279 } 280 i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */ 281 if (i != 0x18) { 282 printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i); 283 ql_zap(priv); 284 set_host_byte(cmd, DID_BAD_INTR); 285 return; 286 } 287 j &= 7; /* j = inb( qbase + 7 ) >> 5; */ 288 289 /* correct status is supposed to be step 4 */ 290 /* it sometimes returns step 3 but with 0 bytes left to send */ 291 /* We can try stuffing the FIFO with the max each time, but we will get a 292 sequence of 3 if any bytes are left (but we do flush the FIFO anyway */ 293 294 if (j != 3 && j != 4) { 295 printk(KERN_ERR "Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n", 296 j, i, inb(qbase + 7) & 0x1f); 297 ql_zap(priv); 298 set_host_byte(cmd, DID_ERROR); 299 return; 300 } 301 302 if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */ 303 outb(1, qbase + 3); /* clear fifo */ 304 /* note that request_bufflen is the total xfer size when sg is used */ 305 reqlen = scsi_bufflen(cmd); 306 /* note that it won't work if transfers > 16M are requested */ 307 if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */ 308 struct scatterlist *sg; 309 rtrc(2) 310 outb(reqlen, qbase); /* low-mid xfer cnt */ 311 outb(reqlen >> 8, qbase + 1); /* low-mid xfer cnt */ 312 outb(reqlen >> 16, qbase + 0xe); /* high xfer cnt */ 313 outb(0x90, qbase + 3); /* command do xfer */ 314 /* PIO pseudo DMA to buffer or sglist */ 315 REG1; 316 317 scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) { 318 if (priv->qabort) { 319 REG0; 320 set_host_byte(cmd, 321 priv->qabort == 1 ? 322 DID_ABORT : DID_RESET); 323 } 324 buf = sg_virt(sg); 325 if (ql_pdma(priv, phase, buf, sg->length)) 326 break; 327 } 328 REG0; 329 rtrc(2); 330 /* 331 * Wait for irq (split into second state of irq handler 332 * if this can take time) 333 */ 334 if ((k = ql_wai(priv))) { 335 set_host_byte(cmd, k); 336 return; 337 } 338 k = inb(qbase + 5); /* should be 0x10, bus service */ 339 } 340 341 /* 342 * Enter Status (and Message In) Phase 343 */ 344 345 k = jiffies + WATCHDOG; 346 347 while (time_before(jiffies, k) && !priv->qabort && 348 !(inb(qbase + 4) & 6)) 349 cpu_relax(); /* wait for status phase */ 350 351 if (time_after_eq(jiffies, k)) { 352 ql_zap(priv); 353 set_host_byte(cmd, DID_TIME_OUT); 354 return; 355 } 356 357 /* FIXME: timeout ?? */ 358 while (inb(qbase + 5)) 359 cpu_relax(); /* clear pending ints */ 360 361 if (priv->qabort) { 362 set_host_byte(cmd, 363 priv->qabort == 1 ? DID_ABORT : DID_RESET); 364 return; 365 } 366 367 outb(0x11, qbase + 3); /* get status and message */ 368 if ((k = ql_wai(priv))) { 369 set_host_byte(cmd, k); 370 return; 371 } 372 i = inb(qbase + 5); /* get chip irq stat */ 373 j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */ 374 status = inb(qbase + 2); 375 message = inb(qbase + 2); 376 377 /* 378 * Should get function complete int if Status and message, else 379 * bus serv if only status 380 */ 381 if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) { 382 printk(KERN_ERR "Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j); 383 set_host_byte(cmd, DID_ERROR); 384 } 385 outb(0x12, qbase + 3); /* done, disconnect */ 386 rtrc(1); 387 if ((k = ql_wai(priv))) { 388 set_host_byte(cmd, k); 389 return; 390 } 391 392 /* 393 * Should get bus service interrupt and disconnect interrupt 394 */ 395 396 i = inb(qbase + 5); /* should be bus service */ 397 while (!priv->qabort && ((i & 0x20) != 0x20)) { 398 barrier(); 399 cpu_relax(); 400 i |= inb(qbase + 5); 401 } 402 rtrc(0); 403 404 if (priv->qabort) { 405 set_host_byte(cmd, 406 priv->qabort == 1 ? DID_ABORT : DID_RESET); 407 return; 408 } 409 410 set_host_byte(cmd, DID_OK); 411 if (message != COMMAND_COMPLETE) 412 scsi_msg_to_host_byte(cmd, message); 413 set_status_byte(cmd, status); 414 return; 415 } 416 417 /* 418 * Interrupt handler 419 */ 420 421 static void ql_ihandl(void *dev_id) 422 { 423 struct scsi_cmnd *icmd; 424 struct Scsi_Host *host = dev_id; 425 struct qlogicfas408_priv *priv = get_priv_by_host(host); 426 int qbase = priv->qbase; 427 REG0; 428 429 if (!(inb(qbase + 4) & 0x80)) /* false alarm? */ 430 return; 431 432 if (priv->qlcmd == NULL) { /* no command to process? */ 433 int i; 434 i = 16; 435 while (i-- && inb(qbase + 5)); /* maybe also ql_zap() */ 436 return; 437 } 438 icmd = priv->qlcmd; 439 ql_pcmd(icmd); 440 priv->qlcmd = NULL; 441 /* 442 * If result is CHECK CONDITION done calls qcommand to request 443 * sense 444 */ 445 scsi_done(icmd); 446 } 447 448 irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) 449 { 450 unsigned long flags; 451 struct Scsi_Host *host = dev_id; 452 453 spin_lock_irqsave(host->host_lock, flags); 454 ql_ihandl(dev_id); 455 spin_unlock_irqrestore(host->host_lock, flags); 456 return IRQ_HANDLED; 457 } 458 459 /* 460 * Queued command 461 */ 462 463 static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd) 464 { 465 void (*done)(struct scsi_cmnd *) = scsi_done; 466 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 467 468 set_host_byte(cmd, DID_OK); 469 set_status_byte(cmd, SAM_STAT_GOOD); 470 if (scmd_id(cmd) == priv->qinitid) { 471 set_host_byte(cmd, DID_BAD_TARGET); 472 done(cmd); 473 return 0; 474 } 475 476 /* wait for the last command's interrupt to finish */ 477 while (priv->qlcmd != NULL) { 478 barrier(); 479 cpu_relax(); 480 } 481 ql_icmd(cmd); 482 return 0; 483 } 484 485 DEF_SCSI_QCMD(qlogicfas408_queuecommand) 486 487 /* 488 * Return bios parameters 489 */ 490 491 int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, 492 sector_t capacity, int ip[]) 493 { 494 /* This should mimic the DOS Qlogic driver's behavior exactly */ 495 ip[0] = 0x40; 496 ip[1] = 0x20; 497 ip[2] = (unsigned long) capacity / (ip[0] * ip[1]); 498 if (ip[2] > 1024) { 499 ip[0] = 0xff; 500 ip[1] = 0x3f; 501 ip[2] = (unsigned long) capacity / (ip[0] * ip[1]); 502 #if 0 503 if (ip[2] > 1023) 504 ip[2] = 1023; 505 #endif 506 } 507 return 0; 508 } 509 510 /* 511 * Abort a command in progress 512 */ 513 514 int qlogicfas408_abort(struct scsi_cmnd *cmd) 515 { 516 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 517 priv->qabort = 1; 518 ql_zap(priv); 519 return SUCCESS; 520 } 521 522 /* 523 * Reset SCSI bus 524 * FIXME: This function is invoked with cmd = NULL directly by 525 * the PCMCIA qlogic_stub code. This wants fixing 526 */ 527 528 int qlogicfas408_host_reset(struct scsi_cmnd *cmd) 529 { 530 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 531 unsigned long flags; 532 533 priv->qabort = 2; 534 535 spin_lock_irqsave(cmd->device->host->host_lock, flags); 536 ql_zap(priv); 537 spin_unlock_irqrestore(cmd->device->host->host_lock, flags); 538 539 return SUCCESS; 540 } 541 542 /* 543 * Return info string 544 */ 545 546 const char *qlogicfas408_info(struct Scsi_Host *host) 547 { 548 struct qlogicfas408_priv *priv = get_priv_by_host(host); 549 return priv->qinfo; 550 } 551 552 /* 553 * Get type of chip 554 */ 555 556 int qlogicfas408_get_chip_type(int qbase, int int_type) 557 { 558 REG1; 559 return inb(qbase + 0xe) & 0xf8; 560 } 561 562 /* 563 * Perform initialization tasks 564 */ 565 566 void qlogicfas408_setup(int qbase, int id, int int_type) 567 { 568 outb(1, qbase + 8); /* set for PIO pseudo DMA */ 569 REG0; 570 outb(0x40 | qlcfg8 | id, qbase + 8); /* (ini) bus id, disable scsi rst */ 571 outb(qlcfg5, qbase + 5); /* select timer */ 572 outb(qlcfg9, qbase + 9); /* prescaler */ 573 574 #if QL_RESET_AT_START 575 outb(3, qbase + 3); 576 577 REG1; 578 /* FIXME: timeout */ 579 while (inb(qbase + 0xf) & 4) 580 cpu_relax(); 581 582 REG0; 583 #endif 584 } 585 586 /* 587 * Checks if this is a QLogic FAS 408 588 */ 589 590 int qlogicfas408_detect(int qbase, int int_type) 591 { 592 REG1; 593 return (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7) && 594 ((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7)); 595 } 596 597 /* 598 * Disable interrupts 599 */ 600 601 void qlogicfas408_disable_ints(struct qlogicfas408_priv *priv) 602 { 603 int qbase = priv->qbase; 604 int int_type = priv->int_type; 605 606 REG1; 607 outb(0, qbase + 0xb); /* disable ints */ 608 } 609 610 /* 611 * Init and exit functions 612 */ 613 614 static int __init qlogicfas408_init(void) 615 { 616 return 0; 617 } 618 619 static void __exit qlogicfas408_exit(void) 620 { 621 622 } 623 624 MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); 625 MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers"); 626 MODULE_LICENSE("GPL"); 627 module_init(qlogicfas408_init); 628 module_exit(qlogicfas408_exit); 629 630 EXPORT_SYMBOL(qlogicfas408_info); 631 EXPORT_SYMBOL(qlogicfas408_queuecommand); 632 EXPORT_SYMBOL(qlogicfas408_abort); 633 EXPORT_SYMBOL(qlogicfas408_host_reset); 634 EXPORT_SYMBOL(qlogicfas408_biosparam); 635 EXPORT_SYMBOL(qlogicfas408_ihandl); 636 EXPORT_SYMBOL(qlogicfas408_get_chip_type); 637 EXPORT_SYMBOL(qlogicfas408_setup); 638 EXPORT_SYMBOL(qlogicfas408_detect); 639 EXPORT_SYMBOL(qlogicfas408_disable_ints); 640 641