summaryrefslogtreecommitdiff
path: root/scsi/adapters/scsi_aha15.h
blob: 52cd9367261fcfc1b5bf8bf5d2ef4c155ebe8255 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/* 
 * Mach Operating System
 * Copyright (c) 1991,1990 Carnegie Mellon University
 * All Rights Reserved.
 * 
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 * 
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 * 
 * Carnegie Mellon requests users of this software to return to
 * 
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 * 
 * any improvements or extensions that they make and grant Carnegie Mellon
 * the rights to redistribute these changes.
 */
/*
 *	File: scsi_aha15.h
 * 	Author: Alessandro Forin, Carnegie Mellon University
 *	Date:	6/91
 *
 *	Definitions for the Adaptec AHA-15xx family
 *	of Intelligent SCSI Host Adapter boards
 */

#ifndef	_SCSI_AHA15_H_
#define	_SCSI_AHA15_H_

/*
 * Addresses/length in 24 bits
 *
 * BEWARE: your compiler must pack these correctly,
 * e.g. without gaps between two such contiguous structs
 * (GCC does)
 */
typedef struct {
	unsigned char	msb;
	unsigned char	mid;
	unsigned char	lsb;
} aha_address_t;

#define AHA_ADDRESS_SET(addr,val)	{\
		(addr).msb = ((val) >> 16);\
		(addr).mid = ((val) >>  8);\
		(addr).lsb =  (val)	  ;\
	}
#define AHA_ADDRESS_GET(addr,val) {\
		(val) = ((addr).msb << 16) |\
			((addr).mid <<  8) |\
			((addr).lsb      ) ;\
	}

#define	aha_length_t	aha_address_t
#define	AHA_LENGTH_SET	AHA_ADDRESS_SET
#define	AHA_LENGTH_GET	AHA_ADDRESS_GET

/*
 * Register map
 */

typedef struct {
	volatile unsigned char	aha_status;	/* r:  Status Register */
#define			aha_ctl aha_status	/* w:  Control Register */

	volatile unsigned char	aha_data;	/* rw: Data Port */
#define			aha_cmd aha_data	/* w:  Command register */

	volatile unsigned char	aha_intr;	/* ro: Interrupt Register */
} aha_regmap_t;

/* ..but on the 386 I/O is not memory mapped */
#define	AHA_STATUS_PORT(port)	((port))
#define	AHA_CONTROL_PORT(port)	((port))
#define	AHA_COMMAND_PORT(port)	((port)+1)
#define	AHA_DATA_PORT(port)	((port)+1)
#define	AHA_INTR_PORT(port)	((port)+2)

/* Status Register */
#define AHA_CSR_CMD_ERR		0x01		/* Invalid command */
#define AHA_CSR_xxx		0x02		/* undefined */
#define AHA_CSR_DATAI_FULL	0x04		/* In-port full */
#define AHA_CSR_DATAO_FULL	0x08		/* Out-port full */
#define AHA_CSR_IDLE		0x10		/* doin nuthin */
#define AHA_CSR_INIT_REQ	0x20		/* initialization required */
#define AHA_CSR_DIAG_FAIL	0x40		/* selftest failed */
#define AHA_CSR_SELF_TEST	0x80		/* selftesting */

/* Control Register */
#define AHA_CTL_xxx		0x0f		/* undefined */
#define AHA_CTL_SCSI_RST	0x10		/* reset SCSIbus */
#define AHA_CTL_INTR_CLR	0x20		/* Clear interrupt reg */
#define AHA_CTL_SOFT_RESET	0x40		/* Board only, no selftest */
#define AHA_CTL_HARD_RESET	0x80		/* Full reset, and SCSIbus */

/* Interrupt Flags register */
#define AHA_INTR_MBI_FULL	0x01		/* scan the In mboxes */
#define AHA_INTR_MBO_AVAIL	0x02		/* scan the Out mboxes */
#define AHA_INTR_DONE		0x04		/* command complete */
#define AHA_INTR_RST		0x08		/* saw a SCSIbus reset */
#define AHA_INTR_xxx		0x70		/* undefined */
#define AHA_INTR_PENDING	0x80		/* Any interrupt bit set */

/*
 * Command register
 */
#define AHA_CMD_NOP		0x00		/* */
#define AHA_CMD_INIT		0x01		/* mbox initialization */
	/* 4 bytes follow: # of Out mboxes (x2->total), and
			   msb, mid, lsb of mbox address */
