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