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 Redistributable under terms of the GNU General Public License
27
28 */
29 /*----------------------------------------------------------------*/
30 /* Configuration */
31
32 /* Set the following to 2 to use normal interrupt (active high/totempole-
33 tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open
34 drain */
35 #define QL_INT_ACTIVE_HIGH 2
36
37 /* Set the following to 1 to enable the use of interrupts. Note that 0 tends
38 to be more stable, but slower (or ties up the system more) */
39 #define QL_USE_IRQ 1
40
41 /* Set the following to max out the speed of the PIO PseudoDMA transfers,
42 again, 0 tends to be slower, but more stable. */
43 #define QL_TURBO_PDMA 1
44
45 /* This should be 1 to enable parity detection */
46 #define QL_ENABLE_PARITY 1
47
48 /* This will reset all devices when the driver is initialized (during bootup).
49 The other linux drivers don't do this, but the DOS drivers do, and after
50 using DOS or some kind of crash or lockup this will bring things back
51 without requiring a cold boot. It does take some time to recover from a
52 reset, so it is slower, and I have seen timeouts so that devices weren't
53 recognized when this was set. */
54 #define QL_RESET_AT_START 0
55
56 /* crystal frequency in megahertz (for offset 5 and 9)
57 Please set this for your card. Most Qlogic cards are 40 Mhz. The
58 Control Concepts ISA (not VLB) is 24 Mhz */
59 #define XTALFREQ 40
60
61 /**********/
62 /* DANGER! modify these at your own risk */
63 /* SLOWCABLE can usually be reset to zero if you have a clean setup and
64 proper termination. The rest are for synchronous transfers and other
65 advanced features if your device can transfer faster than 5Mb/sec.
66 If you are really curious, email me for a quick howto until I have
67 something official */
68 /**********/
69
70 /*****/
71 /* config register 1 (offset 8) options */
72 /* This needs to be set to 1 if your cabling is long or noisy */
73 #define SLOWCABLE 1
74
75 /*****/
76 /* offset 0xc */
77 /* This will set fast (10Mhz) synchronous timing when set to 1
78 For this to have an effect, FASTCLK must also be 1 */
79 #define FASTSCSI 0
80
81 /* This when set to 1 will set a faster sync transfer rate */
82 #define FASTCLK 0
83 /*(XTALFREQ>25?1:0)*/
84
85 /*****/
86 /* offset 6 */
87 /* This is the sync transfer divisor, XTALFREQ/X will be the maximum
88 achievable data rate (assuming the rest of the system is capable
89 and set properly) */
90 #define SYNCXFRPD 5
91 /*(XTALFREQ/5)*/
92
93 /*****/
94 /* offset 7 */
95 /* This is the count of how many synchronous transfers can take place
96 i.e. how many reqs can occur before an ack is given.
97 The maximum value for this is 15, the upper bits can modify
98 REQ/ACK assertion and deassertion during synchronous transfers
99 If this is 0, the bus will only transfer asynchronously */
100 #define SYNCOFFST 0
101 /* for the curious, bits 7&6 control the deassertion delay in 1/2 cycles
102 of the 40Mhz clock. If FASTCLK is 1, specifying 01 (1/2) will
103 cause the deassertion to be early by 1/2 clock. Bits 5&4 control
104 the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */
105
106 /*----------------------------------------------------------------*/
107 #ifdef PCMCIA
108 #undef QL_INT_ACTIVE_HIGH
109 #define QL_INT_ACTIVE_HIGH 0
110 #endif
111
112 #include <linux/module.h>
113
114 #include <linux/blk.h> /* to get disk capacity */
115 #include <linux/kernel.h>
116 #include <linux/string.h>
117 #include <linux/init.h>
118 #include <linux/ioport.h>
119 #include <linux/sched.h>
120 #include <linux/proc_fs.h>
121 #include <linux/unistd.h>
122 #include <linux/spinlock.h>
123 #include <asm/io.h>
124 #include <asm/irq.h>
125 #include "sd.h"
126 #include "hosts.h"
127 #include "qlogicfas.h"
128 #include <linux/stat.h>
129
130 #ifdef PCMCIA
131 #undef MODULE
132 #endif
133
134 /*----------------------------------------------------------------*/
135 /* driver state info, local to driver */
136 static int qbase; /* Port */
137 static int qinitid; /* initiator ID */
138 static int qabort; /* Flag to cause an abort */
139 static int qlirq = -1; /* IRQ being used */
140 static char qinfo[80]; /* description */
141 static Scsi_Cmnd *qlcmd; /* current command being processed */
142
143 static int qlcfg5 = ( XTALFREQ << 5 ); /* 15625/512 */
144 static int qlcfg6 = SYNCXFRPD;
145 static int qlcfg7 = SYNCOFFST;
146 static int qlcfg8 = ( SLOWCABLE << 7 ) | ( QL_ENABLE_PARITY << 4 );
147 static int qlcfg9 = ( ( XTALFREQ + 4 ) / 5 );
148 static int qlcfgc = ( FASTCLK << 3 ) | ( FASTSCSI << 4 );
149
150 struct Scsi_Host *hreg; /* registered host structure */
151
152 /*----------------------------------------------------------------*/
153 /* The qlogic card uses two register maps - These macros select which one */
154 #define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd ))
155 #define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd ))
156
157 /* following is watchdog timeout in microseconds */
158 #define WATCHDOG 5000000
159
160 /*----------------------------------------------------------------*/
161 /* the following will set the monitor border color (useful to find
162 where something crashed or gets stuck at and as a simple profiler) */
163
164 #if 0
165 #define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
166 #else
167 #define rtrc(i) {}
168 #endif
169
170 /*----------------------------------------------------------------*/
171 /* local functions */
172 /*----------------------------------------------------------------*/
173 static void ql_zap(void);
174 /* error recovery - reset everything */
ql_zap()175 void ql_zap()
176 {
177 int x;
178 unsigned long flags;
179 save_flags( flags );
180 cli();
181 x = inb(qbase + 0xd);
182 REG0;
183 outb(3, qbase + 3); /* reset SCSI */
184 outb(2, qbase + 3); /* reset chip */
185 if (x & 0x80)
186 REG1;
187 restore_flags( flags );
188 }
189
190 /*----------------------------------------------------------------*/
191 /* do pseudo-dma */
ql_pdma(int phase,char * request,int reqlen)192 static int ql_pdma(int phase, char *request, int reqlen)
193 {
194 int j;
195 j = 0;
196 if (phase & 1) { /* in */
197 #if QL_TURBO_PDMA
198 rtrc(4)
199 /* empty fifo in large chunks */
200 if( reqlen >= 128 && (inb( qbase + 8 ) & 2) ) { /* full */
201 insl( qbase + 4, request, 32 );
202 reqlen -= 128;
203 request += 128;
204 }
205 while( reqlen >= 84 && !( j & 0xc0 ) ) /* 2/3 */
206 if( (j=inb( qbase + 8 )) & 4 ) {
207 insl( qbase + 4, request, 21 );
208 reqlen -= 84;
209 request += 84;
210 }
211 if( reqlen >= 44 && (inb( qbase + 8 ) & 8) ) { /* 1/3 */
212 insl( qbase + 4, request, 11 );
213 reqlen -= 44;
214 request += 44;
215 }
216 #endif
217 /* until both empty and int (or until reclen is 0) */
218 rtrc(7)
219 j = 0;
220 while( reqlen && !( (j & 0x10) && (j & 0xc0) ) ) {
221 /* while bytes to receive and not empty */
222 j &= 0xc0;
223 while ( reqlen && !( (j=inb(qbase + 8)) & 0x10 ) ) {
224 *request++ = inb(qbase + 4);
225 reqlen--;
226 }
227 if( j & 0x10 )
228 j = inb(qbase+8);
229
230 }
231 }
232 else { /* out */
233 #if QL_TURBO_PDMA
234 rtrc(4)
235 if( reqlen >= 128 && inb( qbase + 8 ) & 0x10 ) { /* empty */
236 outsl(qbase + 4, request, 32 );
237 reqlen -= 128;
238 request += 128;
239 }
240 while( reqlen >= 84 && !( j & 0xc0 ) ) /* 1/3 */
241 if( !((j=inb( qbase + 8 )) & 8) ) {
242 outsl( qbase + 4, request, 21 );
243 reqlen -= 84;
244 request += 84;
245 }
246 if( reqlen >= 40 && !(inb( qbase + 8 ) & 4 ) ) { /* 2/3 */
247 outsl( qbase + 4, request, 10 );
248 reqlen -= 40;
249 request += 40;
250 }
251 #endif
252 /* until full and int (or until reclen is 0) */
253 rtrc(7)
254 j = 0;
255 while( reqlen && !( (j & 2) && (j & 0xc0) ) ) {
256 /* while bytes to send and not full */
257 while ( reqlen && !( (j=inb(qbase + 8)) & 2 ) ) {
258 outb(*request++, qbase + 4);
259 reqlen--;
260 }
261 if( j & 2 )
262 j = inb(qbase+8);
263 }
264 }
265 /* maybe return reqlen */
266 return inb( qbase + 8 ) & 0xc0;
267 }
268
269 /*----------------------------------------------------------------*/
270 /* wait for interrupt flag (polled - not real hardware interrupt) */
ql_wai(void)271 static int ql_wai(void)
272 {
273 int i,k;
274 k = 0;
275 i = jiffies + WATCHDOG;
276 while (time_before(jiffies, i) && !qabort && !((k = inb(qbase + 4)) & 0xe0)) {
277 barrier();
278 cpu_relax();
279 }
280 if (time_after_eq(jiffies, i))
281 return (DID_TIME_OUT);
282 if (qabort)
283 return (qabort == 1 ? DID_ABORT : DID_RESET);
284 if (k & 0x60)
285 ql_zap();
286 if (k & 0x20)
287 return (DID_PARITY);
288 if (k & 0x40)
289 return (DID_ERROR);
290 return 0;
291 }
292
293 /*----------------------------------------------------------------*/
294 /* initiate scsi command - queueing handler */
ql_icmd(Scsi_Cmnd * cmd)295 static void ql_icmd(Scsi_Cmnd * cmd)
296 {
297 unsigned int i;
298 unsigned long flags;
299
300 qabort = 0;
301
302 save_flags( flags );
303 cli();
304 REG0;
305 /* clearing of interrupts and the fifo is needed */
306 inb(qbase + 5); /* clear interrupts */
307 if (inb(qbase + 5)) /* if still interrupting */
308 outb(2, qbase + 3); /* reset chip */
309 else if (inb(qbase + 7) & 0x1f)
310 outb(1, qbase + 3); /* clear fifo */
311 while (inb(qbase + 5)); /* clear ints */
312 REG1;
313 outb(1, qbase + 8); /* set for PIO pseudo DMA */
314 outb(0, qbase + 0xb); /* disable ints */
315 inb(qbase + 8); /* clear int bits */
316 REG0;
317 outb(0x40, qbase + 0xb); /* enable features */
318
319 /* configurables */
320 outb( qlcfgc , qbase + 0xc);
321 /* config: no reset interrupt, (initiator) bus id */
322 outb( 0x40 | qlcfg8 | qinitid, qbase + 8);
323 outb( qlcfg7 , qbase + 7 );
324 outb( qlcfg6 , qbase + 6 );
325 /**/
326 outb(qlcfg5, qbase + 5); /* select timer */
327 outb(qlcfg9 & 7, qbase + 9); /* prescaler */
328 /* outb(0x99, qbase + 5); */
329 outb(cmd->target, qbase + 4);
330
331 for (i = 0; i < cmd->cmd_len; i++)
332 outb(cmd->cmnd[i], qbase + 2);
333 qlcmd = cmd;
334 outb(0x41, qbase + 3); /* select and send command */
335 restore_flags( flags );
336 }
337 /*----------------------------------------------------------------*/
338 /* process scsi command - usually after interrupt */
ql_pcmd(Scsi_Cmnd * cmd)339 static unsigned int ql_pcmd(Scsi_Cmnd * cmd)
340 {
341 unsigned int i, j, k;
342 unsigned int result; /* ultimate return result */
343 unsigned int status; /* scsi returned status */
344 unsigned int message; /* scsi returned message */
345 unsigned int phase; /* recorded scsi phase */
346 unsigned int reqlen; /* total length of transfer */
347 struct scatterlist *sglist; /* scatter-gather list pointer */
348 unsigned int sgcount; /* sg counter */
349
350 rtrc(1)
351 j = inb(qbase + 6);
352 i = inb(qbase + 5);
353 if (i == 0x20) {
354 return (DID_NO_CONNECT << 16);
355 }
356 i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */
357 if (i != 0x18) {
358 printk("Ql:Bad Interrupt status:%02x\n", i);
359 ql_zap();
360 return (DID_BAD_INTR << 16);
361 }
362 j &= 7; /* j = inb( qbase + 7 ) >> 5; */
363 /* correct status is supposed to be step 4 */
364 /* it sometimes returns step 3 but with 0 bytes left to send */
365 /* We can try stuffing the FIFO with the max each time, but we will get a
366 sequence of 3 if any bytes are left (but we do flush the FIFO anyway */
367 if(j != 3 && j != 4) {
368 printk("Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n", j, i, inb( qbase+7 ) & 0x1f );
369 ql_zap();
370 return (DID_ERROR << 16);
371 }
372 result = DID_OK;
373 if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */
374 outb(1, qbase + 3); /* clear fifo */
375 /* note that request_bufflen is the total xfer size when sg is used */
376 reqlen = cmd->request_bufflen;
377 /* note that it won't work if transfers > 16M are requested */
378 if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */
379 rtrc(2)
380 outb(reqlen, qbase); /* low-mid xfer cnt */
381 outb(reqlen >> 8, qbase+1); /* low-mid xfer cnt */
382 outb(reqlen >> 16, qbase + 0xe); /* high xfer cnt */
383 outb(0x90, qbase + 3); /* command do xfer */
384 /* PIO pseudo DMA to buffer or sglist */
385 REG1;
386 if (!cmd->use_sg)
387 ql_pdma(phase, cmd->request_buffer, cmd->request_bufflen);
388 else {
389 sgcount = cmd->use_sg;
390 sglist = cmd->request_buffer;
391 while (sgcount--) {
392 if (qabort) {
393 REG0;
394 return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
395 }
396 if (ql_pdma(phase, sglist->address, sglist->length))
397 break;
398 sglist++;
399 }
400 }
401 REG0;
402 rtrc(2)
403 /* wait for irq (split into second state of irq handler if this can take time) */
404 if ((k = ql_wai()))
405 return (k << 16);
406 k = inb(qbase + 5); /* should be 0x10, bus service */
407 }
408 /*** Enter Status (and Message In) Phase ***/
409 k = jiffies + WATCHDOG;
410 while ( time_before(jiffies, k) && !qabort && !(inb(qbase + 4) & 6)); /* wait for status phase */
411 if ( time_after_eq(jiffies, k) ) {
412 ql_zap();
413 return (DID_TIME_OUT << 16);
414 }
415 while (inb(qbase + 5)); /* clear pending ints */
416 if (qabort)
417 return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
418 outb(0x11, qbase + 3); /* get status and message */
419 if ((k = ql_wai()))
420 return (k << 16);
421 i = inb(qbase + 5); /* get chip irq stat */
422 j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */
423 status = inb(qbase + 2);
424 message = inb(qbase + 2);
425 /* should get function complete int if Status and message, else bus serv if only status */
426 if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) {
427 printk("Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j);
428 result = DID_ERROR;
429 }
430 outb(0x12, qbase + 3); /* done, disconnect */
431 rtrc(1)
432 if ((k = ql_wai()))
433 return (k << 16);
434 /* should get bus service interrupt and disconnect interrupt */
435 i = inb(qbase + 5); /* should be bus service */
436 while (!qabort && ((i & 0x20) != 0x20)) {
437 barrier();
438 cpu_relax();
439 i |= inb(qbase + 5);
440 }
441 rtrc(0)
442 if (qabort)
443 return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
444 return (result << 16) | (message << 8) | (status & STATUS_MASK);
445 }
446
447 #if QL_USE_IRQ
448 /*----------------------------------------------------------------*/
449 /* interrupt handler */
ql_ihandl(int irq,void * dev_id,struct pt_regs * regs)450 static void ql_ihandl(int irq, void *dev_id, struct pt_regs * regs)
451 {
452 Scsi_Cmnd *icmd;
453 REG0;
454 if (!(inb(qbase + 4) & 0x80)) /* false alarm? */
455 return;
456 if (qlcmd == NULL) { /* no command to process? */
457 int i;
458 i = 16;
459 while (i-- && inb(qbase + 5)); /* maybe also ql_zap() */
460 return;
461 }
462 icmd = qlcmd;
463 icmd->result = ql_pcmd(icmd);
464 qlcmd = NULL;
465 /* if result is CHECK CONDITION done calls qcommand to request sense */
466 (icmd->scsi_done) (icmd);
467 }
468
do_ql_ihandl(int irq,void * dev_id,struct pt_regs * regs)469 static void do_ql_ihandl(int irq, void *dev_id, struct pt_regs * regs)
470 {
471 unsigned long flags;
472
473 spin_lock_irqsave(&io_request_lock, flags);
474 ql_ihandl(irq, dev_id, regs);
475 spin_unlock_irqrestore(&io_request_lock, flags);
476 }
477 #endif
478
479 /*----------------------------------------------------------------*/
480 /* global functions */
481 /*----------------------------------------------------------------*/
482 /* non queued command */
483 #if QL_USE_IRQ
qlidone(Scsi_Cmnd * cmd)484 static void qlidone(Scsi_Cmnd * cmd) {}; /* null function */
485 #endif
486
487 /* command process */
qlogicfas_command(Scsi_Cmnd * cmd)488 int qlogicfas_command(Scsi_Cmnd * cmd)
489 {
490 int k;
491 #if QL_USE_IRQ
492 if (qlirq >= 0) {
493 qlogicfas_queuecommand(cmd, qlidone);
494 while (qlcmd != NULL);
495 return cmd->result;
496 }
497 #endif
498 /* non-irq version */
499 if (cmd->target == qinitid)
500 return (DID_BAD_TARGET << 16);
501 ql_icmd(cmd);
502 if ((k = ql_wai()))
503 return (k << 16);
504 return ql_pcmd(cmd);
505
506 }
507
508 #if QL_USE_IRQ
509 /*----------------------------------------------------------------*/
510 /* queued command */
qlogicfas_queuecommand(Scsi_Cmnd * cmd,void (* done)(Scsi_Cmnd *))511 int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
512 {
513 if(cmd->target == qinitid) {
514 cmd->result = DID_BAD_TARGET << 16;
515 done(cmd);
516 return 0;
517 }
518
519 cmd->scsi_done = done;
520 /* wait for the last command's interrupt to finish */
521 while (qlcmd != NULL) {
522 barrier();
523 cpu_relax();
524 }
525 ql_icmd(cmd);
526 return 0;
527 }
528 #else
qlogicfas_queuecommand(Scsi_Cmnd * cmd,void (* done)(Scsi_Cmnd *))529 int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
530 {
531 return 1;
532 }
533 #endif
534
535 #ifdef PCMCIA
536 /*----------------------------------------------------------------*/
537 /* allow PCMCIA code to preset the port */
538 /* port should be 0 and irq to -1 respectively for autoprobing */
qlogicfas_preset(int port,int irq)539 void qlogicfas_preset(int port, int irq)
540 {
541 qbase=port;
542 qlirq=irq;
543 }
544 #endif
545
qlogicfas_release(struct Scsi_Host * hreg)546 int qlogicfas_release(struct Scsi_Host *hreg)
547 {
548 release_region(qbase, 0x10);
549
550 if (qlirq >= 0)
551 free_irq(qlirq, hreg);
552
553 scsi_unregister(hreg);
554
555 return 0;
556 }
557
558 /*----------------------------------------------------------------*/
559 /* look for qlogic card and init if found */
qlogicfas_detect(Scsi_Host_Template * host)560 int __QLINIT qlogicfas_detect(Scsi_Host_Template * host)
561 {
562 int i, j; /* these are only used by IRQ detect */
563 int qltyp; /* type of chip */
564 unsigned long flags;
565
566 host->proc_name = "qlogicfas";
567
568 /* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the
569 address - I check 230 first since MIDI cards are typically at 330
570
571 Theoretically, two Qlogic cards can coexist in the same system. This
572 should work by simply using this as a loadable module for the second
573 card, but I haven't tested this.
574 */
575
576 if( !qbase ) {
577 for (qbase = 0x230; qbase < 0x430; qbase += 0x100) {
578 if( !request_region( qbase , 0x10, "qlogicfas" ) )
579 continue;
580 REG1;
581 if ( ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 )
582 && ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 ) )
583 break;
584 release_region(qbase, 0x10 );
585 }
586 if (qbase == 0x430)
587 return 0;
588 }
589 else
590 printk( "Ql: Using preset base address of %03x\n", qbase );
591
592 qltyp = inb(qbase + 0xe) & 0xf8;
593 qinitid = host->this_id;
594 if (qinitid < 0)
595 qinitid = 7; /* if no ID, use 7 */
596 outb(1, qbase + 8); /* set for PIO pseudo DMA */
597 REG0;
598 outb(0x40 | qlcfg8 | qinitid, qbase + 8); /* (ini) bus id, disable scsi rst */
599 outb(qlcfg5, qbase + 5); /* select timer */
600 outb(qlcfg9, qbase + 9); /* prescaler */
601 #if QL_RESET_AT_START
602 outb( 3 , qbase + 3 );
603 REG1;
604 while( inb( qbase + 0xf ) & 4 );
605 REG0;
606 #endif
607 #if QL_USE_IRQ
608 /* IRQ probe - toggle pin and check request pending */
609
610 if( qlirq == -1 ) {
611 save_flags( flags );
612 cli();
613 i = 0xffff;
614 j = 3;
615 outb(0x90, qbase + 3); /* illegal command - cause interrupt */
616 REG1;
617 outb(10, 0x20); /* access pending interrupt map */
618 outb(10, 0xa0);
619 while (j--) {
620 outb(0xb0 | QL_INT_ACTIVE_HIGH , qbase + 0xd); /* int pin off */
621 i &= ~(inb(0x20) | (inb(0xa0) << 8)); /* find IRQ off */
622 outb(0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd); /* int pin on */
623 i &= inb(0x20) | (inb(0xa0) << 8); /* find IRQ on */
624 }
625 REG0;
626 while (inb(qbase + 5)); /* purge int */
627 j = -1;
628 while (i) /* find on bit */
629 i >>= 1, j++; /* should check for exactly 1 on */
630 qlirq = j;
631 restore_flags( flags );
632 }
633 else
634 printk( "Ql: Using preset IRQ %d\n", qlirq );
635
636 if (qlirq >= 0)
637 host->can_queue = 1;
638 #endif
639 hreg = scsi_register( host , 0 ); /* no host data */
640 if (!hreg)
641 goto err_release_mem;
642
643 #if QL_USE_IRQ
644 #ifdef PCMCIA
645 if(request_irq(qlirq, do_ql_ihandl, SA_SHIRQ, "qlogicfas", hreg) < 0)
646 #else
647 if(request_irq(qlirq, do_ql_ihandl, SA_SHIRQ, "qlogicfas", hreg) < 0)
648 #endif
649 {
650 scsi_unregister(hreg);
651 goto err_release_mem;
652 }
653 #endif
654 hreg->io_port = qbase;
655 hreg->n_io_port = 16;
656 hreg->dma_channel = -1;
657 if( qlirq >= 0 )
658 hreg->irq = qlirq;
659
660 sprintf(qinfo, "Qlogicfas Driver version 0.46, chip %02X at %03X, IRQ %d, TPdma:%d",
661 qltyp, qbase, qlirq, QL_TURBO_PDMA );
662 host->name = qinfo;
663
664 return 1;
665
666 err_release_mem:
667 release_region(qbase, 0x10);
668 if (qlirq >= 0)
669 free_irq(qlirq, hreg);
670 return 0;
671
672 }
673
674 /*----------------------------------------------------------------*/
675 /* return bios parameters */
qlogicfas_biosparam(Disk * disk,kdev_t dev,int ip[])676 int qlogicfas_biosparam(Disk * disk, kdev_t dev, int ip[])
677 {
678 /* This should mimic the DOS Qlogic driver's behavior exactly */
679 ip[0] = 0x40;
680 ip[1] = 0x20;
681 ip[2] = disk->capacity / (ip[0] * ip[1]);
682 if (ip[2] > 1024) {
683 ip[0] = 0xff;
684 ip[1] = 0x3f;
685 ip[2] = disk->capacity / (ip[0] * ip[1]);
686 #if 0
687 if (ip[2] > 1023)
688 ip[2] = 1023;
689 #endif
690 }
691 return 0;
692 }
693
694 /*----------------------------------------------------------------*/
695 /* abort command in progress */
qlogicfas_abort(Scsi_Cmnd * cmd)696 int qlogicfas_abort(Scsi_Cmnd * cmd)
697 {
698 qabort = 1;
699 ql_zap();
700 return 0;
701 }
702
703 /*----------------------------------------------------------------*/
704 /* reset SCSI bus */
qlogicfas_reset(Scsi_Cmnd * cmd,unsigned int ignored)705 int qlogicfas_reset(Scsi_Cmnd * cmd, unsigned int ignored)
706 {
707 qabort = 2;
708 ql_zap();
709 return 1;
710 }
711
712 /*----------------------------------------------------------------*/
713 /* return info string */
qlogicfas_info(struct Scsi_Host * host)714 const char *qlogicfas_info(struct Scsi_Host * host)
715 {
716 return qinfo;
717 }
718 MODULE_LICENSE("GPL");
719
720 #ifndef PCMCIA
721 /* Eventually this will go into an include file, but this will be later */
722 static Scsi_Host_Template driver_template = QLOGICFAS;
723 #include "scsi_module.c"
724 #endif
725
726