1 /*----------------------------------------------------------------*/
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.
7 Copyright 1994, Tom Zerucha.
10 Additional Code, and much appreciated help by
14 Thanks to Eric Youngdale and Dave Hinds for loadable module and PCMCIA
15 help respectively, and for suffering through my foolishness during the
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)
21 Version 0.46 1/30/97 - kernel 1.2.0+
23 Functions as standalone, loadable, and PCMCIA driver, the latter from
24 Dave Hinds' PCMCIA package.
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
29 - Non terminating hardware waits
30 - Some layering violations with its pcmcia stub
32 Redistributable under terms of the GNU General Public License
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.
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>
60 #include "qlogicfas.h"
62 /*----------------------------------------------------------------*/
63 int qlcfg5 = (XTALFREQ << 5); /* 15625/512 */
64 int qlcfg6 = SYNCXFRPD;
65 int qlcfg7 = SYNCOFFST;
66 int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4);
67 int qlcfg9 = ((XTALFREQ + 4) / 5);
68 int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4);
70 static char qlogicfas_name[] = "qlogicfas";
72 int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
74 /*----------------------------------------------------------------*/
76 /*----------------------------------------------------------------*/
78 /*----------------------------------------------------------------*/
80 /* error recovery - reset everything */
82 static void ql_zap(qlogicfas_priv_t priv)
85 int qbase = priv->qbase;
89 outb(3, qbase + 3); /* reset SCSI */
90 outb(2, qbase + 3); /* reset chip */
96 * Do a pseudo-dma tranfer
99 static int ql_pdma(qlogicfas_priv_t priv, int phase, char *request, int reqlen)
102 int qbase = priv->qbase;
104 if (phase & 1) { /* in */
107 /* empty fifo in large chunks */
108 if (reqlen >= 128 && (inb(qbase + 8) & 2)) { /* full */
109 insl(qbase + 4, request, 32);
113 while (reqlen >= 84 && !(j & 0xc0)) /* 2/3 */
114 if ((j = inb(qbase + 8)) & 4)
116 insl(qbase + 4, request, 21);
120 if (reqlen >= 44 && (inb(qbase + 8) & 8)) { /* 1/3 */
121 insl(qbase + 4, request, 11);
126 /* until both empty and int (or until reclen is 0) */
129 while (reqlen && !((j & 0x10) && (j & 0xc0)))
131 /* while bytes to receive and not empty */
133 while (reqlen && !((j = inb(qbase + 8)) & 0x10))
135 *request++ = inb(qbase + 4);
145 if (reqlen >= 128 && inb(qbase + 8) & 0x10) { /* empty */
146 outsl(qbase + 4, request, 32);
150 while (reqlen >= 84 && !(j & 0xc0)) /* 1/3 */
151 if (!((j = inb(qbase + 8)) & 8)) {
152 outsl(qbase + 4, request, 21);
156 if (reqlen >= 40 && !(inb(qbase + 8) & 4)) { /* 2/3 */
157 outsl(qbase + 4, request, 10);
162 /* until full and int (or until reclen is 0) */
165 while (reqlen && !((j & 2) && (j & 0xc0))) {
166 /* while bytes to send and not full */
167 while (reqlen && !((j = inb(qbase + 8)) & 2))
169 outb(*request++, qbase + 4);
176 /* maybe return reqlen */
177 return inb(qbase + 8) & 0xc0;
181 * Wait for interrupt flag (polled - not real hardware interrupt)
184 static int ql_wai(qlogicfas_priv_t priv)
187 int qbase = priv->qbase;
191 i = jiffies + WATCHDOG;
192 while (time_before(jiffies, i) && !priv->qabort &&
193 !((k = inb(qbase + 4)) & 0xe0)) {
197 if (time_after_eq(jiffies, i))
198 return (DID_TIME_OUT);
200 return (priv->qabort == 1 ? DID_ABORT : DID_RESET);
211 * Initiate scsi command - queueing handler
212 * caller must hold host lock
215 static void ql_icmd(Scsi_Cmnd * cmd)
217 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
218 int qbase = priv->qbase;
224 /* clearing of interrupts and the fifo is needed */
226 inb(qbase + 5); /* clear interrupts */
227 if (inb(qbase + 5)) /* if still interrupting */
228 outb(2, qbase + 3); /* reset chip */
229 else if (inb(qbase + 7) & 0x1f)
230 outb(1, qbase + 3); /* clear fifo */
231 while (inb(qbase + 5)); /* clear ints */
233 outb(1, qbase + 8); /* set for PIO pseudo DMA */
234 outb(0, qbase + 0xb); /* disable ints */
235 inb(qbase + 8); /* clear int bits */
237 outb(0x40, qbase + 0xb); /* enable features */
240 outb(qlcfgc, qbase + 0xc);
241 /* config: no reset interrupt, (initiator) bus id */
242 outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8);
243 outb(qlcfg7, qbase + 7);
244 outb(qlcfg6, qbase + 6);
245 /**/ outb(qlcfg5, qbase + 5); /* select timer */
246 outb(qlcfg9 & 7, qbase + 9); /* prescaler */
247 /* outb(0x99, qbase + 5); */
248 outb(cmd->device->id, qbase + 4);
250 for (i = 0; i < cmd->cmd_len; i++)
251 outb(cmd->cmnd[i], qbase + 2);
254 outb(0x41, qbase + 3); /* select and send command */
258 * Process scsi command - usually after interrupt
261 static unsigned int ql_pcmd(Scsi_Cmnd * cmd)
265 unsigned int result; /* ultimate return result */
266 unsigned int status; /* scsi returned status */
267 unsigned int message; /* scsi returned message */
268 unsigned int phase; /* recorded scsi phase */
269 unsigned int reqlen; /* total length of transfer */
270 struct scatterlist *sglist; /* scatter-gather list pointer */
271 unsigned int sgcount; /* sg counter */
273 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
274 int qbase = priv->qbase;
280 return (DID_NO_CONNECT << 16);
282 i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */
284 printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i);
286 return (DID_BAD_INTR << 16);
288 j &= 7; /* j = inb( qbase + 7 ) >> 5; */
290 /* correct status is supposed to be step 4 */
291 /* it sometimes returns step 3 but with 0 bytes left to send */
292 /* We can try stuffing the FIFO with the max each time, but we will get a
293 sequence of 3 if any bytes are left (but we do flush the FIFO anyway */
295 if (j != 3 && j != 4) {
296 printk(KERN_ERR "Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n",
297 j, i, inb(qbase + 7) & 0x1f);
299 return (DID_ERROR << 16);
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 = cmd->request_bufflen;
306 /* note that it won't work if transfers > 16M are requested */
307 if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */
309 outb(reqlen, qbase); /* low-mid xfer cnt */
310 outb(reqlen >> 8, qbase + 1); /* low-mid xfer cnt */
311 outb(reqlen >> 16, qbase + 0xe); /* high xfer cnt */
312 outb(0x90, qbase + 3); /* command do xfer */
313 /* PIO pseudo DMA to buffer or sglist */
316 ql_pdma(priv, phase, cmd->request_buffer,
317 cmd->request_bufflen);
319 sgcount = cmd->use_sg;
320 sglist = cmd->request_buffer;
324 return ((priv->qabort == 1 ?
325 DID_ABORT : DID_RESET) << 16);
327 buf = page_address(sglist->page) + sglist->offset;
328 if (ql_pdma(priv, phase, buf, sglist->length))
336 * Wait for irq (split into second state of irq handler
337 * if this can take time)
339 if ((k = ql_wai(priv)))
341 k = inb(qbase + 5); /* should be 0x10, bus service */
345 * Enter Status (and Message In) Phase
348 k = jiffies + WATCHDOG;
350 while (time_before(jiffies, k) && !priv->qabort &&
351 !(inb(qbase + 4) & 6))
352 cpu_relax(); /* wait for status phase */
354 if (time_after_eq(jiffies, k)) {
356 return (DID_TIME_OUT << 16);
359 /* FIXME: timeout ?? */
360 while (inb(qbase + 5))
361 cpu_relax(); /* clear pending ints */
364 return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16);
366 outb(0x11, qbase + 3); /* get status and message */
367 if ((k = ql_wai(priv)))
369 i = inb(qbase + 5); /* get chip irq stat */
370 j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */
371 status = inb(qbase + 2);
372 message = inb(qbase + 2);
375 * Should get function complete int if Status and message, else
376 * bus serv if only status
378 if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) {
379 printk(KERN_ERR "Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j);
382 outb(0x12, qbase + 3); /* done, disconnect */
384 if ((k = ql_wai(priv)))
388 * Should get bus service interrupt and disconnect interrupt
391 i = inb(qbase + 5); /* should be bus service */
392 while (!priv->qabort && ((i & 0x20) != 0x20)) {
400 return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16);
402 return (result << 16) | (message << 8) | (status & STATUS_MASK);
409 static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs)
412 struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
413 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(host->hostdata[0]);
414 int qbase = priv->qbase;
417 if (!(inb(qbase + 4) & 0x80)) /* false alarm? */
420 if (priv->qlcmd == NULL) { /* no command to process? */
423 while (i-- && inb(qbase + 5)); /* maybe also ql_zap() */
427 icmd->result = ql_pcmd(icmd);
430 * If result is CHECK CONDITION done calls qcommand to request
433 (icmd->scsi_done) (icmd);
436 irqreturn_t do_ql_ihandl(int irq, void *dev_id, struct pt_regs *regs)
439 struct Scsi_Host *host = dev_id;
441 spin_lock_irqsave(host->host_lock, flags);
442 ql_ihandl(irq, dev_id, regs);
443 spin_unlock_irqrestore(host->host_lock, flags);
451 int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
453 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
454 if (cmd->device->id == priv->qinitid) {
455 cmd->result = DID_BAD_TARGET << 16;
460 cmd->scsi_done = done;
461 /* wait for the last command's interrupt to finish */
462 while (priv->qlcmd != NULL) {
472 * Look for qlogic card and init if found
475 struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host, int qbase,
478 int i, j; /* these are only used by IRQ detect */
479 int qltyp; /* type of chip */
481 struct Scsi_Host *hreg; /* registered host structure */
482 qlogicfas_priv_t priv;
484 /* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself
485 * decodes the address - I check 230 first since MIDI cards are
488 * Theoretically, two Qlogic cards can coexist in the same system.
489 * This should work by simply using this as a loadable module for
490 * the second card, but I haven't tested this.
494 for (qbase = 0x230; qbase < 0x430; qbase += 0x100) {
495 if (!request_region(qbase, 0x10, qlogicfas_name))
498 if (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7)
499 && ((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7))
501 release_region(qbase, 0x10);
506 printk(KERN_INFO "Ql: Using preset base address of %03x\n", qbase);
508 qltyp = inb(qbase + 0xe) & 0xf8;
509 qinitid = host->this_id;
511 qinitid = 7; /* if no ID, use 7 */
512 outb(1, qbase + 8); /* set for PIO pseudo DMA */
514 outb(0x40 | qlcfg8 | qinitid, qbase + 8); /* (ini) bus id, disable scsi rst */
515 outb(qlcfg5, qbase + 5); /* select timer */
516 outb(qlcfg9, qbase + 9); /* prescaler */
518 #if QL_RESET_AT_START
522 while (inb(qbase + 0xf) & 4)
528 * IRQ probe - toggle pin and check request pending
534 outb(0x90, qbase + 3); /* illegal command - cause interrupt */
536 outb(10, 0x20); /* access pending interrupt map */
539 outb(0xb0 | QL_INT_ACTIVE_HIGH, qbase + 0xd); /* int pin off */
540 i &= ~(inb(0x20) | (inb(0xa0) << 8)); /* find IRQ off */
541 outb(0xb4 | QL_INT_ACTIVE_HIGH, qbase + 0xd); /* int pin on */
542 i &= inb(0x20) | (inb(0xa0) << 8); /* find IRQ on */
545 while (inb(qbase + 5)); /* purge int */
547 while (i) /* find on bit */
548 i >>= 1, j++; /* should check for exactly 1 on */
551 printk(KERN_INFO "Ql: Using preset IRQ %d\n", qlirq);
553 hreg = scsi_host_alloc(host, sizeof(struct qlogicfas_priv));
555 goto err_release_mem;
556 priv = (qlogicfas_priv_t)&(hreg->hostdata[0]);
557 hreg->io_port = qbase;
558 hreg->n_io_port = 16;
559 hreg->dma_channel = -1;
564 priv->qinitid = qinitid;
568 "Qlogicfas Driver version 0.46, chip %02X at %03X, IRQ %d, TPdma:%d",
569 qltyp, qbase, qlirq, QL_TURBO_PDMA);
570 host->name = qlogicfas_name;
572 if (request_irq(qlirq, do_ql_ihandl, 0, qlogicfas_name, hreg))
575 if (scsi_add_host(hreg, NULL))
578 scsi_scan_host(hreg);
583 free_irq(qlirq, hreg);
589 release_region(qbase, 0x10);
593 #define MAX_QLOGICFAS 8
594 static qlogicfas_priv_t cards;
595 static int iobase[MAX_QLOGICFAS];
596 static int irq[MAX_QLOGICFAS] = { [0 ... MAX_QLOGICFAS-1] = -1 };
597 MODULE_PARM(iobase, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i");
598 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i");
599 MODULE_PARM_DESC(iobase, "I/O address");
600 MODULE_PARM_DESC(irq, "IRQ");
602 int __devinit qlogicfas_detect(Scsi_Host_Template *sht)
604 struct Scsi_Host *shost;
605 qlogicfas_priv_t priv;
609 for (i = 0; i < MAX_QLOGICFAS; i++) {
610 shost = __qlogicfas_detect(sht, iobase[num], irq[num]);
612 /* no more devices */
615 priv = (qlogicfas_priv_t)&(shost->hostdata[0]);
624 static int qlogicfas_release(struct Scsi_Host *shost)
626 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(shost->hostdata[0]);
627 int qbase = priv->qbase;
631 outb(0, qbase + 0xb); /* disable ints */
633 free_irq(shost->irq, shost);
635 if (shost->dma_channel != 0xff)
636 free_dma(shost->dma_channel);
637 if (shost->io_port && shost->n_io_port)
638 release_region(shost->io_port, shost->n_io_port);
639 scsi_remove_host(shost);
640 scsi_host_put(shost);
644 #endif /* ifndef PCMCIA */
647 * Return bios parameters
650 int qlogicfas_biosparam(struct scsi_device * disk,
651 struct block_device *dev,
652 sector_t capacity, int ip[])
654 /* This should mimic the DOS Qlogic driver's behavior exactly */
657 ip[2] = (unsigned long) capacity / (ip[0] * ip[1]);
661 ip[2] = (unsigned long) capacity / (ip[0] * ip[1]);
671 * Abort a command in progress
674 static int qlogicfas_abort(Scsi_Cmnd * cmd)
676 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
684 * FIXME: This function is invoked with cmd = NULL directly by
685 * the PCMCIA qlogic_stub code. This wants fixing
688 int qlogicfas_bus_reset(Scsi_Cmnd * cmd)
690 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
697 * Reset SCSI host controller
700 static int qlogicfas_host_reset(Scsi_Cmnd * cmd)
709 static int qlogicfas_device_reset(Scsi_Cmnd * cmd)
718 static const char *qlogicfas_info(struct Scsi_Host *host)
720 qlogicfas_priv_t priv = (qlogicfas_priv_t)&(host->hostdata[0]);
725 * The driver template is also needed for PCMCIA
727 Scsi_Host_Template qlogicfas_driver_template = {
728 .module = THIS_MODULE,
729 .name = qlogicfas_name,
730 .proc_name = qlogicfas_name,
731 .info = qlogicfas_info,
732 .queuecommand = qlogicfas_queuecommand,
733 .eh_abort_handler = qlogicfas_abort,
734 .eh_bus_reset_handler = qlogicfas_bus_reset,
735 .eh_device_reset_handler= qlogicfas_device_reset,
736 .eh_host_reset_handler = qlogicfas_host_reset,
737 .bios_param = qlogicfas_biosparam,
740 .sg_tablesize = SG_ALL,
742 .use_clustering = DISABLE_CLUSTERING,
746 static __init int qlogicfas_init(void)
748 if (!qlogicfas_detect(&qlogicfas_driver_template)) {
756 static __exit void qlogicfas_exit(void)
758 qlogicfas_priv_t priv;
760 for (priv = cards; priv != NULL; priv = priv->next)
761 qlogicfas_release(priv->shost);
764 MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
765 MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers");
766 MODULE_LICENSE("GPL");
767 module_init(qlogicfas_init);
768 module_exit(qlogicfas_exit);
769 #endif /* ifndef PCMCIA */