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@redhat.com> 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/*----------------------------------------------------------------*/ 63static int qlcfg5 = (XTALFREQ << 5); /* 15625/512 */ 64static int qlcfg6 = SYNCXFRPD; 65static int qlcfg7 = SYNCOFFST; 66static int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4); 67static int qlcfg9 = ((XTALFREQ + 4) / 5); 68static int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4); 69 70/*----------------------------------------------------------------*/ 71 72/*----------------------------------------------------------------*/ 73/* local functions */ 74/*----------------------------------------------------------------*/ 75 76/* error recovery - reset everything */ 77 78static 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 96static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, int reqlen) 97{ 98 int j; 99 int qbase = priv->qbase; 100 j = 0; 101 if (phase & 1) { /* in */ 102#if QL_TURBO_PDMA 103 rtrc(4) 104 /* empty fifo in large chunks */ 105 if (reqlen >= 128 && (inb(qbase + 8) & 2)) { /* full */ 106 insl(qbase + 4, request, 32); 107 reqlen -= 128; 108 request += 128; 109 } 110 while (reqlen >= 84 && !(j & 0xc0)) /* 2/3 */ 111 if ((j = inb(qbase + 8)) & 4) 112 { 113 insl(qbase + 4, request, 21); 114 reqlen -= 84; 115 request += 84; 116 } 117 if (reqlen >= 44 && (inb(qbase + 8) & 8)) { /* 1/3 */ 118 insl(qbase + 4, request, 11); 119 reqlen -= 44; 120 request += 44; 121 } 122#endif 123 /* until both empty and int (or until reclen is 0) */ 124 rtrc(7) 125 j = 0; 126 while (reqlen && !((j & 0x10) && (j & 0xc0))) 127 { 128 /* while bytes to receive and not empty */ 129 j &= 0xc0; 130 while (reqlen && !((j = inb(qbase + 8)) & 0x10)) 131 { 132 *request++ = inb(qbase + 4); 133 reqlen--; 134 } 135 if (j & 0x10) 136 j = inb(qbase + 8); 137 138 } 139 } else { /* out */ 140#if QL_TURBO_PDMA 141 rtrc(4) 142 if (reqlen >= 128 && inb(qbase + 8) & 0x10) { /* empty */ 143 outsl(qbase + 4, request, 32); 144 reqlen -= 128; 145 request += 128; 146 } 147 while (reqlen >= 84 && !(j & 0xc0)) /* 1/3 */ 148 if (!((j = inb(qbase + 8)) & 8)) { 149 outsl(qbase + 4, request, 21); 150 reqlen -= 84; 151 request += 84; 152 } 153 if (reqlen >= 40 && !(inb(qbase + 8) & 4)) { /* 2/3 */ 154 outsl(qbase + 4, request, 10); 155 reqlen -= 40; 156 request += 40; 157 } 158#endif 159 /* until full and int (or until reclen is 0) */ 160 rtrc(7) 161 j = 0; 162 while (reqlen && !((j & 2) && (j & 0xc0))) { 163 /* while bytes to send and not full */ 164 while (reqlen && !((j = inb(qbase + 8)) & 2)) 165 { 166 outb(*request++, qbase + 4); 167 reqlen--; 168 } 169 if (j & 2) 170 j = inb(qbase + 8); 171 } 172 } 173 /* maybe return reqlen */ 174 return inb(qbase + 8) & 0xc0; 175} 176 177/* 178 * Wait for interrupt flag (polled - not real hardware interrupt) 179 */ 180 181static int ql_wai(struct qlogicfas408_priv *priv) 182{ 183 int k; 184 int qbase = priv->qbase; 185 unsigned long i; 186 187 k = 0; 188 i = jiffies + WATCHDOG; 189 while (time_before(jiffies, i) && !priv->qabort && 190 !((k = inb(qbase + 4)) & 0xe0)) { 191 barrier(); 192 cpu_relax(); 193 } 194 if (time_after_eq(jiffies, i)) 195 return (DID_TIME_OUT); 196 if (priv->qabort) 197 return (priv->qabort == 1 ? DID_ABORT : DID_RESET); 198 if (k & 0x60) 199 ql_zap(priv); 200 if (k & 0x20) 201 return (DID_PARITY); 202 if (k & 0x40) 203 return (DID_ERROR); 204 return 0; 205} 206 207/* 208 * Initiate scsi command - queueing handler 209 * caller must hold host lock 210 */ 211 212static void ql_icmd(struct scsi_cmnd *cmd) 213{ 214 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 215 int qbase = priv->qbase; 216 int int_type = priv->int_type; 217 unsigned int i; 218 219 priv->qabort = 0; 220 221 REG0; 222 /* clearing of interrupts and the fifo is needed */ 223 224 inb(qbase + 5); /* clear interrupts */ 225 if (inb(qbase + 5)) /* if still interrupting */ 226 outb(2, qbase + 3); /* reset chip */ 227 else if (inb(qbase + 7) & 0x1f) 228 outb(1, qbase + 3); /* clear fifo */ 229 while (inb(qbase + 5)); /* clear ints */ 230 REG1; 231 outb(1, qbase + 8); /* set for PIO pseudo DMA */ 232 outb(0, qbase + 0xb); /* disable ints */ 233 inb(qbase + 8); /* clear int bits */ 234 REG0; 235 outb(0x40, qbase + 0xb); /* enable features */ 236 237 /* configurables */ 238 outb(qlcfgc, qbase + 0xc); 239 /* config: no reset interrupt, (initiator) bus id */ 240 outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8); 241 outb(qlcfg7, qbase + 7); 242 outb(qlcfg6, qbase + 6); 243 /**/ outb(qlcfg5, qbase + 5); /* select timer */ 244 outb(qlcfg9 & 7, qbase + 9); /* prescaler */ 245/* outb(0x99, qbase + 5); */ 246 outb(scmd_id(cmd), qbase + 4); 247 248 for (i = 0; i < cmd->cmd_len; i++) 249 outb(cmd->cmnd[i], qbase + 2); 250 251 priv->qlcmd = cmd; 252 outb(0x41, qbase + 3); /* select and send command */ 253} 254 255/* 256 * Process scsi command - usually after interrupt 257 */ 258 259static unsigned int ql_pcmd(struct scsi_cmnd *cmd) 260{ 261 unsigned int i, j; 262 unsigned long k; 263 unsigned int result; /* ultimate return result */ 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 struct scatterlist *sglist; /* scatter-gather list pointer */ 269 unsigned int sgcount; /* sg counter */ 270 char *buf; 271 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 272 int qbase = priv->qbase; 273 int int_type = priv->int_type; 274 275 rtrc(1) 276 j = inb(qbase + 6); 277 i = inb(qbase + 5); 278 if (i == 0x20) { 279 return (DID_NO_CONNECT << 16); 280 } 281 i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */ 282 if (i != 0x18) { 283 printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i); 284 ql_zap(priv); 285 return (DID_BAD_INTR << 16); 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 return (DID_ERROR << 16); 299 } 300 result = DID_OK; 301 if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */ 302 outb(1, qbase + 3); /* clear fifo */ 303 /* note that request_bufflen is the total xfer size when sg is used */ 304 reqlen = cmd->request_bufflen; 305 /* note that it won't work if transfers > 16M are requested */ 306 if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */ 307 rtrc(2) 308 outb(reqlen, qbase); /* low-mid xfer cnt */ 309 outb(reqlen >> 8, qbase + 1); /* low-mid xfer cnt */ 310 outb(reqlen >> 16, qbase + 0xe); /* high xfer cnt */ 311 outb(0x90, qbase + 3); /* command do xfer */ 312 /* PIO pseudo DMA to buffer or sglist */ 313 REG1; 314 if (!cmd->use_sg) 315 ql_pdma(priv, phase, cmd->request_buffer, 316 cmd->request_bufflen); 317 else { 318 sgcount = cmd->use_sg; 319 sglist = cmd->request_buffer; 320 while (sgcount--) { 321 if (priv->qabort) { 322 REG0; 323 return ((priv->qabort == 1 ? 324 DID_ABORT : DID_RESET) << 16); 325 } 326 buf = page_address(sglist->page) + sglist->offset; 327 if (ql_pdma(priv, phase, buf, sglist->length)) 328 break; 329 sglist++; 330 } 331 } 332 REG0; 333 rtrc(2) 334 /* 335 * Wait for irq (split into second state of irq handler 336 * if this can take time) 337 */ 338 if ((k = ql_wai(priv))) 339 return (k << 16); 340 k = inb(qbase + 5); /* should be 0x10, bus service */ 341 } 342 343 /* 344 * Enter Status (and Message In) Phase 345 */ 346 347 k = jiffies + WATCHDOG; 348 349 while (time_before(jiffies, k) && !priv->qabort && 350 !(inb(qbase + 4) & 6)) 351 cpu_relax(); /* wait for status phase */ 352 353 if (time_after_eq(jiffies, k)) { 354 ql_zap(priv); 355 return (DID_TIME_OUT << 16); 356 } 357 358 while (inb(qbase + 5)) 359 cpu_relax(); /* clear pending ints */ 360 361 if (priv->qabort) 362 return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16); 363 364 outb(0x11, qbase + 3); /* get status and message */ 365 if ((k = ql_wai(priv))) 366 return (k << 16); 367 i = inb(qbase + 5); /* get chip irq stat */ 368 j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */ 369 status = inb(qbase + 2); 370 message = inb(qbase + 2); 371 372 /* 373 * Should get function complete int if Status and message, else 374 * bus serv if only status 375 */ 376 if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) { 377 printk(KERN_ERR "Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j); 378 result = DID_ERROR; 379 } 380 outb(0x12, qbase + 3); /* done, disconnect */ 381 rtrc(1) 382 if ((k = ql_wai(priv))) 383 return (k << 16); 384 385 /* 386 * Should get bus service interrupt and disconnect interrupt 387 */ 388 389 i = inb(qbase + 5); /* should be bus service */ 390 while (!priv->qabort && ((i & 0x20) != 0x20)) { 391 barrier(); 392 cpu_relax(); 393 i |= inb(qbase + 5); 394 } 395 rtrc(0) 396 397 if (priv->qabort) 398 return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16); 399 400 return (result << 16) | (message << 8) | (status & STATUS_MASK); 401} 402 403/* 404 * Interrupt handler 405 */ 406 407static void ql_ihandl(void *dev_id) 408{ 409 struct scsi_cmnd *icmd; 410 struct Scsi_Host *host = dev_id; 411 struct qlogicfas408_priv *priv = get_priv_by_host(host); 412 int qbase = priv->qbase; 413 REG0; 414 415 if (!(inb(qbase + 4) & 0x80)) /* false alarm? */ 416 return; 417 418 if (priv->qlcmd == NULL) { /* no command to process? */ 419 int i; 420 i = 16; 421 while (i-- && inb(qbase + 5)); /* maybe also ql_zap() */ 422 return; 423 } 424 icmd = priv->qlcmd; 425 icmd->result = ql_pcmd(icmd); 426 priv->qlcmd = NULL; 427 /* 428 * If result is CHECK CONDITION done calls qcommand to request 429 * sense 430 */ 431 (icmd->scsi_done) (icmd); 432} 433 434irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) 435{ 436 unsigned long flags; 437 struct Scsi_Host *host = dev_id; 438 439 spin_lock_irqsave(host->host_lock, flags); 440 ql_ihandl(dev_id); 441 spin_unlock_irqrestore(host->host_lock, flags); 442 return IRQ_HANDLED; 443} 444 445/* 446 * Queued command 447 */ 448 449int qlogicfas408_queuecommand(struct scsi_cmnd *cmd, 450 void (*done) (struct scsi_cmnd *)) 451{ 452 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 453 if (scmd_id(cmd) == priv->qinitid) { 454 cmd->result = DID_BAD_TARGET << 16; 455 done(cmd); 456 return 0; 457 } 458 459 cmd->scsi_done = done; 460 /* wait for the last command's interrupt to finish */ 461 while (priv->qlcmd != NULL) { 462 barrier(); 463 cpu_relax(); 464 } 465 ql_icmd(cmd); 466 return 0; 467} 468 469/* 470 * Return bios parameters 471 */ 472 473int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, 474 sector_t capacity, int ip[]) 475{ 476/* This should mimic the DOS Qlogic driver's behavior exactly */ 477 ip[0] = 0x40; 478 ip[1] = 0x20; 479 ip[2] = (unsigned long) capacity / (ip[0] * ip[1]); 480 if (ip[2] > 1024) { 481 ip[0] = 0xff; 482 ip[1] = 0x3f; 483 ip[2] = (unsigned long) capacity / (ip[0] * ip[1]); 484 } 485 return 0; 486} 487 488/* 489 * Abort a command in progress 490 */ 491 492int qlogicfas408_abort(struct scsi_cmnd *cmd) 493{ 494 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 495 priv->qabort = 1; 496 ql_zap(priv); 497 return SUCCESS; 498} 499 500 501int qlogicfas408_bus_reset(struct scsi_cmnd *cmd) 502{ 503 struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); 504 unsigned long flags; 505 506 priv->qabort = 2; 507 508 spin_lock_irqsave(cmd->device->host->host_lock, flags); 509 ql_zap(priv); 510 spin_unlock_irqrestore(cmd->device->host->host_lock, flags); 511 512 return SUCCESS; 513} 514 515/* 516 * Return info string 517 */ 518 519const char *qlogicfas408_info(struct Scsi_Host *host) 520{ 521 struct qlogicfas408_priv *priv = get_priv_by_host(host); 522 return priv->qinfo; 523} 524 525/* 526 * Get type of chip 527 */ 528 529int qlogicfas408_get_chip_type(int qbase, int int_type) 530{ 531 REG1; 532 return inb(qbase + 0xe) & 0xf8; 533} 534 535/* 536 * Perform initialization tasks 537 */ 538 539void qlogicfas408_setup(int qbase, int id, int int_type) 540{ 541 outb(1, qbase + 8); /* set for PIO pseudo DMA */ 542 REG0; 543 outb(0x40 | qlcfg8 | id, qbase + 8); /* (ini) bus id, disable scsi rst */ 544 outb(qlcfg5, qbase + 5); /* select timer */ 545 outb(qlcfg9, qbase + 9); /* prescaler */ 546 547#if QL_RESET_AT_START 548 outb(3, qbase + 3); 549 550 REG1; 551 while (inb(qbase + 0xf) & 4) 552 cpu_relax(); 553 554 REG0; 555#endif 556} 557 558/* 559 * Checks if this is a QLogic FAS 408 560 */ 561 562int qlogicfas408_detect(int qbase, int int_type) 563{ 564 REG1; 565 return (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7) && 566 ((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7)); 567} 568 569/* 570 * Disable interrupts 571 */ 572 573void qlogicfas408_disable_ints(struct qlogicfas408_priv *priv) 574{ 575 int qbase = priv->qbase; 576 int int_type = priv->int_type; 577 578 REG1; 579 outb(0, qbase + 0xb); /* disable ints */ 580} 581 582/* 583 * Init and exit functions 584 */ 585 586static int __init qlogicfas408_init(void) 587{ 588 return 0; 589} 590 591static void __exit qlogicfas408_exit(void) 592{ 593 594} 595 596MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); 597MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers"); 598MODULE_LICENSE("GPL"); 599module_init(qlogicfas408_init); 600module_exit(qlogicfas408_exit); 601 602EXPORT_SYMBOL(qlogicfas408_info); 603EXPORT_SYMBOL(qlogicfas408_queuecommand); 604EXPORT_SYMBOL(qlogicfas408_abort); 605EXPORT_SYMBOL(qlogicfas408_bus_reset); 606EXPORT_SYMBOL(qlogicfas408_biosparam); 607EXPORT_SYMBOL(qlogicfas408_ihandl); 608EXPORT_SYMBOL(qlogicfas408_get_chip_type); 609EXPORT_SYMBOL(qlogicfas408_setup); 610EXPORT_SYMBOL(qlogicfas408_detect); 611EXPORT_SYMBOL(qlogicfas408_disable_ints); 612