Bug Summary

File:obj-scan-build/../linux/src/drivers/scsi/qlogicisp.c
Location:line 1686, column 16
Description:Function call argument is an uninitialized value

Annotated Source Code

1/*
2 * QLogic ISP1020 Intelligent SCSI Processor Driver (PCI)
3 * Written by Erik H. Moe, ehm@cris.com
4 * Copyright 1995, Erik H. Moe
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17/* Renamed and updated to 1.3.x by Michael Griffith <grif@cs.ucr.edu> */
18
19/*
20 * $Date: 2007/03/27 21:04:30 $
21 * $Revision: 1.1.4.2 $
22 *
23 * Revision 0.5 1995/09/22 02:23:15 root
24 * do auto request sense
25 *
26 * Revision 0.4 1995/08/07 04:44:33 root
27 * supply firmware with driver.
28 * numerous bug fixes/general cleanup of code.
29 *
30 * Revision 0.3 1995/07/16 16:15:39 root
31 * added reset/abort code.
32 *
33 * Revision 0.2 1995/06/29 03:14:19 root
34 * fixed biosparam.
35 * added queue protocol.
36 *
37 * Revision 0.1 1995/06/25 01:55:45 root
38 * Initial release.
39 *
40 */
41
42#include <linux/blk.h>
43#include <linux/kernel.h>
44#include <linux/string.h>
45#include <linux/ioport.h>
46#include <linux/sched.h>
47#include <linux/types.h>
48#include <linux/bios32.h>
49#include <linux/pci.h>
50#include <linux/delay.h>
51#include <linux/unistd.h>
52#include <asm/io.h>
53#include <asm/irq.h>
54
55#include "sd.h"
56#include "hosts.h"
57#include "qlogicisp.h"
58
59/* Configuration section *****************************************************/
60
61/* Set the following macro to 1 to reload the ISP1020's firmware. This is
62 the latest firmware provided by QLogic. This may be an earlier/later
63 revision than supplied by your board. */
64
65#define RELOAD_FIRMWARE0 0
66
67/* Set the following macro to 1 to reload the ISP1020's defaults from nvram.
68 If you are not sure of your settings, leave this alone, the driver will
69 use a set of 'safe' defaults */
70
71#define USE_NVRAM_DEFAULTS0 0
72
73/* Macros used for debugging */
74
75#define DEBUG_ISP10200 0
76#define DEBUG_ISP1020_INT0 0
77#define DEBUG_ISP1020_SETUP0 0
78#define TRACE_ISP0 0
79
80#define DEFAULT_LOOP_COUNT1000000 1000000
81
82/* End Configuration section *************************************************/
83
84#include <linux/module.h>
85
86#if TRACE_ISP0
87
88# define TRACE_BUF_LEN (32*1024)
89
90struct {
91 u_long next;
92 struct {
93 u_long time;
94 u_int index;
95 u_int addr;
96 u_char * name;
97 } buf[TRACE_BUF_LEN];
98} trace;
99
100#define TRACE(w, i, a) \
101{ \
102 unsigned long flags; \
103 \
104 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
; \
105 cli()__asm__ __volatile__ ("cli": : :"memory"); \
106 trace.buf[trace.next].name = (w); \
107 trace.buf[trace.next].time = jiffies; \
108 trace.buf[trace.next].index = (i); \
109 trace.buf[trace.next].addr = (long) (a); \
110 trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1); \
111 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); \
112}
113
114#else
115# define TRACE(w, i, a)
116#endif
117
118#if DEBUG_ISP10200
119#define ENTER(x) printk("isp1020 : entering %s()\n", x);
120#define LEAVE(x) printk("isp1020 : leaving %s()\n", x);
121#define DEBUG(x) x
122#else
123#define ENTER(x)
124#define LEAVE(x)
125#define DEBUG(x)
126#endif /* DEBUG_ISP1020 */
127
128#if DEBUG_ISP1020_INTR
129#define ENTER_INTR(x) printk("isp1020 : entering %s()\n", x);
130#define LEAVE_INTR(x) printk("isp1020 : leaving %s()\n", x);
131#define DEBUG_INTR(x) x
132#else
133#define ENTER_INTR(x)
134#define LEAVE_INTR(x)
135#define DEBUG_INTR(x)
136#endif /* DEBUG ISP1020_INTR */
137
138#define ISP1020_REV_ID1 1
139
140#define MAX_TARGETS16 16
141#define MAX_LUNS8 8
142
143/* host configuration and control registers */
144#define HOST_HCCR0xc0 0xc0 /* host command and control */
145
146/* pci bus interface registers */
147#define PCI_ID_LOW0x00 0x00 /* vendor id */
148#define PCI_ID_HIGH0x02 0x02 /* device id */
149#define ISP_CFG00x04 0x04 /* configuration register #0 */
150#define ISP_CFG10x06 0x06 /* configuration register #1 */
151#define PCI_INTF_CTL0x08 0x08 /* pci interface control */
152#define PCI_INTF_STS0x0a 0x0a /* pci interface status */
153#define PCI_SEMAPHORE0x0c 0x0c /* pci semaphore */
154#define PCI_NVRAM0x0e 0x0e /* pci nvram interface */
155
156/* mailbox registers */
157#define MBOX00x70 0x70 /* mailbox 0 */
158#define MBOX10x72 0x72 /* mailbox 1 */
159#define MBOX20x74 0x74 /* mailbox 2 */
160#define MBOX30x76 0x76 /* mailbox 3 */
161#define MBOX40x78 0x78 /* mailbox 4 */
162#define MBOX50x7a 0x7a /* mailbox 5 */
163
164/* mailbox command complete status codes */
165#define MBOX_COMMAND_COMPLETE0x4000 0x4000
166#define INVALID_COMMAND0x4001 0x4001
167#define HOST_INTERFACE_ERROR0x4002 0x4002
168#define TEST_FAILED0x4003 0x4003
169#define COMMAND_ERROR0x4005 0x4005
170#define COMMAND_PARAM_ERROR0x4006 0x4006
171
172/* async event status codes */
173#define ASYNC_SCSI_BUS_RESET0x8001 0x8001
174#define SYSTEM_ERROR0x8002 0x8002
175#define REQUEST_TRANSFER_ERROR0x8003 0x8003
176#define RESPONSE_TRANSFER_ERROR0x8004 0x8004
177#define REQUEST_QUEUE_WAKEUP0x8005 0x8005
178#define EXECUTION_TIMEOUT_RESET0x8006 0x8006
179
180struct Entry_header {
181 u_char entry_type;
182 u_char entry_cnt;
183 u_char sys_def_1;
184 u_char flags;
185};
186
187/* entry header type commands */
188#define ENTRY_COMMAND1 1
189#define ENTRY_CONTINUATION2 2
190#define ENTRY_STATUS3 3
191#define ENTRY_MARKER4 4
192#define ENTRY_EXTENDED_COMMAND5 5
193
194/* entry header flag definitions */
195#define EFLAG_CONTINUATION1 1
196#define EFLAG_BUSY2 2
197#define EFLAG_BAD_HEADER4 4
198#define EFLAG_BAD_PAYLOAD8 8
199
200struct dataseg {
201 u_int d_base;
202 u_int d_count;
203};
204
205struct Command_Entry {
206 struct Entry_header hdr;
207 u_int handle;
208 u_char target_lun;
209 u_char target_id;
210 u_short cdb_length;
211 u_short control_flags;
212 u_short rsvd;
213 u_short time_out;
214 u_short segment_cnt;
215 u_char cdb[12];
216 struct dataseg dataseg[4];
217};
218
219/* command entry control flag definitions */
220#define CFLAG_NODISC0x01 0x01
221#define CFLAG_HEAD_TAG0x02 0x02
222#define CFLAG_ORDERED_TAG0x04 0x04
223#define CFLAG_SIMPLE_TAG0x08 0x08
224#define CFLAG_TAR_RTN0x10 0x10
225#define CFLAG_READ0x20 0x20
226#define CFLAG_WRITE0x40 0x40
227
228struct Ext_Command_Entry {
229 struct Entry_header hdr;
230 u_int handle;
231 u_char target_lun;
232 u_char target_id;
233 u_short cdb_length;
234 u_short control_flags;
235 u_short rsvd;
236 u_short time_out;
237 u_short segment_cnt;
238 u_char cdb[44];
239};
240
241struct Continuation_Entry {
242 struct Entry_header hdr;
243 u_int reserved;
244 struct dataseg dataseg[7];
245};
246
247struct Marker_Entry {
248 struct Entry_header hdr;
249 u_int reserved;
250 u_char target_lun;
251 u_char target_id;
252 u_char modifier;
253 u_char rsvd;
254 u_char rsvds[52];
255};
256
257/* marker entry modifier definitions */
258#define SYNC_DEVICE0 0
259#define SYNC_TARGET1 1
260#define SYNC_ALL2 2
261
262struct Status_Entry {
263 struct Entry_header hdr;
264 u_int handle;
265 u_short scsi_status;
266 u_short completion_status;
267 u_short state_flags;
268 u_short status_flags;
269 u_short time;
270 u_short req_sense_len;
271 u_int residual;
272 u_char rsvd[8];
273 u_char req_sense_data[32];
274};
275
276/* status entry completion status definitions */
277#define CS_COMPLETE0x0000 0x0000
278#define CS_INCOMPLETE0x0001 0x0001
279#define CS_DMA_ERROR0x0002 0x0002
280#define CS_TRANSPORT_ERROR0x0003 0x0003
281#define CS_RESET_OCCURRED0x0004 0x0004
282#define CS_ABORTED0x0005 0x0005
283#define CS_TIMEOUT0x0006 0x0006
284#define CS_DATA_OVERRUN0x0007 0x0007
285#define CS_COMMAND_OVERRUN0x0008 0x0008
286#define CS_STATUS_OVERRUN0x0009 0x0009
287#define CS_BAD_MESSAGE0x000a 0x000a
288#define CS_NO_MESSAGE_OUT0x000b 0x000b
289#define CS_EXT_ID_FAILED0x000c 0x000c
290#define CS_IDE_MSG_FAILED0x000d 0x000d
291#define CS_ABORT_MSG_FAILED0x000e 0x000e
292#define CS_REJECT_MSG_FAILED0x000f 0x000f
293#define CS_NOP_MSG_FAILED0x0010 0x0010
294#define CS_PARITY_ERROR_MSG_FAILED0x0011 0x0011
295#define CS_DEVICE_RESET_MSG_FAILED0x0012 0x0012
296#define CS_ID_MSG_FAILED0x0013 0x0013
297#define CS_UNEXP_BUS_FREE0x0014 0x0014
298/* as per app note #83120-514-06a: */
299#define CS_DATA_UNDERRUN0x0015 0x0015
300#define CS_INVALID_ENTRY_TYPE0x001b 0x001b
301#define CS_DEVICE_QUEUE_FULL0x001c 0x001c
302#define CS_SCSI_PHASE_SKIPPED0x001d 0x001d
303#define CS_ARS_FAILED0x001e 0x001e /* auto Req. Sense failed */
304
305/* status entry state flag definitions */
306#define SF_GOT_BUS0x0100 0x0100
307#define SF_GOT_TARGET0x0200 0x0200
308#define SF_SENT_CDB0x0400 0x0400
309#define SF_TRANSFERRED_DATA0x0800 0x0800
310#define SF_GOT_STATUS0x1000 0x1000
311#define SF_GOT_SENSE0x2000 0x2000
312
313/* status entry status flag definitions */
314#define STF_DISCONNECT0x0001 0x0001
315#define STF_SYNCHRONOUS0x0002 0x0002
316#define STF_PARITY_ERROR0x0004 0x0004
317#define STF_BUS_RESET0x0008 0x0008
318#define STF_DEVICE_RESET0x0010 0x0010
319#define STF_ABORTED0x0020 0x0020
320#define STF_TIMEOUT0x0040 0x0040
321#define STF_NEGOTIATION0x0080 0x0080
322
323/* interface control commands */
324#define ISP_RESET0x0001 0x0001
325#define ISP_EN_INT0x0002 0x0002
326#define ISP_EN_RISC0x0004 0x0004
327
328/* host control commands */
329#define HCCR_NOP0x0000 0x0000
330#define HCCR_RESET0x1000 0x1000
331#define HCCR_PAUSE0x2000 0x2000
332#define HCCR_RELEASE0x3000 0x3000
333#define HCCR_SINGLE_STEP0x4000 0x4000
334#define HCCR_SET_HOST_INTR0x5000 0x5000
335#define HCCR_CLEAR_HOST_INTR0x6000 0x6000
336#define HCCR_CLEAR_RISC_INTR0x7000 0x7000
337#define HCCR_BP_ENABLE0x8000 0x8000
338#define HCCR_BIOS_DISABLE0x9000 0x9000
339#define HCCR_TEST_MODE0xf000 0xf000
340
341#define RISC_BUSY0x0004 0x0004
342
343/* mailbox commands */
344#define MBOX_NO_OP0x0000 0x0000
345#define MBOX_LOAD_RAM0x0001 0x0001
346#define MBOX_EXEC_FIRMWARE0x0002 0x0002
347#define MBOX_DUMP_RAM0x0003 0x0003
348#define MBOX_WRITE_RAM_WORD0x0004 0x0004
349#define MBOX_READ_RAM_WORD0x0005 0x0005
350#define MBOX_MAILBOX_REG_TEST0x0006 0x0006
351#define MBOX_VERIFY_CHECKSUM0x0007 0x0007
352#define MBOX_ABOUT_FIRMWARE0x0008 0x0008
353#define MBOX_CHECK_FIRMWARE0x000e 0x000e
354#define MBOX_INIT_REQ_QUEUE0x0010 0x0010
355#define MBOX_INIT_RES_QUEUE0x0011 0x0011
356#define MBOX_EXECUTE_IOCB0x0012 0x0012
357#define MBOX_WAKE_UP0x0013 0x0013
358#define MBOX_STOP_FIRMWARE0x0014 0x0014
359#define MBOX_ABORT0x0015 0x0015
360#define MBOX_ABORT_DEVICE0x0016 0x0016
361#define MBOX_ABORT_TARGET0x0017 0x0017
362#define MBOX_BUS_RESET0x0018 0x0018
363#define MBOX_STOP_QUEUE0x0019 0x0019
364#define MBOX_START_QUEUE0x001a 0x001a
365#define MBOX_SINGLE_STEP_QUEUE0x001b 0x001b
366#define MBOX_ABORT_QUEUE0x001c 0x001c
367#define MBOX_GET_DEV_QUEUE_STATUS0x001d 0x001d
368#define MBOX_GET_FIRMWARE_STATUS0x001f 0x001f
369#define MBOX_GET_INIT_SCSI_ID0x0020 0x0020
370#define MBOX_GET_SELECT_TIMEOUT0x0021 0x0021
371#define MBOX_GET_RETRY_COUNT0x0022 0x0022
372#define MBOX_GET_TAG_AGE_LIMIT0x0023 0x0023
373#define MBOX_GET_CLOCK_RATE0x0024 0x0024
374#define MBOX_GET_ACT_NEG_STATE0x0025 0x0025
375#define MBOX_GET_ASYNC_DATA_SETUP_TIME0x0026 0x0026
376#define MBOX_GET_PCI_PARAMS0x0027 0x0027
377#define MBOX_GET_TARGET_PARAMS0x0028 0x0028
378#define MBOX_GET_DEV_QUEUE_PARAMS0x0029 0x0029
379#define MBOX_SET_INIT_SCSI_ID0x0030 0x0030
380#define MBOX_SET_SELECT_TIMEOUT0x0031 0x0031
381#define MBOX_SET_RETRY_COUNT0x0032 0x0032
382#define MBOX_SET_TAG_AGE_LIMIT0x0033 0x0033
383#define MBOX_SET_CLOCK_RATE0x0034 0x0034
384#define MBOX_SET_ACTIVE_NEG_STATE0x0035 0x0035
385#define MBOX_SET_ASYNC_DATA_SETUP_TIME0x0036 0x0036
386#define MBOX_SET_PCI_CONTROL_PARAMS0x0037 0x0037
387#define MBOX_SET_TARGET_PARAMS0x0038 0x0038
388#define MBOX_SET_DEV_QUEUE_PARAMS0x0039 0x0039
389#define MBOX_RETURN_BIOS_BLOCK_ADDR0x0040 0x0040
390#define MBOX_WRITE_FOUR_RAM_WORDS0x0041 0x0041
391#define MBOX_EXEC_BIOS_IOCB0x0042 0x0042
392
393unsigned short risc_code_addr01 = 0x1000 ;
394
395#define PACKB(a, b)(((a)<<4)|(b)) (((a)<<4)|(b))
396
397const u_char mbox_param[] = {
398 PACKB(1, 1)(((1)<<4)|(1)), /* MBOX_NO_OP */
399 PACKB(5, 5)(((5)<<4)|(5)), /* MBOX_LOAD_RAM */
400 PACKB(2, 0)(((2)<<4)|(0)), /* MBOX_EXEC_FIRMWARE */
401 PACKB(5, 5)(((5)<<4)|(5)), /* MBOX_DUMP_RAM */
402 PACKB(3, 3)(((3)<<4)|(3)), /* MBOX_WRITE_RAM_WORD */
403 PACKB(2, 3)(((2)<<4)|(3)), /* MBOX_READ_RAM_WORD */
404 PACKB(6, 6)(((6)<<4)|(6)), /* MBOX_MAILBOX_REG_TEST */
405 PACKB(2, 3)(((2)<<4)|(3)), /* MBOX_VERIFY_CHECKSUM */
406 PACKB(1, 3)(((1)<<4)|(3)), /* MBOX_ABOUT_FIRMWARE */
407 PACKB(0, 0)(((0)<<4)|(0)), /* 0x0009 */
408 PACKB(0, 0)(((0)<<4)|(0)), /* 0x000a */
409 PACKB(0, 0)(((0)<<4)|(0)), /* 0x000b */
410 PACKB(0, 0)(((0)<<4)|(0)), /* 0x000c */
411 PACKB(0, 0)(((0)<<4)|(0)), /* 0x000d */
412 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_CHECK_FIRMWARE */
413 PACKB(0, 0)(((0)<<4)|(0)), /* 0x000f */
414 PACKB(5, 5)(((5)<<4)|(5)), /* MBOX_INIT_REQ_QUEUE */
415 PACKB(6, 6)(((6)<<4)|(6)), /* MBOX_INIT_RES_QUEUE */
416 PACKB(4, 4)(((4)<<4)|(4)), /* MBOX_EXECUTE_IOCB */
417 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_WAKE_UP */
418 PACKB(1, 6)(((1)<<4)|(6)), /* MBOX_STOP_FIRMWARE */
419 PACKB(4, 4)(((4)<<4)|(4)), /* MBOX_ABORT */
420 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_ABORT_DEVICE */
421 PACKB(3, 3)(((3)<<4)|(3)), /* MBOX_ABORT_TARGET */
422 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_BUS_RESET */
423 PACKB(2, 3)(((2)<<4)|(3)), /* MBOX_STOP_QUEUE */
424 PACKB(2, 3)(((2)<<4)|(3)), /* MBOX_START_QUEUE */
425 PACKB(2, 3)(((2)<<4)|(3)), /* MBOX_SINGLE_STEP_QUEUE */
426 PACKB(2, 3)(((2)<<4)|(3)), /* MBOX_ABORT_QUEUE */
427 PACKB(2, 4)(((2)<<4)|(4)), /* MBOX_GET_DEV_QUEUE_STATUS */
428 PACKB(0, 0)(((0)<<4)|(0)), /* 0x001e */
429 PACKB(1, 3)(((1)<<4)|(3)), /* MBOX_GET_FIRMWARE_STATUS */
430 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_GET_INIT_SCSI_ID */
431 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_GET_SELECT_TIMEOUT */
432 PACKB(1, 3)(((1)<<4)|(3)), /* MBOX_GET_RETRY_COUNT */
433 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_GET_TAG_AGE_LIMIT */
434 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_GET_CLOCK_RATE */
435 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_GET_ACT_NEG_STATE */
436 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_GET_ASYNC_DATA_SETUP_TIME */
437 PACKB(1, 3)(((1)<<4)|(3)), /* MBOX_GET_PCI_PARAMS */
438 PACKB(2, 4)(((2)<<4)|(4)), /* MBOX_GET_TARGET_PARAMS */
439 PACKB(2, 4)(((2)<<4)|(4)), /* MBOX_GET_DEV_QUEUE_PARAMS */
440 PACKB(0, 0)(((0)<<4)|(0)), /* 0x002a */
441 PACKB(0, 0)(((0)<<4)|(0)), /* 0x002b */
442 PACKB(0, 0)(((0)<<4)|(0)), /* 0x002c */
443 PACKB(0, 0)(((0)<<4)|(0)), /* 0x002d */
444 PACKB(0, 0)(((0)<<4)|(0)), /* 0x002e */
445 PACKB(0, 0)(((0)<<4)|(0)), /* 0x002f */
446 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_SET_INIT_SCSI_ID */
447 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_SET_SELECT_TIMEOUT */
448 PACKB(3, 3)(((3)<<4)|(3)), /* MBOX_SET_RETRY_COUNT */
449 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_SET_TAG_AGE_LIMIT */
450 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_SET_CLOCK_RATE */
451 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_SET_ACTIVE_NEG_STATE */
452 PACKB(2, 2)(((2)<<4)|(2)), /* MBOX_SET_ASYNC_DATA_SETUP_TIME */
453 PACKB(3, 3)(((3)<<4)|(3)), /* MBOX_SET_PCI_CONTROL_PARAMS */
454 PACKB(4, 4)(((4)<<4)|(4)), /* MBOX_SET_TARGET_PARAMS */
455 PACKB(4, 4)(((4)<<4)|(4)), /* MBOX_SET_DEV_QUEUE_PARAMS */
456 PACKB(0, 0)(((0)<<4)|(0)), /* 0x003a */
457 PACKB(0, 0)(((0)<<4)|(0)), /* 0x003b */
458 PACKB(0, 0)(((0)<<4)|(0)), /* 0x003c */
459 PACKB(0, 0)(((0)<<4)|(0)), /* 0x003d */
460 PACKB(0, 0)(((0)<<4)|(0)), /* 0x003e */
461 PACKB(0, 0)(((0)<<4)|(0)), /* 0x003f */
462 PACKB(1, 2)(((1)<<4)|(2)), /* MBOX_RETURN_BIOS_BLOCK_ADDR */
463 PACKB(6, 1)(((6)<<4)|(1)), /* MBOX_WRITE_FOUR_RAM_WORDS */
464 PACKB(2, 3)(((2)<<4)|(3)) /* MBOX_EXEC_BIOS_IOCB */
465};
466
467#define MAX_MBOX_COMMAND(sizeof(mbox_param)/sizeof(u_short)) (sizeof(mbox_param)/sizeof(u_short))
468
469struct host_param {
470 u_short fifo_threshold;
471 u_short host_adapter_enable;
472 u_short initiator_scsi_id;
473 u_short bus_reset_delay;
474 u_short retry_count;
475 u_short retry_delay;
476 u_short async_data_setup_time;
477 u_short req_ack_active_negation;
478 u_short data_line_active_negation;
479 u_short data_dma_burst_enable;
480 u_short command_dma_burst_enable;
481 u_short tag_aging;
482 u_short selection_timeout;
483 u_short max_queue_depth;
484};
485
486/*
487 * Device Flags:
488 *
489 * Bit Name
490 * ---------
491 * 7 Disconnect Privilege
492 * 6 Parity Checking
493 * 5 Wide Data Transfers
494 * 4 Synchronous Data Transfers
495 * 3 Tagged Queuing
496 * 2 Automatic Request Sense
497 * 1 Stop Queue on Check Condition
498 * 0 Renegotiate on Error
499 */
500
501struct dev_param {
502 u_short device_flags;
503 u_short execution_throttle;
504 u_short synchronous_period;
505 u_short synchronous_offset;
506 u_short device_enable;
507 u_short reserved; /* pad */
508};
509
510/*
511 * The result queue can be quite a bit smaller since continuation entries
512 * do not show up there:
513 */
514#define RES_QUEUE_LEN((63 + 1) / 8 - 1) ((QLOGICISP_REQ_QUEUE_LEN63 + 1) / 8 - 1)
515#define QUEUE_ENTRY_LEN64 64
516
517struct isp1020_hostdata {
518 u_char bus;
519 u_char revision;
520 u_char device_fn;
521 struct host_param host_param;
522 struct dev_param dev_param[MAX_TARGETS16];
523
524 /* result and request queues (shared with isp1020): */
525 u_int req_in_ptr; /* index of next request slot */
526 u_int res_out_ptr; /* index of next result slot */
527
528 /* this is here so the queues are nicely aligned */
529 long send_marker; /* do we need to send a marker? */
530
531 char res[RES_QUEUE_LEN((63 + 1) / 8 - 1)+1][QUEUE_ENTRY_LEN64];
532 char req[QLOGICISP_REQ_QUEUE_LEN63+1][QUEUE_ENTRY_LEN64];
533};
534
535/* queue length's _must_ be power of two: */
536#define QUEUE_DEPTH(in, out, ql)((in - out) & (ql)) ((in - out) & (ql))
537#define REQ_QUEUE_DEPTH(in, out)((in - out) & (63)) QUEUE_DEPTH(in, out, \((in - out) & (63))
538 QLOGICISP_REQ_QUEUE_LEN)((in - out) & (63))
539#define RES_QUEUE_DEPTH(in, out)((in - out) & (((63 + 1) / 8 - 1))) QUEUE_DEPTH(in, out, RES_QUEUE_LEN)((in - out) & (((63 + 1) / 8 - 1)))
540
541struct Scsi_Host *irq2host[NR_IRQS16];
542
543static void isp1020_enable_irqs(struct Scsi_Host *);
544static void isp1020_disable_irqs(struct Scsi_Host *);
545static int isp1020_init(struct Scsi_Host *);
546static int isp1020_reset_hardware(struct Scsi_Host *);
547static int isp1020_set_defaults(struct Scsi_Host *);
548static int isp1020_load_parameters(struct Scsi_Host *);
549static int isp1020_mbox_command(struct Scsi_Host *, u_short []);
550static int isp1020_return_status(struct Status_Entry *);
551static void isp1020_intr_handler(int, void *, struct pt_regs *);
552
553#if USE_NVRAM_DEFAULTS0
554static int isp1020_get_defaults(struct Scsi_Host *);
555static int isp1020_verify_nvram(struct Scsi_Host *);
556static u_short isp1020_read_nvram_word(struct Scsi_Host *, u_short);
557#endif
558
559#if DEBUG_ISP10200
560static void isp1020_print_scsi_cmd(Scsi_Cmnd *);
561#endif
562#if DEBUG_ISP1020_INTR
563static void isp1020_print_status_entry(struct Status_Entry *);
564#endif
565
566static struct proc_dir_entry proc_scsi_isp1020 = {
567 PROC_SCSI_QLOGICISP, 7, "isp1020",
568 S_IFDIR0040000 | S_IRUGO(00400|00040|00004) | S_IXUGO(00100|00010|00001), 2
569};
570
571
572static inlineinline __attribute__((always_inline)) void isp1020_enable_irqs(struct Scsi_Host *host)
573{
574 outw(ISP_EN_INT|ISP_EN_RISC, host->io_port + PCI_INTF_CTL)((__builtin_constant_p((host->io_port + 0x08)) && (
host->io_port + 0x08) < 256) ? __outwc((0x0002|0x0004),
(host->io_port + 0x08)) : __outw((0x0002|0x0004),(host->
io_port + 0x08)))
;
575}
576
577
578static inlineinline __attribute__((always_inline)) void isp1020_disable_irqs(struct Scsi_Host *host)
579{
580 outw(0x0, host->io_port + PCI_INTF_CTL)((__builtin_constant_p((host->io_port + 0x08)) && (
host->io_port + 0x08) < 256) ? __outwc((0x0),(host->
io_port + 0x08)) : __outw((0x0),(host->io_port + 0x08)))
;
581}
582
583
584int isp1020_detect(Scsi_Host_Template *tmpt)
585{
586 int hosts = 0;
587 u_short index;
588 u_char bus, device_fn;
589 struct Scsi_Host *host;
590 struct isp1020_hostdata *hostdata;
591
592 ENTER("isp1020_detect");
593
594 tmpt->proc_dir = &proc_scsi_isp1020;
595
596 if (pcibios_present() == 0) {
597 printk("qlogicisp : PCI bios not present\n");
598 return 0;
599 }
600
601 memset(irq2host, 0, sizeof(irq2host))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(irq2host
))) ? __constant_c_and_count_memset(((irq2host)),((0x01010101UL
*(unsigned char)(0))),((sizeof(irq2host)))) : __constant_c_memset
(((irq2host)),((0x01010101UL*(unsigned char)(0))),((sizeof(irq2host
))))) : (__builtin_constant_p((sizeof(irq2host))) ? __memset_generic
((((irq2host))),(((0))),(((sizeof(irq2host))))) : __memset_generic
(((irq2host)),((0)),((sizeof(irq2host))))))
;
602
603 for (index = 0; pcibios_find_device(PCI_VENDOR_ID_QLOGIC0x1077,
604 PCI_DEVICE_ID_QLOGIC_ISP10200x1020,
605 index, &bus, &device_fn) == 0;
606 index++)
607 {
608 host = scsi_register(tmpt, sizeof(struct isp1020_hostdata));
609 hostdata = (struct isp1020_hostdata *) host->hostdata;
610
611 memset(hostdata, 0, sizeof(struct isp1020_hostdata))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(struct
isp1020_hostdata))) ? __constant_c_and_count_memset(((hostdata
)),((0x01010101UL*(unsigned char)(0))),((sizeof(struct isp1020_hostdata
)))) : __constant_c_memset(((hostdata)),((0x01010101UL*(unsigned
char)(0))),((sizeof(struct isp1020_hostdata))))) : (__builtin_constant_p
((sizeof(struct isp1020_hostdata))) ? __memset_generic((((hostdata
))),(((0))),(((sizeof(struct isp1020_hostdata))))) : __memset_generic
(((hostdata)),((0)),((sizeof(struct isp1020_hostdata))))))
;
612 hostdata->bus = bus;
613 hostdata->device_fn = device_fn;
614
615 if (isp1020_init(host) || isp1020_reset_hardware(host)
616#if USE_NVRAM_DEFAULTS0
617 || isp1020_get_defaults(host)
618#else
619 || isp1020_set_defaults(host)
620#endif /* USE_NVRAM_DEFAULTS */
621 || isp1020_load_parameters(host)) {
622 scsi_unregister(host);
623 continue;
624 }
625
626 host->this_id = hostdata->host_param.initiator_scsi_id;
627
628 if (request_irq(host->irq, isp1020_intr_handler, SA_INTERRUPT0x20000000,
629 "qlogicisp", NULL((void *) 0)))
630 {
631 printk("qlogicisp : interrupt %d already in use\n",
632 host->irq);
633 scsi_unregister(host);
634 continue;
635 }
636
637 if (check_region(host->io_port, 0xff)) {
638 printk("qlogicisp : i/o region 0x%04x-0x%04x already "
639 "in use\n",
640 host->io_port, host->io_port + 0xff);
641 free_irq(host->irq, NULL((void *) 0));
642 scsi_unregister(host);
643 continue;
644 }
645
646 request_region(host->io_port, 0xff, "qlogicisp");
647 irq2host[host->irq] = host;
648
649 outw(0x0, host->io_port + PCI_SEMAPHORE)((__builtin_constant_p((host->io_port + 0x0c)) && (
host->io_port + 0x0c) < 256) ? __outwc((0x0),(host->
io_port + 0x0c)) : __outw((0x0),(host->io_port + 0x0c)))
;
650 outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x7000),(host->
io_port + 0xc0)) : __outw((0x7000),(host->io_port + 0xc0))
)
;
651 isp1020_enable_irqs(host);
652
653 hosts++;
654 }
655
656 LEAVE("isp1020_detect");
657
658 return hosts;
659}
660
661
662int isp1020_release(struct Scsi_Host *host)
663{
664 struct isp1020_hostdata *hostdata;
665
666 ENTER("isp1020_release");
667
668 hostdata = (struct isp1020_hostdata *) host->hostdata;
669
670 outw(0x0, host->io_port + PCI_INTF_CTL)((__builtin_constant_p((host->io_port + 0x08)) && (
host->io_port + 0x08) < 256) ? __outwc((0x0),(host->
io_port + 0x08)) : __outw((0x0),(host->io_port + 0x08)))
;
671 free_irq(host->irq, NULL((void *) 0));
672
673 release_region(host->io_port, 0xff);
674
675 LEAVE("isp1020_release");
676
677 return 0;
678}
679
680
681const char *isp1020_info(struct Scsi_Host *host)
682{
683 static char buf[80];
684 struct isp1020_hostdata *hostdata;
685
686 ENTER("isp1020_info");
687
688 hostdata = (struct isp1020_hostdata *) host->hostdata;
689 sprintflinux_sprintf(buf,
690 "QLogic ISP1020 SCSI on PCI bus %d device %d irq %d base 0x%x",
691 hostdata->bus, (hostdata->device_fn & 0xf8) >> 3, host->irq,
692 host->io_port);
693
694 LEAVE("isp1020_info");
695
696 return buf;
697}
698
699
700/*
701 * The middle SCSI layer ensures that queuecommand never gets invoked
702 * concurrently with itself or the interrupt handler (though the
703 * interrupt handler may call this routine as part of
704 * request-completion handling).
705 */
706int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
707{
708 int i, sg_count, n, num_free;
709 u_int in_ptr, out_ptr;
710 struct dataseg * ds;
711 struct scatterlist *sg;
712 struct Command_Entry *cmd;
713 struct Continuation_Entry *cont;
714 struct Scsi_Host *host;
715 struct isp1020_hostdata *hostdata;
716
717 ENTER("isp1020_queuecommand");
718
719 host = Cmnd->host;
720 hostdata = (struct isp1020_hostdata *) host->hostdata;
721 Cmnd->scsi_done = done;
722
723 DEBUG(isp1020_print_scsi_cmd(Cmnd));
724
725 out_ptr = inw(host->io_port + MBOX4)((__builtin_constant_p((host->io_port + 0x78)) && (
host->io_port + 0x78) < 256) ? __inwc(host->io_port +
0x78) : __inw(host->io_port + 0x78))
;
726 in_ptr = hostdata->req_in_ptr;
727
728 DEBUG(printk("qlogicisp : request queue depth %d\n",
729 REQ_QUEUE_DEPTH(in_ptr, out_ptr)));
730
731 cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
732 in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN63;
733 if (in_ptr == out_ptr) {
734 printk("qlogicisp : request queue overflow\n");
735 return 1;
736 }
737
738 if (hostdata->send_marker) {
739 struct Marker_Entry *marker;
740
741 TRACE("queue marker", in_ptr, 0);
742
743 DEBUG(printk("qlogicisp : adding marker entry\n"));
744 marker = (struct Marker_Entry *) cmd;
745 memset(marker, 0, sizeof(struct Marker_Entry))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(struct
Marker_Entry))) ? __constant_c_and_count_memset(((marker)),(
(0x01010101UL*(unsigned char)(0))),((sizeof(struct Marker_Entry
)))) : __constant_c_memset(((marker)),((0x01010101UL*(unsigned
char)(0))),((sizeof(struct Marker_Entry))))) : (__builtin_constant_p
((sizeof(struct Marker_Entry))) ? __memset_generic((((marker)
)),(((0))),(((sizeof(struct Marker_Entry))))) : __memset_generic
(((marker)),((0)),((sizeof(struct Marker_Entry))))))
;
746
747 marker->hdr.entry_type = ENTRY_MARKER4;
748 marker->hdr.entry_cnt = 1;
749 marker->modifier = SYNC_ALL2;
750
751 hostdata->send_marker = 0;
752
753 if (((in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN63) == out_ptr) {
754 outw(in_ptr, host->io_port + MBOX4)((__builtin_constant_p((host->io_port + 0x78)) && (
host->io_port + 0x78) < 256) ? __outwc((in_ptr),(host->
io_port + 0x78)) : __outw((in_ptr),(host->io_port + 0x78))
)
;
755 hostdata->req_in_ptr = in_ptr;
756 printk("qlogicisp : request queue overflow\n");
757 return 1;
758 }
759 cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
760 in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN63;
761 }
762
763 TRACE("queue command", in_ptr, Cmnd);
764
765 memset(cmd, 0, sizeof(struct Command_Entry))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(struct
Command_Entry))) ? __constant_c_and_count_memset(((cmd)),((0x01010101UL
*(unsigned char)(0))),((sizeof(struct Command_Entry)))) : __constant_c_memset
(((cmd)),((0x01010101UL*(unsigned char)(0))),((sizeof(struct Command_Entry
))))) : (__builtin_constant_p((sizeof(struct Command_Entry)))
? __memset_generic((((cmd))),(((0))),(((sizeof(struct Command_Entry
))))) : __memset_generic(((cmd)),((0)),((sizeof(struct Command_Entry
))))))
;
766
767 cmd->hdr.entry_type = ENTRY_COMMAND1;
768 cmd->hdr.entry_cnt = 1;
769
770 cmd->handle = (u_int) virt_to_busvirt_to_phys(Cmnd);
771 cmd->target_lun = Cmnd->lun;
772 cmd->target_id = Cmnd->target;
773 cmd->cdb_length = Cmnd->cmd_len;
774 cmd->control_flags = CFLAG_READ0x20 | CFLAG_WRITE0x40;
775 cmd->time_out = 30;
776
777 memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len)(__builtin_constant_p(Cmnd->cmd_len) ? __constant_memcpy((
cmd->cdb),(Cmnd->cmnd),(Cmnd->cmd_len)) : __memcpy((
cmd->cdb),(Cmnd->cmnd),(Cmnd->cmd_len)))
;
778
779 if (Cmnd->use_sg) {
780 cmd->segment_cnt = sg_count = Cmnd->use_sg;
781 sg = (struct scatterlist *) Cmnd->request_buffer;
782 ds = cmd->dataseg;
783
784 /* fill in first four sg entries: */
785 n = sg_count;
786 if (n > 4)
787 n = 4;
788 for (i = 0; i < n; i++) {
789 ds[i].d_base = (u_int) virt_to_busvirt_to_phys(sg->address);
790 ds[i].d_count = sg->length;
791 ++sg;
792 }
793 sg_count -= 4;
794
795 while (sg_count > 0) {
796 ++cmd->hdr.entry_cnt;
797 cont = (struct Continuation_Entry *)
798 &hostdata->req[in_ptr][0];
799 in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN63;
800 if (in_ptr == out_ptr) {
801 printk("isp1020: unexpected request queue "
802 "overflow\n");
803 return 1;
804 }
805 TRACE("queue continuation", in_ptr, 0);
806 cont->hdr.entry_type = ENTRY_CONTINUATION2;
807 cont->hdr.entry_cnt = 0;
808 cont->hdr.sys_def_1 = 0;
809 cont->hdr.flags = 0;
810 cont->reserved = 0;
811 ds = cont->dataseg;
812 n = sg_count;
813 if (n > 7)
814 n = 7;
815 for (i = 0; i < n; ++i) {
816 ds[i].d_base = (u_int)virt_to_busvirt_to_phys(sg->address);
817 ds[i].d_count = sg->length;
818 ++sg;
819 }
820 sg_count -= n;
821 }
822 } else {
823 cmd->dataseg[0].d_base =
824 (u_int) virt_to_busvirt_to_phys(Cmnd->request_buffer);
825 cmd->dataseg[0].d_count =
826 (u_int) Cmnd->request_bufflen;
827 cmd->segment_cnt = 1;
828 }
829
830 outw(in_ptr, host->io_port + MBOX4)((__builtin_constant_p((host->io_port + 0x78)) && (
host->io_port + 0x78) < 256) ? __outwc((in_ptr),(host->
io_port + 0x78)) : __outw((in_ptr),(host->io_port + 0x78))
)
;
831 hostdata->req_in_ptr = in_ptr;
832
833 num_free = QLOGICISP_REQ_QUEUE_LEN63 - REQ_QUEUE_DEPTH(in_ptr, out_ptr)((in_ptr - out_ptr) & (63));
834 host->can_queue = host->host_busy + num_free;
835 host->sg_tablesize = QLOGICISP_MAX_SG(num_free)(4 + ((num_free) > 0) ? 7*((num_free) - 1) : 0);
836
837 LEAVE("isp1020_queuecommand");
838
839 return 0;
840}
841
842
843#define ASYNC_EVENT_INTERRUPT0x01 0x01
844
845void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
846{
847 Scsi_Cmnd *Cmnd;
848 struct Status_Entry *sts;
849 struct Scsi_Host *host;
850 struct isp1020_hostdata *hostdata;
851 u_int in_ptr, out_ptr;
852 u_short status;
853
854 ENTER_INTR("isp1020_intr_handler");
855
856 host = irq2host[irq];
857 if (!host) {
858 printk("qlogicisp : unexpected interrupt on line %d\n", irq);
859 return;
860 }
861 hostdata = (struct isp1020_hostdata *) host->hostdata;
862
863 DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq));
864
865 if (!(inw(host->io_port + PCI_INTF_STS)((__builtin_constant_p((host->io_port + 0x0a)) && (
host->io_port + 0x0a) < 256) ? __inwc(host->io_port +
0x0a) : __inw(host->io_port + 0x0a))
& 0x04)) {
866 /* spurious interrupts can happen legally */
867 DEBUG_INTR(printk("qlogicisp: got spurious interrupt\n"));
868 return;
869 }
870 in_ptr = inw(host->io_port + MBOX5)((__builtin_constant_p((host->io_port + 0x7a)) && (
host->io_port + 0x7a) < 256) ? __inwc(host->io_port +
0x7a) : __inw(host->io_port + 0x7a))
;
871 outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x7000),(host->
io_port + 0xc0)) : __outw((0x7000),(host->io_port + 0xc0))
)
;
872
873 if ((inw(host->io_port + PCI_SEMAPHORE)((__builtin_constant_p((host->io_port + 0x0c)) && (
host->io_port + 0x0c) < 256) ? __inwc(host->io_port +
0x0c) : __inw(host->io_port + 0x0c))
& ASYNC_EVENT_INTERRUPT0x01)) {
874 status = inw(host->io_port + MBOX0)((__builtin_constant_p((host->io_port + 0x70)) && (
host->io_port + 0x70) < 256) ? __inwc(host->io_port +
0x70) : __inw(host->io_port + 0x70))
;
875
876 DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n",
877 status));
878
879 switch (status) {
880 case ASYNC_SCSI_BUS_RESET0x8001:
881 case EXECUTION_TIMEOUT_RESET0x8006:
882 hostdata->send_marker = 1;
883 break;
884 case INVALID_COMMAND0x4001:
885 case HOST_INTERFACE_ERROR0x4002:
886 case COMMAND_ERROR0x4005:
887 case COMMAND_PARAM_ERROR0x4006:
888 printk("qlogicisp : bad mailbox return status\n");
889 break;
890 }
891 outw(0x0, host->io_port + PCI_SEMAPHORE)((__builtin_constant_p((host->io_port + 0x0c)) && (
host->io_port + 0x0c) < 256) ? __outwc((0x0),(host->
io_port + 0x0c)) : __outw((0x0),(host->io_port + 0x0c)))
;
892 }
893 out_ptr = hostdata->res_out_ptr;
894
895 DEBUG_INTR(printk("qlogicisp : response queue update\n"));
896 DEBUG_INTR(printk("qlogicisp : response queue depth %d\n",
897 QUEUE_DEPTH(in_ptr, out_ptr)));
898
899 while (out_ptr != in_ptr) {
900 sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
901 out_ptr = (out_ptr + 1) & RES_QUEUE_LEN((63 + 1) / 8 - 1);
902
903 Cmnd = (Scsi_Cmnd *) bus_to_virtphys_to_virt(sts->handle);
904
905 TRACE("done", out_ptr, Cmnd);
906
907 if (sts->completion_status == CS_RESET_OCCURRED0x0004
908 || sts->completion_status == CS_ABORTED0x0005
909 || (sts->status_flags & STF_BUS_RESET0x0008))
910 hostdata->send_marker = 1;
911
912 if (sts->state_flags & SF_GOT_SENSE0x2000)
913 memcpy(Cmnd->sense_buffer, sts->req_sense_data,(__builtin_constant_p(sizeof(Cmnd->sense_buffer)) ? __constant_memcpy
((Cmnd->sense_buffer),(sts->req_sense_data),(sizeof(Cmnd
->sense_buffer))) : __memcpy((Cmnd->sense_buffer),(sts->
req_sense_data),(sizeof(Cmnd->sense_buffer))))
914 sizeof(Cmnd->sense_buffer))(__builtin_constant_p(sizeof(Cmnd->sense_buffer)) ? __constant_memcpy
((Cmnd->sense_buffer),(sts->req_sense_data),(sizeof(Cmnd
->sense_buffer))) : __memcpy((Cmnd->sense_buffer),(sts->
req_sense_data),(sizeof(Cmnd->sense_buffer))))
;
915
916 DEBUG_INTR(isp1020_print_status_entry(sts));
917
918 if (sts->hdr.entry_type == ENTRY_STATUS3)
919 Cmnd->result = isp1020_return_status(sts);
920 else
921 Cmnd->result = DID_ERROR0x07 << 16;
922
923 outw(out_ptr, host->io_port + MBOX5)((__builtin_constant_p((host->io_port + 0x7a)) && (
host->io_port + 0x7a) < 256) ? __outwc((out_ptr),(host->
io_port + 0x7a)) : __outw((out_ptr),(host->io_port + 0x7a)
))
;
924 (*Cmnd->scsi_done)(Cmnd);
925 }
926 hostdata->res_out_ptr = out_ptr;
927
928 LEAVE_INTR("isp1020_intr_handler");
929}
930
931
932static int isp1020_return_status(struct Status_Entry *sts)
933{
934 int host_status = DID_ERROR0x07;
935#if DEBUG_ISP1020_INTR
936 static char *reason[] = {
937 "DID_OK",
938 "DID_NO_CONNECT",
939 "DID_BUS_BUSY",
940 "DID_TIME_OUT",
941 "DID_BAD_TARGET",
942 "DID_ABORT",
943 "DID_PARITY",
944 "DID_ERROR",
945 "DID_RESET",
946 "DID_BAD_INTR"
947 };
948#endif /* DEBUG_ISP1020_INTR */
949
950 ENTER("isp1020_return_status");
951
952 DEBUG(printk("qlogicisp : completion status = 0x%04x\n",
953 sts->completion_status));
954
955 switch(sts->completion_status) {
956 case CS_COMPLETE0x0000:
957 host_status = DID_OK0x00;
958 break;
959 case CS_INCOMPLETE0x0001:
960 if (!(sts->state_flags & SF_GOT_BUS0x0100))
961 host_status = DID_NO_CONNECT0x01;
962 else if (!(sts->state_flags & SF_GOT_TARGET0x0200))
963 host_status = DID_BAD_TARGET0x04;
964 else if (!(sts->state_flags & SF_SENT_CDB0x0400))
965 host_status = DID_ERROR0x07;
966 else if (!(sts->state_flags & SF_TRANSFERRED_DATA0x0800))
967 host_status = DID_ERROR0x07;
968 else if (!(sts->state_flags & SF_GOT_STATUS0x1000))
969 host_status = DID_ERROR0x07;
970 else if (!(sts->state_flags & SF_GOT_SENSE0x2000))
971 host_status = DID_ERROR0x07;
972 break;
973 case CS_DMA_ERROR0x0002:
974 case CS_TRANSPORT_ERROR0x0003:
975 host_status = DID_ERROR0x07;
976 break;
977 case CS_RESET_OCCURRED0x0004:
978 host_status = DID_RESET0x08;
979 break;
980 case CS_ABORTED0x0005:
981 host_status = DID_ABORT0x05;
982 break;
983 case CS_TIMEOUT0x0006:
984 host_status = DID_TIME_OUT0x03;
985 break;
986 case CS_DATA_OVERRUN0x0007:
987 case CS_COMMAND_OVERRUN0x0008:
988 case CS_STATUS_OVERRUN0x0009:
989 case CS_BAD_MESSAGE0x000a:
990 case CS_NO_MESSAGE_OUT0x000b:
991 case CS_EXT_ID_FAILED0x000c:
992 case CS_IDE_MSG_FAILED0x000d:
993 case CS_ABORT_MSG_FAILED0x000e:
994 case CS_NOP_MSG_FAILED0x0010:
995 case CS_PARITY_ERROR_MSG_FAILED0x0011:
996 case CS_DEVICE_RESET_MSG_FAILED0x0012:
997 case CS_ID_MSG_FAILED0x0013:
998 case CS_UNEXP_BUS_FREE0x0014:
999 case CS_INVALID_ENTRY_TYPE0x001b:
1000 case CS_DEVICE_QUEUE_FULL0x001c:
1001 case CS_SCSI_PHASE_SKIPPED0x001d:
1002 case CS_ARS_FAILED0x001e:
1003 host_status = DID_ERROR0x07;
1004 break;
1005 case CS_DATA_UNDERRUN0x0015:
1006 host_status = DID_OK0x00;
1007 break;
1008 default:
1009 printk("qlogicisp : unknown completion status 0x%04x\n",
1010 sts->completion_status);
1011 host_status = DID_ERROR0x07;
1012 break;
1013 }
1014
1015 DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n",
1016 reason[host_status], sts->scsi_status));
1017
1018 LEAVE("isp1020_return_status");
1019
1020 return (sts->scsi_status & STATUS_MASK0x3e) | (host_status << 16);
1021}
1022
1023
1024int isp1020_abort(Scsi_Cmnd *Cmnd)
1025{
1026 u_short param[6];
1027 struct Scsi_Host *host;
1028 struct isp1020_hostdata *hostdata;
1029 int return_status = SCSI_ABORT_SUCCESS1;
1030 u_int cmdaddr = virt_to_busvirt_to_phys(Cmnd);
1031
1032 ENTER("isp1020_abort");
1033
1034 host = Cmnd->host;
1035 hostdata = (struct isp1020_hostdata *) host->hostdata;
1036
1037 isp1020_disable_irqs(host);
1038
1039 param[0] = MBOX_ABORT0x0015;
1040 param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
1041 param[2] = cmdaddr >> 16;
1042 param[3] = cmdaddr & 0xffff;
1043
1044 isp1020_mbox_command(host, param);
1045
1046 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1047 printk("qlogicisp : scsi abort failure: %x\n", param[0]);
1048 return_status = SCSI_ABORT_ERROR5;
1049 }
1050
1051 isp1020_enable_irqs(host);
1052
1053 LEAVE("isp1020_abort");
1054
1055 return return_status;
1056}
1057
1058
1059int isp1020_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags)
1060{
1061 u_short param[6];
1062 struct Scsi_Host *host;
1063 struct isp1020_hostdata *hostdata;
1064 int return_status = SCSI_RESET_SUCCESS2;
1065
1066 ENTER("isp1020_reset");
1067
1068 host = Cmnd->host;
1069 hostdata = (struct isp1020_hostdata *) host->hostdata;
1070
1071 param[0] = MBOX_BUS_RESET0x0018;
1072 param[1] = hostdata->host_param.bus_reset_delay;
1073
1074 isp1020_disable_irqs(host);
1075
1076 isp1020_mbox_command(host, param);
1
Calling 'isp1020_mbox_command'
1077
1078 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1079 printk("qlogicisp : scsi bus reset failure: %x\n", param[0]);
1080 return_status = SCSI_RESET_ERROR6;
1081 }
1082
1083 isp1020_enable_irqs(host);
1084
1085 LEAVE("isp1020_reset");
1086
1087 return return_status;;
1088}
1089
1090
1091int isp1020_biosparam(Disk *disk, kdev_t n, int ip[])
1092{
1093 int size = disk->capacity;
1094
1095 ENTER("isp1020_biosparam");
1096
1097 ip[0] = 64;
1098 ip[1] = 32;
1099 ip[2] = size >> 11;
1100 if (ip[2] > 1024) {
1101 ip[0] = 255;
1102 ip[1] = 63;
1103 ip[2] = size / (ip[0] * ip[1]);
1104 if (ip[2] > 1023)
1105 ip[2] = 1023;
1106 }
1107
1108 LEAVE("isp1020_biosparam");
1109
1110 return 0;
1111}
1112
1113
1114static int isp1020_reset_hardware(struct Scsi_Host *host)
1115{
1116 u_short param[6];
1117 int loop_count;
1118
1119 ENTER("isp1020_reset_hardware");
1120
1121 outw(ISP_RESET, host->io_port + PCI_INTF_CTL)((__builtin_constant_p((host->io_port + 0x08)) && (
host->io_port + 0x08) < 256) ? __outwc((0x0001),(host->
io_port + 0x08)) : __outw((0x0001),(host->io_port + 0x08))
)
;
1122 outw(HCCR_RESET, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x1000),(host->
io_port + 0xc0)) : __outw((0x1000),(host->io_port + 0xc0))
)
;
1123 outw(HCCR_RELEASE, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x3000),(host->
io_port + 0xc0)) : __outw((0x3000),(host->io_port + 0xc0))
)
;
1124 outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x9000),(host->
io_port + 0xc0)) : __outw((0x9000),(host->io_port + 0xc0))
)
;
1125
1126 loop_count = DEFAULT_LOOP_COUNT1000000;
1127 while (--loop_count && inw(host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __inwc(host->io_port +
0xc0) : __inw(host->io_port + 0xc0))
== RISC_BUSY0x0004)
1128 barrier()__asm__ __volatile__("": : :"memory");
1129 if (!loop_count)
1130 printk("qlogicisp: reset_hardware loop timeout\n");
1131
1132 outw(0, host->io_port + ISP_CFG1)((__builtin_constant_p((host->io_port + 0x06)) && (
host->io_port + 0x06) < 256) ? __outwc((0),(host->io_port
+ 0x06)) : __outw((0),(host->io_port + 0x06)))
;
1133
1134#if DEBUG_ISP10200
1135 printk("qlogicisp : mbox 0 0x%04x \n", inw(host->io_port + MBOX0)((__builtin_constant_p((host->io_port + 0x70)) && (
host->io_port + 0x70) < 256) ? __inwc(host->io_port +
0x70) : __inw(host->io_port + 0x70))
);
1136 printk("qlogicisp : mbox 1 0x%04x \n", inw(host->io_port + MBOX1)((__builtin_constant_p((host->io_port + 0x72)) && (
host->io_port + 0x72) < 256) ? __inwc(host->io_port +
0x72) : __inw(host->io_port + 0x72))
);
1137 printk("qlogicisp : mbox 2 0x%04x \n", inw(host->io_port + MBOX2)((__builtin_constant_p((host->io_port + 0x74)) && (
host->io_port + 0x74) < 256) ? __inwc(host->io_port +
0x74) : __inw(host->io_port + 0x74))
);
1138 printk("qlogicisp : mbox 3 0x%04x \n", inw(host->io_port + MBOX3)((__builtin_constant_p((host->io_port + 0x76)) && (
host->io_port + 0x76) < 256) ? __inwc(host->io_port +
0x76) : __inw(host->io_port + 0x76))
);
1139 printk("qlogicisp : mbox 4 0x%04x \n", inw(host->io_port + MBOX4)((__builtin_constant_p((host->io_port + 0x78)) && (
host->io_port + 0x78) < 256) ? __inwc(host->io_port +
0x78) : __inw(host->io_port + 0x78))
);
1140 printk("qlogicisp : mbox 5 0x%04x \n", inw(host->io_port + MBOX5)((__builtin_constant_p((host->io_port + 0x7a)) && (
host->io_port + 0x7a) < 256) ? __inwc(host->io_port +
0x7a) : __inw(host->io_port + 0x7a))
);
1141#endif /* DEBUG_ISP1020 */
1142
1143 DEBUG(printk("qlogicisp : loading risc ram\n"));
1144
1145#if RELOAD_FIRMWARE0
1146 {
1147 int i;
1148 for (i = 0; i < risc_code_length01; i++) {
1149 param[0] = MBOX_WRITE_RAM_WORD0x0004;
1150 param[1] = risc_code_addr01 + i;
1151 param[2] = risc_code01[i];
1152
1153 isp1020_mbox_command(host, param);
1154
1155 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1156 printk("qlogicisp : firmware load failure\n");
1157 return 1;
1158 }
1159 }
1160 }
1161#endif /* RELOAD_FIRMWARE */
1162
1163 DEBUG(printk("qlogicisp : verifying checksum\n"));
1164
1165 param[0] = MBOX_VERIFY_CHECKSUM0x0007;
1166 param[1] = risc_code_addr01;
1167
1168 isp1020_mbox_command(host, param);
1169
1170 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1171 printk("qlogicisp : ram checksum failure\n");
1172 return 1;
1173 }
1174
1175 DEBUG(printk("qlogicisp : executing firmware\n"));
1176
1177 param[0] = MBOX_EXEC_FIRMWARE0x0002;
1178 param[1] = risc_code_addr01;
1179
1180 isp1020_mbox_command(host, param);
1181
1182 param[0] = MBOX_ABOUT_FIRMWARE0x0008;
1183
1184 isp1020_mbox_command(host, param);
1185
1186 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1187 printk("qlogicisp : about firmware failure\n");
1188 return 1;
1189 }
1190
1191 DEBUG(printk("qlogicisp : firmware major revision %d\n", param[1]));
1192 DEBUG(printk("qlogicisp : firmware minor revision %d\n", param[2]));
1193
1194 LEAVE("isp1020_reset_hardware");
1195
1196 return 0;
1197}
1198
1199
1200static int isp1020_init(struct Scsi_Host *sh)
1201{
1202 u_int io_base;
1203 struct isp1020_hostdata *hostdata;
1204 u_char bus, device_fn, revision, irq;
1205 u_short vendor_id, device_id, command;
1206
1207 ENTER("isp1020_init");
1208
1209 hostdata = (struct isp1020_hostdata *) sh->hostdata;
1210 bus = hostdata->bus;
1211 device_fn = hostdata->device_fn;
1212
1213 if (pcibios_read_config_word(bus, device_fn, PCI_VENDOR_ID0x00, &vendor_id)
1214 || pcibios_read_config_word(bus, device_fn,
1215 PCI_DEVICE_ID0x02, &device_id)
1216 || pcibios_read_config_word(bus, device_fn,
1217 PCI_COMMAND0x04, &command)
1218 || pcibios_read_config_dword(bus, device_fn,
1219 PCI_BASE_ADDRESS_00x10, &io_base)
1220 || pcibios_read_config_byte(bus, device_fn,
1221 PCI_CLASS_REVISION0x08, &revision)
1222 || pcibios_read_config_byte(bus, device_fn,
1223 PCI_INTERRUPT_LINE0x3c, &irq))
1224 {
1225 printk("qlogicisp : error reading PCI configuration\n");
1226 return 1;
1227 }
1228
1229 if (vendor_id != PCI_VENDOR_ID_QLOGIC0x1077) {
1230 printk("qlogicisp : 0x%04x is not QLogic vendor ID\n",
1231 vendor_id);
1232 return 1;
1233 }
1234
1235 if (device_id != PCI_DEVICE_ID_QLOGIC_ISP10200x1020) {
1236 printk("qlogicisp : 0x%04x does not match ISP1020 device id\n",
1237 device_id);
1238 return 1;
1239 }
1240
1241 if (command & PCI_COMMAND_IO0x1 && (io_base & 3) == 1)
1242 io_base &= PCI_BASE_ADDRESS_IO_MASK(~0x03);
1243 else {
1244 printk("qlogicisp : i/o mapping is disabled\n");
1245 return 1;
1246 }
1247
1248 if (!(command & PCI_COMMAND_MASTER0x4)) {
1249 printk("qlogicisp : bus mastering is disabled\n");
1250 return 1;
1251 }
1252
1253 if (revision != ISP1020_REV_ID1)
1254 printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);
1255
1256 if (inw(io_base + PCI_ID_LOW)((__builtin_constant_p((io_base + 0x00)) && (io_base +
0x00) < 256) ? __inwc(io_base + 0x00) : __inw(io_base + 0x00
))
!= PCI_VENDOR_ID_QLOGIC0x1077
1257 || inw(io_base + PCI_ID_HIGH)((__builtin_constant_p((io_base + 0x02)) && (io_base +
0x02) < 256) ? __inwc(io_base + 0x02) : __inw(io_base + 0x02
))
!= PCI_DEVICE_ID_QLOGIC_ISP10200x1020)
1258 {
1259 printk("qlogicisp : can't decode i/o address space at 0x%x\n",
1260 io_base);
1261 return 1;
1262 }
1263
1264 hostdata->revision = revision;
1265
1266 sh->irq = irq;
1267 sh->io_port = io_base;
1268
1269 LEAVE("isp1020_init");
1270
1271 return 0;
1272}
1273
1274
1275#if USE_NVRAM_DEFAULTS0
1276
1277static int isp1020_get_defaults(struct Scsi_Host *host)
1278{
1279 int i;
1280 u_short value;
1281 struct isp1020_hostdata *hostdata =
1282 (struct isp1020_hostdata *) host->hostdata;
1283
1284 ENTER("isp1020_get_defaults");
1285
1286 if (!isp1020_verify_nvram(host)) {
1287 printk("qlogicisp : nvram checksum failure\n");
1288 printk("qlogicisp : attempting to use default parameters\n");
1289 return isp1020_set_defaults(host);
1290 }
1291
1292 value = isp1020_read_nvram_word(host, 2);
1293 hostdata->host_param.fifo_threshold = (value >> 8) & 0x03;
1294 hostdata->host_param.host_adapter_enable = (value >> 11) & 0x01;
1295 hostdata->host_param.initiator_scsi_id = (value >> 12) & 0x0f;
1296
1297 value = isp1020_read_nvram_word(host, 3);
1298 hostdata->host_param.bus_reset_delay = value & 0xff;
1299 hostdata->host_param.retry_count = value >> 8;
1300
1301 value = isp1020_read_nvram_word(host, 4);
1302 hostdata->host_param.retry_delay = value & 0xff;
1303 hostdata->host_param.async_data_setup_time = (value >> 8) & 0x0f;
1304 hostdata->host_param.req_ack_active_negation = (value >> 12) & 0x01;
1305 hostdata->host_param.data_line_active_negation = (value >> 13) & 0x01;
1306 hostdata->host_param.data_dma_burst_enable = (value >> 14) & 0x01;
1307 hostdata->host_param.command_dma_burst_enable = (value >> 15);
1308
1309 value = isp1020_read_nvram_word(host, 5);
1310 hostdata->host_param.tag_aging = value & 0xff;
1311
1312 value = isp1020_read_nvram_word(host, 6);
1313 hostdata->host_param.selection_timeout = value & 0xffff;
1314
1315 value = isp1020_read_nvram_word(host, 7);
1316 hostdata->host_param.max_queue_depth = value & 0xffff;
1317
1318#if DEBUG_ISP1020_SETUP0
1319 printk("qlogicisp : fifo threshold=%d\n",
1320 hostdata->host_param.fifo_threshold);
1321 printk("qlogicisp : initiator scsi id=%d\n",
1322 hostdata->host_param.initiator_scsi_id);
1323 printk("qlogicisp : bus reset delay=%d\n",
1324 hostdata->host_param.bus_reset_delay);
1325 printk("qlogicisp : retry count=%d\n",
1326 hostdata->host_param.retry_count);
1327 printk("qlogicisp : retry delay=%d\n",
1328 hostdata->host_param.retry_delay);
1329 printk("qlogicisp : async data setup time=%d\n",
1330 hostdata->host_param.async_data_setup_time);
1331 printk("qlogicisp : req/ack active negation=%d\n",
1332 hostdata->host_param.req_ack_active_negation);
1333 printk("qlogicisp : data line active negation=%d\n",
1334 hostdata->host_param.data_line_active_negation);
1335 printk("qlogicisp : data DMA burst enable=%d\n",
1336 hostdata->host_param.data_dma_burst_enable);
1337 printk("qlogicisp : command DMA burst enable=%d\n",
1338 hostdata->host_param.command_dma_burst_enable);
1339 printk("qlogicisp : tag age limit=%d\n",
1340 hostdata->host_param.tag_aging);
1341 printk("qlogicisp : selection timeout limit=%d\n",
1342 hostdata->host_param.selection_timeout);
1343 printk("qlogicisp : max queue depth=%d\n",
1344 hostdata->host_param.max_queue_depth);
1345#endif /* DEBUG_ISP1020_SETUP */
1346
1347 for (i = 0; i < MAX_TARGETS16; i++) {
1348
1349 value = isp1020_read_nvram_word(host, 14 + i * 3);
1350 hostdata->dev_param[i].device_flags = value & 0xff;
1351 hostdata->dev_param[i].execution_throttle = value >> 8;
1352
1353 value = isp1020_read_nvram_word(host, 15 + i * 3);
1354 hostdata->dev_param[i].synchronous_period = value & 0xff;
1355 hostdata->dev_param[i].synchronous_offset = (value >> 8) & 0x0f;
1356 hostdata->dev_param[i].device_enable = (value >> 12) & 0x01;
1357
1358#if DEBUG_ISP1020_SETUP0
1359 printk("qlogicisp : target 0x%02x\n", i);
1360 printk("qlogicisp : device flags=0x%02x\n",
1361 hostdata->dev_param[i].device_flags);
1362 printk("qlogicisp : execution throttle=%d\n",
1363 hostdata->dev_param[i].execution_throttle);
1364 printk("qlogicisp : synchronous period=%d\n",
1365 hostdata->dev_param[i].synchronous_period);
1366 printk("qlogicisp : synchronous offset=%d\n",
1367 hostdata->dev_param[i].synchronous_offset);
1368 printk("qlogicisp : device enable=%d\n",
1369 hostdata->dev_param[i].device_enable);
1370#endif /* DEBUG_ISP1020_SETUP */
1371 }
1372
1373 LEAVE("isp1020_get_defaults");
1374
1375 return 0;
1376}
1377
1378
1379#define ISP1020_NVRAM_LEN 0x40
1380#define ISP1020_NVRAM_SIG1 0x5349
1381#define ISP1020_NVRAM_SIG2 0x2050
1382
1383static int isp1020_verify_nvram(struct Scsi_Host *host)
1384{
1385 int i;
1386 u_short value;
1387 u_char checksum = 0;
1388
1389 for (i = 0; i < ISP1020_NVRAM_LEN; i++) {
1390 value = isp1020_read_nvram_word(host, i);
1391
1392 switch (i) {
1393 case 0:
1394 if (value != ISP1020_NVRAM_SIG1) return 0;
1395 break;
1396 case 1:
1397 if (value != ISP1020_NVRAM_SIG2) return 0;
1398 break;
1399 case 2:
1400 if ((value & 0xff) != 0x02) return 0;
1401 break;
1402 }
1403 checksum += value & 0xff;
1404 checksum += value >> 8;
1405 }
1406
1407 return (checksum == 0);
1408}
1409
1410#define NVRAM_DELAY() udelay(2)(__builtin_constant_p(2) ? __const_udelay((2) * 0x10c6ul) : __udelay
(2))
/* 2 microsecond delay */
1411
1412
1413u_short isp1020_read_nvram_word(struct Scsi_Host *host, u_short byte)
1414{
1415 int i;
1416 u_short value, output, input;
1417
1418 byte &= 0x3f; byte |= 0x0180;
1419
1420 for (i = 8; i >= 0; i--) {
1421 output = ((byte >> i) & 0x1) ? 0x4 : 0x0;
1422 outw(output | 0x2, host->io_port + PCI_NVRAM)((__builtin_constant_p((host->io_port + 0x0e)) && (
host->io_port + 0x0e) < 256) ? __outwc((output | 0x2),(
host->io_port + 0x0e)) : __outw((output | 0x2),(host->io_port
+ 0x0e)))
; NVRAM_DELAY();
1423 outw(output | 0x3, host->io_port + PCI_NVRAM)((__builtin_constant_p((host->io_port + 0x0e)) && (
host->io_port + 0x0e) < 256) ? __outwc((output | 0x3),(
host->io_port + 0x0e)) : __outw((output | 0x3),(host->io_port
+ 0x0e)))
; NVRAM_DELAY();
1424 outw(output | 0x2, host->io_port + PCI_NVRAM)((__builtin_constant_p((host->io_port + 0x0e)) && (
host->io_port + 0x0e) < 256) ? __outwc((output | 0x2),(
host->io_port + 0x0e)) : __outw((output | 0x2),(host->io_port
+ 0x0e)))
; NVRAM_DELAY();
1425 }
1426
1427 for (i = 0xf, value = 0; i >= 0; i--) {
1428 value <<= 1;
1429 outw(0x3, host->io_port + PCI_NVRAM)((__builtin_constant_p((host->io_port + 0x0e)) && (
host->io_port + 0x0e) < 256) ? __outwc((0x3),(host->
io_port + 0x0e)) : __outw((0x3),(host->io_port + 0x0e)))
; NVRAM_DELAY();
1430 input = inw(host->io_port + PCI_NVRAM)((__builtin_constant_p((host->io_port + 0x0e)) && (
host->io_port + 0x0e) < 256) ? __inwc(host->io_port +
0x0e) : __inw(host->io_port + 0x0e))
; NVRAM_DELAY();
1431 outw(0x2, host->io_port + PCI_NVRAM)((__builtin_constant_p((host->io_port + 0x0e)) && (
host->io_port + 0x0e) < 256) ? __outwc((0x2),(host->
io_port + 0x0e)) : __outw((0x2),(host->io_port + 0x0e)))
; NVRAM_DELAY();
1432 if (input & 0x8) value |= 1;
1433 }
1434
1435 outw(0x0, host->io_port + PCI_NVRAM)((__builtin_constant_p((host->io_port + 0x0e)) && (
host->io_port + 0x0e) < 256) ? __outwc((0x0),(host->
io_port + 0x0e)) : __outw((0x0),(host->io_port + 0x0e)))
; NVRAM_DELAY();
1436
1437 return value;
1438}
1439
1440#endif /* USE_NVRAM_DEFAULTS */
1441
1442
1443static int isp1020_set_defaults(struct Scsi_Host *host)
1444{
1445 struct isp1020_hostdata *hostdata =
1446 (struct isp1020_hostdata *) host->hostdata;
1447 int i;
1448
1449 ENTER("isp1020_set_defaults");
1450
1451 hostdata->host_param.fifo_threshold = 2;
1452 hostdata->host_param.host_adapter_enable = 1;
1453 hostdata->host_param.initiator_scsi_id = 7;
1454 hostdata->host_param.bus_reset_delay = 3;
1455 hostdata->host_param.retry_count = 0;
1456 hostdata->host_param.retry_delay = 1;
1457 hostdata->host_param.async_data_setup_time = 6;
1458 hostdata->host_param.req_ack_active_negation = 1;
1459 hostdata->host_param.data_line_active_negation = 1;
1460 hostdata->host_param.data_dma_burst_enable = 1;
1461 hostdata->host_param.command_dma_burst_enable = 1;
1462 hostdata->host_param.tag_aging = 8;
1463 hostdata->host_param.selection_timeout = 250;
1464 hostdata->host_param.max_queue_depth = 256;
1465
1466 for (i = 0; i < MAX_TARGETS16; i++) {
1467 hostdata->dev_param[i].device_flags = 0xfd;
1468 hostdata->dev_param[i].execution_throttle = 16;
1469 hostdata->dev_param[i].synchronous_period = 25;
1470 hostdata->dev_param[i].synchronous_offset = 12;
1471 hostdata->dev_param[i].device_enable = 1;
1472 }
1473
1474 LEAVE("isp1020_set_defaults");
1475
1476 return 0;
1477}
1478
1479
1480static int isp1020_load_parameters(struct Scsi_Host *host)
1481{
1482 int i, k;
1483 u_int queue_addr;
1484 u_short param[6];
1485 u_short isp_cfg1;
1486 unsigned long flags;
1487 struct isp1020_hostdata *hostdata =
1488 (struct isp1020_hostdata *) host->hostdata;
1489
1490 ENTER("isp1020_load_parameters");
1491
1492 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
1493 cli()__asm__ __volatile__ ("cli": : :"memory");
1494
1495 outw(hostdata->host_param.fifo_threshold, host->io_port + ISP_CFG1)((__builtin_constant_p((host->io_port + 0x06)) && (
host->io_port + 0x06) < 256) ? __outwc((hostdata->host_param
.fifo_threshold),(host->io_port + 0x06)) : __outw((hostdata
->host_param.fifo_threshold),(host->io_port + 0x06)))
;
1496
1497 param[0] = MBOX_SET_INIT_SCSI_ID0x0030;
1498 param[1] = hostdata->host_param.initiator_scsi_id;
1499
1500 isp1020_mbox_command(host, param);
1501
1502 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1503 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1504 printk("qlogicisp : set initiator id failure\n");
1505 return 1;
1506 }
1507
1508 param[0] = MBOX_SET_RETRY_COUNT0x0032;
1509 param[1] = hostdata->host_param.retry_count;
1510 param[2] = hostdata->host_param.retry_delay;
1511
1512 isp1020_mbox_command(host, param);
1513
1514 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1515 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1516 printk("qlogicisp : set retry count failure\n");
1517 return 1;
1518 }
1519
1520 param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME0x0036;
1521 param[1] = hostdata->host_param.async_data_setup_time;
1522
1523 isp1020_mbox_command(host, param);
1524
1525 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1526 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1527 printk("qlogicisp : async data setup time failure\n");
1528 return 1;
1529 }
1530
1531 param[0] = MBOX_SET_ACTIVE_NEG_STATE0x0035;
1532 param[1] = (hostdata->host_param.req_ack_active_negation << 4)
1533 | (hostdata->host_param.data_line_active_negation << 5);
1534
1535 isp1020_mbox_command(host, param);
1536
1537 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1538 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1539 printk("qlogicisp : set active negation state failure\n");
1540 return 1;
1541 }
1542
1543 param[0] = MBOX_SET_PCI_CONTROL_PARAMS0x0037;
1544 param[1] = hostdata->host_param.data_dma_burst_enable << 1;
1545 param[2] = hostdata->host_param.command_dma_burst_enable << 1;
1546
1547 isp1020_mbox_command(host, param);
1548
1549 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1550 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1551 printk("qlogicisp : set pci control parameter failure\n");
1552 return 1;
1553 }
1554
1555 isp_cfg1 = inw(host->io_port + ISP_CFG1)((__builtin_constant_p((host->io_port + 0x06)) && (
host->io_port + 0x06) < 256) ? __inwc(host->io_port +
0x06) : __inw(host->io_port + 0x06))
;
1556
1557 if (hostdata->host_param.data_dma_burst_enable
1558 || hostdata->host_param.command_dma_burst_enable)
1559 isp_cfg1 |= 0x0004;
1560 else
1561 isp_cfg1 &= 0xfffb;
1562
1563 outw(isp_cfg1, host->io_port + ISP_CFG1)((__builtin_constant_p((host->io_port + 0x06)) && (
host->io_port + 0x06) < 256) ? __outwc((isp_cfg1),(host
->io_port + 0x06)) : __outw((isp_cfg1),(host->io_port +
0x06)))
;
1564
1565 param[0] = MBOX_SET_TAG_AGE_LIMIT0x0033;
1566 param[1] = hostdata->host_param.tag_aging;
1567
1568 isp1020_mbox_command(host, param);
1569
1570 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1571 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1572 printk("qlogicisp : set tag age limit failure\n");
1573 return 1;
1574 }
1575
1576 param[0] = MBOX_SET_SELECT_TIMEOUT0x0031;
1577 param[1] = hostdata->host_param.selection_timeout;
1578
1579 isp1020_mbox_command(host, param);
1580
1581 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1582 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1583 printk("qlogicisp : set selection timeout failure\n");
1584 return 1;
1585 }
1586
1587 for (i = 0; i < MAX_TARGETS16; i++) {
1588
1589 if (!hostdata->dev_param[i].device_enable)
1590 continue;
1591
1592 param[0] = MBOX_SET_TARGET_PARAMS0x0038;
1593 param[1] = i << 8;
1594 param[2] = hostdata->dev_param[i].device_flags << 8;
1595 param[3] = (hostdata->dev_param[i].synchronous_offset << 8)
1596 | hostdata->dev_param[i].synchronous_period;
1597
1598 isp1020_mbox_command(host, param);
1599
1600 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1601 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1602 printk("qlogicisp : set target parameter failure\n");
1603 return 1;
1604 }
1605
1606 for (k = 0; k < MAX_LUNS8; k++) {
1607
1608 param[0] = MBOX_SET_DEV_QUEUE_PARAMS0x0039;
1609 param[1] = (i << 8) | k;
1610 param[2] = hostdata->host_param.max_queue_depth;
1611 param[3] = hostdata->dev_param[i].execution_throttle;
1612
1613 isp1020_mbox_command(host, param);
1614
1615 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1616 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1617 printk("qlogicisp : set device queue "
1618 "parameter failure\n");
1619 return 1;
1620 }
1621 }
1622 }
1623
1624 queue_addr = (u_int) virt_to_busvirt_to_phys(&hostdata->res[0][0]);
1625
1626 param[0] = MBOX_INIT_RES_QUEUE0x0011;
1627 param[1] = RES_QUEUE_LEN((63 + 1) / 8 - 1) + 1;
1628 param[2] = (u_short) (queue_addr >> 16);
1629 param[3] = (u_short) (queue_addr & 0xffff);
1630 param[4] = 0;
1631 param[5] = 0;
1632
1633 isp1020_mbox_command(host, param);
1634
1635 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1636 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1637 printk("qlogicisp : set response queue failure\n");
1638 return 1;
1639 }
1640
1641 queue_addr = (u_int) virt_to_busvirt_to_phys(&hostdata->req[0][0]);
1642
1643 param[0] = MBOX_INIT_REQ_QUEUE0x0010;
1644 param[1] = QLOGICISP_REQ_QUEUE_LEN63 + 1;
1645 param[2] = (u_short) (queue_addr >> 16);
1646 param[3] = (u_short) (queue_addr & 0xffff);
1647 param[4] = 0;
1648
1649 isp1020_mbox_command(host, param);
1650
1651 if (param[0] != MBOX_COMMAND_COMPLETE0x4000) {
1652 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1653 printk("qlogicisp : set request queue failure\n");
1654 return 1;
1655 }
1656
1657 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1658
1659 LEAVE("isp1020_load_parameters");
1660
1661 return 0;
1662}
1663
1664
1665/*
1666 * currently, this is only called during initialization or abort/reset,
1667 * at which times interrupts are disabled, so polling is OK, I guess...
1668 */
1669static int isp1020_mbox_command(struct Scsi_Host *host, u_short param[])
1670{
1671 int loop_count;
1672
1673 if (mbox_param[param[0]] == 0)
2
Taking false branch
1674 return 1;
1675
1676 loop_count = DEFAULT_LOOP_COUNT1000000;
1677 while (--loop_count && inw(host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __inwc(host->io_port +
0xc0) : __inw(host->io_port + 0xc0))
& 0x0080)
3
Loop condition is false. Execution continues on line 1679
1678 barrier()__asm__ __volatile__("": : :"memory");
1679 if (!loop_count)
4
Taking false branch
1680 printk("qlogicisp: mbox_command loop timeout #1\n");
1681
1682 switch(mbox_param[param[0]] >> 4) {
5
Control jumps to 'case 3:' at line 1686
1683 case 6: outw(param[5], host->io_port + MBOX5)((__builtin_constant_p((host->io_port + 0x7a)) && (
host->io_port + 0x7a) < 256) ? __outwc((param[5]),(host
->io_port + 0x7a)) : __outw((param[5]),(host->io_port +
0x7a)))
;
1684 case 5: outw(param[4], host->io_port + MBOX4)((__builtin_constant_p((host->io_port + 0x78)) && (
host->io_port + 0x78) < 256) ? __outwc((param[4]),(host
->io_port + 0x78)) : __outw((param[4]),(host->io_port +
0x78)))
;
1685 case 4: outw(param[3], host->io_port + MBOX3)((__builtin_constant_p((host->io_port + 0x76)) && (
host->io_port + 0x76) < 256) ? __outwc((param[3]),(host
->io_port + 0x76)) : __outw((param[3]),(host->io_port +
0x76)))
;
1686 case 3: outw(param[2], host->io_port + MBOX2)((__builtin_constant_p((host->io_port + 0x74)) && (
host->io_port + 0x74) < 256) ? __outwc((param[2]),(host
->io_port + 0x74)) : __outw((param[2]),(host->io_port +
0x74)))
;
6
Within the expansion of the macro 'outw':
a
Function call argument is an uninitialized value
1687 case 2: outw(param[1], host->io_port + MBOX1)((__builtin_constant_p((host->io_port + 0x72)) && (
host->io_port + 0x72) < 256) ? __outwc((param[1]),(host
->io_port + 0x72)) : __outw((param[1]),(host->io_port +
0x72)))
;
1688 case 1: outw(param[0], host->io_port + MBOX0)((__builtin_constant_p((host->io_port + 0x70)) && (
host->io_port + 0x70) < 256) ? __outwc((param[0]),(host
->io_port + 0x70)) : __outw((param[0]),(host->io_port +
0x70)))
;
1689 }
1690
1691 outw(0x0, host->io_port + PCI_SEMAPHORE)((__builtin_constant_p((host->io_port + 0x0c)) && (
host->io_port + 0x0c) < 256) ? __outwc((0x0),(host->
io_port + 0x0c)) : __outw((0x0),(host->io_port + 0x0c)))
;
1692 outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x7000),(host->
io_port + 0xc0)) : __outw((0x7000),(host->io_port + 0xc0))
)
;
1693 outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x5000),(host->
io_port + 0xc0)) : __outw((0x5000),(host->io_port + 0xc0))
)
;
1694
1695 loop_count = DEFAULT_LOOP_COUNT1000000;
1696 while (--loop_count && !(inw(host->io_port + PCI_INTF_STS)((__builtin_constant_p((host->io_port + 0x0a)) && (
host->io_port + 0x0a) < 256) ? __inwc(host->io_port +
0x0a) : __inw(host->io_port + 0x0a))
& 0x04))
1697 barrier()__asm__ __volatile__("": : :"memory");
1698 if (!loop_count)
1699 printk("qlogicisp: mbox_command loop timeout #2\n");
1700
1701 loop_count = DEFAULT_LOOP_COUNT1000000;
1702 while (--loop_count && inw(host->io_port + MBOX0)((__builtin_constant_p((host->io_port + 0x70)) && (
host->io_port + 0x70) < 256) ? __inwc(host->io_port +
0x70) : __inw(host->io_port + 0x70))
== 0x04)
1703 barrier()__asm__ __volatile__("": : :"memory");
1704 if (!loop_count)
1705 printk("qlogicisp: mbox_command loop timeout #3\n");
1706
1707 switch(mbox_param[param[0]] & 0xf) {
1708 case 6: param[5] = inw(host->io_port + MBOX5)((__builtin_constant_p((host->io_port + 0x7a)) && (
host->io_port + 0x7a) < 256) ? __inwc(host->io_port +
0x7a) : __inw(host->io_port + 0x7a))
;
1709 case 5: param[4] = inw(host->io_port + MBOX4)((__builtin_constant_p((host->io_port + 0x78)) && (
host->io_port + 0x78) < 256) ? __inwc(host->io_port +
0x78) : __inw(host->io_port + 0x78))
;
1710 case 4: param[3] = inw(host->io_port + MBOX3)((__builtin_constant_p((host->io_port + 0x76)) && (
host->io_port + 0x76) < 256) ? __inwc(host->io_port +
0x76) : __inw(host->io_port + 0x76))
;
1711 case 3: param[2] = inw(host->io_port + MBOX2)((__builtin_constant_p((host->io_port + 0x74)) && (
host->io_port + 0x74) < 256) ? __inwc(host->io_port +
0x74) : __inw(host->io_port + 0x74))
;
1712 case 2: param[1] = inw(host->io_port + MBOX1)((__builtin_constant_p((host->io_port + 0x72)) && (
host->io_port + 0x72) < 256) ? __inwc(host->io_port +
0x72) : __inw(host->io_port + 0x72))
;
1713 case 1: param[0] = inw(host->io_port + MBOX0)((__builtin_constant_p((host->io_port + 0x70)) && (
host->io_port + 0x70) < 256) ? __inwc(host->io_port +
0x70) : __inw(host->io_port + 0x70))
;
1714 }
1715
1716 outw(0x0, host->io_port + PCI_SEMAPHORE)((__builtin_constant_p((host->io_port + 0x0c)) && (
host->io_port + 0x0c) < 256) ? __outwc((0x0),(host->
io_port + 0x0c)) : __outw((0x0),(host->io_port + 0x0c)))
;
1717 outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR)((__builtin_constant_p((host->io_port + 0xc0)) && (
host->io_port + 0xc0) < 256) ? __outwc((0x7000),(host->
io_port + 0xc0)) : __outw((0x7000),(host->io_port + 0xc0))
)
;
1718
1719 return 0;
1720}
1721
1722
1723#if DEBUG_ISP1020_INTR
1724
1725void isp1020_print_status_entry(struct Status_Entry *status)
1726{
1727 int i;
1728
1729 printk("qlogicisp : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n",
1730 status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);
1731 printk("qlogicisp : scsi status = 0x%04x, completion status = 0x%04x\n",
1732 status->scsi_status, status->completion_status);
1733 printk("qlogicisp : state flags = 0x%04x, status flags = 0x%04x\n",
1734 status->state_flags, status->status_flags);
1735 printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n",
1736 status->time, status->req_sense_len);
1737 printk("qlogicisp : residual transfer length = 0x%08x\n", status->residual);
1738
1739 for (i = 0; i < status->req_sense_len; i++)
1740 printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]);
1741}
1742
1743#endif /* DEBUG_ISP1020_INTR */
1744
1745
1746#if DEBUG_ISP10200
1747
1748void isp1020_print_scsi_cmd(Scsi_Cmnd *cmd)
1749{
1750 int i;
1751
1752 printk("qlogicisp : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
1753 cmd->target, cmd->lun, cmd->cmd_len);
1754 printk("qlogicisp : command = ");
1755 for (i = 0; i < cmd->cmd_len; i++)
1756 printk("0x%02x ", cmd->cmnd[i]);
1757 printk("\n");
1758}
1759
1760#endif /* DEBUG_ISP1020 */
1761
1762
1763#ifdef MODULE
1764Scsi_Host_Template driver_template = QLOGICISP{ ((void *) 0), ((void *) 0), ((void *) 0), ((void *) 0), ((void
*) 0), isp1020_detect, isp1020_release, isp1020_info, ((void
*) 0), isp1020_queuecommand, isp1020_abort, isp1020_reset, (
(void *) 0), isp1020_biosparam, 63, -1, (4 + ((63) > 0) ? 7
*((63) - 1) : 0), 1, 0, 0, 0 }
;
1765
1766#include "scsi_module.c"
1767#endif /* MODULE */