cregit-Linux how code gets into the kernel

Release 4.11 drivers/scsi/advansys.c

Directory: drivers/scsi
/*
 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
 *
 * Copyright (c) 1995-2000 Advanced System Products, Inc.
 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
 * Copyright (c) 2014 Hannes Reinecke <hare@suse.de>
 * All Rights Reserved.
 *
 * 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 of the License, or
 * (at your option) any later version.
 */

/*
 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
 * changed its name to ConnectCom Solutions, Inc.
 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
 */

#include <linux/module.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/isa.h>
#include <linux/eisa.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/dmapool.h>

#include <asm/io.h>
#include <asm/dma.h>

#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>


#define DRV_NAME "advansys"

#define ASC_VERSION "3.5"	
/* AdvanSys Driver Version */

/* FIXME:
 *
 *  1. Use scsi_transport_spi
 *  2. advansys_info is not safe against multiple simultaneous callers
 *  3. Add module_param to override ISA/VLB ioport array
 */

/* Enable driver /proc statistics. */

#define ADVANSYS_STATS

/* Enable driver tracing. */

#undef ADVANSYS_DEBUG


typedef unsigned char uchar;


#define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)


#define PCI_VENDOR_ID_ASP		0x10cd

#define PCI_DEVICE_ID_ASP_1200A		0x1100

#define PCI_DEVICE_ID_ASP_ABP940	0x1200

#define PCI_DEVICE_ID_ASP_ABP940U	0x1300

#define PCI_DEVICE_ID_ASP_ABP940UW	0x2300

#define PCI_DEVICE_ID_38C0800_REV1	0x2500

#define PCI_DEVICE_ID_38C1600_REV1	0x2700


#define PortAddr                 unsigned int	
/* port address size  */

#define inp(port)                inb(port)

#define outp(port, byte)         outb((byte), (port))


#define inpw(port)               inw(port)

#define outpw(port, word)        outw((word), (port))


#define ASC_MAX_SG_QUEUE    7

#define ASC_MAX_SG_LIST     255


#define ASC_CS_TYPE  unsigned short


#define ASC_IS_ISA          (0x0001)

#define ASC_IS_ISAPNP       (0x0081)

#define ASC_IS_EISA         (0x0002)

#define ASC_IS_PCI          (0x0004)

#define ASC_IS_PCI_ULTRA    (0x0104)

#define ASC_IS_PCMCIA       (0x0008)

#define ASC_IS_MCA          (0x0020)

#define ASC_IS_VL           (0x0040)

#define ASC_IS_WIDESCSI_16  (0x0100)

#define ASC_IS_WIDESCSI_32  (0x0200)

#define ASC_IS_BIG_ENDIAN   (0x8000)


#define ASC_CHIP_MIN_VER_VL      (0x01)

#define ASC_CHIP_MAX_VER_VL      (0x07)

#define ASC_CHIP_MIN_VER_PCI     (0x09)

#define ASC_CHIP_MAX_VER_PCI     (0x0F)

#define ASC_CHIP_VER_PCI_BIT     (0x08)

#define ASC_CHIP_MIN_VER_ISA     (0x11)

#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)

#define ASC_CHIP_MAX_VER_ISA     (0x27)

#define ASC_CHIP_VER_ISA_BIT     (0x30)

#define ASC_CHIP_VER_ISAPNP_BIT  (0x20)

#define ASC_CHIP_VER_ASYN_BUG    (0x21)

#define ASC_CHIP_VER_PCI             0x08

#define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)

#define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)

#define ASC_CHIP_MIN_VER_EISA (0x41)

#define ASC_CHIP_MAX_VER_EISA (0x47)

#define ASC_CHIP_VER_EISA_BIT (0x40)

#define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)

#define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)

#define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)

#define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)


#define ASC_SCSI_ID_BITS  3

#define ASC_SCSI_TIX_TYPE     uchar

#define ASC_ALL_DEVICE_BIT_SET  0xFF

#define ASC_SCSI_BIT_ID_TYPE  uchar

#define ASC_MAX_TID       7

#define ASC_MAX_LUN       7

#define ASC_SCSI_WIDTH_BIT_SET  0xFF