struct aha_init {
	unsigned char		mb_count;
	aha_address_t		mb_ptr;
};
#define AHA_CMD_START		0x02		/* start SCSI cmd */
#define AHA_CMD_BIOS		0x03		
#define AHA_CMD_INQUIRY		0x04
	/* returns 4 bytes: */
struct aha_inq {
	unsigned char		board_id;
#	define	AHA_BID_1540_B16		0x00
#	define	AHA_BID_1540_B64		0x30
#	define	AHA_BID_1540B			0x41
#	define	AHA_BID_1640			0x42
#	define	AHA_BID_1740			0x43
#	define	AHA_BID_1542C			0x44
#	define  AHA_BID_1542CF			0x45  	/* BIOS v2.0x */

	unsigned char		options;
#	define	AHA_BOPT_STD			0x41	/* in 154x, standard model */

	unsigned char		frl_1;		/* rev level */
	unsigned char		frl_2;
};
#define AHA_CMD_MBO_IE		0x05
	/* 1 byte follows: */
#	define	AHA_MBO_DISABLE			0x00
#	define	AHA_MBO_ENABLE			0x01

#define AHA_CMD_SET_SELTO	0x06		/* select timeout */
	/* 4 bytes follow: */
struct aha_selto {
	unsigned char		enable;
	char			xxx;
	unsigned char		timeo_msb;
	unsigned char		timeo_lsb;
};
#define AHA_CMD_SET_BUSON	0x07
	/* 1 byte value follows: 2..15 default 11 usecs */
#define AHA_CMD_SET_BUSOFF	0x08
	/* 1 byte value follows: 1..64 default 4 usecs */
#define AHA_CMD_SET_XSPEED	0x09
	/* 1 byte value follows: */
#	define AHA_DMASPEED_5Mb		0x00
#	define AHA_DMASPEED_7Mb		0x01
#	define AHA_DMASPEED_8Mb		0x02
#	define AHA_DMASPEED_10Mb	0x03
#	define AHA_DMASPEED_6Mb		0x04
	/* values in the range 80..ff encoded as follows:
		bit 7	on	--> custom speed
		bits 6..4	read pulse width
			0	100ns
			1	150
			2	200
			3	250
			4	300
			5	350
			6	400
			7	450
		bit 3		strobe off time
			0	100ns
			1	150ns
		bits 2..0	write pulse width
			<same as read pulse>
	 */
#define AHA_CMD_FIND_DEVICES	0x0a
	/* returns 8 bytes, each one is a bitmask of the LUNs
	   available for the given target ID */
struct aha_devs {
	unsigned char		tgt_luns[8];
};
#define AHA_CMD_GET_CONFIG	0x0b
	/* returns 3 bytes: */
struct aha_conf {
	unsigned char		dma_arbitration;/* bit N -> channel N */
	unsigned char		intr_ch;/* bit N -> intr 9+N (but 13,16)*/
	unsigned char		my_scsi_id;	/* both of I and T role */
};
#define AHA_CMD_ENB_TGT_MODE	0x0c
	/* 2 bytes follow: */
struct aha_tgt {
	unsigned char		enable;
	unsigned char		luns;	/* bitmask */
};

#define AHA_CMD_GET_SETUP	0x0d
	/* 1 byte follows: allocation len (N) */
	/* returns N bytes, 17 significant: */
struct aha_setup {
	BITFIELD_3( unsigned char,
				initiate_SDT:1,
				enable_parity:1,
				res:6);
	unsigned char		xspeed;	/* see above */
	unsigned char		buson;
	unsigned char		busoff;
	unsigned char		n_mboxes;/* 0 if not initialized */
	aha_address_t		mb_ptr; /* garbage if not inited */
	struct {
	    BITFIELD_3( unsigned char,
	    			offset: 4,
				period: 3,	/* 200 + 50 * N */
				negotiated: 1);
	} SDT_params[8];
	unsigned char		no_disconnect;	/* bitmask */
};

#define AHA_CMD_WRITE_CH2	0x1a
	/* 3 bytes (aha_address_t) follow for the buffer pointer */
#define AHA_CMD_READ_CH2	0x1b
	/* 3 bytes (aha_address_t) follow for the buffer pointer */
#define AHA_CMD_WRITE_FIFO	0x1c
	/* 3 bytes (aha_address_t) follow for the buffer pointer */
#define AHA_CMD_READ_FIFO	0x1d
	/* 3 bytes (aha_address_t) follow for the buffer pointer */
#define AHA_CMD_ECHO		0x1f
	/* 1 byte follows, which should then be read back */
