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