#define ASC_MAX_SENSE_LEN   32

#define ASC_MIN_SENSE_LEN   14

#define ASC_SCSI_RESET_HOLD_TIME_US  60

/*
 * Narrow boards only support 12-byte commands, while wide boards
 * extend to 16-byte commands.
 */

#define ASC_MAX_CDB_LEN     12

#define ADV_MAX_CDB_LEN     16


#define MS_SDTR_LEN    0x03

#define MS_WDTR_LEN    0x02


#define ASC_SG_LIST_PER_Q   7

#define QS_FREE        0x00

#define QS_READY       0x01

#define QS_DISC1       0x02

#define QS_DISC2       0x04

#define QS_BUSY        0x08

#define QS_ABORTED     0x40

#define QS_DONE        0x80

#define QC_NO_CALLBACK   0x01

#define QC_SG_SWAP_QUEUE 0x02

#define QC_SG_HEAD       0x04

#define QC_DATA_IN       0x08

#define QC_DATA_OUT      0x10

#define QC_URGENT        0x20

#define QC_MSG_OUT       0x40

#define QC_REQ_SENSE     0x80

#define QCSG_SG_XFER_LIST  0x02

#define QCSG_SG_XFER_MORE  0x04

#define QCSG_SG_XFER_END   0x08

#define QD_IN_PROGRESS       0x00

#define QD_NO_ERROR          0x01

#define QD_ABORTED_BY_HOST   0x02

#define QD_WITH_ERROR        0x04

#define QD_INVALID_REQUEST   0x80

#define QD_INVALID_HOST_NUM  0x81

#define QD_INVALID_DEVICE    0x82

#define QD_ERR_INTERNAL      0xFF

#define QHSTA_NO_ERROR               0x00

#define QHSTA_M_SEL_TIMEOUT          0x11

#define QHSTA_M_DATA_OVER_RUN        0x12

#define QHSTA_M_DATA_UNDER_RUN       0x12

#define QHSTA_M_UNEXPECTED_BUS_FREE  0x13

#define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14

#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21

#define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22

#define QHSTA_D_HOST_ABORT_FAILED       0x23

#define QHSTA_D_EXE_SCSI_Q_FAILED       0x24

#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25

#define QHSTA_D_ASPI_NO_BUF_POOL        0x26

#define QHSTA_M_WTM_TIMEOUT         0x41

#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42

#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43

#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44

#define QHSTA_M_TARGET_STATUS_BUSY  0x45

#define QHSTA_M_BAD_TAG_CODE        0x46

#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47

#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48

#define QHSTA_D_LRAM_CMP_ERROR        0x81

#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1

#define ASC_FLAG_SCSIQ_REQ        0x01

#define ASC_FLAG_BIOS_SCSIQ_REQ   0x02

#define ASC_FLAG_BIOS_ASYNC_IO    0x04

#define ASC_FLAG_SRB_LINEAR_ADDR  0x08

#define ASC_FLAG_WIN16            0x10

#define ASC_FLAG_WIN32            0x20

#define ASC_FLAG_ISA_OVER_16MB    0x40

#define ASC_FLAG_DOS_VM_CALLBACK  0x80

#define ASC_TAG_FLAG_EXTRA_BYTES               0x10

#define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04

#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08

#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40

#define ASC_SCSIQ_CPY_BEG              4

#define ASC_SCSIQ_SGHD_CPY_BEG         2

#define ASC_SCSIQ_B_FWD                0

#define ASC_SCSIQ_B_BWD                1

#define ASC_SCSIQ_B_STATUS             2

#define ASC_SCSIQ_B_QNO                3

#define ASC_SCSIQ_B_CNTL               4

#define ASC_SCSIQ_B_SG_QUEUE_CNT       5

#define ASC_SCSIQ_D_DATA_ADDR          8

#define ASC_SCSIQ_D_DATA_CNT          12

#define ASC_SCSIQ_B_SENSE_LEN         20

#define ASC_SCSIQ_DONE_INFO_BEG       22

#define ASC_SCSIQ_D_SRBPTR            22

#define ASC_SCSIQ_B_TARGET_IX         26

#define ASC_SCSIQ_B_CDB_LEN           28

