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
|
/* $NetBSD: sfasvar.h,v 1.1 1996/01/31 23:26:49 mark Exp $ */
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _SFASVAR_H_
#define _SFASVAR_H_
#ifndef _SFASREG_H_
#include <arm32/podulebus/sfasreg.h>
#endif
/*
* MAXCHAIN is the anticipated maximum number of chain blocks needed. This
* assumes that we are NEVER requested to transfer more than MAXPHYS bytes.
*/
#define MAXCHAIN (MAXPHYS/NBPG+2)
/*
* Maximum number of requests standing by. Could be anything, but I think 9
* looks nice :-) NOTE: This does NOT include requests already started!
*/
#define MAXPENDING 9 /* 7 IDs + 2 extra */
/*
* DMA chain block. If flg == SFAS_CHAIN_PRG or flg == SFAS_CHAIN_BUMP then
* ptr is a VIRTUAL adress. If flg == SFAS_CHAIN_DMA then ptr is a PHYSICAL
* adress.
*/
struct sfas_dma_chain {
vm_offset_t ptr;
u_short len;
short flg;
};
#define SFAS_CHAIN_DMA 0x00
#define SFAS_CHAIN_BUMP 0x01
#define SFAS_CHAIN_PRG 0x02
/*
* This struct contains the necessary info for a pending request. Pointer to
* a scsi_xfer struct.
*/
struct sfas_pending {
TAILQ_ENTRY(sfas_pending) link;
struct scsi_xfer *xs;
};
/*
* nexus contains all active data for one SCSI unit. Parts of the info in this
* struct survives between scsi commands.
*/
struct nexus {
struct scsi_xfer *xs; /* Pointer to request */
u_char ID; /* ID message to be sent */
u_char clen; /* scsi command length + */
u_char cbuf[14]; /* the actual command bytes */
struct sfas_dma_chain dma[MAXCHAIN]; /* DMA chain blocks */
short max_link; /* Maximum used of above */
short cur_link; /* Currently handled block */
u_char *buf; /* Virtual adress of data */
int len; /* Bytes left to transfer */
vm_offset_t dma_buf; /* Current DMA adress */
int dma_len; /* Current DMA length */
vm_offset_t dma_blk_ptr; /* Current chain adress */
int dma_blk_len; /* Current chain length */
u_char dma_blk_flg; /* Current chain flags */
u_char state; /* Nexus state, see below */
u_short flags; /* Nexus flags, see below */
short period; /* Sync period to request */
u_char offset; /* Sync offset to request */
u_char syncper; /* FAS216 variable storage */
u_char syncoff; /* FAS216 variable storage */
u_char config3; /* FAS216 variable storage */
u_char lun_unit; /* (Lun<<4) | Unit of nexus */
u_char status; /* Status byte from unit*/
};
/* SCSI nexus_states */
#define SFAS_NS_IDLE 0 /* Nexus idle */
#define SFAS_NS_SELECTED 1 /* Last command was a SELECT command */
#define SFAS_NS_DATA_IN 2 /* Last command was a TRANSFER_INFO */
/* command during a data in phase */
#define SFAS_NS_DATA_OUT 3 /* Last command was a TRANSFER_INFO */
/* command during a data out phase */
#define SFAS_NS_STATUS 4 /* We have send a COMMAND_COMPLETE */
/* command and are awaiting status */
#define SFAS_NS_MSG_IN 5 /* Last phase was MESSAGE IN */
#define SFAS_NS_MSG_OUT 6 /* Last phase was MESSAGE OUT */
#define SFAS_NS_SVC 7 /* We have sent the command */
#define SFAS_NS_DISCONNECTING 8 /* We have recieved a disconnect msg */
#define SFAS_NS_DISCONNECTED 9 /* We are disconnected */
#define SFAS_NS_RESELECTED 10 /* We was reselected */
#define SFAS_NS_DONE 11 /* Done. Prephsase to FINISHED */
#define SFAS_NS_FINISHED 12 /* Realy done. Call scsi_done */
#define SFAS_NS_SENSE 13 /* We are requesting sense */
#define SFAS_NS_RESET 14 /* We are reseting this unit */
/* SCSI nexus flags */
#define SFAS_NF_UNIT_BUSY 0x0001 /* Unit is not available */
#define SFAS_NF_SELECT_ME 0x0002 /* Nexus is set up, waiting for bus */
#define SFAS_NF_REQUEST_SENSE 0x0004 /* We should request sense */
#define SFAS_NF_SENSING 0x0008 /* We are sensing */
#define SFAS_NF_HAS_MSG 0x0010 /* We have recieved a complete msg */
#define SFAS_NF_DO_SDTR 0x0020 /* We should send a SDTR */
#define SFAS_NF_SDTR_SENT 0x0040 /* We have sent a SDTR */
#define SFAS_NF_SYNC_TESTED 0x0080 /* We have negotiated sync */
#define SFAS_NF_RESET 0x0100 /* Reset this nexus */
#define SFAS_NF_IMMEDIATE 0x0200 /* We are operating from sfasicmd */
#define SFAS_NF_DEBUG 0x8000 /* As it says: DEBUG */
struct sfas_softc {
struct device sc_dev; /* System required struct */
struct scsi_link sc_link; /* For sub devices */
irqhandler_t sc_ih; /* Interrupt chain struct */
TAILQ_HEAD(,sfas_pending) sc_xs_pending;
TAILQ_HEAD(,sfas_pending) sc_xs_free;
struct sfas_pending sc_xs_store[MAXPENDING];
sfas_regmap_p sc_fas; /* FAS216 Address */
void *sc_spec; /* Board-specific data */
u_char *sc_bump_va; /* Bumpbuf virtual adr */
vm_offset_t sc_bump_pa; /* Bumpbuf physical adr */
int sc_bump_sz; /* Bumpbuf size */
/* Configuration registers, must be set BEFORE sfasinitialize */
u_char sc_clock_freq;
u_short sc_timeout;
u_char sc_host_id;
u_char sc_config_flags;
/* Generic DMA functions */
int (*sc_setup_dma)();
int (*sc_build_dma_chain)();
int (*sc_need_bump)();
/* Generic Led data */
int sc_led_status;
void (*sc_led)();
/* Nexus list */
struct nexus sc_nexus[8];
struct nexus *sc_cur_nexus;
struct nexus *sc_sel_nexus;
/* Current transfer data */
u_char *sc_buf; /* va */
int sc_len;
vm_offset_t sc_dma_buf; /* pa */
int sc_dma_len;
vm_offset_t sc_dma_blk_ptr;
int sc_dma_blk_len;
short sc_dma_blk_flg;
struct sfas_dma_chain *sc_chain; /* Current DMA chain */
short sc_max_link;
short sc_cur_link;
/* Interrupt registers */
u_char sc_status;
u_char sc_interrupt;
u_char sc_resel[2];
u_char sc_units_disconnected;
/* Storage for FAS216 config registers (current values) */
u_char sc_config1;
u_char sc_config2;
u_char sc_config3;
u_char sc_clock_conv_fact;
u_char sc_timeout_val;
u_char sc_clock_period;
u_char sc_msg_in[7];
u_char sc_msg_in_len;
u_char sc_msg_out[7];
u_char sc_msg_out_len;
u_char sc_unit;
u_char sc_lun;
u_char sc_flags;
};
#define SFAS_DMA_READ 0
#define SFAS_DMA_WRITE 1
#define SFAS_DMA_CLEAR 2
/* sc_flags */
#define SFAS_ACTIVE 0x01
#define SFAS_DONT_WAIT 0x02
/* SCSI Selection modes */
#define SFAS_SELECT 0x00 /* Normal selection: No sync, no resel */
#define SFAS_SELECT_R 0x01 /* Reselection allowed */
#define SFAS_SELECT_S 0x02 /* Synchronous transfer allowed */
#define SFAS_SELECT_I 0x04 /* Selection for sfasicmd */
#define SFAS_SELECT_K 0x08 /* Send a BUS DEVICE RESET message (Kill) */
/* Nice abbreviations of the above */
#define SFAS_SELECT_RS (SFAS_SELECT_R|SFAS_SELECT_S)
#define SFAS_SELECT_RI (SFAS_SELECT_R|SFAS_SELECT_I)
#define SFAS_SELECT_SI (SFAS_SELECT_S|SFAS_SELECT_I)
#define SFAS_SELECT_RSI (SFAS_SELECT_R|SFAS_SELECT_S|SFAS_SELECT_I)
/* sc_config_flags */
#define SFAS_NO_SYNCH 0x01 /* Disable synchronous transfer */
#define SFAS_NO_DMA 0x02 /* Do not use DMA! EVER! */
#define SFAS_NO_RESELECT 0x04 /* Do not allow relesection */
#define SFAS_SLOW_CABLE 0x08 /* Cable is "unsafe" for fast scsi-2 */
#define SFAS_SLOW_START 0x10 /* There are slow starters on the bus */
void sfasinitialize __P((struct sfas_softc *sc));
void sfas_minphys __P((struct buf *bp));
int sfas_scsicmd __P((struct scsi_xfer *));
#endif /* _SFASVAR_H_ */
|