#define AHA_CMD_DIAG		0x20
#define AHA_CMD_SET_OPT		0x21
	/* 2+ bytes follow: */
struct aha_diag {
	unsigned char		parmlen;	/* bytes to follow */
	unsigned char		no_disconnect;	/* bitmask */
	/* rest is undefined */
};

#define AHA_EXT_BIOS            0x28    /* return extended bios info */
#define AHA_MBX_ENABLE          0x29    /* enable mail box interface */
struct aha_extbios {
        unsigned char  	flags;		/* Bit 3 == 1 extended bios enabled */
        unsigned char  	mailboxlock;    /* mail box lock code to unlock it */
};

/*
 * Command Control Block
 */
typedef struct {
	unsigned char		ccb_code;
#	define		AHA_CCB_I_CMD		0x00
#	define		AHA_CCB_T_CMD		0x01
#	define		AHA_CCB_I_CMD_SG	0x02
#	define		AHA_CCB_ICMD_R		0x03
#	define		AHA_CCB_ICMD_SG_R	0x04
#	define		AHA_CCB_BDEV_RST	0x81
	BITFIELD_4( unsigned char,
				ccb_lun:3,
				ccb_in:1,
				ccb_out:1,
				ccb_scsi_id:3);
	unsigned char		ccb_cmd_len;
	unsigned char		ccb_reqsns_len;	/* if 1 no automatic reqsns*/
	aha_length_t		ccb_datalen;
	aha_address_t		ccb_dataptr;
	aha_address_t		ccb_linkptr;
	unsigned char		ccb_linkid;
	unsigned char		ccb_hstatus;
#	define	AHA_HST_SUCCESS			0x00
#	define	AHA_HST_SEL_TIMEO		0x11
#	define	AHA_HST_DATA_OVRUN		0x12
#	define	AHA_HST_BAD_DISCONN		0x13
#	define	AHA_HST_BAD_PHASE_SEQ		0x14
#	define	AHA_HST_BAD_OPCODE		0x16
#	define	AHA_HST_BAD_LINK_LUN		0x17
#	define	AHA_HST_INVALID_TDIR		0x18
#	define	AHA_HST_DUPLICATED_CCB		0x19
#	define	AHA_HST_BAD_PARAM		0x1a

	scsi2_status_byte_t	ccb_status;
	unsigned char		ccb_xxx;
	unsigned char		ccb_xxx1;
	scsi_command_group_5	ccb_scsi_cmd;	/* cast as needed */
} aha_ccb_t;

/* For scatter/gather use a list of (len,ptr) segments, each field
   is 3 bytes (aha_address_t) long. Max 17 segments, min 1 */

/*
 * Ring descriptor, aka Mailbox
 */
typedef union {

    struct {
	volatile unsigned char	mb_cmd;		/* Out mbox */
#	define		mb_status mb_cmd	/* In mbox */

	aha_address_t		mb_ptr;
#define AHA_MB_SET_PTR(mbx,val)	AHA_ADDRESS_SET((mbx)->mb.mb_ptr,(val))
#define AHA_MB_GET_PTR(mbx,val)	AHA_ADDRESS_GET((mbx)->mb.mb_ptr,(val))

    } mb;

    struct {					/* ccb required In mbox */
	volatile unsigned char	mb_cmd;
	BITFIELD_4( unsigned char,
				mb_lun : 3,
				mb_isa_send : 1,
				mb_isa_recv : 1,
				mb_initiator_id : 3);
	unsigned char		mb_data_len_msb;
	unsigned char		mb_data_len_mid;
    } mbt;

    unsigned int	bits;			/* quick access */

} aha_mbox_t;

/* Out mbox, values for the mb_cmd field */
#define	AHA_MBO_FREE		0x00
#define	AHA_MBO_START		0x01
#define	AHA_MBO_ABORT		0x02

/* In mbox, values for the mb_status field */
#define	AHA_MBI_FREE		0x00
#define	AHA_MBI_SUCCESS		0x01
#define	AHA_MBI_ABORTED		0x02
#define	AHA_MBI_NOT_FOUND	0x03
#define	AHA_MBI_ERROR		0x04
#define AHA_MBI_NEED_CCB	0x10

/*
 * Scatter/gather segment lists
 */
typedef struct {
	aha_length_t	len;
	aha_address_t	ptr;
} aha_seglist_t;

#define	AHA_MAX_SEGLIST		17		/* which means max 64Kb */
#endif	/*_SCSI_AHA15_H_*/