#define ASC_SCSIQ_B_TAG_CODE          29

#define ASC_SCSIQ_W_VM_ID             30

#define ASC_SCSIQ_DONE_STATUS         32

#define ASC_SCSIQ_HOST_STATUS         33

#define ASC_SCSIQ_SCSI_STATUS         34

#define ASC_SCSIQ_CDB_BEG             36

#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56

#define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60

#define ASC_SCSIQ_B_FIRST_SG_WK_QP    48

#define ASC_SCSIQ_B_SG_WK_QP          49

#define ASC_SCSIQ_B_SG_WK_IX          50

#define ASC_SCSIQ_W_ALT_DC1           52

#define ASC_SCSIQ_B_LIST_CNT          6

#define ASC_SCSIQ_B_CUR_LIST_CNT      7

#define ASC_SGQ_B_SG_CNTL             4

#define ASC_SGQ_B_SG_HEAD_QP          5

#define ASC_SGQ_B_SG_LIST_CNT         6

#define ASC_SGQ_B_SG_CUR_LIST_CNT     7

#define ASC_SGQ_LIST_BEG              8

#define ASC_DEF_SCSI1_QNG    4

#define ASC_MAX_SCSI1_QNG    4

#define ASC_DEF_SCSI2_QNG    16

#define ASC_MAX_SCSI2_QNG    32

#define ASC_TAG_CODE_MASK    0x23

#define ASC_STOP_REQ_RISC_STOP      0x01

#define ASC_STOP_ACK_RISC_STOP      0x03

#define ASC_STOP_CLEAN_UP_BUSY_Q    0x10

#define ASC_STOP_CLEAN_UP_DISC_Q    0x20

#define ASC_STOP_HOST_REQ_RISC_HALT 0x40

#define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))

#define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))

#define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))

#define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)

#define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)

#define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)

#define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))


typedef struct asc_scsiq_1 {
	
uchar status;
	
uchar q_no;
	
uchar cntl;
	
uchar sg_queue_cnt;
	
uchar target_id;
	
uchar target_lun;
	
__le32 data_addr;
	
__le32 data_cnt;
	
__le32 sense_addr;
	
uchar sense_len;
	
uchar extra_bytes;
} 
ASC_SCSIQ_1;


typedef struct asc_scsiq_2 {
	
u32 srb_tag;
	
uchar target_ix;
	
uchar flag;
	
uchar cdb_len;
	
uchar tag_code;
	
ushort vm_id;
} 
ASC_SCSIQ_2;


typedef struct asc_scsiq_3 {
	
uchar done_stat;
	
uchar host_stat;
	
uchar scsi_stat;
	
uchar scsi_msg;
} 
ASC_SCSIQ_3;


typedef struct asc_scsiq_4 {
	
uchar cdb[ASC_MAX_CDB_LEN];
	
uchar y_first_sg_list_qp;
	
uchar y_working_sg_qp;
	
uchar y_working_sg_ix;
	
uchar y_res;
	
ushort x_req_count;
	
ushort x_reconnect_rtn;
	
__le32 x_saved_data_addr;
	
__le32 x_saved_data_cnt;
} 
ASC_SCSIQ_4;


typedef struct asc_q_done_info {
	
ASC_SCSIQ_2 d2;
	
ASC_SCSIQ_3 d3;
	
uchar q_status;
	
uchar q_no;
	
uchar cntl;
	
uchar sense_len;
	
uchar extra_bytes;
	
uchar res;
	
u32 remain_bytes;
} 
ASC_QDONE_INFO;


typedef struct asc_sg_list {
	
__le32 addr;
	
__le32 bytes;
} 
ASC_SG_LIST;


typedef struct asc_sg_head {
	
ushort entry_cnt;
	
ushort queue_cnt;
	
ushort entry_to_copy;
	
ushort res;
	
ASC_SG_LIST sg_list[0];
} 
ASC_SG_HEAD;


typedef struct asc_scsi_q {
	
ASC_SCSIQ_1 q1;
	
ASC_SCSIQ_2 q2;
	
uchar *cdbptr;
	
ASC_SG_HEAD *sg_head;
	
ushort remain_sg_entry_cnt;
	
ushort next_sg_index;
} 
ASC_SCSI_Q;


