summaryrefslogtreecommitdiff
path: root/sys/dev/ic/ninjascsi32var.h
blob: f1a3ce300663ec1d8ae4f27c386dd9c05dc0dc46 (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
/*	$NetBSD: ninjascsi32var.h,v 1.8 2021/10/06 20:42:44 andvar Exp $	*/

/*-
 * Copyright (c) 2004, 2007 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by ITOH Yasufumi.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _NJSC32VAR_H_
#define _NJSC32VAR_H_

typedef unsigned	njsc32_model_t;
#define NJSC32_MODEL_MASK	0xff
#define NJSC32_MODEL_INVALID	0
#define NJSC32_MODEL_32BI	1
#define NJSC32_MODEL_32UDE	2
#define NJSC32_FLAG_DUALEDGE	0x100	/* supports DualEdge */

/*
 * time parameters (25us per unit?)
 */
#define NJSC32_SEL_TIMEOUT_TIME		20000	/* selection timeout (500ms) */
#define NJSC32_ARBITRATION_RETRY_TIME	4	/* 100us */

/* in microseconds */
#define NJSC32_REQ_TIMEOUT		10000	/* 10ms */
#define NJSC32_RESET_HOLD_TIME		26	/* 25us min */

/*
 * DMA page
 */
#ifdef NJSC32_AUTOPARAM
#define NJSC32_NUM_CMD	14	/* # simultaneous commands */
#else
#define NJSC32_NUM_CMD	15	/* # simultaneous commands */
#endif
#define NJSC32_NUM_SG	17	/* # scatter/gather table entries per command */

struct njsc32_dma_page {
	/*
	 * scatter/gather transfer table
	 */
	struct njsc32_sgtable	dp_sg[NJSC32_NUM_CMD][NJSC32_NUM_SG];
#define NJSC32_SIZE_SGT \
	(sizeof(struct njsc32_sgtable) * NJSC32_NUM_SG)

#ifdef NJSC32_AUTOPARAM
	/*
	 * device reads parameters from this structure (autoparam)
	 */
	struct njsc32_autoparam	dp_ap;
#endif
};

/* per command */
struct njsc32_cmd {
	TAILQ_ENTRY(njsc32_cmd)	c_q;
	struct njsc32_softc	*c_sc;

	/* on transfer */
	struct scsipi_xfer	*c_xs;
	struct njsc32_target	*c_target;
	struct njsc32_lu	*c_lu;
	u_int32_t		c_datacnt;	/* I/O buffer length */

	/* command status */
	int		c_flags;
#define NJSC32_CMD_DMA_MAPPED	0x01
#define NJSC32_CMD_TAGGED	0x02
#define NJSC32_CMD_TAGGED_HEAD	0x04

	/* SCSI pointer */
	u_int32_t	c_dp_cur;	/* current (or active) data pointer */
	u_int32_t	c_dp_saved;	/* saved data pointer */
	u_int32_t	c_dp_max;	/* max value of data pointer */

	/* last loaded scatter/gather table */
	unsigned	c_sgoffset;	/* # skip entries */
	u_int32_t	c_sgfixcnt;	/* # skip bytes in the top entry */

	/* command start/restart parameter */
	u_int8_t	c_msg_identify;	/* Identify message */
	u_int16_t	c_xferctl;
	u_int32_t	c_sgtdmaaddr;

	/* DMA resource */
	struct njsc32_sgtable	*c_sgt;		/* for host */
	bus_addr_t		c_sgt_dma;	/* for device */
#define NJSC32_CMD_DMAADDR_SGT(cmd, n)	\
		((cmd)->c_sgt_dma + sizeof(struct njsc32_sgtable) * (n))
	bus_dmamap_t		c_dmamap_xfer;
};

/* -1 for unaligned access */
#define NJSC32_MAX_XFER	((NJSC32_NUM_SG - 1) << PGSHIFT)

struct njsc32_softc {
	device_t		sc_dev;

	/* device spec */
	njsc32_model_t		sc_model;

	int			sc_clk;		/* one of following */
#define NJSC32_CLK_40M		NJSC32_CLOCK_DIV_4	/* 20MB/s */
#define NJSC32_CLK_20M		NJSC32_CLOCK_DIV_2	/* 10MB/s */
#define NJSC32_CLK_PCI_33M	NJSC32_CLOCK_PCICLK	/* 16.6MB/s */

	/* device register */
	bus_space_tag_t		sc_regt;
	bus_space_handle_t	sc_regh;

	unsigned		sc_flags;
#define NJSC32_IO_MAPPED		0x00000001
#define NJSC32_MEM_MAPPED		0x00000002
#define NJSC32_CMDPG_MAPPED		0x00000004
#define NJSC32_CANNOT_SUPPLY_TERMPWR	0x00000100

	/*
	 * controller state
	 */
	enum njsc32_stat {
		NJSC32_STAT_IDLE,
		NJSC32_STAT_ARBIT,	/* initiator started arbitration */
		NJSC32_STAT_CONNECT,	/* command is active (connection) */
		NJSC32_STAT_RESEL,	/* a target did Reselection */
		NJSC32_STAT_RESEL_LUN,	/* received Identify message */
		NJSC32_STAT_RECONNECT,	/* command is active (reconnection) */
		NJSC32_STAT_RESET,	/* resetting bus */
		NJSC32_STAT_RESET1,	/* waiting for bus reset release */
		NJSC32_STAT_RESET2,	/* waiting for bus reset release */
		NJSC32_STAT_DETACH	/* detaching */
	} sc_stat;

	/* interrupt handle */
	void			*sc_ih;

	/* for DMA */
	bus_dma_tag_t		sc_dmat;
	struct njsc32_dma_page	*sc_cmdpg;	/* scatter/gather table page */
#if 0
	bus_addr_t		sc_cmdpg_dma;
#endif
	bus_dma_segment_t	sc_cmdpg_seg;
	bus_dmamap_t		sc_dmamap_cmdpg;
	int			sc_cmdpg_nsegs;

#ifdef NJSC32_AUTOPARAM
	u_int32_t		sc_ap_dma;	/* autoparam DMA address */
#endif

	/* for monitoring bus reset */
	struct callout		sc_callout;

	/*
	 * command control structure
	 */
	struct njsc32_cmd	sc_cmds[NJSC32_NUM_CMD];
	TAILQ_HEAD(njsc32_cmd_head, njsc32_cmd)
				sc_freecmd,	/* free list */
				sc_reqcmd;	/* waiting commands */

	struct njsc32_cmd	*sc_curcmd;	/* currently active command */
	int			sc_ncmd;	/* total # commands available */
	int			sc_nusedcmds;	/* # used commands */

	/* reselection */
	int			sc_reselid, sc_resellun;

	/* message in buffer */
#define NJSC32_MSGIN_LEN	20
	u_int8_t		sc_msginbuf[NJSC32_MSGIN_LEN];
	int			sc_msgincnt;

	/* message out buffer */
#define NJSC32_MSGOUT_LEN	16
	u_int8_t		sc_msgout[NJSC32_MSGOUT_LEN];
	size_t			sc_msgoutlen;
	size_t			sc_msgoutidx;

	/* sync timing table */
	const struct njsc32_sync_param {
		u_int8_t	sp_period;	/* transfer period */
		u_int8_t	sp_ackw;	/* ACK width parameter */
		u_int8_t	sp_sample;	/* sampling period */
	} *sc_synct;
	int	sc_sync_max;

	/* for scsipi layer */
	device_t		sc_scsi;
	struct scsipi_adapter	sc_adapter;
	struct scsipi_channel	sc_channel;

	/* per-target */
	struct njsc32_target {
		enum njsc32_tarst {
			NJSC32_TARST_DONE,	/* negotiation done */
			NJSC32_TARST_INIT,
			NJSC32_TARST_DE,	/* negotiating DualEdge */
			NJSC32_TARST_WDTR,	/* negotiating width */
			NJSC32_TARST_SDTR,	/* negotiating sync */
			NJSC32_TARST_ASYNC	/* negotiating async */
		} t_state;
		int	t_flags;
#define NJSC32_TARF_TAG		0x0001	/* tagged queueing is enabled */
#define NJSC32_TARF_SYNC	0x0002	/* negotiate for sync transfer */
#define NJSC32_TARF_DE		0x0004	/* negotiate for DualEdge transfer */

		int		t_syncperiod;
		int		t_syncoffset;

		u_int8_t	t_sync;
		u_int8_t	t_ackwidth;
		u_int8_t	t_targetid;	/* initiator and target id */
		u_int8_t	t_sample;

		u_int16_t	t_xferctl;	/* DualEdge flag */

		/* per logical unit */
		struct njsc32_lu {
			/*
			 * disconnected commands
			 */
			struct njsc32_cmd *lu_cmd;	/* untagged command */
			struct njsc32_cmd_head	lu_q;	/* tagged commands */
		} t_lus[NJSC32_NLU];
	} sc_targets[NJSC32_MAX_TARGET_ID + 1];
};

#ifdef _KERNEL
void	njsc32_attach(struct njsc32_softc *);
int	njsc32_detach(struct njsc32_softc *, int);
int	njsc32_intr(void *);
#endif

#endif	/* _NJSC32VAR_H_ */