OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [qlogicisp.c] - Blame information for rev 1772

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.