typedef struct asc_scsi_bios_req_q {
	
ASC_SCSIQ_1 r1;
	
ASC_SCSIQ_2 r2;
	
uchar *cdbptr;
	
ASC_SG_HEAD *sg_head;
	
uchar *sense_ptr;
	
ASC_SCSIQ_3 r3;
	
uchar cdb[ASC_MAX_CDB_LEN];
	
uchar sense[ASC_MIN_SENSE_LEN];
} 
ASC_SCSI_BIOS_REQ_Q;


typedef struct asc_risc_q {
	
uchar fwd;
	
uchar bwd;
	
ASC_SCSIQ_1 i1;
	
ASC_SCSIQ_2 i2;
	
ASC_SCSIQ_3 i3;
	
ASC_SCSIQ_4 i4;
} 
ASC_RISC_Q;


typedef struct asc_sg_list_q {
	
uchar seq_no;
	
uchar q_no;
	
uchar cntl;
	
uchar sg_head_qp;
	
uchar sg_list_cnt;
	
uchar sg_cur_list_cnt;
} 
ASC_SG_LIST_Q;


typedef struct asc_risc_sg_list_q {
	
uchar fwd;
	
uchar bwd;
	
ASC_SG_LIST_Q sg;
	
ASC_SG_LIST sg_list[7];
} 
ASC_RISC_SG_LIST_Q;


#define ASCQ_ERR_Q_STATUS             0x0D

#define ASCQ_ERR_CUR_QNG              0x17

#define ASCQ_ERR_SG_Q_LINKS           0x18

#define ASCQ_ERR_ISR_RE_ENTRY         0x1A

#define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B

#define ASCQ_ERR_ISR_ON_CRITICAL      0x1C

/*
 * Warning code values are set in ASC_DVC_VAR  'warn_code'.
 */

#define ASC_WARN_NO_ERROR             0x0000

#define ASC_WARN_IO_PORT_ROTATE       0x0001

#define ASC_WARN_EEPROM_CHKSUM        0x0002

#define ASC_WARN_IRQ_MODIFIED         0x0004

#define ASC_WARN_AUTO_CONFIG          0x0008

#define ASC_WARN_CMD_QNG_CONFLICT     0x0010

#define ASC_WARN_EEPROM_RECOVER       0x0020

#define ASC_WARN_CFG_MSW_RECOVER      0x0040

/*
 * Error code values are set in {ASC/ADV}_DVC_VAR  'err_code'.
 */

#define ASC_IERR_NO_CARRIER		0x0001	
/* No more carrier memory */

#define ASC_IERR_MCODE_CHKSUM		0x0002	
/* micro code check sum error */

#define ASC_IERR_SET_PC_ADDR		0x0004

#define ASC_IERR_START_STOP_CHIP	0x0008	
/* start/stop chip failed */

#define ASC_IERR_ILLEGAL_CONNECTION	0x0010	
/* Illegal cable connection */

#define ASC_IERR_SINGLE_END_DEVICE	0x0020	
/* SE device on DIFF bus */

#define ASC_IERR_REVERSED_CABLE		0x0040	
/* Narrow flat cable reversed */

#define ASC_IERR_SET_SCSI_ID		0x0080	
/* set SCSI ID failed */

#define ASC_IERR_HVD_DEVICE		0x0100	
/* HVD device on LVD port */

#define ASC_IERR_BAD_SIGNATURE		0x0200	
/* signature not found */

#define ASC_IERR_NO_BUS_TYPE		0x0400

#define ASC_IERR_BIST_PRE_TEST		0x0800	
/* BIST pre-test error */

#define ASC_IERR_BIST_RAM_TEST		0x1000	
/* BIST RAM test error */

#define ASC_IERR_BAD_CHIPTYPE		0x2000	
/* Invalid chip_type setting */


#define ASC_DEF_MAX_TOTAL_QNG   (0xF0)

#define ASC_MIN_TAG_Q_PER_DVC   (0x04)

#define ASC_MIN_FREE_Q        (0x02)

#define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))

#define ASC_MAX_TOTAL_QNG 240

