1 /*-
2  * Hardware structure definitions for the Adaptec 174X CAM SCSI device driver.
3  *
4  * Copyright (c) 1998 Justin T. Gibbs
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice immediately at the beginning of the file, without modification,
12  *    this list of conditions, and the following disclaimer.
13  * 2. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD: stable/9/sys/dev/ahb/ahbreg.h 251164 2013-05-30 21:54:48Z scottl $
29  */
30 
31 /* Resource Constatns */
32 #define	AHB_NECB	64
33 #define AHB_NSEG	32
34 
35 /* AHA1740 EISA ID, IO port range size, and offset from slot base */
36 #define EISA_DEVICE_ID_ADAPTEC_1740  0x04900000
37 #define	AHB_EISA_IOSIZE 0x100
38 #define	AHB_EISA_SLOT_OFFSET 0xc00
39 
40 /* AHA1740 EISA board control registers (Offset from slot base) */
41 #define	EBCTRL				0x084
42 #define		CDEN			0x01
43 
44 /*
45  * AHA1740 EISA board mode registers (Offset from slot base)
46  */
47 #define PORTADDR			0x0C0
48 #define		PORTADDR_ENHANCED	0x80
49 
50 #define BIOSADDR			0x0C1
51 
52 #define	INTDEF				0x0C2
53 #define		INT9			0x00
54 #define		INT10			0x01
55 #define		INT11			0x02
56 #define		INT12			0x03
57 #define		INT14			0x05
58 #define		INT15			0x06
59 #define		INTLEVEL		0x08
60 #define		INTEN			0x10
61 
62 #define	SCSIDEF				0x0C3
63 #define		HSCSIID			0x0F	/* our SCSI ID */
64 #define		RSTBUS			0x10
65 
66 #define	BUSDEF				0x0C4
67 #define		B0uS			0x00	/* give up bus immediatly */
68 #define		B4uS			0x01	/* delay 4uSec. */
69 #define		B8uS			0x02	/* delay 8uSec. */
70 
71 #define	RESV0				0x0C5
72 
73 #define	RESV1				0x0C6
74 #define		EXTENDED_TRANS		0x01
75 
76 #define	RESV2				0x0C7
77 
78 /*
79  * AHA1740 ENHANCED mode mailbox control regs (Offset from slot base)
80  */
81 #define MBOXOUT0			0x0D0
82 #define MBOXOUT1			0x0D1
83 #define MBOXOUT2			0x0D2
84 #define MBOXOUT3			0x0D3
85 
86 #define	ATTN				0x0D4
87 #define		ATTN_TARGMASK		0x0F
88 #define		ATTN_IMMED		0x10
89 #define		ATTN_STARTECB		0x40
90 #define		ATTN_ABORTECB		0x50
91 #define		ATTN_TARG_RESET		0x80
92 
93 #define	CONTROL				0x0D5
94 #define		CNTRL_SET_HRDY		0x20
95 #define		CNTRL_CLRINT		0x40
96 #define		CNTRL_HARD_RST		0x80
97 
98 #define	INTSTAT				0x0D6
99 #define		INTSTAT_TARGET_MASK	0x0F
100 #define		INTSTAT_MASK		0xF0
101 #define		INTSTAT_ECB_OK		0x10	/* ECB Completed w/out error */
102 #define		INTSTAT_ECB_CMPWRETRY	0x50	/* ECB Completed w/retries */
103 #define		INTSTAT_HW_ERR		0x70	/* Adapter Hardware Failure */
104 #define		INTSTAT_IMMED_OK	0xA0	/* Immediate command complete */
105 #define		INTSTAT_ECB_CMPWERR	0xC0	/* ECB Completed w/error */
106 #define		INTSTAT_AEN_OCCURED	0xD0	/* Async Event Notification */
107 #define		INTSTAT_IMMED_ERR	0xE0	/* Immediate command failed */
108 
109 #define HOSTSTAT			0x0D7
110 #define		HOSTSTAT_MBOX_EMPTY	0x04
111 #define		HOSTSTAT_INTPEND	0x02
112 #define		HOSTSTAT_BUSY		0x01
113 
114 
115 #define	MBOXIN0				0x0D8
116 #define	MBOXIN1				0x0D9
117 #define	MBOXIN2				0x0DA
118 #define	MBOXIN3				0x0DB
119 
120 #define STATUS2				0x0DC
121 #define	STATUS2_HOST_READY		0x01
122 
123 typedef enum {
124 	IMMED_RESET		  = 0x000080,
125 	IMMED_DEVICE_CLEAR_QUEUE  = 0x000480,
126 	IMMED_ADAPTER_CLEAR_QUEUE = 0x000880,
127 	IMMED_RESUME		  = 0x200090
128 } immed_cmd;
129 
130 struct ecb_status {
131 	/* Status Flags */
132 	u_int16_t 	no_error      :1, /* Completed with no error */
133 			data_underrun :1,
134 				      :1,
135 			ha_queue_full :1,
136 			spec_check    :1,
137 			data_overrun  :1,
138 			chain_halted  :1,
139 			intr_issued   :1,
140 			status_avail  :1, /* status bytes 14-31 are valid */
141 			sense_stored  :1,
142 				      :1,
143 			init_requied  :1,
144 			major_error   :1,
145 				      :1,
146 			extended_ca   :1,
147 				      :1;
148 	/* Host Status */
149 	u_int8_t	ha_status;
150 	u_int8_t	scsi_status;
151 	int32_t		resid_count;
152 	u_int32_t	resid_addr;
153 	u_int16_t	addit_status;
154 	u_int8_t	sense_len;
155 	u_int8_t	unused[9];
156 	u_int8_t	cdb[6];
157 };
158 
159 typedef enum {
160 	HS_OK			= 0x00,
161 	HS_CMD_ABORTED_HOST	= 0x04,
162 	HS_CMD_ABORTED_ADAPTER	= 0x05,
163 	HS_FIRMWARE_LOAD_REQ	= 0x08,
164 	HS_TARGET_NOT_ASSIGNED	= 0x0A,
165 	HS_SEL_TIMEOUT		= 0x11,
166 	HS_DATA_RUN_ERR		= 0x12,
167 	HS_UNEXPECTED_BUSFREE	= 0x13,
168 	HS_INVALID_PHASE	= 0x14,
169 	HS_INVALID_OPCODE	= 0x16,
170 	HS_INVALID_CMD_LINK	= 0x17,
171 	HS_INVALID_ECB_PARAM	= 0x18,
172 	HS_DUP_TCB_RECEIVED	= 0x19,
173 	HS_REQUEST_SENSE_FAILED	= 0x1A,
174 	HS_TAG_MSG_REJECTED	= 0x1C,
175 	HS_HARDWARE_ERR		= 0x20,
176 	HS_ATN_TARGET_FAILED	= 0x21,
177 	HS_SCSI_RESET_ADAPTER	= 0x22,
178 	HS_SCSI_RESET_INCOMING	= 0x23,
179 	HS_PROGRAM_CKSUM_ERROR	= 0x80
180 } host_status;
181 
182 typedef enum {
183 	ECBOP_NOP		 = 0x00,
184 	ECBOP_INITIATOR_SCSI_CMD = 0x01,
185 	ECBOP_RUN_DIAGNOSTICS	 = 0x05,
186 	ECBOP_INITIALIZE_SCSI	 = 0x06, /* Set syncrate/disc/parity */
187 	ECBOP_READ_SENSE	 = 0x08,
188 	ECBOP_DOWNLOAD_FIRMWARE  = 0x09,
189 	ECBOP_READ_HA_INQDATA	 = 0x0a,
190 	ECBOP_TARGET_SCSI_CMD	 = 0x10
191 } ecb_op;
192 
193 struct ha_inquiry_data {
194 	struct	  scsi_inquiry_data scsi_data;
195 	u_int8_t  release_date[8];
196 	u_int8_t  release_time[8];
197 	u_int16_t firmware_cksum;
198 	u_int16_t reserved;
199 	u_int16_t target_data[16];
200 };
201 
202 struct hardware_ecb {
203 	u_int16_t	opcode;
204 	u_int16_t	flag_word1;
205 #define	FW1_LINKED_CMD		0x0001
206 #define FW1_DISABLE_INTR	0x0080
207 #define FW1_SUPPRESS_URUN_ERR	0x0400
208 #define	FW1_SG_ECB		0x1000
209 #define FW1_ERR_STATUS_BLK_ONLY	0x4000
210 #define FW1_AUTO_REQUEST_SENSE	0x8000
211 	u_int16_t	flag_word2;
212 #define FW2_LUN_MASK		0x0007
213 #define FW2_TAG_ENB		0x0008
214 #define FW2_TAG_TYPE		0x0030
215 #define FW2_TAG_TYPE_SHIFT	4
216 #define FW2_DISABLE_DISC	0x0040
217 #define FW2_CHECK_DATA_DIR	0x0100
218 #define FW2_DATA_DIR_IN		0x0200
219 #define FW2_SUPRESS_TRANSFER	0x0400
220 #define FW2_CALC_CKSUM		0x0800
221 #define FW2_RECOVERY_ECB	0x4000
222 #define FW2_NO_RETRY_ON_BUSY	0x8000
223 	u_int16_t	reserved;
224 	u_int32_t	data_ptr;
225 	u_int32_t	data_len;
226 	u_int32_t	status_ptr;
227 	u_int32_t	link_ptr;
228 	u_int32_t	reserved2;
229 	u_int32_t	sense_ptr;
230 	u_int8_t	sense_len;
231 	u_int8_t	cdb_len;
232 	u_int16_t	cksum;
233 	u_int8_t	cdb[12];
234 };
235 
236 typedef struct {
237 	u_int32_t addr;
238 	u_int32_t len;
239 } ahb_sg_t;
240 
241 typedef enum {
242 	ECB_FREE		= 0x0,
243 	ECB_ACTIVE		= 0x1,
244 	ECB_DEVICE_RESET	= 0x2,
245 	ECB_SCSIBUS_RESET	= 0x4,
246 	ECB_RELEASE_SIMQ	= 0x8
247 } ecb_state;
248 
249 struct ecb {
250 	struct hardware_ecb	 hecb;
251 	struct ecb_status	 status;
252 	struct scsi_sense_data	 sense;
253 	ahb_sg_t		 sg_list[AHB_NSEG];
254 	SLIST_ENTRY(ecb)	 links;
255 	ecb_state		 state;
256 	union ccb		*ccb;
257 	bus_dmamap_t		 dmamap;
258 	struct callout		 timer;
259 };
260 
261 struct ahb_softc {
262 	device_t		 dev;
263 	struct	resource	*res;
264 	struct	mtx		 lock;
265 	struct	cam_sim		*sim;
266 	struct	cam_path	*path;
267 	SLIST_HEAD(,ecb)	 free_ecbs;
268 	LIST_HEAD(,ccb_hdr)	 pending_ccbs;
269 	struct ecb		*ecb_array;
270 	u_int32_t		 ecb_physbase;
271 	bus_dma_tag_t		 buffer_dmat;	/* dmat for buffer I/O */
272 	bus_dma_tag_t		 ecb_dmat;	/* dmat for our ecb array */
273 	bus_dmamap_t		 ecb_dmamap;
274 	volatile u_int32_t	 immed_cmd;
275 	struct	ecb		*immed_ecb;
276 	struct	ha_inquiry_data	*ha_inq_data;
277 	u_int32_t		 ha_inq_physbase;
278 	u_int			 init_level;
279 	u_int			 scsi_id;
280 	u_int			 num_ecbs;
281 	u_int			 extended_trans;
282 	u_int8_t		 disc_permitted;
283 	u_int8_t		 tags_permitted;
284 };
285