Bug Summary

File:obj-scan-build/../linux/src/drivers/scsi/qlogicfas.c
Location:line 406, column 3
Description:Value stored to 'k' is never read

Annotated Source Code

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 zerucha@shell.portal.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.45 6/9/96 - kernel 1.2.0+
22
23 Functions as standalone, loadable, and PCMCIA driver, the latter from
24 Dave Hind's PCMCIA package.
25
26 Redistributable under terms of the GNU 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_HIGH2 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_IRQ1 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_PDMA1 1
44
45/* This should be 1 to enable parity detection */
46#define QL_ENABLE_PARITY1 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_START0 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 XTALFREQ40 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 SLOWCABLE1 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 FASTSCSI0 0
80
81/* This when set to 1 will set a faster sync transfer rate */
82#define FASTCLK0 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 SYNCXFRPD5 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 SYNCOFFST0 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_HIGH2
109#define QL_INT_ACTIVE_HIGH2 0
110#define MODULE
111#endif
112
113#include <linux/module.h>
114
115#ifdef PCMCIA
116#undef MODULE
117#endif
118
119#include <linux/blk.h> /* to get disk capacity */
120#include <linux/kernel.h>
121#include <linux/string.h>
122#include <linux/ioport.h>
123#include <linux/sched.h>
124#include <linux/proc_fs.h>
125#include <linux/unistd.h>
126#include <asm/io.h>
127#include <asm/irq.h>
128#include "sd.h"
129#include "hosts.h"
130#include "qlogicfas.h"
131#include<linux/stat.h>
132
133struct proc_dir_entry proc_scsi_qlogicfas = {
134 PROC_SCSI_QLOGICFAS, 6, "qlogicfas",
135 S_IFDIR0040000 | S_IRUGO(00400|00040|00004) | S_IXUGO(00100|00010|00001), 2
136};
137
138/*----------------------------------------------------------------*/
139/* driver state info, local to driver */
140static int qbase = 0; /* Port */
141static int qinitid; /* initiator ID */
142static int qabort; /* Flag to cause an abort */
143static int qlirq = -1; /* IRQ being used */
144static char qinfo[80]; /* description */
145static Scsi_Cmnd *qlcmd; /* current command being processed */
146
147static int qlcfg5 = ( XTALFREQ40 << 5 ); /* 15625/512 */
148static int qlcfg6 = SYNCXFRPD5;
149static int qlcfg7 = SYNCOFFST0;
150static int qlcfg8 = ( SLOWCABLE1 << 7 ) | ( QL_ENABLE_PARITY1 << 4 );
151static int qlcfg9 = ( ( XTALFREQ40 + 4 ) / 5 );
152static int qlcfgc = ( FASTCLK0 << 3 ) | ( FASTSCSI0 << 4 );
153
154/*----------------------------------------------------------------*/
155/* The qlogic card uses two register maps - These macros select which one */
156#define REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd )((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd)))
, outb( 4 , qbase + 0xd )((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase +
0xd)))
)
157#define REG1( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd))), ((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __outbc(
(0xb4 | 2),(qbase + 0xd)) : __outb((0xb4 | 2),(qbase + 0xd)))
)
( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd )((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd)))
, outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd )((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((0xb4 | 2),(qbase + 0xd)) : __outb((0xb4
| 2),(qbase + 0xd)))
)
158
159/* following is watchdog timeout in microseconds */
160#define WATCHDOG5000000 5000000
161
162/*----------------------------------------------------------------*/
163/* the following will set the monitor border color (useful to find
164 where something crashed or gets stuck at and as a simple profiler) */
165
166#if 0
167#define rtrc(i){} {inb(0x3da)((__builtin_constant_p((0x3da)) && (0x3da) < 256) ?
__inbc(0x3da) : __inb(0x3da))
;outb(0x31,0x3c0)((__builtin_constant_p((0x3c0)) && (0x3c0) < 256) ?
__outbc((0x31),(0x3c0)) : __outb((0x31),(0x3c0)))
;outb((i),0x3c0)((__builtin_constant_p((0x3c0)) && (0x3c0) < 256) ?
__outbc(((i)),(0x3c0)) : __outb(((i)),(0x3c0)))
;}
168#else
169#define rtrc(i){} {}
170#endif
171
172/*----------------------------------------------------------------*/
173/* local functions */
174/*----------------------------------------------------------------*/
175static void ql_zap(void);
176/* error recovery - reset everything */
177void ql_zap()
178{
179int x;
180unsigned long flags;
181 save_flags( flags )__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
182 cli()__asm__ __volatile__ ("cli": : :"memory");
183 x = inb(qbase + 0xd)((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __inbc(qbase + 0xd) : __inb(qbase + 0xd))
;
184 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
185 outb(3, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((3),(qbase + 3)) : __outb((3),(qbase + 3)))
; /* reset SCSI */
186 outb(2, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((2),(qbase + 3)) : __outb((2),(qbase + 3)))
; /* reset chip */
187 if (x & 0x80)
188 REG1( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd))), ((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __outbc(
(0xb4 | 2),(qbase + 0xd)) : __outb((0xb4 | 2),(qbase + 0xd)))
)
;
189 restore_flags( flags )__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
190}
191
192/*----------------------------------------------------------------*/
193/* do pseudo-dma */
194static int ql_pdma(int phase, char *request, int reqlen)
195{
196int j;
197 j = 0;
198 if (phase & 1) { /* in */
199#if QL_TURBO_PDMA1
200rtrc(4){}
201 /* empty fifo in large chunks */
202 if( reqlen >= 128 && (inb( qbase + 8 )((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
& 2) ) { /* full */
203 insl( qbase + 4, request, 32 );
204 reqlen -= 128;
205 request += 128;
206 }
207 while( reqlen >= 84 && !( j & 0xc0 ) ) /* 2/3 */
208 if( (j=inb( qbase + 8 )((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
) & 4 ) {
209 insl( qbase + 4, request, 21 );
210 reqlen -= 84;
211 request += 84;
212 }
213 if( reqlen >= 44 && (inb( qbase + 8 )((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
& 8) ) { /* 1/3 */
214 insl( qbase + 4, request, 11 );
215 reqlen -= 44;
216 request += 44;
217 }
218#endif
219 /* until both empty and int (or until reclen is 0) */
220rtrc(7){}
221 j = 0;
222 while( reqlen && !( (j & 0x10) && (j & 0xc0) ) ) {
223 /* while bytes to receive and not empty */
224 j &= 0xc0;
225 while ( reqlen && !( (j=inb(qbase + 8)((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
) & 0x10 ) ) {
226 *request++ = inb(qbase + 4)((__builtin_constant_p((qbase + 4)) && (qbase + 4) <
256) ? __inbc(qbase + 4) : __inb(qbase + 4))
;
227 reqlen--;
228 }
229 if( j & 0x10 )
230 j = inb(qbase+8)((__builtin_constant_p((qbase+8)) && (qbase+8) < 256
) ? __inbc(qbase+8) : __inb(qbase+8))
;
231
232 }
233 }
234 else { /* out */
235#if QL_TURBO_PDMA1
236rtrc(4){}
237 if( reqlen >= 128 && inb( qbase + 8 )((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
& 0x10 ) { /* empty */
238 outsl(qbase + 4, request, 32 );
239 reqlen -= 128;
240 request += 128;
241 }
242 while( reqlen >= 84 && !( j & 0xc0 ) ) /* 1/3 */
243 if( !((j=inb( qbase + 8 )((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
) & 8) ) {
244 outsl( qbase + 4, request, 21 );
245 reqlen -= 84;
246 request += 84;
247 }
248 if( reqlen >= 40 && !(inb( qbase + 8 )((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
& 4 ) ) { /* 2/3 */
249 outsl( qbase + 4, request, 10 );
250 reqlen -= 40;
251 request += 40;
252 }
253#endif
254 /* until full and int (or until reclen is 0) */
255rtrc(7){}
256 j = 0;
257 while( reqlen && !( (j & 2) && (j & 0xc0) ) ) {
258 /* while bytes to send and not full */
259 while ( reqlen && !( (j=inb(qbase + 8)((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
) & 2 ) ) {
260 outb(*request++, qbase + 4)((__builtin_constant_p((qbase + 4)) && (qbase + 4) <
256) ? __outbc((*request++),(qbase + 4)) : __outb((*request++
),(qbase + 4)))
;
261 reqlen--;
262 }
263 if( j & 2 )
264 j = inb(qbase+8)((__builtin_constant_p((qbase+8)) && (qbase+8) < 256
) ? __inbc(qbase+8) : __inb(qbase+8))
;
265 }
266 }
267/* maybe return reqlen */
268 return inb( qbase + 8 )((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
& 0xc0;
269}
270
271/*----------------------------------------------------------------*/
272/* wait for interrupt flag (polled - not real hardware interrupt) */
273static int ql_wai(void)
274{
275int i,k;
276 k = 0;
277 i = jiffies + WATCHDOG5000000;
278 while ( i > jiffies && !qabort && !((k = inb(qbase + 4)((__builtin_constant_p((qbase + 4)) && (qbase + 4) <
256) ? __inbc(qbase + 4) : __inb(qbase + 4))
) & 0xe0))
279 barrier()__asm__ __volatile__("": : :"memory");
280 if (i <= jiffies)
281 return (DID_TIME_OUT0x03);
282 if (qabort)
283 return (qabort == 1 ? DID_ABORT0x05 : DID_RESET0x08);
284 if (k & 0x60)
285 ql_zap();
286 if (k & 0x20)
287 return (DID_PARITY0x06);
288 if (k & 0x40)
289 return (DID_ERROR0x07);
290 return 0;
291}
292
293/*----------------------------------------------------------------*/
294/* initiate scsi command - queueing handler */
295static void ql_icmd(Scsi_Cmnd * cmd)
296{
297unsigned int i;
298unsigned long flags;
299
300 qabort = 0;
301
302 save_flags( flags )__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
303 cli()__asm__ __volatile__ ("cli": : :"memory");
304 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
305/* clearing of interrupts and the fifo is needed */
306 inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
; /* clear interrupts */
307 if (inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
) /* if still interrupting */
308 outb(2, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((2),(qbase + 3)) : __outb((2),(qbase + 3)))
; /* reset chip */
309 else if (inb(qbase + 7)((__builtin_constant_p((qbase + 7)) && (qbase + 7) <
256) ? __inbc(qbase + 7) : __inb(qbase + 7))
& 0x1f)
310 outb(1, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((1),(qbase + 3)) : __outb((1),(qbase + 3)))
; /* clear fifo */
311 while (inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
); /* clear ints */
312 REG1( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd))), ((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __outbc(
(0xb4 | 2),(qbase + 0xd)) : __outb((0xb4 | 2),(qbase + 0xd)))
)
;
313 outb(1, qbase + 8)((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __outbc((1),(qbase + 8)) : __outb((1),(qbase + 8)))
; /* set for PIO pseudo DMA */
314 outb(0, qbase + 0xb)((__builtin_constant_p((qbase + 0xb)) && (qbase + 0xb
) < 256) ? __outbc((0),(qbase + 0xb)) : __outb((0),(qbase +
0xb)))
; /* disable ints */
315 inb(qbase + 8)((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __inbc(qbase + 8) : __inb(qbase + 8))
; /* clear int bits */
316 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
317 outb(0x40, qbase + 0xb)((__builtin_constant_p((qbase + 0xb)) && (qbase + 0xb
) < 256) ? __outbc((0x40),(qbase + 0xb)) : __outb((0x40),(
qbase + 0xb)))
; /* enable features */
318
319/* configurables */
320 outb( qlcfgc , qbase + 0xc)((__builtin_constant_p((qbase + 0xc)) && (qbase + 0xc
) < 256) ? __outbc((qlcfgc),(qbase + 0xc)) : __outb((qlcfgc
),(qbase + 0xc)))
;
321/* config: no reset interrupt, (initiator) bus id */
322 outb( 0x40 | qlcfg8 | qinitid, qbase + 8)((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __outbc((0x40 | qlcfg8 | qinitid),(qbase + 8)) : __outb
((0x40 | qlcfg8 | qinitid),(qbase + 8)))
;
323 outb( qlcfg7 , qbase + 7 )((__builtin_constant_p((qbase + 7)) && (qbase + 7) <
256) ? __outbc((qlcfg7),(qbase + 7)) : __outb((qlcfg7),(qbase
+ 7)))
;
324 outb( qlcfg6 , qbase + 6 )((__builtin_constant_p((qbase + 6)) && (qbase + 6) <
256) ? __outbc((qlcfg6),(qbase + 6)) : __outb((qlcfg6),(qbase
+ 6)))
;
325/**/
326 outb(qlcfg5, qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __outbc((qlcfg5),(qbase + 5)) : __outb((qlcfg5),(qbase
+ 5)))
; /* select timer */
327 outb(qlcfg9 & 7, qbase + 9)((__builtin_constant_p((qbase + 9)) && (qbase + 9) <
256) ? __outbc((qlcfg9 & 7),(qbase + 9)) : __outb((qlcfg9
& 7),(qbase + 9)))
; /* prescaler */
328/* outb(0x99, qbase + 5); */
329 outb(cmd->target, qbase + 4)((__builtin_constant_p((qbase + 4)) && (qbase + 4) <
256) ? __outbc((cmd->target),(qbase + 4)) : __outb((cmd->
target),(qbase + 4)))
;
330
331 for (i = 0; i < cmd->cmd_len; i++)
332 outb(cmd->cmnd[i], qbase + 2)((__builtin_constant_p((qbase + 2)) && (qbase + 2) <
256) ? __outbc((cmd->cmnd[i]),(qbase + 2)) : __outb((cmd->
cmnd[i]),(qbase + 2)))
;
333 qlcmd = cmd;
334 outb(0x41, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((0x41),(qbase + 3)) : __outb((0x41),(qbase + 3
)))
; /* select and send command */
335 restore_flags( flags )__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
336}
337/*----------------------------------------------------------------*/
338/* process scsi command - usually after interrupt */
339static unsigned int ql_pcmd(Scsi_Cmnd * cmd)
340{
341unsigned int i, j, k;
342unsigned int result; /* ultimate return result */
343unsigned int status; /* scsi returned status */
344unsigned int message; /* scsi returned message */
345unsigned int phase; /* recorded scsi phase */
346unsigned int reqlen; /* total length of transfer */
347struct scatterlist *sglist; /* scatter-gather list pointer */
348unsigned int sgcount; /* sg counter */
349
350rtrc(1){}
351 j = inb(qbase + 6)((__builtin_constant_p((qbase + 6)) && (qbase + 6) <
256) ? __inbc(qbase + 6) : __inb(qbase + 6))
;
352 i = inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
;
353 if (i == 0x20) {
354 return (DID_NO_CONNECT0x01 << 16);
355 }
356 i |= inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __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_INTR0x09 << 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 )((__builtin_constant_p((qbase+7)) && (qbase+7) < 256
) ? __inbc(qbase+7) : __inb(qbase+7))
& 0x1f );
369 ql_zap();
370 return (DID_ERROR0x07 << 16);
371 }
372 result = DID_OK0x00;
373 if (inb(qbase + 7)((__builtin_constant_p((qbase + 7)) && (qbase + 7) <
256) ? __inbc(qbase + 7) : __inb(qbase + 7))
& 0x1f) /* if some bytes in fifo */
374 outb(1, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((1),(qbase + 3)) : __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)((__builtin_constant_p((qbase + 4)) && (qbase + 4) <
256) ? __inbc(qbase + 4) : __inb(qbase + 4))
) & 6)) { /* data phase */
379rtrc(2){}
380 outb(reqlen, qbase)((__builtin_constant_p((qbase)) && (qbase) < 256) ?
__outbc((reqlen),(qbase)) : __outb((reqlen),(qbase)))
; /* low-mid xfer cnt */
381 outb(reqlen >> 8, qbase+1)((__builtin_constant_p((qbase+1)) && (qbase+1) < 256
) ? __outbc((reqlen >> 8),(qbase+1)) : __outb((reqlen >>
8),(qbase+1)))
; /* low-mid xfer cnt */
382 outb(reqlen >> 16, qbase + 0xe)((__builtin_constant_p((qbase + 0xe)) && (qbase + 0xe
) < 256) ? __outbc((reqlen >> 16),(qbase + 0xe)) : __outb
((reqlen >> 16),(qbase + 0xe)))
; /* high xfer cnt */
383 outb(0x90, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((0x90),(qbase + 3)) : __outb((0x90),(qbase + 3
)))
; /* command do xfer */
384/* PIO pseudo DMA to buffer or sglist */
385 REG1( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd))), ((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __outbc(
(0xb4 | 2),(qbase + 0xd)) : __outb((0xb4 | 2),(qbase + 0xd)))
)
;
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( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
394 return ((qabort == 1 ? DID_ABORT0x05 : DID_RESET0x08) << 16);
395 }
396 if (ql_pdma(phase, sglist->address, sglist->length))
397 break;
398 sglist++;
399 }
400 }
401 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
402rtrc(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)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
; /* should be 0x10, bus service */
Value stored to 'k' is never read
407 }
408/*** Enter Status (and Message In) Phase ***/
409 k = jiffies + WATCHDOG5000000;
410 while ( k > jiffies && !qabort && !(inb(qbase + 4)((__builtin_constant_p((qbase + 4)) && (qbase + 4) <
256) ? __inbc(qbase + 4) : __inb(qbase + 4))
& 6)); /* wait for status phase */
411 if ( k <= jiffies ) {
412 ql_zap();
413 return (DID_TIME_OUT0x03 << 16);
414 }
415 while (inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
); /* clear pending ints */
416 if (qabort)
417 return ((qabort == 1 ? DID_ABORT0x05 : DID_RESET0x08) << 16);
418 outb(0x11, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((0x11),(qbase + 3)) : __outb((0x11),(qbase + 3
)))
; /* get status and message */
419 if ((k = ql_wai()))
420 return (k << 16);
421 i = inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
; /* get chip irq stat */
422 j = inb(qbase + 7)((__builtin_constant_p((qbase + 7)) && (qbase + 7) <
256) ? __inbc(qbase + 7) : __inb(qbase + 7))
& 0x1f; /* and bytes rec'd */
423 status = inb(qbase + 2)((__builtin_constant_p((qbase + 2)) && (qbase + 2) <
256) ? __inbc(qbase + 2) : __inb(qbase + 2))
;
424 message = inb(qbase + 2)((__builtin_constant_p((qbase + 2)) && (qbase + 2) <
256) ? __inbc(qbase + 2) : __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_ERROR0x07;
429 }
430 outb(0x12, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((0x12),(qbase + 3)) : __outb((0x12),(qbase + 3
)))
; /* done, disconnect */
431rtrc(1){}
432 if ((k = ql_wai()))
433 return (k << 16);
434/* should get bus service interrupt and disconnect interrupt */
435 i = inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
; /* should be bus service */
436 while (!qabort && ((i & 0x20) != 0x20)) {
437 barrier()__asm__ __volatile__("": : :"memory");
438 i |= inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
;
439 }
440rtrc(0){}
441 if (qabort)
442 return ((qabort == 1 ? DID_ABORT0x05 : DID_RESET0x08) << 16);
443 return (result << 16) | (message << 8) | (status & STATUS_MASK0x3e);
444}
445
446#if QL_USE_IRQ1
447/*----------------------------------------------------------------*/
448/* interrupt handler */
449static void ql_ihandl(int irq, void *dev_id, struct pt_regs * regs)
450{
451Scsi_Cmnd *icmd;
452 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
453 if (!(inb(qbase + 4)((__builtin_constant_p((qbase + 4)) && (qbase + 4) <
256) ? __inbc(qbase + 4) : __inb(qbase + 4))
& 0x80)) /* false alarm? */
454 return;
455 if (qlcmd == NULL((void *) 0)) { /* no command to process? */
456 int i;
457 i = 16;
458 while (i-- && inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
); /* maybe also ql_zap() */
459 return;
460 }
461 icmd = qlcmd;
462 icmd->result = ql_pcmd(icmd);
463 qlcmd = NULL((void *) 0);
464/* if result is CHECK CONDITION done calls qcommand to request sense */
465 (icmd->scsi_done) (icmd);
466}
467#endif
468
469/*----------------------------------------------------------------*/
470/* global functions */
471/*----------------------------------------------------------------*/
472/* non queued command */
473#if QL_USE_IRQ1
474static void qlidone(Scsi_Cmnd * cmd) {}; /* null function */
475#endif
476
477/* command process */
478int qlogicfas_command(Scsi_Cmnd * cmd)
479{
480int k;
481#if QL_USE_IRQ1
482 if (qlirq >= 0) {
483 qlogicfas_queuecommand(cmd, qlidone);
484 while (qlcmd != NULL((void *) 0));
485 return cmd->result;
486 }
487#endif
488/* non-irq version */
489 if (cmd->target == qinitid)
490 return (DID_BAD_TARGET0x04 << 16);
491 ql_icmd(cmd);
492 if ((k = ql_wai()))
493 return (k << 16);
494 return ql_pcmd(cmd);
495
496}
497
498#if QL_USE_IRQ1
499/*----------------------------------------------------------------*/
500/* queued command */
501int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
502{
503 if(cmd->target == qinitid) {
504 cmd->result = DID_BAD_TARGET0x04 << 16;
505 done(cmd);
506 return 0;
507 }
508
509 cmd->scsi_done = done;
510/* wait for the last command's interrupt to finish */
511 while (qlcmd != NULL((void *) 0))
512 barrier()__asm__ __volatile__("": : :"memory");
513 ql_icmd(cmd);
514 return 0;
515}
516#else
517int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
518{
519 return 1;
520}
521#endif
522
523#ifdef PCMCIA
524/*----------------------------------------------------------------*/
525/* allow PCMCIA code to preset the port */
526/* port should be 0 and irq to -1 respectively for autoprobing */
527void qlogicfas_preset(int port, int irq)
528{
529 qbase=port;
530 qlirq=irq;
531}
532#endif
533
534/*----------------------------------------------------------------*/
535/* look for qlogic card and init if found */
536int qlogicfas_detect(Scsi_Host_Template * host)
537{
538int i, j; /* these are only used by IRQ detect */
539int qltyp; /* type of chip */
540struct Scsi_Host *hreg; /* registered host structure */
541unsigned long flags;
542
543host->proc_dir = &proc_scsi_qlogicfas;
544
545/* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the
546 address - I check 230 first since MIDI cards are typically at 330
547
548 Theoretically, two Qlogic cards can coexist in the same system. This
549 should work by simply using this as a loadable module for the second
550 card, but I haven't tested this.
551*/
552
553 if( !qbase ) {
554 for (qbase = 0x230; qbase < 0x430; qbase += 0x100) {
555 if( check_region( qbase , 0x10 ) )
556 continue;
557 REG1( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd))), ((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __outbc(
(0xb4 | 2),(qbase + 0xd)) : __outb((0xb4 | 2),(qbase + 0xd)))
)
;
558 if ( ( (inb(qbase + 0xe)((__builtin_constant_p((qbase + 0xe)) && (qbase + 0xe
) < 256) ? __inbc(qbase + 0xe) : __inb(qbase + 0xe))
^ inb(qbase + 0xe)((__builtin_constant_p((qbase + 0xe)) && (qbase + 0xe
) < 256) ? __inbc(qbase + 0xe) : __inb(qbase + 0xe))
) == 7 )
559 && ( (inb(qbase + 0xe)((__builtin_constant_p((qbase + 0xe)) && (qbase + 0xe
) < 256) ? __inbc(qbase + 0xe) : __inb(qbase + 0xe))
^ inb(qbase + 0xe)((__builtin_constant_p((qbase + 0xe)) && (qbase + 0xe
) < 256) ? __inbc(qbase + 0xe) : __inb(qbase + 0xe))
) == 7 ) )
560 break;
561 }
562 if (qbase == 0x430)
563 return 0;
564 }
565 else
566 printk( "Ql: Using preset base address of %03x\n", qbase );
567
568 qltyp = inb(qbase + 0xe)((__builtin_constant_p((qbase + 0xe)) && (qbase + 0xe
) < 256) ? __inbc(qbase + 0xe) : __inb(qbase + 0xe))
& 0xf8;
569 qinitid = host->this_id;
570 if (qinitid < 0)
571 qinitid = 7; /* if no ID, use 7 */
572 outb(1, qbase + 8)((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __outbc((1),(qbase + 8)) : __outb((1),(qbase + 8)))
; /* set for PIO pseudo DMA */
573 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
574 outb(0x40 | qlcfg8 | qinitid, qbase + 8)((__builtin_constant_p((qbase + 8)) && (qbase + 8) <
256) ? __outbc((0x40 | qlcfg8 | qinitid),(qbase + 8)) : __outb
((0x40 | qlcfg8 | qinitid),(qbase + 8)))
; /* (ini) bus id, disable scsi rst */
575 outb(qlcfg5, qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __outbc((qlcfg5),(qbase + 5)) : __outb((qlcfg5),(qbase
+ 5)))
; /* select timer */
576 outb(qlcfg9, qbase + 9)((__builtin_constant_p((qbase + 9)) && (qbase + 9) <
256) ? __outbc((qlcfg9),(qbase + 9)) : __outb((qlcfg9),(qbase
+ 9)))
; /* prescaler */
577#if QL_RESET_AT_START0
578 outb( 3 , qbase + 3 )((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((3),(qbase + 3)) : __outb((3),(qbase + 3)))
;
579 REG1( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd))), ((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __outbc(
(0xb4 | 2),(qbase + 0xd)) : __outb((0xb4 | 2),(qbase + 0xd)))
)
;
580 while( inb( qbase + 0xf )((__builtin_constant_p((qbase + 0xf)) && (qbase + 0xf
) < 256) ? __inbc(qbase + 0xf) : __inb(qbase + 0xf))
& 4 );
581 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
582#endif
583#if QL_USE_IRQ1
584/* IRQ probe - toggle pin and check request pending */
585
586 if( qlirq == -1 ) {
587 save_flags( flags )__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
588 cli()__asm__ __volatile__ ("cli": : :"memory");
589 i = 0xffff;
590 j = 3;
591 outb(0x90, qbase + 3)((__builtin_constant_p((qbase + 3)) && (qbase + 3) <
256) ? __outbc((0x90),(qbase + 3)) : __outb((0x90),(qbase + 3
)))
; /* illegal command - cause interrupt */
592 REG1( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) | 0x80),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) | 0x80),(qbase + 0xd))), ((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __outbc(
(0xb4 | 2),(qbase + 0xd)) : __outb((0xb4 | 2),(qbase + 0xd)))
)
;
593 outb(10, 0x20)((__builtin_constant_p((0x20)) && (0x20) < 256) ? __outbc
((10),(0x20)) : __outb((10),(0x20)))
; /* access pending interrupt map */
594 outb(10, 0xa0)((__builtin_constant_p((0xa0)) && (0xa0) < 256) ? __outbc
((10),(0xa0)) : __outb((10),(0xa0)))
;
595 while (j--) {
596 outb(0xb0 | QL_INT_ACTIVE_HIGH , qbase + 0xd)((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((0xb0 | 2),(qbase + 0xd)) : __outb((0xb0
| 2),(qbase + 0xd)))
; /* int pin off */
597 i &= ~(inb(0x20)((__builtin_constant_p((0x20)) && (0x20) < 256) ? __inbc
(0x20) : __inb(0x20))
| (inb(0xa0)((__builtin_constant_p((0xa0)) && (0xa0) < 256) ? __inbc
(0xa0) : __inb(0xa0))
<< 8)); /* find IRQ off */
598 outb(0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd)((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((0xb4 | 2),(qbase + 0xd)) : __outb((0xb4
| 2),(qbase + 0xd)))
; /* int pin on */
599 i &= inb(0x20)((__builtin_constant_p((0x20)) && (0x20) < 256) ? __inbc
(0x20) : __inb(0x20))
| (inb(0xa0)((__builtin_constant_p((0xa0)) && (0xa0) < 256) ? __inbc
(0xa0) : __inb(0xa0))
<< 8); /* find IRQ on */
600 }
601 REG0( ((__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd
) < 256) ? __outbc((((__builtin_constant_p((qbase + 0xd)) &&
(qbase + 0xd) < 256) ? __inbc(qbase + 0xd) : __inb(qbase +
0xd)) & 0x7f),(qbase + 0xd)) : __outb((((__builtin_constant_p
((qbase + 0xd)) && (qbase + 0xd) < 256) ? __inbc(qbase
+ 0xd) : __inb(qbase + 0xd)) & 0x7f),(qbase + 0xd))), ((
__builtin_constant_p((qbase + 0xd)) && (qbase + 0xd) <
256) ? __outbc((4),(qbase + 0xd)) : __outb((4),(qbase + 0xd)
)))
;
602 while (inb(qbase + 5)((__builtin_constant_p((qbase + 5)) && (qbase + 5) <
256) ? __inbc(qbase + 5) : __inb(qbase + 5))
); /* purge int */
603 j = -1;
604 while (i) /* find on bit */
605 i >>= 1, j++; /* should check for exactly 1 on */
606 qlirq = j;
607 restore_flags( flags )__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
608 }
609 else
610 printk( "Ql: Using preset IRQ %d\n", qlirq );
611
612 if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogicfas", NULL((void *) 0)))
613 host->can_queue = 1;
614#endif
615 request_region( qbase , 0x10 ,"qlogicfas");
616 hreg = scsi_register( host , 0 ); /* no host data */
617 hreg->io_port = qbase;
618 hreg->n_io_port = 16;
619 hreg->dma_channel = -1;
620 if( qlirq != -1 )
621 hreg->irq = qlirq;
622
623 sprintflinux_sprintf(qinfo, "Qlogicfas Driver version 0.45, chip %02X at %03X, IRQ %d, TPdma:%d",
624 qltyp, qbase, qlirq, QL_TURBO_PDMA1 );
625 host->name = qinfo;
626
627 return 1;
628}
629
630/*----------------------------------------------------------------*/
631/* return bios parameters */
632int qlogicfas_biosparam(Disk * disk, kdev_t dev, int ip[])
633{
634/* This should mimic the DOS Qlogic driver's behavior exactly */
635 ip[0] = 0x40;
636 ip[1] = 0x20;
637 ip[2] = disk->capacity / (ip[0] * ip[1]);
638 if (ip[2] > 1024) {
639 ip[0] = 0xff;
640 ip[1] = 0x3f;
641 ip[2] = disk->capacity / (ip[0] * ip[1]);
642 if (ip[2] > 1023)
643 ip[2] = 1023;
644 }
645 return 0;
646}
647
648/*----------------------------------------------------------------*/
649/* abort command in progress */
650int qlogicfas_abort(Scsi_Cmnd * cmd)
651{
652 qabort = 1;
653 ql_zap();
654 return 0;
655}
656
657/*----------------------------------------------------------------*/
658/* reset SCSI bus */
659int qlogicfas_reset(Scsi_Cmnd * cmd, unsigned int flags)
660{
661 qabort = 2;
662 ql_zap();
663 return 1;
664}
665
666/*----------------------------------------------------------------*/
667/* return info string */
668const char *qlogicfas_info(struct Scsi_Host * host)
669{
670 return qinfo;
671}
672
673#ifdef MODULE
674/* Eventually this will go into an include file, but this will be later */
675Scsi_Host_Template driver_template = QLOGICFAS{ ((void *) 0), ((void *) 0), ((void *) 0), ((void *) 0), ((void
*) 0), qlogicfas_detect, ((void *) 0), qlogicfas_info, qlogicfas_command
, qlogicfas_queuecommand, qlogicfas_abort, qlogicfas_reset, (
(void *) 0), qlogicfas_biosparam, 0, -1, 0xff, 1, 0, 0, 0 }
;
676
677#include "scsi_module.c"
678#endif
679