#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16

#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8

#define ASC_MAX_PCI_INRAM_TOTAL_QNG  20

#define ASC_MAX_INRAM_TAG_QNG   16

#define ASC_IOADR_GAP   0x10

#define ASC_SYN_MAX_OFFSET         0x0F

#define ASC_DEF_SDTR_OFFSET        0x0F

#define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02

#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41

/* The narrow chip only supports a limited selection of transfer rates.
 * These are encoded in the range 0..7 or 0..15 depending whether the chip
 * is Ultra-capable or not.  These tables let us convert from one to the other.
 */

static const unsigned char asc_syn_xfer_period[8] = {
	25, 30, 35, 40, 50, 60, 70, 85
};


static const unsigned char asc_syn_ultra_xfer_period[16] = {
	12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107
};


typedef struct ext_msg {
	
uchar msg_type;
	
uchar msg_len;
	
uchar msg_req;
	union {
		struct {
			
uchar sdtr_xfer_period;
			
uchar sdtr_req_ack_offset;
		} 
sdtr;
		struct {
			
uchar wdtr_width;
		} 
wdtr;
		struct {
			
uchar mdp_b3;
			
uchar mdp_b2;
			
uchar mdp_b1;
			
uchar mdp_b0;
		} 
mdp;
	} 
u_ext_msg;
	
uchar res;
} 
EXT_MSG;


#define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period

#define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset

#define wdtr_width      u_ext_msg.wdtr.wdtr_width

#define mdp_b3          u_ext_msg.mdp_b3

#define mdp_b2          u_ext_msg.mdp_b2

#define mdp_b1          u_ext_msg.mdp_b1

#define mdp_b0          u_ext_msg.mdp_b0


typedef struct asc_dvc_cfg {
	
ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
	
ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
	
ASC_SCSI_BIT_ID_TYPE disc_enable;
	
ASC_SCSI_BIT_ID_TYPE sdtr_enable;
	
uchar chip_scsi_id;
	
uchar isa_dma_speed;
	
uchar isa_dma_channel;
	
uchar chip_version;
	
ushort mcode_date;
	
ushort mcode_version;
	
uchar max_tag_qng[ASC_MAX_TID + 1];
	
uchar sdtr_period_offset[ASC_MAX_TID + 1];
	
uchar adapter_info[6];
} 
ASC_DVC_CFG;


#define ASC_DEF_DVC_CNTL       0xFFFF

#define ASC_DEF_CHIP_SCSI_ID   7

#define ASC_DEF_ISA_DMA_SPEED  4

#define ASC_INIT_STATE_BEG_GET_CFG   0x0001

#define ASC_INIT_STATE_END_GET_CFG   0x0002

#define ASC_INIT_STATE_BEG_SET_CFG   0x0004

#define ASC_INIT_STATE_END_SET_CFG   0x0008

#define ASC_INIT_STATE_BEG_LOAD_MC   0x0010

#define ASC_INIT_STATE_END_LOAD_MC   0x0020

#define ASC_INIT_STATE_BEG_INQUIRY   0x0040

#define ASC_INIT_STATE_END_INQUIRY   0x0080

#define ASC_INIT_RESET_SCSI_DONE     0x0100

#define ASC_INIT_STATE_WITHOUT_EEP   0x8000

#define ASC_BUG_FIX_IF_NOT_DWB       0x0001

#define ASC_BUG_FIX_ASYN_USE_SYN     0x0002

#define ASC_MIN_TAGGED_CMD  7

#define ASC_MAX_SCSI_RESET_WAIT      30

#define ASC_OVERRUN_BSIZE		64

struct asc_dvc_var;		/* Forward Declaration. */


