1139749Simp/*-
239219Sgibbs * Hardware structure definitions for the Adaptec 174X CAM SCSI device driver.
339219Sgibbs *
439219Sgibbs * Copyright (c) 1998 Justin T. Gibbs
539219Sgibbs * All rights reserved.
639219Sgibbs *
739219Sgibbs * Redistribution and use in source and binary forms, with or without
839219Sgibbs * modification, are permitted provided that the following conditions
939219Sgibbs * are met:
1039219Sgibbs * 1. Redistributions of source code must retain the above copyright
1139219Sgibbs *    notice immediately at the beginning of the file, without modification,
1239219Sgibbs *    this list of conditions, and the following disclaimer.
1339219Sgibbs * 2. The name of the author may not be used to endorse or promote products
1439219Sgibbs *    derived from this software without specific prior written permission.
1539219Sgibbs *
1639219Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1739219Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1839219Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1939219Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2039219Sgibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2139219Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2239219Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2339219Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2439219Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2539219Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2639219Sgibbs * SUCH DAMAGE.
2739219Sgibbs *
2850477Speter * $FreeBSD$
2939219Sgibbs */
3039219Sgibbs
3139219Sgibbs/* Resource Constatns */
3239219Sgibbs#define	AHB_NECB	64
3339219Sgibbs#define AHB_NSEG	32
3439219Sgibbs
3539219Sgibbs/* AHA1740 EISA ID, IO port range size, and offset from slot base */
3639219Sgibbs#define EISA_DEVICE_ID_ADAPTEC_1740  0x04900000
3739219Sgibbs#define	AHB_EISA_IOSIZE 0x100
3839219Sgibbs#define	AHB_EISA_SLOT_OFFSET 0xc00
3939219Sgibbs
4039219Sgibbs/* AHA1740 EISA board control registers (Offset from slot base) */
4139219Sgibbs#define	EBCTRL				0x084
4239219Sgibbs#define		CDEN			0x01
4339219Sgibbs
4439219Sgibbs/*
4539219Sgibbs * AHA1740 EISA board mode registers (Offset from slot base)
4639219Sgibbs */
4739219Sgibbs#define PORTADDR			0x0C0
4839219Sgibbs#define		PORTADDR_ENHANCED	0x80
4939219Sgibbs
5039219Sgibbs#define BIOSADDR			0x0C1
5139219Sgibbs
5239219Sgibbs#define	INTDEF				0x0C2
5339219Sgibbs#define		INT9			0x00
5439219Sgibbs#define		INT10			0x01
5539219Sgibbs#define		INT11			0x02
5639219Sgibbs#define		INT12			0x03
5739219Sgibbs#define		INT14			0x05
5839219Sgibbs#define		INT15			0x06
5939219Sgibbs#define		INTLEVEL		0x08
6039219Sgibbs#define		INTEN			0x10
6139219Sgibbs
6239219Sgibbs#define	SCSIDEF				0x0C3
6339219Sgibbs#define		HSCSIID			0x0F	/* our SCSI ID */
6439219Sgibbs#define		RSTBUS			0x10
6539219Sgibbs
6639219Sgibbs#define	BUSDEF				0x0C4
6739219Sgibbs#define		B0uS			0x00	/* give up bus immediatly */
6839219Sgibbs#define		B4uS			0x01	/* delay 4uSec. */
6939219Sgibbs#define		B8uS			0x02	/* delay 8uSec. */
7039219Sgibbs
7139219Sgibbs#define	RESV0				0x0C5
7239219Sgibbs
7339219Sgibbs#define	RESV1				0x0C6
7439219Sgibbs#define		EXTENDED_TRANS		0x01
7539219Sgibbs
7639219Sgibbs#define	RESV2				0x0C7
7739219Sgibbs
7839219Sgibbs/*
7939219Sgibbs * AHA1740 ENHANCED mode mailbox control regs (Offset from slot base)
8039219Sgibbs */
8139219Sgibbs#define MBOXOUT0			0x0D0
8239219Sgibbs#define MBOXOUT1			0x0D1
8339219Sgibbs#define MBOXOUT2			0x0D2
8439219Sgibbs#define MBOXOUT3			0x0D3
8539219Sgibbs
8639219Sgibbs#define	ATTN				0x0D4
8739219Sgibbs#define		ATTN_TARGMASK		0x0F
8839219Sgibbs#define		ATTN_IMMED		0x10
8939219Sgibbs#define		ATTN_STARTECB		0x40
9039219Sgibbs#define		ATTN_ABORTECB		0x50
9139219Sgibbs#define		ATTN_TARG_RESET		0x80
9239219Sgibbs
9339219Sgibbs#define	CONTROL				0x0D5
9439219Sgibbs#define		CNTRL_SET_HRDY		0x20
9539219Sgibbs#define		CNTRL_CLRINT		0x40
9639219Sgibbs#define		CNTRL_HARD_RST		0x80
9739219Sgibbs
9839219Sgibbs#define	INTSTAT				0x0D6
9939219Sgibbs#define		INTSTAT_TARGET_MASK	0x0F
10039219Sgibbs#define		INTSTAT_MASK		0xF0
10139219Sgibbs#define		INTSTAT_ECB_OK		0x10	/* ECB Completed w/out error */
10239219Sgibbs#define		INTSTAT_ECB_CMPWRETRY	0x50	/* ECB Completed w/retries */
10339219Sgibbs#define		INTSTAT_HW_ERR		0x70	/* Adapter Hardware Failure */
10439219Sgibbs#define		INTSTAT_IMMED_OK	0xA0	/* Immediate command complete */
10539219Sgibbs#define		INTSTAT_ECB_CMPWERR	0xC0	/* ECB Completed w/error */
10639219Sgibbs#define		INTSTAT_AEN_OCCURED	0xD0	/* Async Event Notification */
10739219Sgibbs#define		INTSTAT_IMMED_ERR	0xE0	/* Immediate command failed */
10839219Sgibbs
10939219Sgibbs#define HOSTSTAT			0x0D7
11039219Sgibbs#define		HOSTSTAT_MBOX_EMPTY	0x04
11139219Sgibbs#define		HOSTSTAT_INTPEND	0x02
11239219Sgibbs#define		HOSTSTAT_BUSY		0x01
11339219Sgibbs
11439219Sgibbs
11539219Sgibbs#define	MBOXIN0				0x0D8
11639219Sgibbs#define	MBOXIN1				0x0D9
11739219Sgibbs#define	MBOXIN2				0x0DA
11839219Sgibbs#define	MBOXIN3				0x0DB
11939219Sgibbs
12039219Sgibbs#define STATUS2				0x0DC
12139219Sgibbs#define	STATUS2_HOST_READY		0x01
12239219Sgibbs
12339219Sgibbstypedef enum {
12439219Sgibbs	IMMED_RESET		  = 0x000080,
12539219Sgibbs	IMMED_DEVICE_CLEAR_QUEUE  = 0x000480,
12639219Sgibbs	IMMED_ADAPTER_CLEAR_QUEUE = 0x000880,
12739219Sgibbs	IMMED_RESUME		  = 0x200090
12839219Sgibbs} immed_cmd;
12939219Sgibbs
13039219Sgibbsstruct ecb_status {
13139219Sgibbs	/* Status Flags */
13239219Sgibbs	u_int16_t 	no_error      :1, /* Completed with no error */
13339219Sgibbs			data_underrun :1,
13439219Sgibbs				      :1,
13539219Sgibbs			ha_queue_full :1,
13639219Sgibbs			spec_check    :1,
13739219Sgibbs			data_overrun  :1,
13839219Sgibbs			chain_halted  :1,
13939219Sgibbs			intr_issued   :1,
14039219Sgibbs			status_avail  :1, /* status bytes 14-31 are valid */
14139219Sgibbs			sense_stored  :1,
14239219Sgibbs				      :1,
14339219Sgibbs			init_requied  :1,
14439219Sgibbs			major_error   :1,
14539219Sgibbs				      :1,
14639219Sgibbs			extended_ca   :1,
14739219Sgibbs				      :1;
14839219Sgibbs	/* Host Status */
14939219Sgibbs	u_int8_t	ha_status;
15039219Sgibbs	u_int8_t	scsi_status;
15139219Sgibbs	int32_t		resid_count;
15239219Sgibbs	u_int32_t	resid_addr;
15339219Sgibbs	u_int16_t	addit_status;
15439219Sgibbs	u_int8_t	sense_len;
15539219Sgibbs	u_int8_t	unused[9];
15639219Sgibbs	u_int8_t	cdb[6];
15739219Sgibbs};
15839219Sgibbs
15939219Sgibbstypedef enum {
16039219Sgibbs	HS_OK			= 0x00,
16139219Sgibbs	HS_CMD_ABORTED_HOST	= 0x04,
16239219Sgibbs	HS_CMD_ABORTED_ADAPTER	= 0x05,
16339219Sgibbs	HS_FIRMWARE_LOAD_REQ	= 0x08,
16439219Sgibbs	HS_TARGET_NOT_ASSIGNED	= 0x0A,
16539219Sgibbs	HS_SEL_TIMEOUT		= 0x11,
16639219Sgibbs	HS_DATA_RUN_ERR		= 0x12,
16739219Sgibbs	HS_UNEXPECTED_BUSFREE	= 0x13,
16839219Sgibbs	HS_INVALID_PHASE	= 0x14,
16939219Sgibbs	HS_INVALID_OPCODE	= 0x16,
17039219Sgibbs	HS_INVALID_CMD_LINK	= 0x17,
17139219Sgibbs	HS_INVALID_ECB_PARAM	= 0x18,
17239219Sgibbs	HS_DUP_TCB_RECEIVED	= 0x19,
17339219Sgibbs	HS_REQUEST_SENSE_FAILED	= 0x1A,
17439219Sgibbs	HS_TAG_MSG_REJECTED	= 0x1C,
17539219Sgibbs	HS_HARDWARE_ERR		= 0x20,
17639219Sgibbs	HS_ATN_TARGET_FAILED	= 0x21,
17739219Sgibbs	HS_SCSI_RESET_ADAPTER	= 0x22,
17839219Sgibbs	HS_SCSI_RESET_INCOMING	= 0x23,
17939219Sgibbs	HS_PROGRAM_CKSUM_ERROR	= 0x80
18039219Sgibbs} host_status;
18139219Sgibbs
18239219Sgibbstypedef enum {
18339219Sgibbs	ECBOP_NOP		 = 0x00,
18439219Sgibbs	ECBOP_INITIATOR_SCSI_CMD = 0x01,
18539219Sgibbs	ECBOP_RUN_DIAGNOSTICS	 = 0x05,
18639219Sgibbs	ECBOP_INITIALIZE_SCSI	 = 0x06, /* Set syncrate/disc/parity */
18739219Sgibbs	ECBOP_READ_SENSE	 = 0x08,
18839219Sgibbs	ECBOP_DOWNLOAD_FIRMWARE  = 0x09,
18939219Sgibbs	ECBOP_READ_HA_INQDATA	 = 0x0a,
19039219Sgibbs	ECBOP_TARGET_SCSI_CMD	 = 0x10
19139219Sgibbs} ecb_op;
19239219Sgibbs
19339219Sgibbsstruct ha_inquiry_data {
19439219Sgibbs	struct	  scsi_inquiry_data scsi_data;
19539219Sgibbs	u_int8_t  release_date[8];
19639219Sgibbs	u_int8_t  release_time[8];
19739219Sgibbs	u_int16_t firmware_cksum;
19839219Sgibbs	u_int16_t reserved;
19939219Sgibbs	u_int16_t target_data[16];
20039219Sgibbs};
20139219Sgibbs
20239219Sgibbsstruct hardware_ecb {
20339219Sgibbs	u_int16_t	opcode;
20439219Sgibbs	u_int16_t	flag_word1;
20539219Sgibbs#define	FW1_LINKED_CMD		0x0001
20639219Sgibbs#define FW1_DISABLE_INTR	0x0080
20739219Sgibbs#define FW1_SUPPRESS_URUN_ERR	0x0400
20839219Sgibbs#define	FW1_SG_ECB		0x1000
20939219Sgibbs#define FW1_ERR_STATUS_BLK_ONLY	0x4000
21039219Sgibbs#define FW1_AUTO_REQUEST_SENSE	0x8000
21139219Sgibbs	u_int16_t	flag_word2;
21239219Sgibbs#define FW2_LUN_MASK		0x0007
21339219Sgibbs#define FW2_TAG_ENB		0x0008
21439219Sgibbs#define FW2_TAG_TYPE		0x0030
21539219Sgibbs#define FW2_TAG_TYPE_SHIFT	4
21639219Sgibbs#define FW2_DISABLE_DISC	0x0040
21739219Sgibbs#define FW2_CHECK_DATA_DIR	0x0100
21839219Sgibbs#define FW2_DATA_DIR_IN		0x0200
21939219Sgibbs#define FW2_SUPRESS_TRANSFER	0x0400
22039219Sgibbs#define FW2_CALC_CKSUM		0x0800
22139219Sgibbs#define FW2_RECOVERY_ECB	0x4000
22239219Sgibbs#define FW2_NO_RETRY_ON_BUSY	0x8000
22339219Sgibbs	u_int16_t	reserved;
22439219Sgibbs	u_int32_t	data_ptr;
22539219Sgibbs	u_int32_t	data_len;
22639219Sgibbs	u_int32_t	status_ptr;
22739219Sgibbs	u_int32_t	link_ptr;
22839219Sgibbs	u_int32_t	reserved2;
22939219Sgibbs	u_int32_t	sense_ptr;
23039219Sgibbs	u_int8_t	sense_len;
23139219Sgibbs	u_int8_t	cdb_len;
23239219Sgibbs	u_int16_t	cksum;
23339219Sgibbs	u_int8_t	cdb[12];
23439219Sgibbs};
23539219Sgibbs
23639219Sgibbstypedef struct {
23739219Sgibbs	u_int32_t addr;
23839219Sgibbs	u_int32_t len;
23939219Sgibbs} ahb_sg_t;
24039219Sgibbs
24139219Sgibbstypedef enum {
24239219Sgibbs	ECB_FREE		= 0x0,
24339219Sgibbs	ECB_ACTIVE		= 0x1,
24439219Sgibbs	ECB_DEVICE_RESET	= 0x2,
24539219Sgibbs	ECB_SCSIBUS_RESET	= 0x4,
24639219Sgibbs	ECB_RELEASE_SIMQ	= 0x8
24739219Sgibbs} ecb_state;
24839219Sgibbs
24939219Sgibbsstruct ecb {
25039219Sgibbs	struct hardware_ecb	 hecb;
25139219Sgibbs	struct ecb_status	 status;
25239219Sgibbs	struct scsi_sense_data	 sense;
25339219Sgibbs	ahb_sg_t		 sg_list[AHB_NSEG];
25460938Sjake	SLIST_ENTRY(ecb)	 links;
25539219Sgibbs	ecb_state		 state;
25639219Sgibbs	union ccb		*ccb;
25739219Sgibbs	bus_dmamap_t		 dmamap;
258251164Sscottl	struct callout		 timer;
25939219Sgibbs};
26039219Sgibbs
26139219Sgibbsstruct ahb_softc {
262170872Sscottl	device_t		 dev;
263251164Sscottl	struct	resource	*res;
264251164Sscottl	struct	mtx		 lock;
26539219Sgibbs	struct	cam_sim		*sim;
26639219Sgibbs	struct	cam_path	*path;
26760938Sjake	SLIST_HEAD(,ecb)	 free_ecbs;
26860938Sjake	LIST_HEAD(,ccb_hdr)	 pending_ccbs;
26939219Sgibbs	struct ecb		*ecb_array;
27039219Sgibbs	u_int32_t		 ecb_physbase;
27139219Sgibbs	bus_dma_tag_t		 buffer_dmat;	/* dmat for buffer I/O */
27239219Sgibbs	bus_dma_tag_t		 ecb_dmat;	/* dmat for our ecb array */
27339219Sgibbs	bus_dmamap_t		 ecb_dmamap;
27439219Sgibbs	volatile u_int32_t	 immed_cmd;
27539219Sgibbs	struct	ecb		*immed_ecb;
27639219Sgibbs	struct	ha_inquiry_data	*ha_inq_data;
27739219Sgibbs	u_int32_t		 ha_inq_physbase;
27839219Sgibbs	u_int			 init_level;
27939219Sgibbs	u_int			 scsi_id;
28039219Sgibbs	u_int			 num_ecbs;
28139219Sgibbs	u_int			 extended_trans;
28239219Sgibbs	u_int8_t		 disc_permitted;
28339219Sgibbs	u_int8_t		 tags_permitted;
28439219Sgibbs};
285