xref: /NextBSD/sys/dev/aha/ahareg.h (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /*-
2  * Generic register and struct definitions for the Adaptech 1540, 1542,
3  * 1640, 1642 SCSI host adapters. Product specific probe and attach
4  * routines can be found in:
5  *	aha_isa.c, aha_mca.c
6  *
7  * Derived from bt.c written by:
8  *
9  * Copyright (c) 1998 Justin T. Gibbs.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification, immediately at the beginning of the file.
18  * 2. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * $FreeBSD$
34  */
35 
36 #ifndef _AHAREG_H_
37 #define _AHAREG_H_
38 
39 #include <sys/queue.h>
40 #include <cam/scsi/scsi_all.h>
41 
42 #define AHA_MAXTRANSFER_SIZE	 0xffffff	/* limited by 24bit counter */
43 #define AHA_NSEG		17	/* The number of dma segments
44 					 * supported. */
45 #define ALL_TARGETS (~0)
46 
47 /*
48  * Control Register pp. 1-8, 1-9 (Write Only)
49  */
50 #define	CONTROL_REG		0x00
51 #define		HARD_RESET	0x80	/* Hard Reset - return to POST state */
52 #define		SOFT_RESET	0x40	/* Soft Reset - Clears Adapter state */
53 #define		RESET_INTR	0x20	/* Reset/Ack Interrupt */
54 #define		RESET_SBUS	0x10	/* Drive SCSI bus reset signal */
55 
56 /*
57  * Status Register pp. 1-9, 1-10 (Read Only)
58  */
59 #define STATUS_REG			0x00
60 #define		DIAG_ACTIVE		0x80	/* Performing Internal Diags */
61 #define		DIAG_FAIL		0x40	/* Internal Diags failed */
62 #define		INIT_REQUIRED		0x20	/* MBOXes need initialization */
63 #define		HA_READY		0x10	/* HA ready for new commands */
64 #define		CMD_REG_BUSY		0x08	/* HA busy with last cmd byte */
65 #define		DATAIN_REG_READY	0x04	/* Data-in Byte available */
66 #define		STATUS_REG_RSVD		0x02
67 #define		CMD_INVALID		0x01	/* Invalid Command detected */
68 
69 /*
70  * Command/Parameter Register pp. 1-10, 1-11 (Write Only)
71  */
72 #define	COMMAND_REG			0x01
73 
74 /*
75  * Data in Register p. 1-11 (Read Only)
76  */
77 #define	DATAIN_REG			0x01
78 
79 /*
80  * Interrupt Status Register pp. 1-12 -> 1-14 (Read Only)
81  */
82 #define INTSTAT_REG			0x02
83 #define		INTR_PENDING		0x80	/* There is a pending INTR */
84 #define		INTSTAT_REG_RSVD	0x70
85 #define		SCSI_BUS_RESET		0x08	/* Bus Reset detected */
86 #define		CMD_COMPLETE		0x04
87 #define		OMB_READY		0x02	/* Outgoin Mailbox Ready */
88 #define		IMB_LOADED		0x01	/* Incoming Mailbox loaded */
89 
90 /*
91  * Definitions for the "undocumented" geometry register, we just need
92  * its location.
93  */
94 #define GEOMETRY_REG			0x03
95 
96 #define AHA_NREGS	(4)
97 
98 /*
99  * Opcodes for Adapter commands.
100  */
101 typedef enum {
102 	AOP_NOP			= 0x00,
103 	AOP_INITIALIZE_MBOX	= 0x01,
104 	AOP_START_MBOX		= 0x02,
105 	AOP_EXECUTE_BIOS_CMD	= 0x03,
106 	AOP_INQUIRE_BOARD_ID	= 0x04,
107 	AOP_ENABLE_OMBR_INT	= 0x05,
108 	AOP_SET_SEL_TIMOUT	= 0x06,
109 	AOP_SET_TIME_ON_BUS	= 0x07,
110 	AOP_SET_TIME_OFF_BUS	= 0x08,
111 	AOP_SET_BUS_TRANS_RATE	= 0x09,
112 	AOP_INQUIRE_INST_LDEVS	= 0x0A,
113 	AOP_INQUIRE_CONFIG	= 0x0B,
114 	AOP_ENABLE_TARGET_MODE	= 0x0C,
115 	AOP_INQUIRE_SETUP_INFO	= 0x0D,
116 	AOP_WRITE_LRAM		= 0x1A,
117 	AOP_READ_LRAM		= 0x1B,
118 	AOP_WRITE_CHIP_FIFO	= 0x1C,
119 	AOP_READ_CHIP_FIFO	= 0x1D,
120 	AOP_ECHO_DATA_BYTE	= 0x1F,
121 	AOP_ADAPTER_DIAGNOSTICS	= 0x20,
122 	AOP_SET_ADAPTER_OPTIONS	= 0x21,
123 	AOP_SET_EEPROM          = 0x22,
124 	AOP_RETURN_EEPROM	= 0x23,
125 	AOP_ENABLE_SHADOW_RAM	= 0x24,
126 	AOP_INIT_BIOS_MBOX	= 0x25,
127 	AOP_SET_BIOS_BANK_1	= 0x26,
128 	AOP_SET_BIOS_BANK_2	= 0x27,
129 	AOP_RETURN_EXT_BIOS_INFO= 0x28,
130 	AOP_MBOX_IF_ENABLE	= 0x29,
131 	AOP_SCSI_TERM_STATUS	= 0x2C,
132 	AOP_INQUIRE_SCAM_DEV	= 0x2D,
133 	AOP_SCSI_DEV_TABLE	= 0x2E,
134 	AOP_SCAM_OP		= 0x2F,
135 	AOP_START_BIOS_CMD	= 0x82,
136 	AOP_INQUIRE_ESETUP_INFO	= 0x8D
137 } aha_op_t;
138 
139 /************** Definitions of Multi-byte commands and responses ************/
140 
141 struct	aha_extbios
142 {
143 	uint8_t flags;			/* Bit 3 == 1 extended bios enabled */
144 	uint8_t mailboxlock;		/* mail box lock code to unlock it */
145 };
146 
147 typedef struct {
148 	uint8_t num_mboxes;
149 	uint8_t base_addr[3];
150 } init_24b_mbox_params_t;
151 
152 typedef struct {
153 	uint8_t board_type;
154 /* These values are mostly from the aha-1540CP technical reference, but */
155 /* with other values from the old aha1542.c driver. The values from the */
156 /* aha-1540CP technical manual are used where conflicts arise */
157 #define		BOARD_1540_16HEAD_BIOS	0x00
158 #define		BOARD_1540_64HEAD_BIOS	0x30
159 #define		BOARD_1542		0x41	/* aha-1540/1542 w/64-h bios */
160 #define		BOARD_1640		0x42	/* aha-1640 */
161 #define		BOARD_1740		0x43	/* aha-1740A/1742A/1744 */
162 #define		BOARD_1542C		0x44	/* aha-1542C */
163 #define		BOARD_1542CF		0x45	/* aha-1542CF */
164 #define		BOARD_1542CP		0x46	/* aha-1542CP, plug and play */
165 	uint8_t cust_features;
166 #define		FEATURES_STANDARD	0x30
167 	uint8_t firmware_rev_major;
168 	uint8_t firmware_rev_minor;
169 } board_id_data_t;
170 
171 typedef struct {
172 	uint8_t dma_chan;
173 #define		DMA_CHAN_5	0x20
174 #define		DMA_CHAN_6	0x40
175 #define		DMA_CHAN_7	0x80
176 	uint8_t irq;
177 #define		IRQ_9		0x01
178 #define		IRQ_10		0x02
179 #define		IRQ_11		0x04
180 #define		IRQ_12		0x08
181 #define		IRQ_14		0x20
182 #define		IRQ_15		0x40
183 	uint8_t scsi_id;
184 } config_data_t;
185 
186 typedef struct {
187 	uint8_t offset : 4,
188 		 period : 3,
189 		 sync	: 1;
190 } targ_syncinfo_t;
191 
192 typedef struct {
193 	uint8_t	initiate_sync	: 1,
194 		 	parity_enable	: 1,
195 					: 6;
196 
197 	uint8_t	bus_transfer_rate;
198 	uint8_t	time_on_bus;
199 	uint8_t	time_off_bus;
200 	uint8_t	num_mboxes;
201 	uint8_t	mbox_base_addr[3];
202 	targ_syncinfo_t	syncinfo[8];
203 	uint8_t	discinfo;
204 	uint8_t	customer_sig[20];
205 	uint8_t	auto_retry;
206 	uint8_t	board_switches;
207 	uint8_t	firmware_cksum[2];
208 	uint8_t	bios_mbox_addr[3];
209 } setup_data_t;
210 
211 #define AHA_NUM_ISAPORTS 6
212 
213 typedef struct {
214 	uint8_t len[3];
215 	uint8_t addr[3];
216 } aha_sg_t;
217 
218 /********************** Mail Box definitions *******************************/
219 
220 typedef enum {
221 	AMBO_FREE		= 0x0,	/* MBO intry is free */
222 	AMBO_START		= 0x1,	/* MBO activate entry */
223 	AMBO_ABORT		= 0x2	/* MBO abort entry */
224 } aha_mbo_action_code_t;
225 
226 typedef struct aha_mbox_out {
227 	uint8_t  action_code;
228 	uint8_t  ccb_addr[3];
229 } aha_mbox_out_t;
230 
231 typedef enum {
232 	AMBI_FREE		= 0x0,	/* MBI entry is free */
233 	AMBI_OK			= 0x1,	/* completed without error */
234 	AMBI_ABORT		= 0x2,	/* aborted ccb */
235 	AMBI_NOT_FOUND		= 0x3,	/* Tried to abort invalid CCB */
236 	AMBI_ERROR		= 0x4	/* Completed with error */
237 } aha_mbi_comp_code_t;
238 
239 typedef struct aha_mbox_in {
240 	uint8_t  comp_code;
241 	uint8_t  ccb_addr[3];
242 } aha_mbox_in_t;
243 
244 /****************** Hardware CCB definition *********************************/
245 typedef enum {
246 	INITIATOR_CCB		= 0x00,
247 	INITIATOR_SG_CCB	= 0x02,
248 	INITIATOR_CCB_WRESID	= 0x03,
249 	INITIATOR_SG_CCB_WRESID	= 0x04,
250 	INITIATOR_BUS_DEV_RESET = 0x81
251 } aha_ccb_opcode_t;
252 
253 typedef enum {
254 	AHASTAT_NOERROR			= 0x00,
255 	AHASTAT_SELTIMEOUT		= 0x11,
256 	AHASTAT_DATARUN_ERROR		= 0x12,
257 	AHASTAT_UNEXPECTED_BUSFREE	= 0x13,
258 	AHASTAT_INVALID_PHASE		= 0x14,
259 	AHASTAT_INVALID_ACTION_CODE	= 0x15,
260 	AHASTAT_INVALID_OPCODE		= 0x16,
261 	AHASTAT_LINKED_CCB_LUN_MISMATCH	= 0x17,
262 	AHASTAT_INVALID_CCB_OR_SG_PARAM	= 0x1A,
263 	AHASTAT_HA_SCSI_BUS_RESET	= 0x22,	/* stolen from bt */
264 	AHASTAT_HA_BDR			= 0x25	/* Stolen from bt */
265 } ahastat_t;
266 
267 struct aha_hccb {
268 	uint8_t  opcode;			/* 0 */
269 	uint8_t  lun		: 3,		/* 1 */
270 		  datain	: 1,
271 		  dataout	: 1,
272 		  target	: 3;
273 	uint8_t  cmd_len;			/* 2 */
274 	uint8_t  sense_len;			/* 3 */
275 	uint8_t  data_len[3];			/* 4 */
276 	uint8_t  data_addr[3];			/* 7 */
277 	uint8_t  link_ptr[3];			/* 10 */
278 	uint8_t  link_id;			/* 13 */
279 	uint8_t  ahastat;			/* 14 */
280 	uint8_t  sdstat;			/* 15 */
281 	uint8_t  reserved1;			/* 16 */
282 	uint8_t  reserved2;			/* 17 */
283 	uint8_t  scsi_cdb[16];			/* 18 */
284 	uint8_t  sense_data[SSD_FULL_SIZE];
285 };
286 
287 typedef enum {
288 	ACCB_FREE		= 0x0,
289 	ACCB_ACTIVE		= 0x1,
290 	ACCB_DEVICE_RESET	= 0x2,
291 	ACCB_RELEASE_SIMQ	= 0x4
292 } accb_flags_t;
293 
294 struct aha_ccb {
295 	struct	aha_hccb	 hccb;		/* hccb assumed to be at 0 */
296 	SLIST_ENTRY(aha_ccb)	 links;
297 	uint32_t		 flags;
298 	union ccb		*ccb;
299 	bus_dmamap_t		 dmamap;
300 	struct callout		 timer;
301 	aha_sg_t		*sg_list;
302 	uint32_t		 sg_list_phys;
303 };
304 
305 struct sg_map_node {
306 	bus_dmamap_t		 sg_dmamap;
307 	bus_addr_t		 sg_physaddr;
308 	aha_sg_t*		 sg_vaddr;
309 	SLIST_ENTRY(sg_map_node) links;
310 };
311 
312 struct aha_softc {
313 	struct	cam_sim		*sim;
314 	struct	cam_path	*path;
315 	aha_mbox_out_t		*cur_outbox;
316 	aha_mbox_in_t		*cur_inbox;
317 	aha_mbox_out_t		*last_outbox;
318 	aha_mbox_in_t		*last_inbox;
319 	struct	aha_ccb		*aha_ccb_array;
320 	SLIST_HEAD(,aha_ccb)	 free_aha_ccbs;
321 	LIST_HEAD(,ccb_hdr)	 pending_ccbs;
322 	u_int			 active_ccbs;
323 	uint32_t		 aha_ccb_physbase;
324 	aha_ccb_opcode_t	 ccb_sg_opcode;
325 	aha_ccb_opcode_t	 ccb_ccb_opcode;
326 	aha_mbox_in_t		*in_boxes;
327 	aha_mbox_out_t		*out_boxes;
328 	struct scsi_sense_data	*sense_buffers;
329 	uint32_t		 sense_buffers_physbase;
330 	struct	aha_ccb		*recovery_accb;
331 	u_int			 num_boxes;
332 	bus_dma_tag_t		 parent_dmat;	/*
333 						 * All dmat's derive from
334 						 * the dmat defined by our
335 						 * bus.
336 						 */
337 	bus_dma_tag_t		 buffer_dmat;	/* dmat for buffer I/O */
338 	bus_dma_tag_t		 mailbox_dmat;	/* dmat for our mailboxes */
339 	bus_dmamap_t		 mailbox_dmamap;
340 	bus_dma_tag_t		 ccb_dmat;	/* dmat for our ccb array */
341 	bus_dmamap_t		 ccb_dmamap;
342 	bus_dma_tag_t		 sg_dmat;	/* dmat for our sg maps */
343 	SLIST_HEAD(, sg_map_node) sg_maps;
344 	bus_addr_t		 mailbox_physbase;
345 	u_int			 num_ccbs;	/* Number of CCBs malloc'd */
346 	u_int			 max_ccbs;	/* Maximum allocatable CCBs */
347 	u_int			 max_sg;
348 	u_int			 unit;
349 	u_int			 scsi_id;
350 	uint32_t		 extended_trans	  :1,
351 				 diff_bus	  :1,
352 				 extended_lun	  :1,
353 				 strict_rr	  :1,
354 				 tag_capable	  :1,
355 				 resource_shortage:1,
356 						  :26;
357 	uint16_t		 disc_permitted;
358 	uint16_t		 sync_permitted;
359 	uint8_t			 init_level;
360 	volatile uint8_t	 command_cmp;
361 	volatile uint8_t	 latched_status;
362 	uint32_t		 bios_addr;
363 	uint8_t			 fw_major;
364 	uint8_t			 fw_minor;
365 	char			 model[32];
366 	uint8_t			 boardid;
367 	struct resource		*irq;
368 	struct resource		*port;
369 	struct resource		*drq;
370 	int			 irqrid;
371 	int			 portrid;
372 	int			 drqrid;
373 	void			 *ih;
374 	device_t		 dev;
375 	struct mtx		 lock;
376 };
377 
378 void aha_alloc(struct aha_softc *);
379 int aha_attach(struct aha_softc *);
380 int aha_cmd(struct aha_softc *, aha_op_t, uint8_t *, u_int, uint8_t *, u_int,
381     u_int);
382 int aha_detach(struct aha_softc *);
383 int aha_fetch_adapter_info(struct aha_softc *);
384 void aha_find_probe_range(int, int *, int *);
385 void aha_free(struct aha_softc *);
386 int aha_init(struct aha_softc *);
387 void aha_intr(void *);
388 int aha_probe(struct aha_softc *);
389 
390 #define DEFAULT_CMD_TIMEOUT 10000	/* 1 sec */
391 
392 #define aha_inb(aha, reg)				\
393 	bus_read_1((aha)->port, reg)
394 
395 #define aha_outb(aha, reg, value)			\
396 	bus_write_1((aha)->port, reg, value)
397 
398 #define ADP0100_PNP		0x00019004	/* ADP0100 */
399 #define AHA1540_PNP		0x40159004	/* ADP1540 */
400 #define AHA1542_PNP		0x42159004	/* ADP1542 */
401 #define AHA1542_PNPCOMPAT	0xA000D040	/* PNP00A0 */
402 #define ICU0091_PNP		0X91005AA4	/* ICU0091 */
403 
404 #endif	/* _AHAREG_H_ */
405