typedef struct asc_dvc_var {
	
PortAddr iop_base;
	
ushort err_code;
	
ushort dvc_cntl;
	
ushort bug_fix_cntl;
	
ushort bus_type;
	
ASC_SCSI_BIT_ID_TYPE init_sdtr;
	
ASC_SCSI_BIT_ID_TYPE sdtr_done;
	
ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
	
ASC_SCSI_BIT_ID_TYPE unit_not_ready;
	
ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
	
ASC_SCSI_BIT_ID_TYPE start_motor;
	
uchar *overrun_buf;
	
dma_addr_t overrun_dma;
	
uchar scsi_reset_wait;
	
uchar chip_no;
	
bool is_in_int;
	
uchar max_total_qng;
	
uchar cur_total_qng;
	
uchar in_critical_cnt;
	
uchar last_q_shortage;
	
ushort init_state;
	
uchar cur_dvc_qng[ASC_MAX_TID + 1];
	
uchar max_dvc_qng[ASC_MAX_TID + 1];
	
ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
	
ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
	
const uchar *sdtr_period_tbl;
	
ASC_DVC_CFG *cfg;
	
ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
	
char redo_scam;
	
ushort res2;
	
uchar dos_int13_table[ASC_MAX_TID + 1];
	
unsigned int max_dma_count;
	
ASC_SCSI_BIT_ID_TYPE no_scam;
	
ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
	
uchar min_sdtr_index;
	
uchar max_sdtr_index;
	
struct asc_board *drv_ptr;
	
unsigned int uc_break;
} 
ASC_DVC_VAR;


typedef struct asc_dvc_inq_info {
	
uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
} 
ASC_DVC_INQ_INFO;


typedef struct asc_cap_info {
	
u32 lba;
	
u32 blk_size;
} 
ASC_CAP_INFO;


typedef struct asc_cap_info_array {
	
ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
} 
ASC_CAP_INFO_ARRAY;


#define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001

#define ASC_MCNTL_NULL_TARGET     (ushort)0x0002

#define ASC_CNTL_INITIATOR         (ushort)0x0001

#define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002

#define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004

#define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008

#define ASC_CNTL_NO_SCAM           (ushort)0x0010

#define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080

#define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040

#define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100

#define ASC_CNTL_RESET_SCSI        (ushort)0x0200

#define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400

#define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800

#define ASC_CNTL_SCSI_PARITY       (ushort)0x1000

#define ASC_CNTL_BURST_MODE        (ushort)0x2000

#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000

#define ASC_EEP_DVC_CFG_BEG_VL    2

#define ASC_EEP_MAX_DVC_ADDR_VL   15

#define ASC_EEP_DVC_CFG_BEG      32

#define ASC_EEP_MAX_DVC_ADDR     45

#define ASC_EEP_MAX_RETRY        20

/*
 * These macros keep the chip SCSI id and ISA DMA speed
 * bitfields in board order. C bitfields aren't portable
 * between big and little-endian platforms so they are
 * not used.
 */


#define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)

#define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)

#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
   ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))

#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
   ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)


typedef struct asceep_config {
	
ushort cfg_lsw;
	
ushort cfg_msw;
	
uchar init_sdtr;
	
uchar disc_enable;
	
uchar use_cmd_qng;
	
uchar start_motor;
	
uchar max_total_qng;
	
uchar max_tag_qng;
	
uchar bios_scan;
	
uchar power_up_wait;
	
uchar no_scam;
	
uchar id_speed;		/* low order 4 bits is chip scsi id */
	/* high order 4 bits is isa dma speed */
	
uchar dos_int13_table[ASC_MAX_TID + 1];
	
uchar adapter_info[6];
	
ushort cntl;
	
ushort chksum;
} 
ASCEEP_CONFIG;


#define ASC_EEP_CMD_READ          0x80

#define ASC_EEP_CMD_WRITE         0x40

#define ASC_EEP_CMD_WRITE_ABLE    0x30

#define ASC_EEP_CMD_WRITE_DISABLE 0x00

#define ASCV_MSGOUT_BEG         0x0000

#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)

#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)

#define ASCV_BREAK_SAVED_CODE   (ushort)0x0006

#define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)

#define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)

#define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)

#define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)

#define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)

#define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020

#define ASCV_BREAK_ADDR           (ushort)0x0028

#define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A

#define ASCV_BREAK_CONTROL        (ushort)0x002C

#define ASCV_BREAK_HIT_COUNT      (ushort)0x002E


#define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030

#define ASCV_MCODE_CHKSUM_W   (ushort)0x0032

#define ASCV_MCODE_SIZE_W     (ushort)0x0034

#define ASCV_STOP_CODE_B      (ushort)0x0036

