1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Generic register and struct definitions for the Adaptech 1540, 1542,
5  * SCSI host adapters. Product specific probe and attach
6  * routines can be found in:
7  *	aha_isa.c
8  *
9  * Derived from bt.c written by:
10  *
11  * Copyright (c) 1998 Justin T. Gibbs.
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions, and the following disclaimer,
19  *    without modification, immediately at the beginning of the file.
20  * 2. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  * $FreeBSD: stable/12/sys/dev/aha/ahareg.h 326255 2017-11-27 14:52:40Z pfg $
36  */
37 
38 #ifndef _AHAREG_H_
39 #define _AHAREG_H_
40 
41 #include <sys/queue.h>
42 #include <cam/scsi/scsi_all.h>
43 
44 #define AHA_MAXTRANSFER_SIZE	 0xffffff	/* limited by 24bit counter */
45 #define AHA_NSEG		17	/* The number of dma segments
46 					 * supported. */
47 #define ALL_TARGETS (~0)
48 
49 /*
50  * Control Register pp. 1-8, 1-9 (Write Only)
51  */
52 #define	CONTROL_REG		0x00
53 #define		HARD_RESET	0x80	/* Hard Reset - return to POST state */
54 #define		SOFT_RESET	0x40	/* Soft Reset - Clears Adapter state */
55 #define		RESET_INTR	0x20	/* Reset/Ack Interrupt */
56 #define		RESET_SBUS	0x10	/* Drive SCSI bus reset signal */
57 
58 /*
59  * Status Register pp. 1-9, 1-10 (Read Only)
60  */
61 #define STATUS_REG			0x00
62 #define		DIAG_ACTIVE		0x80	/* Performing Internal Diags */
63 #define		DIAG_FAIL		0x40	/* Internal Diags failed */
64 #define		INIT_REQUIRED		0x20	/* MBOXes need initialization */
65 #define		HA_READY		0x10	/* HA ready for new commands */
66 #define		CMD_REG_BUSY		0x08	/* HA busy with last cmd byte */
67 #define		DATAIN_REG_READY	0x04	/* Data-in Byte available */
68 #define		STATUS_REG_RSVD		0x02
69 #define		CMD_INVALID		0x01	/* Invalid Command detected */
70 
71 /*
72  * Command/Parameter Register pp. 1-10, 1-11 (Write Only)
73  */
74 #define	COMMAND_REG			0x01
75 
76 /*
77  * Data in Register p. 1-11 (Read Only)
78  */
79 #define	DATAIN_REG			0x01
80 
81 /*
82  * Interrupt Status Register pp. 1-12 -> 1-14 (Read Only)
83  */
84 #define INTSTAT_REG			0x02
85 #define		INTR_PENDING		0x80	/* There is a pending INTR */
86 #define		INTSTAT_REG_RSVD	0x70
87 #define		SCSI_BUS_RESET		0x08	/* Bus Reset detected */
88 #define		CMD_COMPLETE		0x04
89 #define		OMB_READY		0x02	/* Outgoin Mailbox Ready */
90 #define		IMB_LOADED		0x01	/* Incoming Mailbox loaded */
91 
92 /*
93  * Definitions for the "undocumented" geometry register, we just need
94  * its location.
95  */
96 #define GEOMETRY_REG			0x03
97 
98 #define AHA_NREGS	(4)
99 
100 /*
101  * Opcodes for Adapter commands.
102  */
103 typedef enum {
104 	AOP_NOP			= 0x00,
105 	AOP_INITIALIZE_MBOX	= 0x01,
106 	AOP_START_MBOX		= 0x02,
107 	AOP_EXECUTE_BIOS_CMD	= 0x03,
108 	AOP_INQUIRE_BOARD_ID	= 0x04,
109 	AOP_ENABLE_OMBR_INT	= 0x05,
110 	AOP_SET_SEL_TIMOUT	= 0x06,
111 	AOP_SET_TIME_ON_BUS	= 0x07,
112 	AOP_SET_TIME_OFF_BUS	= 0x08,
113 	AOP_SET_BUS_TRANS_RATE	= 0x09,
114 	AOP_INQUIRE_INST_LDEVS	= 0x0A,
115 	AOP_INQUIRE_CONFIG	= 0x0B,
116 	AOP_ENABLE_TARGET_MODE	= 0x0C,
117 	AOP_INQUIRE_SETUP_INFO	= 0x0D,
118 	AOP_WRITE_LRAM		= 0x1A,
119 	AOP_READ_LRAM		= 0x1B,
120 	AOP_WRITE_CHIP_FIFO	= 0x1C,
121 	AOP_READ_CHIP_FIFO	= 0x1D,
122 	AOP_ECHO_DATA_BYTE	= 0x1F,
123 	AOP_ADAPTER_DIAGNOSTICS	= 0x20,
124 	AOP_SET_ADAPTER_OPTIONS	= 0x21,
125 	AOP_SET_EEPROM          = 0x22,
126 	AOP_RETURN_EEPROM	= 0x23,
127 	AOP_ENABLE_SHADOW_RAM	= 0x24,
128 	AOP_INIT_BIOS_MBOX	= 0x25,
129 	AOP_SET_BIOS_BANK_1	= 0x26,
130 	AOP_SET_BIOS_BANK_2	= 0x27,
131 	AOP_RETURN_EXT_BIOS_INFO= 0x28,
132 	AOP_MBOX_IF_ENABLE	= 0x29,
133 	AOP_SCSI_TERM_STATUS	= 0x2C,
134 	AOP_INQUIRE_SCAM_DEV	= 0x2D,
135 	AOP_SCSI_DEV_TABLE	= 0x2E,
136 	AOP_SCAM_OP		= 0x2F,
137 	AOP_START_BIOS_CMD	= 0x82,
138 	AOP_INQUIRE_ESETUP_INFO	= 0x8D
139 } aha_op_t;
140 
141 /************** Definitions of Multi-byte commands and responses ************/
142 
143 struct	aha_extbios
144 {
145 	uint8_t flags;			/* Bit 3 == 1 extended bios enabled */
146 	uint8_t mailboxlock;		/* mail box lock code to unlock it */
147 };
148 
149 typedef struct {
150 	uint8_t num_mboxes;
151 	uint8_t base_addr[3];
152 } init_24b_mbox_params_t;
153 
154 typedef struct {
155 	uint8_t board_type;
156 /* These values are mostly from the aha-1540CP technical reference, but */
157 /* with other values from the old aha1542.c driver. The values from the */
158 /* aha-1540CP technical manual are used where conflicts arise */
159 #define		BOARD_1540_16HEAD_BIOS	0x00
160 #define		BOARD_1540_64HEAD_BIOS	0x30
161 #define		BOARD_1542		0x41	/* aha-1540/1542 w/64-h bios */
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