diff options
Diffstat (limited to 'drivers/scsi/qlogicisp.c')
| -rw-r--r-- | drivers/scsi/qlogicisp.c | 1934 | 
1 files changed, 0 insertions, 1934 deletions
diff --git a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c deleted file mode 100644 index 6c9266b8ffd..00000000000 --- a/drivers/scsi/qlogicisp.c +++ /dev/null @@ -1,1934 +0,0 @@ -/* - * QLogic ISP1020 Intelligent SCSI Processor Driver (PCI) - * Written by Erik H. Moe, ehm@cris.com - * Copyright 1995, Erik H. Moe - * Copyright 1996, 1997  Michael A. Griffith <grif@acm.org> - * Copyright 2000, Jayson C. Vantuyl <vantuyl@csc.smsu.edu> - *             and Bryon W. Roche    <bryon@csc.smsu.edu> - * - * 64-bit addressing added by Kanoj Sarcar <kanoj@sgi.com> - * 			   and Leo Dagum    <dagum@sgi.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * General Public License for more details. - */ - -#include <linux/blkdev.h> -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/unistd.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/byteorder.h> -#include "scsi.h" -#include <scsi/scsi_host.h> - -/* - * With the qlogic interface, every queue slot can hold a SCSI - * command with up to 4 scatter/gather entries.  If we need more - * than 4 entries, continuation entries can be used that hold - * another 7 entries each.  Unlike for other drivers, this means - * that the maximum number of scatter/gather entries we can - * support at any given time is a function of the number of queue - * slots available.  That is, host->can_queue and host->sg_tablesize - * are dynamic and _not_ independent.  This all works fine because - * requests are queued serially and the scatter/gather limit is - * determined for each queue request anew. - */ -#define QLOGICISP_REQ_QUEUE_LEN	63	/* must be power of two - 1 */ -#define QLOGICISP_MAX_SG(ql)	(4 + ((ql) > 0) ? 7*((ql) - 1) : 0) - -/* Configuration section *****************************************************/ - -/* Set the following macro to 1 to reload the ISP1020's firmware.  This is -   the latest firmware provided by QLogic.  This may be an earlier/later -   revision than supplied by your board. */ - -#define RELOAD_FIRMWARE		1 - -/* Set the following macro to 1 to reload the ISP1020's defaults from nvram. -   If you are not sure of your settings, leave this alone, the driver will -   use a set of 'safe' defaults */ - -#define USE_NVRAM_DEFAULTS	0 - -/*  Macros used for debugging */ - -#define DEBUG_ISP1020		0 -#define DEBUG_ISP1020_INTR	0 -#define DEBUG_ISP1020_SETUP	0 -#define TRACE_ISP		0 - -#define DEFAULT_LOOP_COUNT	1000000 - -/* End Configuration section *************************************************/ - -#include <linux/module.h> - -#if TRACE_ISP - -# define TRACE_BUF_LEN	(32*1024) - -struct { -	u_long		next; -	struct { -		u_long		time; -		u_int		index; -		u_int		addr; -		u_char *	name; -	} buf[TRACE_BUF_LEN]; -} trace; - -#define TRACE(w, i, a)						\ -{								\ -	unsigned long flags;					\ -								\ -	trace.buf[trace.next].name  = (w);			\ -	trace.buf[trace.next].time  = jiffies;			\ -	trace.buf[trace.next].index = (i);			\ -	trace.buf[trace.next].addr  = (long) (a);		\ -	trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1);	\ -} - -#else -# define TRACE(w, i, a) -#endif - -#if DEBUG_ISP1020 -#define ENTER(x)	printk("isp1020 : entering %s()\n", x); -#define LEAVE(x)	printk("isp1020 : leaving %s()\n", x); -#define DEBUG(x)	x -#else -#define ENTER(x) -#define LEAVE(x) -#define DEBUG(x) -#endif /* DEBUG_ISP1020 */ - -#if DEBUG_ISP1020_INTR -#define ENTER_INTR(x)	printk("isp1020 : entering %s()\n", x); -#define LEAVE_INTR(x)	printk("isp1020 : leaving %s()\n", x); -#define DEBUG_INTR(x)	x -#else -#define ENTER_INTR(x) -#define LEAVE_INTR(x) -#define DEBUG_INTR(x) -#endif /* DEBUG ISP1020_INTR */ - -#define ISP1020_REV_ID	1 - -#define MAX_TARGETS	16 -#define MAX_LUNS	8 - -/* host configuration and control registers */ -#define HOST_HCCR	0xc0	/* host command and control */ - -/* pci bus interface registers */ -#define PCI_ID_LOW	0x00	/* vendor id */ -#define PCI_ID_HIGH	0x02	/* device id */ -#define ISP_CFG0	0x04	/* configuration register #0 */ -#define  ISP_CFG0_HWMSK  0x000f	/* Hardware revision mask */ -#define  ISP_CFG0_1020	 0x0001 /* ISP1020 */ -#define  ISP_CFG0_1020A	 0x0002 /* ISP1020A */ -#define  ISP_CFG0_1040	 0x0003 /* ISP1040 */ -#define  ISP_CFG0_1040A	 0x0004 /* ISP1040A */ -#define  ISP_CFG0_1040B	 0x0005 /* ISP1040B */ -#define  ISP_CFG0_1040C	 0x0006 /* ISP1040C */ -#define ISP_CFG1	0x06	/* configuration register #1 */ -#define  ISP_CFG1_F128	 0x0040	/* 128-byte FIFO threshold */ -#define  ISP_CFG1_F64	 0x0030	/* 128-byte FIFO threshold */ -#define  ISP_CFG1_F32	 0x0020	/* 128-byte FIFO threshold */ -#define  ISP_CFG1_F16	 0x0010	/* 128-byte FIFO threshold */ -#define  ISP_CFG1_BENAB	 0x0004	/* Global Bus burst enable */ -#define  ISP_CFG1_SXP	 0x0001	/* SXP register select */ -#define PCI_INTF_CTL	0x08	/* pci interface control */ -#define PCI_INTF_STS	0x0a	/* pci interface status */ -#define PCI_SEMAPHORE	0x0c	/* pci semaphore */ -#define PCI_NVRAM	0x0e	/* pci nvram interface */ -#define CDMA_CONF	0x20	/* Command DMA Config */ -#define DDMA_CONF	0x40	/* Data DMA Config */ -#define  DMA_CONF_SENAB	 0x0008	/* SXP to DMA Data enable */ -#define  DMA_CONF_RIRQ	 0x0004	/* RISC interrupt enable */ -#define  DMA_CONF_BENAB	 0x0002	/* Bus burst enable */ -#define  DMA_CONF_DIR	 0x0001	/* DMA direction (0=fifo->host 1=host->fifo) */ - -/* mailbox registers */ -#define MBOX0		0x70	/* mailbox 0 */ -#define MBOX1		0x72	/* mailbox 1 */ -#define MBOX2		0x74	/* mailbox 2 */ -#define MBOX3		0x76	/* mailbox 3 */ -#define MBOX4		0x78	/* mailbox 4 */ -#define MBOX5		0x7a	/* mailbox 5 */ -#define MBOX6           0x7c    /* mailbox 6 */ -#define MBOX7           0x7e    /* mailbox 7 */ - -/* mailbox command complete status codes */ -#define MBOX_COMMAND_COMPLETE		0x4000 -#define INVALID_COMMAND			0x4001 -#define HOST_INTERFACE_ERROR		0x4002 -#define TEST_FAILED			0x4003 -#define COMMAND_ERROR			0x4005 -#define COMMAND_PARAM_ERROR		0x4006 - -/* async event status codes */ -#define ASYNC_SCSI_BUS_RESET		0x8001 -#define SYSTEM_ERROR			0x8002 -#define REQUEST_TRANSFER_ERROR		0x8003 -#define RESPONSE_TRANSFER_ERROR		0x8004 -#define REQUEST_QUEUE_WAKEUP		0x8005 -#define EXECUTION_TIMEOUT_RESET		0x8006 - -#ifdef CONFIG_QL_ISP_A64 -#define IOCB_SEGS                       2 -#define CONTINUATION_SEGS               5 -#define MAX_CONTINUATION_ENTRIES        254 -#else -#define IOCB_SEGS                       4 -#define CONTINUATION_SEGS               7 -#endif /* CONFIG_QL_ISP_A64 */ - -struct Entry_header { -	u_char	entry_type; -	u_char	entry_cnt; -	u_char	sys_def_1; -	u_char	flags; -}; - -/* entry header type commands */ -#ifdef CONFIG_QL_ISP_A64 -#define ENTRY_COMMAND           9 -#define ENTRY_CONTINUATION      0xa -#else -#define ENTRY_COMMAND		1 -#define ENTRY_CONTINUATION	2 -#endif /* CONFIG_QL_ISP_A64 */ - -#define ENTRY_STATUS		3 -#define ENTRY_MARKER		4 -#define ENTRY_EXTENDED_COMMAND	5 - -/* entry header flag definitions */ -#define EFLAG_CONTINUATION	1 -#define EFLAG_BUSY		2 -#define EFLAG_BAD_HEADER	4 -#define EFLAG_BAD_PAYLOAD	8 - -struct dataseg { -	u_int			d_base; -#ifdef CONFIG_QL_ISP_A64 -	u_int                   d_base_hi; -#endif -	u_int			d_count; -}; - -struct Command_Entry { -	struct Entry_header	hdr; -	u_int			handle; -	u_char			target_lun; -	u_char			target_id; -	u_short			cdb_length; -	u_short			control_flags; -	u_short			rsvd; -	u_short			time_out; -	u_short			segment_cnt; -	u_char			cdb[12]; -#ifdef CONFIG_QL_ISP_A64 -	u_int                   rsvd1; -	u_int                   rsvd2; -#endif -	struct dataseg		dataseg[IOCB_SEGS]; -}; - -/* command entry control flag definitions */ -#define CFLAG_NODISC		0x01 -#define CFLAG_HEAD_TAG		0x02 -#define CFLAG_ORDERED_TAG	0x04 -#define CFLAG_SIMPLE_TAG	0x08 -#define CFLAG_TAR_RTN		0x10 -#define CFLAG_READ		0x20 -#define CFLAG_WRITE		0x40 - -struct Ext_Command_Entry { -	struct Entry_header	hdr; -	u_int			handle; -	u_char			target_lun; -	u_char			target_id; -	u_short			cdb_length; -	u_short			control_flags; -	u_short			rsvd; -	u_short			time_out; -	u_short			segment_cnt; -	u_char			cdb[44]; -}; - -struct Continuation_Entry { -	struct Entry_header	hdr; -#ifndef CONFIG_QL_ISP_A64 -	u_int			reserved; -#endif -	struct dataseg		dataseg[CONTINUATION_SEGS]; -}; - -struct Marker_Entry { -	struct Entry_header	hdr; -	u_int			reserved; -	u_char			target_lun; -	u_char			target_id; -	u_char			modifier; -	u_char			rsvd; -	u_char			rsvds[52]; -}; - -/* marker entry modifier definitions */ -#define SYNC_DEVICE	0 -#define SYNC_TARGET	1 -#define SYNC_ALL	2 - -struct Status_Entry { -	struct Entry_header	hdr; -	u_int			handle; -	u_short			scsi_status; -	u_short			completion_status; -	u_short			state_flags; -	u_short			status_flags; -	u_short			time; -	u_short			req_sense_len; -	u_int			residual; -	u_char			rsvd[8]; -	u_char			req_sense_data[32]; -}; - -/* status entry completion status definitions */ -#define CS_COMPLETE			0x0000 -#define CS_INCOMPLETE			0x0001 -#define CS_DMA_ERROR			0x0002 -#define CS_TRANSPORT_ERROR		0x0003 -#define CS_RESET_OCCURRED		0x0004 -#define CS_ABORTED			0x0005 -#define CS_TIMEOUT			0x0006 -#define CS_DATA_OVERRUN			0x0007 -#define CS_COMMAND_OVERRUN		0x0008 -#define CS_STATUS_OVERRUN		0x0009 -#define CS_BAD_MESSAGE			0x000a -#define CS_NO_MESSAGE_OUT		0x000b -#define CS_EXT_ID_FAILED		0x000c -#define CS_IDE_MSG_FAILED		0x000d -#define CS_ABORT_MSG_FAILED		0x000e -#define CS_REJECT_MSG_FAILED		0x000f -#define CS_NOP_MSG_FAILED		0x0010 -#define CS_PARITY_ERROR_MSG_FAILED	0x0011 -#define CS_DEVICE_RESET_MSG_FAILED	0x0012 -#define CS_ID_MSG_FAILED		0x0013 -#define CS_UNEXP_BUS_FREE		0x0014 -#define CS_DATA_UNDERRUN		0x0015 - -/* status entry state flag definitions */ -#define SF_GOT_BUS			0x0100 -#define SF_GOT_TARGET			0x0200 -#define SF_SENT_CDB			0x0400 -#define SF_TRANSFERRED_DATA		0x0800 -#define SF_GOT_STATUS			0x1000 -#define SF_GOT_SENSE			0x2000 - -/* status entry status flag definitions */ -#define STF_DISCONNECT			0x0001 -#define STF_SYNCHRONOUS			0x0002 -#define STF_PARITY_ERROR		0x0004 -#define STF_BUS_RESET			0x0008 -#define STF_DEVICE_RESET		0x0010 -#define STF_ABORTED			0x0020 -#define STF_TIMEOUT			0x0040 -#define STF_NEGOTIATION			0x0080 - -/* interface control commands */ -#define ISP_RESET			0x0001 -#define ISP_EN_INT			0x0002 -#define ISP_EN_RISC			0x0004 - -/* host control commands */ -#define HCCR_NOP			0x0000 -#define HCCR_RESET			0x1000 -#define HCCR_PAUSE			0x2000 -#define HCCR_RELEASE			0x3000 -#define HCCR_SINGLE_STEP		0x4000 -#define HCCR_SET_HOST_INTR		0x5000 -#define HCCR_CLEAR_HOST_INTR		0x6000 -#define HCCR_CLEAR_RISC_INTR		0x7000 -#define HCCR_BP_ENABLE			0x8000 -#define HCCR_BIOS_DISABLE		0x9000 -#define HCCR_TEST_MODE			0xf000 - -#define RISC_BUSY			0x0004 - -/* mailbox commands */ -#define MBOX_NO_OP			0x0000 -#define MBOX_LOAD_RAM			0x0001 -#define MBOX_EXEC_FIRMWARE		0x0002 -#define MBOX_DUMP_RAM			0x0003 -#define MBOX_WRITE_RAM_WORD		0x0004 -#define MBOX_READ_RAM_WORD		0x0005 -#define MBOX_MAILBOX_REG_TEST		0x0006 -#define MBOX_VERIFY_CHECKSUM		0x0007 -#define MBOX_ABOUT_FIRMWARE		0x0008 -#define MBOX_CHECK_FIRMWARE		0x000e -#define MBOX_INIT_REQ_QUEUE		0x0010 -#define MBOX_INIT_RES_QUEUE		0x0011 -#define MBOX_EXECUTE_IOCB		0x0012 -#define MBOX_WAKE_UP			0x0013 -#define MBOX_STOP_FIRMWARE		0x0014 -#define MBOX_ABORT			0x0015 -#define MBOX_ABORT_DEVICE		0x0016 -#define MBOX_ABORT_TARGET		0x0017 -#define MBOX_BUS_RESET			0x0018 -#define MBOX_STOP_QUEUE			0x0019 -#define MBOX_START_QUEUE		0x001a -#define MBOX_SINGLE_STEP_QUEUE		0x001b -#define MBOX_ABORT_QUEUE		0x001c -#define MBOX_GET_DEV_QUEUE_STATUS	0x001d -#define MBOX_GET_FIRMWARE_STATUS	0x001f -#define MBOX_GET_INIT_SCSI_ID		0x0020 -#define MBOX_GET_SELECT_TIMEOUT		0x0021 -#define MBOX_GET_RETRY_COUNT		0x0022 -#define MBOX_GET_TAG_AGE_LIMIT		0x0023 -#define MBOX_GET_CLOCK_RATE		0x0024 -#define MBOX_GET_ACT_NEG_STATE		0x0025 -#define MBOX_GET_ASYNC_DATA_SETUP_TIME	0x0026 -#define MBOX_GET_PCI_PARAMS		0x0027 -#define MBOX_GET_TARGET_PARAMS		0x0028 -#define MBOX_GET_DEV_QUEUE_PARAMS	0x0029 -#define MBOX_SET_INIT_SCSI_ID		0x0030 -#define MBOX_SET_SELECT_TIMEOUT		0x0031 -#define MBOX_SET_RETRY_COUNT		0x0032 -#define MBOX_SET_TAG_AGE_LIMIT		0x0033 -#define MBOX_SET_CLOCK_RATE		0x0034 -#define MBOX_SET_ACTIVE_NEG_STATE	0x0035 -#define MBOX_SET_ASYNC_DATA_SETUP_TIME	0x0036 -#define MBOX_SET_PCI_CONTROL_PARAMS	0x0037 -#define MBOX_SET_TARGET_PARAMS		0x0038 -#define MBOX_SET_DEV_QUEUE_PARAMS	0x0039 -#define MBOX_RETURN_BIOS_BLOCK_ADDR	0x0040 -#define MBOX_WRITE_FOUR_RAM_WORDS	0x0041 -#define MBOX_EXEC_BIOS_IOCB		0x0042 - -#ifdef CONFIG_QL_ISP_A64 -#define MBOX_CMD_INIT_REQUEST_QUEUE_64      0x0052 -#define MBOX_CMD_INIT_RESPONSE_QUEUE_64     0x0053 -#endif /* CONFIG_QL_ISP_A64 */ - -#include "qlogicisp_asm.c" - -#define PACKB(a, b)			(((a)<<4)|(b)) - -static const u_char mbox_param[] = { -	PACKB(1, 1),	/* MBOX_NO_OP */ -	PACKB(5, 5),	/* MBOX_LOAD_RAM */ -	PACKB(2, 0),	/* MBOX_EXEC_FIRMWARE */ -	PACKB(5, 5),	/* MBOX_DUMP_RAM */ -	PACKB(3, 3),	/* MBOX_WRITE_RAM_WORD */ -	PACKB(2, 3),	/* MBOX_READ_RAM_WORD */ -	PACKB(6, 6),	/* MBOX_MAILBOX_REG_TEST */ -	PACKB(2, 3),	/* MBOX_VERIFY_CHECKSUM	*/ -	PACKB(1, 3),	/* MBOX_ABOUT_FIRMWARE */ -	PACKB(0, 0),	/* 0x0009 */ -	PACKB(0, 0),	/* 0x000a */ -	PACKB(0, 0),	/* 0x000b */ -	PACKB(0, 0),	/* 0x000c */ -	PACKB(0, 0),	/* 0x000d */ -	PACKB(1, 2),	/* MBOX_CHECK_FIRMWARE */ -	PACKB(0, 0),	/* 0x000f */ -	PACKB(5, 5),	/* MBOX_INIT_REQ_QUEUE */ -	PACKB(6, 6),	/* MBOX_INIT_RES_QUEUE */ -	PACKB(4, 4),	/* MBOX_EXECUTE_IOCB */ -	PACKB(2, 2),	/* MBOX_WAKE_UP	*/ -	PACKB(1, 6),	/* MBOX_STOP_FIRMWARE */ -	PACKB(4, 4),	/* MBOX_ABORT */ -	PACKB(2, 2),	/* MBOX_ABORT_DEVICE */ -	PACKB(3, 3),	/* MBOX_ABORT_TARGET */ -	PACKB(2, 2),	/* MBOX_BUS_RESET */ -	PACKB(2, 3),	/* MBOX_STOP_QUEUE */ -	PACKB(2, 3),	/* MBOX_START_QUEUE */ -	PACKB(2, 3),	/* MBOX_SINGLE_STEP_QUEUE */ -	PACKB(2, 3),	/* MBOX_ABORT_QUEUE */ -	PACKB(2, 4),	/* MBOX_GET_DEV_QUEUE_STATUS */ -	PACKB(0, 0),	/* 0x001e */ -	PACKB(1, 3),	/* MBOX_GET_FIRMWARE_STATUS */ -	PACKB(1, 2),	/* MBOX_GET_INIT_SCSI_ID */ -	PACKB(1, 2),	/* MBOX_GET_SELECT_TIMEOUT */ -	PACKB(1, 3),	/* MBOX_GET_RETRY_COUNT	*/ -	PACKB(1, 2),	/* MBOX_GET_TAG_AGE_LIMIT */ -	PACKB(1, 2),	/* MBOX_GET_CLOCK_RATE */ -	PACKB(1, 2),	/* MBOX_GET_ACT_NEG_STATE */ -	PACKB(1, 2),	/* MBOX_GET_ASYNC_DATA_SETUP_TIME */ -	PACKB(1, 3),	/* MBOX_GET_PCI_PARAMS */ -	PACKB(2, 4),	/* MBOX_GET_TARGET_PARAMS */ -	PACKB(2, 4),	/* MBOX_GET_DEV_QUEUE_PARAMS */ -	PACKB(0, 0),	/* 0x002a */ -	PACKB(0, 0),	/* 0x002b */ -	PACKB(0, 0),	/* 0x002c */ -	PACKB(0, 0),	/* 0x002d */ -	PACKB(0, 0),	/* 0x002e */ -	PACKB(0, 0),	/* 0x002f */ -	PACKB(2, 2),	/* MBOX_SET_INIT_SCSI_ID */ -	PACKB(2, 2),	/* MBOX_SET_SELECT_TIMEOUT */ -	PACKB(3, 3),	/* MBOX_SET_RETRY_COUNT	*/ -	PACKB(2, 2),	/* MBOX_SET_TAG_AGE_LIMIT */ -	PACKB(2, 2),	/* MBOX_SET_CLOCK_RATE */ -	PACKB(2, 2),	/* MBOX_SET_ACTIVE_NEG_STATE */ -	PACKB(2, 2),	/* MBOX_SET_ASYNC_DATA_SETUP_TIME */ -	PACKB(3, 3),	/* MBOX_SET_PCI_CONTROL_PARAMS */ -	PACKB(4, 4),	/* MBOX_SET_TARGET_PARAMS */ -	PACKB(4, 4),	/* MBOX_SET_DEV_QUEUE_PARAMS */ -	PACKB(0, 0),	/* 0x003a */ -	PACKB(0, 0),	/* 0x003b */ -	PACKB(0, 0),	/* 0x003c */ -	PACKB(0, 0),	/* 0x003d */ -	PACKB(0, 0),	/* 0x003e */ -	PACKB(0, 0),	/* 0x003f */ -	PACKB(1, 2),	/* MBOX_RETURN_BIOS_BLOCK_ADDR */ -	PACKB(6, 1),	/* MBOX_WRITE_FOUR_RAM_WORDS */ -	PACKB(2, 3)	/* MBOX_EXEC_BIOS_IOCB */ -#ifdef CONFIG_QL_ISP_A64 -	,PACKB(0, 0),	/* 0x0043 */ -	PACKB(0, 0),	/* 0x0044 */ -	PACKB(0, 0),	/* 0x0045 */ -	PACKB(0, 0),	/* 0x0046 */ -	PACKB(0, 0),	/* 0x0047 */ -	PACKB(0, 0),	/* 0x0048 */ -	PACKB(0, 0),	/* 0x0049 */ -	PACKB(0, 0),	/* 0x004a */ -	PACKB(0, 0),	/* 0x004b */ -	PACKB(0, 0),	/* 0x004c */ -	PACKB(0, 0),	/* 0x004d */ -	PACKB(0, 0),	/* 0x004e */ -	PACKB(0, 0),	/* 0x004f */ -	PACKB(0, 0),	/* 0x0050 */ -	PACKB(0, 0),	/* 0x0051 */ -	PACKB(8, 8),	/* MBOX_CMD_INIT_REQUEST_QUEUE_64 (0x0052) */ -	PACKB(8, 8)	/* MBOX_CMD_INIT_RESPONSE_QUEUE_64 (0x0053) */ -#endif /* CONFIG_QL_ISP_A64 */ -}; - -#define MAX_MBOX_COMMAND	(sizeof(mbox_param)/sizeof(u_short)) - -struct host_param { -	u_short		fifo_threshold; -	u_short		host_adapter_enable; -	u_short		initiator_scsi_id; -	u_short		bus_reset_delay; -	u_short		retry_count; -	u_short		retry_delay; -	u_short		async_data_setup_time; -	u_short		req_ack_active_negation; -	u_short		data_line_active_negation; -	u_short		data_dma_burst_enable; -	u_short		command_dma_burst_enable; -	u_short		tag_aging; -	u_short		selection_timeout; -	u_short		max_queue_depth; -}; - -/* - * Device Flags: - * - * Bit  Name - * --------- - *  7   Disconnect Privilege - *  6   Parity Checking - *  5   Wide Data Transfers - *  4   Synchronous Data Transfers - *  3   Tagged Queuing - *  2   Automatic Request Sense - *  1   Stop Queue on Check Condition - *  0   Renegotiate on Error - */ - -struct dev_param { -	u_short		device_flags; -	u_short		execution_throttle; -	u_short		synchronous_period; -	u_short		synchronous_offset; -	u_short		device_enable; -	u_short		reserved; /* pad */ -}; - -/* - * The result queue can be quite a bit smaller since continuation entries - * do not show up there: - */ -#define RES_QUEUE_LEN		((QLOGICISP_REQ_QUEUE_LEN + 1) / 8 - 1) -#define QUEUE_ENTRY_LEN		64 -#define QSIZE(entries)  (((entries) + 1) * QUEUE_ENTRY_LEN) - -struct isp_queue_entry { -	char __opaque[QUEUE_ENTRY_LEN]; -}; - -struct isp1020_hostdata { -	void __iomem *memaddr; -	u_char	revision; -	struct	host_param host_param; -	struct	dev_param dev_param[MAX_TARGETS]; -	struct	pci_dev *pci_dev; -	 -	struct isp_queue_entry *res_cpu; /* CPU-side address of response queue. */ -	struct isp_queue_entry *req_cpu; /* CPU-size address of request queue. */ - -	/* result and request queues (shared with isp1020): */ -	u_int	req_in_ptr;		/* index of next request slot */ -	u_int	res_out_ptr;		/* index of next result slot */ - -	/* this is here so the queues are nicely aligned */ -	long	send_marker;		/* do we need to send a marker? */ - -	/* The cmd->handle has a fixed size, and is only 32-bits.  We -	 * need to take care to handle 64-bit systems correctly thus what -	 * we actually place in cmd->handle is an index to the following -	 * table.  Kudos to Matt Jacob for the technique.  -DaveM -	 */ -	Scsi_Cmnd *cmd_slots[QLOGICISP_REQ_QUEUE_LEN + 1]; - -	dma_addr_t res_dma;	/* PCI side view of response queue */ -	dma_addr_t req_dma;	/* PCI side view of request queue */ -}; - -/* queue length's _must_ be power of two: */ -#define QUEUE_DEPTH(in, out, ql)	((in - out) & (ql)) -#define REQ_QUEUE_DEPTH(in, out)	QUEUE_DEPTH(in, out, 		     \ -						    QLOGICISP_REQ_QUEUE_LEN) -#define RES_QUEUE_DEPTH(in, out)	QUEUE_DEPTH(in, out, RES_QUEUE_LEN) - -static void	isp1020_enable_irqs(struct Scsi_Host *); -static void	isp1020_disable_irqs(struct Scsi_Host *); -static int	isp1020_init(struct Scsi_Host *); -static int	isp1020_reset_hardware(struct Scsi_Host *); -static int	isp1020_set_defaults(struct Scsi_Host *); -static int	isp1020_load_parameters(struct Scsi_Host *); -static int	isp1020_mbox_command(struct Scsi_Host *, u_short []);  -static int	isp1020_return_status(struct Status_Entry *); -static void	isp1020_intr_handler(int, void *, struct pt_regs *); -static irqreturn_t do_isp1020_intr_handler(int, void *, struct pt_regs *); - -#if USE_NVRAM_DEFAULTS -static int	isp1020_get_defaults(struct Scsi_Host *); -static int	isp1020_verify_nvram(struct Scsi_Host *); -static u_short	isp1020_read_nvram_word(struct Scsi_Host *, u_short); -#endif - -#if DEBUG_ISP1020 -static void	isp1020_print_scsi_cmd(Scsi_Cmnd *); -#endif -#if DEBUG_ISP1020_INTR -static void	isp1020_print_status_entry(struct Status_Entry *); -#endif - -/* memaddr should be used to determine if memmapped port i/o is being used - * non-null memaddr == mmap'd - * JV 7-Jan-2000 - */ -static inline u_short isp_inw(struct Scsi_Host *host, long offset) -{ -	struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata; -	if (h->memaddr) -		return readw(h->memaddr + offset); -	else -		return inw(host->io_port + offset); -} - -static inline void isp_outw(u_short val, struct Scsi_Host *host, long offset) -{ -	struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata; -	if (h->memaddr) -		writew(val, h->memaddr + offset); -	else -		outw(val, host->io_port + offset); -} - -static inline void isp1020_enable_irqs(struct Scsi_Host *host) -{ -	isp_outw(ISP_EN_INT|ISP_EN_RISC, host, PCI_INTF_CTL); -} - - -static inline void isp1020_disable_irqs(struct Scsi_Host *host) -{ -	isp_outw(0x0, host, PCI_INTF_CTL); -} - - -static int isp1020_detect(Scsi_Host_Template *tmpt) -{ -	int hosts = 0; -	struct Scsi_Host *host; -	struct isp1020_hostdata *hostdata; -	struct pci_dev *pdev = NULL; - -	ENTER("isp1020_detect"); - -	tmpt->proc_name = "isp1020"; - -	while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, pdev))) -	{ -		if (pci_enable_device(pdev)) -			continue; - -		host = scsi_register(tmpt, sizeof(struct isp1020_hostdata)); -		if (!host) -			continue; - -		hostdata = (struct isp1020_hostdata *) host->hostdata; - -		memset(hostdata, 0, sizeof(struct isp1020_hostdata)); - -		hostdata->pci_dev = pdev; - -		if (isp1020_init(host)) -			goto fail_and_unregister; - -		if (isp1020_reset_hardware(host) -#if USE_NVRAM_DEFAULTS -		    || isp1020_get_defaults(host) -#else -		    || isp1020_set_defaults(host) -#endif /* USE_NVRAM_DEFAULTS */ -		    || isp1020_load_parameters(host)) { -			goto fail_uninit; -		} - -		host->this_id = hostdata->host_param.initiator_scsi_id; -		host->max_sectors = 64; - -		if (request_irq(host->irq, do_isp1020_intr_handler, SA_INTERRUPT | SA_SHIRQ, -				"qlogicisp", host)) -		{ -			printk("qlogicisp : interrupt %d already in use\n", -			       host->irq); -			goto fail_uninit; -		} - -		isp_outw(0x0, host, PCI_SEMAPHORE); -		isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); -		isp1020_enable_irqs(host); - -		hosts++; -		continue; - -	fail_uninit: -		iounmap(hostdata->memaddr); -		release_region(host->io_port, 0xff); -	fail_and_unregister: -		if (hostdata->res_cpu) -			pci_free_consistent(hostdata->pci_dev, -					    QSIZE(RES_QUEUE_LEN), -					    hostdata->res_cpu, -					    hostdata->res_dma); -		if (hostdata->req_cpu) -			pci_free_consistent(hostdata->pci_dev, -					    QSIZE(QLOGICISP_REQ_QUEUE_LEN), -					    hostdata->req_cpu, -					    hostdata->req_dma); -		scsi_unregister(host); -	} - -	LEAVE("isp1020_detect"); - -	return hosts; -} - - -static int isp1020_release(struct Scsi_Host *host) -{ -	struct isp1020_hostdata *hostdata; - -	ENTER("isp1020_release"); - -	hostdata = (struct isp1020_hostdata *) host->hostdata; - -	isp_outw(0x0, host, PCI_INTF_CTL); -	free_irq(host->irq, host); - -	iounmap(hostdata->memaddr); - -	release_region(host->io_port, 0xff); - -	LEAVE("isp1020_release"); - -	return 0; -} - - -static const char *isp1020_info(struct Scsi_Host *host) -{ -	static char buf[80]; -	struct isp1020_hostdata *hostdata; - -	ENTER("isp1020_info"); - -	hostdata = (struct isp1020_hostdata *) host->hostdata; -	sprintf(buf, -		"QLogic ISP1020 SCSI on PCI bus %02x device %02x irq %d %s base 0x%lx", -		hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq, -		(hostdata->memaddr ? "MEM" : "I/O"), -		(hostdata->memaddr ? (unsigned long)hostdata->memaddr : host->io_port)); - -	LEAVE("isp1020_info"); - -	return buf; -} - - -/* - * The middle SCSI layer ensures that queuecommand never gets invoked - * concurrently with itself or the interrupt handler (though the - * interrupt handler may call this routine as part of - * request-completion handling). - */ -static int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) -{ -	int i, n, num_free; -	u_int in_ptr, out_ptr; -	struct dataseg * ds; -	struct scatterlist *sg; -	struct Command_Entry *cmd; -	struct Continuation_Entry *cont; -	struct Scsi_Host *host; -	struct isp1020_hostdata *hostdata; -	dma_addr_t	dma_addr; - -	ENTER("isp1020_queuecommand"); - -	host = Cmnd->device->host; -	hostdata = (struct isp1020_hostdata *) host->hostdata; -	Cmnd->scsi_done = done; - -	DEBUG(isp1020_print_scsi_cmd(Cmnd)); - -	out_ptr = isp_inw(host, + MBOX4); -	in_ptr  = hostdata->req_in_ptr; - -	DEBUG(printk("qlogicisp : request queue depth %d\n", -		     REQ_QUEUE_DEPTH(in_ptr, out_ptr))); - -	cmd = (struct Command_Entry *) &hostdata->req_cpu[in_ptr]; -	in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN; -	if (in_ptr == out_ptr) { -		printk("qlogicisp : request queue overflow\n"); -		return 1; -	} - -	if (hostdata->send_marker) { -		struct Marker_Entry *marker; - -		TRACE("queue marker", in_ptr, 0); - -		DEBUG(printk("qlogicisp : adding marker entry\n")); -		marker = (struct Marker_Entry *) cmd; -		memset(marker, 0, sizeof(struct Marker_Entry)); - -		marker->hdr.entry_type = ENTRY_MARKER; -		marker->hdr.entry_cnt = 1; -		marker->modifier = SYNC_ALL; - -		hostdata->send_marker = 0; - -		if (((in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN) == out_ptr) { -			isp_outw(in_ptr, host, MBOX4); -			hostdata->req_in_ptr = in_ptr; -			printk("qlogicisp : request queue overflow\n"); -			return 1; -		} -		cmd = (struct Command_Entry *) &hostdata->req_cpu[in_ptr]; -		in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN; -	} - -	TRACE("queue command", in_ptr, Cmnd); - -	memset(cmd, 0, sizeof(struct Command_Entry)); - -	cmd->hdr.entry_type = ENTRY_COMMAND; -	cmd->hdr.entry_cnt = 1; - -	cmd->target_lun = Cmnd->device->lun; -	cmd->target_id = Cmnd->device->id; -	cmd->cdb_length = cpu_to_le16(Cmnd->cmd_len); -	cmd->control_flags = cpu_to_le16(CFLAG_READ | CFLAG_WRITE); -	cmd->time_out = cpu_to_le16(30); - -	memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len); - -	if (Cmnd->use_sg) { -		int sg_count; - -		sg = (struct scatterlist *) Cmnd->request_buffer; -		ds = cmd->dataseg; - -		sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, -				      Cmnd->sc_data_direction); - -		cmd->segment_cnt = cpu_to_le16(sg_count); - -		/* fill in first four sg entries: */ -		n = sg_count; -		if (n > IOCB_SEGS) -			n = IOCB_SEGS; -		for (i = 0; i < n; i++) { -			dma_addr = sg_dma_address(sg); -			ds[i].d_base  = cpu_to_le32((u32) dma_addr); -#ifdef CONFIG_QL_ISP_A64 -			ds[i].d_base_hi = cpu_to_le32((u32) (dma_addr>>32)); -#endif /* CONFIG_QL_ISP_A64 */ -			ds[i].d_count = cpu_to_le32(sg_dma_len(sg)); -			++sg; -		} -		sg_count -= IOCB_SEGS; - -		while (sg_count > 0) { -			++cmd->hdr.entry_cnt; -			cont = (struct Continuation_Entry *) -				&hostdata->req_cpu[in_ptr]; -			in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN; -			if (in_ptr == out_ptr) { -				printk("isp1020: unexpected request queue " -				       "overflow\n"); -				return 1; -			} -			TRACE("queue continuation", in_ptr, 0); -			cont->hdr.entry_type = ENTRY_CONTINUATION; -			cont->hdr.entry_cnt  = 0; -			cont->hdr.sys_def_1  = 0; -			cont->hdr.flags      = 0; -#ifndef CONFIG_QL_ISP_A64 -			cont->reserved = 0; -#endif -			ds = cont->dataseg; -			n = sg_count; -			if (n > CONTINUATION_SEGS) -				n = CONTINUATION_SEGS; -			for (i = 0; i < n; ++i) { -				dma_addr = sg_dma_address(sg); -				ds[i].d_base = cpu_to_le32((u32) dma_addr); -#ifdef CONFIG_QL_ISP_A64 -				ds[i].d_base_hi = cpu_to_le32((u32)(dma_addr>>32)); -#endif /* CONFIG_QL_ISP_A64 */ -				ds[i].d_count = cpu_to_le32(sg_dma_len(sg)); -				++sg; -			} -			sg_count -= n; -		} -	} else if (Cmnd->request_bufflen) { -		/*Cmnd->SCp.ptr = (char *)(unsigned long)*/ -		dma_addr = pci_map_single(hostdata->pci_dev, -				       Cmnd->request_buffer, -				       Cmnd->request_bufflen, -				       Cmnd->sc_data_direction); -		Cmnd->SCp.ptr = (char *)(unsigned long) dma_addr; - -		cmd->dataseg[0].d_base = -			cpu_to_le32((u32) dma_addr); -#ifdef CONFIG_QL_ISP_A64 -		cmd->dataseg[0].d_base_hi = -			cpu_to_le32((u32) (dma_addr>>32)); -#endif /* CONFIG_QL_ISP_A64 */ -		cmd->dataseg[0].d_count = -			cpu_to_le32((u32)Cmnd->request_bufflen); -		cmd->segment_cnt = cpu_to_le16(1); -	} else { -		cmd->dataseg[0].d_base = 0; -#ifdef CONFIG_QL_ISP_A64 -		cmd->dataseg[0].d_base_hi = 0; -#endif /* CONFIG_QL_ISP_A64 */ -		cmd->dataseg[0].d_count = 0; -		cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */ -	} - -	/* Committed, record Scsi_Cmd so we can find it later. */ -	cmd->handle = in_ptr; -	hostdata->cmd_slots[in_ptr] = Cmnd; - -	isp_outw(in_ptr, host, MBOX4); -	hostdata->req_in_ptr = in_ptr; - -	num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr); -	host->can_queue = host->host_busy + num_free; -	host->sg_tablesize = QLOGICISP_MAX_SG(num_free); - -	LEAVE("isp1020_queuecommand"); - -	return 0; -} - - -#define ASYNC_EVENT_INTERRUPT	0x01 - -irqreturn_t do_isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs) -{ -	struct Scsi_Host *host = dev_id; -	unsigned long flags; - -	spin_lock_irqsave(host->host_lock, flags); -	isp1020_intr_handler(irq, dev_id, regs); -	spin_unlock_irqrestore(host->host_lock, flags); - -	return IRQ_HANDLED; -} - -void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs) -{ -	Scsi_Cmnd *Cmnd; -	struct Status_Entry *sts; -	struct Scsi_Host *host = dev_id; -	struct isp1020_hostdata *hostdata; -	u_int in_ptr, out_ptr; -	u_short status; - -	ENTER_INTR("isp1020_intr_handler"); - -	hostdata = (struct isp1020_hostdata *) host->hostdata; - -	DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq)); - -	if (!(isp_inw(host, PCI_INTF_STS) & 0x04)) { -		/* spurious interrupts can happen legally */ -		DEBUG_INTR(printk("qlogicisp: got spurious interrupt\n")); -		return; -	} -	in_ptr = isp_inw(host, MBOX5); -	isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); - -	if ((isp_inw(host, PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) { -		status = isp_inw(host, MBOX0); - -		DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n", -				  status)); - -		switch (status) { -		      case ASYNC_SCSI_BUS_RESET: -		      case EXECUTION_TIMEOUT_RESET: -			hostdata->send_marker = 1; -			break; -		      case INVALID_COMMAND: -		      case HOST_INTERFACE_ERROR: -		      case COMMAND_ERROR: -		      case COMMAND_PARAM_ERROR: -			printk("qlogicisp : bad mailbox return status\n"); -			break; -		} -		isp_outw(0x0, host, PCI_SEMAPHORE); -	} -	out_ptr = hostdata->res_out_ptr; - -	DEBUG_INTR(printk("qlogicisp : response queue update\n")); -	DEBUG_INTR(printk("qlogicisp : response queue depth %d\n", -			  QUEUE_DEPTH(in_ptr, out_ptr, RES_QUEUE_LEN))); - -	while (out_ptr != in_ptr) { -		u_int cmd_slot; - -		sts = (struct Status_Entry *) &hostdata->res_cpu[out_ptr]; -		out_ptr = (out_ptr + 1) & RES_QUEUE_LEN; - -		cmd_slot = sts->handle; -		Cmnd = hostdata->cmd_slots[cmd_slot]; -		hostdata->cmd_slots[cmd_slot] = NULL; - -		TRACE("done", out_ptr, Cmnd); - -		if (le16_to_cpu(sts->completion_status) == CS_RESET_OCCURRED -		    || le16_to_cpu(sts->completion_status) == CS_ABORTED -		    || (le16_to_cpu(sts->status_flags) & STF_BUS_RESET)) -			hostdata->send_marker = 1; - -		if (le16_to_cpu(sts->state_flags) & SF_GOT_SENSE) -			memcpy(Cmnd->sense_buffer, sts->req_sense_data, -			       sizeof(Cmnd->sense_buffer)); - -		DEBUG_INTR(isp1020_print_status_entry(sts)); - -		if (sts->hdr.entry_type == ENTRY_STATUS) -			Cmnd->result = isp1020_return_status(sts); -		else -			Cmnd->result = DID_ERROR << 16; - -		if (Cmnd->use_sg) -			pci_unmap_sg(hostdata->pci_dev, -				     (struct scatterlist *)Cmnd->buffer, -				     Cmnd->use_sg, -				     Cmnd->sc_data_direction); -		else if (Cmnd->request_bufflen) -			pci_unmap_single(hostdata->pci_dev, -#ifdef CONFIG_QL_ISP_A64 -					 (dma_addr_t)((long)Cmnd->SCp.ptr), -#else -					 (u32)((long)Cmnd->SCp.ptr), -#endif -					 Cmnd->request_bufflen, -					 Cmnd->sc_data_direction); - -		isp_outw(out_ptr, host, MBOX5); -		(*Cmnd->scsi_done)(Cmnd); -	} -	hostdata->res_out_ptr = out_ptr; - -	LEAVE_INTR("isp1020_intr_handler"); -} - - -static int isp1020_return_status(struct Status_Entry *sts) -{ -	int host_status = DID_ERROR; -#if DEBUG_ISP1020_INTR -	static char *reason[] = { -		"DID_OK", -		"DID_NO_CONNECT", -		"DID_BUS_BUSY", -		"DID_TIME_OUT", -		"DID_BAD_TARGET", -		"DID_ABORT", -		"DID_PARITY", -		"DID_ERROR", -		"DID_RESET", -		"DID_BAD_INTR" -	}; -#endif /* DEBUG_ISP1020_INTR */ - -	ENTER("isp1020_return_status"); - -	DEBUG(printk("qlogicisp : completion status = 0x%04x\n", -		     le16_to_cpu(sts->completion_status))); - -	switch(le16_to_cpu(sts->completion_status)) { -	      case CS_COMPLETE: -		host_status = DID_OK; -		break; -	      case CS_INCOMPLETE: -		if (!(le16_to_cpu(sts->state_flags) & SF_GOT_BUS)) -			host_status = DID_NO_CONNECT; -		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_TARGET)) -			host_status = DID_BAD_TARGET; -		else if (!(le16_to_cpu(sts->state_flags) & SF_SENT_CDB)) -			host_status = DID_ERROR; -		else if (!(le16_to_cpu(sts->state_flags) & SF_TRANSFERRED_DATA)) -			host_status = DID_ERROR; -		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_STATUS)) -			host_status = DID_ERROR; -		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_SENSE)) -			host_status = DID_ERROR; -		break; -	      case CS_DMA_ERROR: -	      case CS_TRANSPORT_ERROR: -		host_status = DID_ERROR; -		break; -	      case CS_RESET_OCCURRED: -		host_status = DID_RESET; -		break; -	      case CS_ABORTED: -		host_status = DID_ABORT; -		break; -	      case CS_TIMEOUT: -		host_status = DID_TIME_OUT; -		break; -	      case CS_DATA_OVERRUN: -	      case CS_COMMAND_OVERRUN: -	      case CS_STATUS_OVERRUN: -	      case CS_BAD_MESSAGE: -	      case CS_NO_MESSAGE_OUT: -	      case CS_EXT_ID_FAILED: -	      case CS_IDE_MSG_FAILED: -	      case CS_ABORT_MSG_FAILED: -	      case CS_NOP_MSG_FAILED: -	      case CS_PARITY_ERROR_MSG_FAILED: -	      case CS_DEVICE_RESET_MSG_FAILED: -	      case CS_ID_MSG_FAILED: -	      case CS_UNEXP_BUS_FREE: -		host_status = DID_ERROR; -		break; -	      case CS_DATA_UNDERRUN: -		host_status = DID_OK; -		break; -	      default: -		printk("qlogicisp : unknown completion status 0x%04x\n", -		       le16_to_cpu(sts->completion_status)); -		host_status = DID_ERROR; -		break; -	} - -	DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n", -			  reason[host_status], le16_to_cpu(sts->scsi_status))); - -	LEAVE("isp1020_return_status"); - -	return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16); -} - - -static int isp1020_biosparam(struct scsi_device *sdev, struct block_device *n, -		sector_t capacity, int ip[]) -{ -	int size = capacity; - -	ENTER("isp1020_biosparam"); - -	ip[0] = 64; -	ip[1] = 32; -	ip[2] = size >> 11; -	if (ip[2] > 1024) { -		ip[0] = 255; -		ip[1] = 63; -		ip[2] = size / (ip[0] * ip[1]); -#if 0 -		if (ip[2] > 1023) -			ip[2] = 1023; -#endif			 -	} - -	LEAVE("isp1020_biosparam"); - -	return 0; -} - - -static int isp1020_reset_hardware(struct Scsi_Host *host) -{ -	u_short param[6]; -	int loop_count; - -	ENTER("isp1020_reset_hardware"); - -	isp_outw(ISP_RESET, host, PCI_INTF_CTL); -	udelay(100); -	isp_outw(HCCR_RESET, host, HOST_HCCR); -	udelay(100); -	isp_outw(HCCR_RELEASE, host, HOST_HCCR); -	isp_outw(HCCR_BIOS_DISABLE, host, HOST_HCCR); - -	loop_count = DEFAULT_LOOP_COUNT; -	while (--loop_count && isp_inw(host, HOST_HCCR) == RISC_BUSY) { -		barrier(); -		cpu_relax(); -	} -	if (!loop_count) -		printk("qlogicisp: reset_hardware loop timeout\n"); - -	isp_outw(0, host, ISP_CFG1); - -#if DEBUG_ISP1020 -	printk("qlogicisp : mbox 0 0x%04x \n", isp_inw(host, MBOX0)); -	printk("qlogicisp : mbox 1 0x%04x \n", isp_inw(host, MBOX1)); -	printk("qlogicisp : mbox 2 0x%04x \n", isp_inw(host, MBOX2)); -	printk("qlogicisp : mbox 3 0x%04x \n", isp_inw(host, MBOX3)); -	printk("qlogicisp : mbox 4 0x%04x \n", isp_inw(host, MBOX4)); -	printk("qlogicisp : mbox 5 0x%04x \n", isp_inw(host, MBOX5)); -#endif /* DEBUG_ISP1020 */ - -	param[0] = MBOX_NO_OP; -	isp1020_mbox_command(host, param); -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : NOP test failed\n"); -		return 1; -	} - -	DEBUG(printk("qlogicisp : loading risc ram\n")); - -#if RELOAD_FIRMWARE -	for (loop_count = 0; loop_count < risc_code_length01; loop_count++) { -		param[0] = MBOX_WRITE_RAM_WORD; -		param[1] = risc_code_addr01 + loop_count; -		param[2] = risc_code01[loop_count]; -		isp1020_mbox_command(host, param); -		if (param[0] != MBOX_COMMAND_COMPLETE) { -			printk("qlogicisp : firmware load failure at %d\n", -			    loop_count); -			return 1; -		} -	} -#endif /* RELOAD_FIRMWARE */ - -	DEBUG(printk("qlogicisp : verifying checksum\n")); - -	param[0] = MBOX_VERIFY_CHECKSUM; -	param[1] = risc_code_addr01; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : ram checksum failure\n"); -		return 1; -	} - -	DEBUG(printk("qlogicisp : executing firmware\n")); - -	param[0] = MBOX_EXEC_FIRMWARE; -	param[1] = risc_code_addr01; - -	isp1020_mbox_command(host, param); - -	param[0] = MBOX_ABOUT_FIRMWARE; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : about firmware failure\n"); -		return 1; -	} - -	DEBUG(printk("qlogicisp : firmware major revision %d\n", param[1])); -	DEBUG(printk("qlogicisp : firmware minor revision %d\n", param[2])); - -	LEAVE("isp1020_reset_hardware"); - -	return 0; -} - - -static int isp1020_init(struct Scsi_Host *sh) -{ -	u_long io_base, mem_base, io_flags, mem_flags; -	struct isp1020_hostdata *hostdata; -	u_char revision; -	u_int irq; -	u_short command; -	struct pci_dev *pdev; - -	ENTER("isp1020_init"); - -	hostdata = (struct isp1020_hostdata *) sh->hostdata; -	pdev = hostdata->pci_dev; - -	if (pci_read_config_word(pdev, PCI_COMMAND, &command) -	    || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) -	{ -		printk("qlogicisp : error reading PCI configuration\n"); -		return 1; -	} - -	io_base = pci_resource_start(pdev, 0); -	mem_base = pci_resource_start(pdev, 1); -	io_flags = pci_resource_flags(pdev, 0); -	mem_flags = pci_resource_flags(pdev, 1); -	irq = pdev->irq; - -	if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) { -		printk("qlogicisp : 0x%04x is not QLogic vendor ID\n", -		       pdev->vendor); -		return 1; -	} - -	if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP1020) { -		printk("qlogicisp : 0x%04x does not match ISP1020 device id\n", -		       pdev->device); -		return 1; -	} - -#ifdef __alpha__ -	/* Force ALPHA to use bus I/O and not bus MEM. -	   This is to avoid having to use HAE_MEM registers, -	   which is broken on some platforms and with SMP.  */ -	command &= ~PCI_COMMAND_MEMORY;  -#endif - -	sh->io_port = io_base; - -	if (!request_region(sh->io_port, 0xff, "qlogicisp")) { -		printk("qlogicisp : i/o region 0x%lx-0x%lx already " -		       "in use\n", -		       sh->io_port, sh->io_port + 0xff); -		return 1; -	} - - 	if ((command & PCI_COMMAND_MEMORY) && - 	    ((mem_flags & 1) == 0)) { - 		hostdata->memaddr = ioremap(mem_base, PAGE_SIZE); -		if (!hostdata->memaddr) { - 			printk("qlogicisp : i/o remapping failed.\n"); -			goto out_release; -		} - 	} else { -		if (command & PCI_COMMAND_IO && (io_flags & 3) != 1) { -			printk("qlogicisp : i/o mapping is disabled\n"); -			goto out_release; - 		} - 		hostdata->memaddr = NULL; /* zero to signify no i/o mapping */ - 		mem_base = 0; -	} - -	if (revision != ISP1020_REV_ID) -		printk("qlogicisp : new isp1020 revision ID (%d)\n", revision); - -	if (isp_inw(sh,  PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC -	    || isp_inw(sh, PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020) -	{ -		printk("qlogicisp : can't decode %s address space 0x%lx\n", -		       (io_base ? "I/O" : "MEM"), -		       (io_base ? io_base : mem_base)); -		goto out_unmap; -	} - -	hostdata->revision = revision; - -	sh->irq = irq; -	sh->max_id = MAX_TARGETS; -	sh->max_lun = MAX_LUNS; - -	hostdata->res_cpu = pci_alloc_consistent(hostdata->pci_dev, -						 QSIZE(RES_QUEUE_LEN), -						 &hostdata->res_dma); -	if (hostdata->res_cpu == NULL) { -		printk("qlogicisp : can't allocate response queue\n"); -		goto out_unmap; -	} - -	hostdata->req_cpu = pci_alloc_consistent(hostdata->pci_dev, -						 QSIZE(QLOGICISP_REQ_QUEUE_LEN), -						 &hostdata->req_dma); -	if (hostdata->req_cpu == NULL) { -		pci_free_consistent(hostdata->pci_dev, -				    QSIZE(RES_QUEUE_LEN), -				    hostdata->res_cpu, -				    hostdata->res_dma); -		printk("qlogicisp : can't allocate request queue\n"); -		goto out_unmap; -	} - -	pci_set_master(pdev); - -	LEAVE("isp1020_init"); - -	return 0; - -out_unmap: -	iounmap(hostdata->memaddr); -out_release: -	release_region(sh->io_port, 0xff); -	return 1; -} - - -#if USE_NVRAM_DEFAULTS - -static int isp1020_get_defaults(struct Scsi_Host *host) -{ -	int i; -	u_short value; -	struct isp1020_hostdata *hostdata = -		(struct isp1020_hostdata *) host->hostdata; - -	ENTER("isp1020_get_defaults"); - -	if (!isp1020_verify_nvram(host)) { -		printk("qlogicisp : nvram checksum failure\n"); -		printk("qlogicisp : attempting to use default parameters\n"); -		return isp1020_set_defaults(host); -	} - -	value = isp1020_read_nvram_word(host, 2); -	hostdata->host_param.fifo_threshold = (value >> 8) & 0x03; -	hostdata->host_param.host_adapter_enable = (value >> 11) & 0x01; -	hostdata->host_param.initiator_scsi_id = (value >> 12) & 0x0f; - -	value = isp1020_read_nvram_word(host, 3); -	hostdata->host_param.bus_reset_delay = value & 0xff; -	hostdata->host_param.retry_count = value >> 8; - -	value = isp1020_read_nvram_word(host, 4); -	hostdata->host_param.retry_delay = value & 0xff; -	hostdata->host_param.async_data_setup_time = (value >> 8) & 0x0f; -	hostdata->host_param.req_ack_active_negation = (value >> 12) & 0x01; -	hostdata->host_param.data_line_active_negation = (value >> 13) & 0x01; -	hostdata->host_param.data_dma_burst_enable = (value >> 14) & 0x01; -	hostdata->host_param.command_dma_burst_enable = (value >> 15); - -	value = isp1020_read_nvram_word(host, 5); -	hostdata->host_param.tag_aging = value & 0xff; - -	value = isp1020_read_nvram_word(host, 6); -	hostdata->host_param.selection_timeout = value & 0xffff; - -	value = isp1020_read_nvram_word(host, 7); -	hostdata->host_param.max_queue_depth = value & 0xffff; - -#if DEBUG_ISP1020_SETUP -	printk("qlogicisp : fifo threshold=%d\n", -	       hostdata->host_param.fifo_threshold); -	printk("qlogicisp : initiator scsi id=%d\n", -	       hostdata->host_param.initiator_scsi_id); -	printk("qlogicisp : bus reset delay=%d\n", -	       hostdata->host_param.bus_reset_delay); -	printk("qlogicisp : retry count=%d\n", -	       hostdata->host_param.retry_count); -	printk("qlogicisp : retry delay=%d\n", -	       hostdata->host_param.retry_delay); -	printk("qlogicisp : async data setup time=%d\n", -	       hostdata->host_param.async_data_setup_time); -	printk("qlogicisp : req/ack active negation=%d\n", -	       hostdata->host_param.req_ack_active_negation); -	printk("qlogicisp : data line active negation=%d\n", -	       hostdata->host_param.data_line_active_negation); -	printk("qlogicisp : data DMA burst enable=%d\n", -	       hostdata->host_param.data_dma_burst_enable); -	printk("qlogicisp : command DMA burst enable=%d\n", -	       hostdata->host_param.command_dma_burst_enable); -	printk("qlogicisp : tag age limit=%d\n", -	       hostdata->host_param.tag_aging); -	printk("qlogicisp : selection timeout limit=%d\n", -	       hostdata->host_param.selection_timeout); -	printk("qlogicisp : max queue depth=%d\n", -	       hostdata->host_param.max_queue_depth); -#endif /* DEBUG_ISP1020_SETUP */ - -	for (i = 0; i < MAX_TARGETS; i++) { - -		value = isp1020_read_nvram_word(host, 14 + i * 3); -		hostdata->dev_param[i].device_flags = value & 0xff; -		hostdata->dev_param[i].execution_throttle = value >> 8; - -		value = isp1020_read_nvram_word(host, 15 + i * 3); -		hostdata->dev_param[i].synchronous_period = value & 0xff; -		hostdata->dev_param[i].synchronous_offset = (value >> 8) & 0x0f; -		hostdata->dev_param[i].device_enable = (value >> 12) & 0x01; - -#if DEBUG_ISP1020_SETUP -		printk("qlogicisp : target 0x%02x\n", i); -		printk("qlogicisp :     device flags=0x%02x\n", -		       hostdata->dev_param[i].device_flags); -		printk("qlogicisp :     execution throttle=%d\n", -		       hostdata->dev_param[i].execution_throttle); -		printk("qlogicisp :     synchronous period=%d\n", -		       hostdata->dev_param[i].synchronous_period); -		printk("qlogicisp :     synchronous offset=%d\n", -		       hostdata->dev_param[i].synchronous_offset); -		printk("qlogicisp :     device enable=%d\n", -		       hostdata->dev_param[i].device_enable); -#endif /* DEBUG_ISP1020_SETUP */ -	} - -	LEAVE("isp1020_get_defaults"); - -	return 0; -} - - -#define ISP1020_NVRAM_LEN	0x40 -#define ISP1020_NVRAM_SIG1	0x5349 -#define ISP1020_NVRAM_SIG2	0x2050 - -static int isp1020_verify_nvram(struct Scsi_Host *host) -{ -	int	i; -	u_short value; -	u_char checksum = 0; - -	for (i = 0; i < ISP1020_NVRAM_LEN; i++) { -		value = isp1020_read_nvram_word(host, i); - -		switch (i) { -		      case 0: -			if (value != ISP1020_NVRAM_SIG1) return 0; -			break; -		      case 1: -			if (value != ISP1020_NVRAM_SIG2) return 0; -			break; -		      case 2: -			if ((value & 0xff) != 0x02) return 0; -			break; -		} -		checksum += value & 0xff; -		checksum += value >> 8; -	} - -	return (checksum == 0); -} - -#define NVRAM_DELAY() udelay(2) /* 2 microsecond delay */ - - -u_short isp1020_read_nvram_word(struct Scsi_Host *host, u_short byte) -{ -	int i; -	u_short value, output, input; - -	byte &= 0x3f; byte |= 0x0180; - -	for (i = 8; i >= 0; i--) { -		output = ((byte >> i) & 0x1) ? 0x4 : 0x0; -		isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY(); -		isp_outw(output | 0x3, host, PCI_NVRAM); NVRAM_DELAY(); -		isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY(); -	} - -	for (i = 0xf, value = 0; i >= 0; i--) { -		value <<= 1; -		isp_outw(0x3, host, PCI_NVRAM); NVRAM_DELAY(); -		input = isp_inw(host, PCI_NVRAM); NVRAM_DELAY(); -		isp_outw(0x2, host, PCI_NVRAM); NVRAM_DELAY(); -		if (input & 0x8) value |= 1; -	} - -	isp_outw(0x0, host, PCI_NVRAM); NVRAM_DELAY(); - -	return value; -} - -#endif /* USE_NVRAM_DEFAULTS */ - - -static int isp1020_set_defaults(struct Scsi_Host *host) -{ -	struct isp1020_hostdata *hostdata = -		(struct isp1020_hostdata *) host->hostdata; -	int i; - -	ENTER("isp1020_set_defaults"); - -	hostdata->host_param.fifo_threshold = 2; -	hostdata->host_param.host_adapter_enable = 1; -	hostdata->host_param.initiator_scsi_id = 7; -	hostdata->host_param.bus_reset_delay = 3; -	hostdata->host_param.retry_count = 0; -	hostdata->host_param.retry_delay = 1; -	hostdata->host_param.async_data_setup_time = 6; -	hostdata->host_param.req_ack_active_negation = 1; -	hostdata->host_param.data_line_active_negation = 1; -	hostdata->host_param.data_dma_burst_enable = 1; -	hostdata->host_param.command_dma_burst_enable = 1; -	hostdata->host_param.tag_aging = 8; -	hostdata->host_param.selection_timeout = 250; -	hostdata->host_param.max_queue_depth = 256; - -	for (i = 0; i < MAX_TARGETS; i++) { -		hostdata->dev_param[i].device_flags = 0xfd; -		hostdata->dev_param[i].execution_throttle = 16; -		hostdata->dev_param[i].synchronous_period = 25; -		hostdata->dev_param[i].synchronous_offset = 12; -		hostdata->dev_param[i].device_enable = 1; -	} - -	LEAVE("isp1020_set_defaults"); - -	return 0; -} - - -static int isp1020_load_parameters(struct Scsi_Host *host) -{ -	int i, k; -#ifdef CONFIG_QL_ISP_A64 -	u_long queue_addr; -	u_short param[8]; -#else -	u_int queue_addr; -	u_short param[6]; -#endif -	u_short isp_cfg1, hwrev; -	struct isp1020_hostdata *hostdata = -		(struct isp1020_hostdata *) host->hostdata; - -	ENTER("isp1020_load_parameters"); - -	hwrev = isp_inw(host, ISP_CFG0) & ISP_CFG0_HWMSK; -	isp_cfg1 = ISP_CFG1_F64 | ISP_CFG1_BENAB; -	if (hwrev == ISP_CFG0_1040A) { -		/* Busted fifo, says mjacob. */ -		isp_cfg1 &= ISP_CFG1_BENAB; -	} - -	isp_outw(isp_inw(host, ISP_CFG1) | isp_cfg1, host, ISP_CFG1); -	isp_outw(isp_inw(host, CDMA_CONF) | DMA_CONF_BENAB, host, CDMA_CONF); -	isp_outw(isp_inw(host, DDMA_CONF) | DMA_CONF_BENAB, host, DDMA_CONF); - -	param[0] = MBOX_SET_INIT_SCSI_ID; -	param[1] = hostdata->host_param.initiator_scsi_id; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set initiator id failure\n"); -		return 1; -	} - -	param[0] = MBOX_SET_RETRY_COUNT; -	param[1] = hostdata->host_param.retry_count; -	param[2] = hostdata->host_param.retry_delay; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set retry count failure\n"); -		return 1; -	} - -	param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; -	param[1] = hostdata->host_param.async_data_setup_time; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : async data setup time failure\n"); -		return 1; -	} - -	param[0] = MBOX_SET_ACTIVE_NEG_STATE; -	param[1] = (hostdata->host_param.req_ack_active_negation << 4) -		| (hostdata->host_param.data_line_active_negation << 5); - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set active negation state failure\n"); -		return 1; -	} - -	param[0] = MBOX_SET_PCI_CONTROL_PARAMS; -	param[1] = hostdata->host_param.data_dma_burst_enable << 1; -	param[2] = hostdata->host_param.command_dma_burst_enable << 1; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set pci control parameter failure\n"); -		return 1; -	} - -	param[0] = MBOX_SET_TAG_AGE_LIMIT; -	param[1] = hostdata->host_param.tag_aging; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set tag age limit failure\n"); -		return 1; -	} - -	param[0] = MBOX_SET_SELECT_TIMEOUT; -	param[1] = hostdata->host_param.selection_timeout; - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set selection timeout failure\n"); -		return 1; -	} - -	for (i = 0; i < MAX_TARGETS; i++) { - -		if (!hostdata->dev_param[i].device_enable) -			continue; - -		param[0] = MBOX_SET_TARGET_PARAMS; -		param[1] = i << 8; -		param[2] = hostdata->dev_param[i].device_flags << 8; -		param[3] = (hostdata->dev_param[i].synchronous_offset << 8) -			| hostdata->dev_param[i].synchronous_period; - -		isp1020_mbox_command(host, param); - -		if (param[0] != MBOX_COMMAND_COMPLETE) { -			printk("qlogicisp : set target parameter failure\n"); -			return 1; -		} - -		for (k = 0; k < MAX_LUNS; k++) { - -			param[0] = MBOX_SET_DEV_QUEUE_PARAMS; -			param[1] = (i << 8) | k; -			param[2] = hostdata->host_param.max_queue_depth; -			param[3] = hostdata->dev_param[i].execution_throttle; - -			isp1020_mbox_command(host, param); - -			if (param[0] != MBOX_COMMAND_COMPLETE) { -				printk("qlogicisp : set device queue " -				       "parameter failure\n"); -				return 1; -			} -		} -	} - -	queue_addr = hostdata->res_dma; -#ifdef CONFIG_QL_ISP_A64 -	param[0] = MBOX_CMD_INIT_RESPONSE_QUEUE_64; -#else -	param[0] = MBOX_INIT_RES_QUEUE; -#endif -	param[1] = RES_QUEUE_LEN + 1; -	param[2] = (u_short) (queue_addr >> 16); -	param[3] = (u_short) (queue_addr & 0xffff); -	param[4] = 0; -	param[5] = 0; -#ifdef CONFIG_QL_ISP_A64 -	param[6] = (u_short) (queue_addr >> 48); -	param[7] = (u_short) (queue_addr >> 32); -#endif - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set response queue failure\n"); -		return 1; -	} - -	queue_addr = hostdata->req_dma; -#ifdef CONFIG_QL_ISP_A64 -	param[0] = MBOX_CMD_INIT_REQUEST_QUEUE_64; -#else -	param[0] = MBOX_INIT_REQ_QUEUE; -#endif -	param[1] = QLOGICISP_REQ_QUEUE_LEN + 1; -	param[2] = (u_short) (queue_addr >> 16); -	param[3] = (u_short) (queue_addr & 0xffff); -	param[4] = 0; - -#ifdef CONFIG_QL_ISP_A64 -	param[5] = 0; -	param[6] = (u_short) (queue_addr >> 48); -	param[7] = (u_short) (queue_addr >> 32); -#endif - -	isp1020_mbox_command(host, param); - -	if (param[0] != MBOX_COMMAND_COMPLETE) { -		printk("qlogicisp : set request queue failure\n"); -		return 1; -	} - -	LEAVE("isp1020_load_parameters"); - -	return 0; -} - - -/* - * currently, this is only called during initialization or abort/reset, - * at which times interrupts are disabled, so polling is OK, I guess... - */ -static int isp1020_mbox_command(struct Scsi_Host *host, u_short param[]) -{ -	int loop_count; - -	if (mbox_param[param[0]] == 0) -		return 1; - -	loop_count = DEFAULT_LOOP_COUNT; -	while (--loop_count && isp_inw(host, HOST_HCCR) & 0x0080) { -		barrier(); -		cpu_relax(); -	} -	if (!loop_count) -		printk("qlogicisp: mbox_command loop timeout #1\n"); - -	switch(mbox_param[param[0]] >> 4) { -	      case 8: isp_outw(param[7], host, MBOX7); -	      case 7: isp_outw(param[6], host, MBOX6); -	      case 6: isp_outw(param[5], host, MBOX5); -	      case 5: isp_outw(param[4], host, MBOX4); -	      case 4: isp_outw(param[3], host, MBOX3); -	      case 3: isp_outw(param[2], host, MBOX2); -	      case 2: isp_outw(param[1], host, MBOX1); -	      case 1: isp_outw(param[0], host, MBOX0); -	} - -	isp_outw(0x0, host, PCI_SEMAPHORE); -	isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); -	isp_outw(HCCR_SET_HOST_INTR, host, HOST_HCCR); - -	loop_count = DEFAULT_LOOP_COUNT; -	while (--loop_count && !(isp_inw(host, PCI_INTF_STS) & 0x04)) { -		barrier(); -		cpu_relax(); -	} -	if (!loop_count) -		printk("qlogicisp: mbox_command loop timeout #2\n"); - -	loop_count = DEFAULT_LOOP_COUNT; -	while (--loop_count && isp_inw(host, MBOX0) == 0x04) { -		barrier(); -		cpu_relax(); -	} -	if (!loop_count) -		printk("qlogicisp: mbox_command loop timeout #3\n"); - -	switch(mbox_param[param[0]] & 0xf) { -	      case 8: param[7] = isp_inw(host, MBOX7); -	      case 7: param[6] = isp_inw(host, MBOX6); -	      case 6: param[5] = isp_inw(host, MBOX5); -	      case 5: param[4] = isp_inw(host, MBOX4); -	      case 4: param[3] = isp_inw(host, MBOX3); -	      case 3: param[2] = isp_inw(host, MBOX2); -	      case 2: param[1] = isp_inw(host, MBOX1); -	      case 1: param[0] = isp_inw(host, MBOX0); -	} - -	isp_outw(0x0, host, PCI_SEMAPHORE); -	isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); - -	return 0; -} - - -#if DEBUG_ISP1020_INTR - -void isp1020_print_status_entry(struct Status_Entry *status) -{ -	int i; - -	printk("qlogicisp : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", -	       status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags); -	printk("qlogicisp : scsi status = 0x%04x, completion status = 0x%04x\n", -	       le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status)); -	printk("qlogicisp : state flags = 0x%04x, status flags = 0x%04x\n", -	       le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags)); -	printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n", -	       le16_to_cpu(status->time), le16_to_cpu(status->req_sense_len)); -	printk("qlogicisp : residual transfer length = 0x%08x\n", -	       le32_to_cpu(status->residual)); - -	for (i = 0; i < le16_to_cpu(status->req_sense_len); i++) -		printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]); -} - -#endif /* DEBUG_ISP1020_INTR */ - - -#if DEBUG_ISP1020 - -void isp1020_print_scsi_cmd(Scsi_Cmnd *cmd) -{ -	int i; - -	printk("qlogicisp : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", -	       cmd->target, cmd->lun, cmd->cmd_len); -	printk("qlogicisp : command = "); -	for (i = 0; i < cmd->cmd_len; i++) -		printk("0x%02x ", cmd->cmnd[i]); -	printk("\n"); -} - -#endif /* DEBUG_ISP1020 */ - -MODULE_LICENSE("GPL"); - -static Scsi_Host_Template driver_template = { -	.detect			= isp1020_detect, -	.release		= isp1020_release, -	.info			= isp1020_info,	 -	.queuecommand		= isp1020_queuecommand, -	.bios_param		= isp1020_biosparam, -	.can_queue		= QLOGICISP_REQ_QUEUE_LEN, -	.this_id		= -1, -	.sg_tablesize		= QLOGICISP_MAX_SG(QLOGICISP_REQ_QUEUE_LEN), -	.cmd_per_lun		= 1, -	.use_clustering		= DISABLE_CLUSTERING, -}; -#include "scsi_module.c"  | 