#define ASCV_DVC_ERR_CODE_B   (ushort)0x0037

#define ASCV_OVERRUN_PADDR_D  (ushort)0x0038

#define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C

#define ASCV_HALTCODE_W       (ushort)0x0040

#define ASCV_CHKSUM_W         (ushort)0x0042

#define ASCV_MC_DATE_W        (ushort)0x0044

#define ASCV_MC_VER_W         (ushort)0x0046

#define ASCV_NEXTRDY_B        (ushort)0x0048

#define ASCV_DONENEXT_B       (ushort)0x0049

#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A

#define ASCV_SCSIBUSY_B       (ushort)0x004B

#define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C

#define ASCV_CURCDB_B         (ushort)0x004D

#define ASCV_RCLUN_B          (ushort)0x004E

#define ASCV_BUSY_QHEAD_B     (ushort)0x004F

#define ASCV_DISC1_QHEAD_B    (ushort)0x0050

#define ASCV_DISC_ENABLE_B    (ushort)0x0052

#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053

#define ASCV_HOSTSCSI_ID_B    (ushort)0x0055

#define ASCV_MCODE_CNTL_B     (ushort)0x0056

#define ASCV_NULL_TARGET_B    (ushort)0x0057

#define ASCV_FREE_Q_HEAD_W    (ushort)0x0058

#define ASCV_DONE_Q_TAIL_W    (ushort)0x005A

#define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)

#define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)

#define ASCV_HOST_FLAG_B      (ushort)0x005D

#define ASCV_TOTAL_READY_Q_B  (ushort)0x0064

#define ASCV_VER_SERIAL_B     (ushort)0x0065

#define ASCV_HALTCODE_SAVED_W (ushort)0x0066

#define ASCV_WTM_FLAG_B       (ushort)0x0068

#define ASCV_RISC_FLAG_B      (ushort)0x006A

#define ASCV_REQ_SG_LIST_QP   (ushort)0x006B

#define ASC_HOST_FLAG_IN_ISR        0x01

#define ASC_HOST_FLAG_ACK_INT       0x02

#define ASC_RISC_FLAG_GEN_INT      0x01

#define ASC_RISC_FLAG_REQ_SG_LIST  0x02

#define IOP_CTRL         (0x0F)

#define IOP_STATUS       (0x0E)

#define IOP_INT_ACK      IOP_STATUS

#define IOP_REG_IFC      (0x0D)

#define IOP_SYN_OFFSET    (0x0B)

#define IOP_EXTRA_CONTROL (0x0D)

#define IOP_REG_PC        (0x0C)

#define IOP_RAM_ADDR      (0x0A)

#define IOP_RAM_DATA      (0x08)

#define IOP_EEP_DATA      (0x06)

#define IOP_EEP_CMD       (0x07)

#define IOP_VERSION       (0x03)

#define IOP_CONFIG_HIGH   (0x04)

#define IOP_CONFIG_LOW    (0x02)

#define IOP_SIG_BYTE      (0x01)

#define IOP_SIG_WORD      (0x00)

#define IOP_REG_DC1      (0x0E)

#define IOP_REG_DC0      (0x0C)

#define IOP_REG_SB       (0x0B)

#define IOP_REG_DA1      (0x0A)

#define IOP_REG_DA0      (0x08)

#define IOP_REG_SC       (0x09)

#define IOP_DMA_SPEED    (0x07)

#define IOP_REG_FLAG     (0x07)

#define IOP_FIFO_H       (0x06)

#define IOP_FIFO_L       (0x04)

#define IOP_REG_ID       (0x05)

#define IOP_REG_QP       (0x03)

#define IOP_REG_IH       (0x02)

#define IOP_REG_IX       (0x01)

#define IOP_REG_AX       (0x00)

#define IFC_REG_LOCK      (0x00)

#define IFC_REG_UNLOCK    (0x09)

#define IFC_WR_EN_FILTER  (0x10)

#define IFC_RD_NO_EEPROM  (0x10)

#define IFC_SLEW_RATE     (0x20)

#define IFC_ACT_NEG       (0x40)

#define IFC_INP_FILTER    (0x80)

#define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)

