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 */
101typedef 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
141struct	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
147typedef struct {
148	uint8_t num_mboxes;
149	uint8_t base_addr[3];
150} init_24b_mbox_params_t;
151
152typedef 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
171typedef 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
186typedef struct {
187	uint8_t offset : 4,
188		 period : 3,
189		 sync	: 1;
190} targ_syncinfo_t;
191
192typedef 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
213typedef struct {
214	uint8_t len[3];
215	uint8_t addr[3];
216} aha_sg_t;
217
218/********************** Mail Box definitions *******************************/
219
220typedef 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
226typedef struct aha_mbox_out {
227	uint8_t  action_code;
228	uint8_t  ccb_addr[3];
229} aha_mbox_out_t;
230
231typedef 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
239typedef 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 *********************************/
245typedef 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
253typedef 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
267struct 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
287typedef enum {
288	ACCB_FREE		= 0x0,
289	ACCB_ACTIVE		= 0x1,
290	ACCB_DEVICE_RESET	= 0x2,
291	ACCB_RELEASE_SIMQ	= 0x4
292} accb_flags_t;
293
294struct 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
305struct 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
312struct 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
378void aha_alloc(struct aha_softc *);
379int aha_attach(struct aha_softc *);
380int aha_cmd(struct aha_softc *, aha_op_t, uint8_t *, u_int, uint8_t *, u_int,
381    u_int);
382int aha_detach(struct aha_softc *);
383int aha_fetch_adapter_info(struct aha_softc *);
384void aha_find_probe_range(int, int *, int *);
385void aha_free(struct aha_softc *);
386int aha_init(struct aha_softc *);
387void aha_intr(void *);
388int 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