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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [scsi/] [qlogicisp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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