#define SC_SEL   (uchar)(0x80)

#define SC_BSY   (uchar)(0x40)

#define SC_ACK   (uchar)(0x20)

#define SC_REQ   (uchar)(0x10)

#define SC_ATN   (uchar)(0x08)

#define SC_IO    (uchar)(0x04)

#define SC_CD    (uchar)(0x02)

#define SC_MSG   (uchar)(0x01)

#define SEC_SCSI_CTL         (uchar)(0x80)

#define SEC_ACTIVE_NEGATE    (uchar)(0x40)

#define SEC_SLEW_RATE        (uchar)(0x20)

#define SEC_ENABLE_FILTER    (uchar)(0x10)

#define ASC_HALT_EXTMSG_IN     (ushort)0x8000

#define ASC_HALT_CHK_CONDITION (ushort)0x8100

#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200

#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300

#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400

#define ASC_HALT_SDTR_REJECTED (ushort)0x4000

#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000

#define ASC_MAX_QNO        0xF8

#define ASC_DATA_SEC_BEG   (ushort)0x0080

#define ASC_DATA_SEC_END   (ushort)0x0080

#define ASC_CODE_SEC_BEG   (ushort)0x0080

#define ASC_CODE_SEC_END   (ushort)0x0080

#define ASC_QADR_BEG       (0x4000)

#define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)

#define ASC_QADR_END       (ushort)0x7FFF

#define ASC_QLAST_ADR      (ushort)0x7FC0

#define ASC_QBLK_SIZE      0x40

#define ASC_BIOS_DATA_QBEG 0xF8

#define ASC_MIN_ACTIVE_QNO 0x01

#define ASC_QLINK_END      0xFF

#define ASC_EEPROM_WORDS   0x10

#define ASC_MAX_MGS_LEN    0x10

#define ASC_BIOS_ADDR_DEF  0xDC00

#define ASC_BIOS_SIZE      0x3800

#define ASC_BIOS_RAM_OFF   0x3800

#define ASC_BIOS_RAM_SIZE  0x800

#define ASC_BIOS_MIN_ADDR  0xC000

#define ASC_BIOS_MAX_ADDR  0xEC00

#define ASC_BIOS_BANK_SIZE 0x0400

#define ASC_MCODE_START_ADDR  0x0080

#define ASC_CFG0_HOST_INT_ON    0x0020

#define ASC_CFG0_BIOS_ON        0x0040

#define ASC_CFG0_VERA_BURST_ON  0x0080

#define ASC_CFG0_SCSI_PARITY_ON 0x0800

#define ASC_CFG1_SCSI_TARGET_ON 0x0080

#define ASC_CFG1_LRAM_8BITS_ON  0x0800

#define ASC_CFG_MSW_CLR_MASK    0x3080

#define CSW_TEST1             (ASC_CS_TYPE)0x8000

#define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000

#define CSW_RESERVED1         (ASC_CS_TYPE)0x2000

#define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000

#define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800

#define CSW_TEST2             (ASC_CS_TYPE)0x0400

#define CSW_TEST3             (ASC_CS_TYPE)0x0200

#define CSW_RESERVED2         (ASC_CS_TYPE)0x0100

#define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080

#define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040

#define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020

#define CSW_HALTED            (ASC_CS_TYPE)0x0010

#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008

#define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004

#define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002

#define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001

#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000

#define CIW_INT_ACK      (ASC_CS_TYPE)0x0100

#define CIW_TEST1        (ASC_CS_TYPE)0x0200

#define CIW_TEST2        (ASC_CS_TYPE)0x0400

#define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800

#define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000

#define CC_CHIP_RESET   (uchar)0x80

#define CC_SCSI_RESET   (uchar)0x40

#define CC_HALT         (uchar)0x20

#define CC_SINGLE_STEP  (uchar)0x10

#define CC_DMA_ABLE     (uchar)0x08

#define CC_TEST         (uchar)0x04

#define CC_BANK_ONE     (uchar)0x02

#define CC_DIAG         (uchar)0x01

#define ASC_1000_ID0W      0x04C1

#define ASC_1000_ID0W_FIX  0x00C1

#define ASC_1000_ID1B      0x25