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
|
/* $OpenBSD: qlwreg.h,v 1.7 2014/03/15 21:49:47 kettenis Exp $ */
/*
* Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
* Copyright (c) 2014 Mark Kettenis <kettenis@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* firmware loading */
#define QLW_CODE_ORG 0x1000
/* interrupt types */
#define QLW_INT_TYPE_MBOX 1
#define QLW_INT_TYPE_ASYNC 2
#define QLW_INT_TYPE_IO 3
#define QLW_INT_TYPE_OTHER 4
/* ISP registers */
#define QLW_CFG0 0x04
#define QLW_CFG1 0x06
#define QLW_INT_CTRL 0x08
#define QLW_INT_STATUS 0x0a
#define QLW_SEMA 0x0c
#define QLW_NVRAM 0x0e
#define QLW_FLASH_BIOS_DATA 0x10
#define QLW_FLASH_BIOS_ADDR 0x12
#define QLW_CDMA_CFG 0x20
#define QLW_DDMA_CFG 0x40
#define QLW_MBOX_BASE_PCI 0x70
#define QLW_MBOX_BASE_SBUS 0x80
#define QLW_CDMA_CFG_1080 0x80
#define QLW_DDMA_CFG_1080 0xa0
#define QLW_HOST_CMD_CTRL_PCI 0xc0
#define QLW_GPIO_DATA 0xcc
#define QLW_GPIO_ENABLE 0xce
#define QLW_HOST_CMD_CTRL_SBUS 0x440
#define QLW_REQ_IN 0x08
#define QLW_REQ_OUT 0x08
#define QLW_RESP_IN 0x0a
#define QLW_RESP_OUT 0x0a
/* QLW_CFG1 */
#define QLW_BURST_ENABLE 0x0004
#define QLW_PCI_FIFO_16 0x0010
#define QLW_PCI_FIFO_32 0x0020
#define QLW_PCI_FIFO_64 0x0030
#define QLW_PCI_FIFO_128 0x0040
#define QLW_PCI_FIFO_MASK 0x0070
#define QLW_SBUS_FIFO_64 0x0003
#define QLW_SBUS_FIFO_32 0x0002
#define QLW_SBUS_FIFO_16 0x0001
#define QLW_SBUS_FIFO_8 0x0000
#define QLW_SBUS_FIFO_MASK 0x0003
#define QLW_SBUS_BURST_8 0x0008
#define QLW_DMA_BANK 0x0300
/* QLW_INT_CTRL */
#define QLW_RESET 0x0001
/* QLW_INT_STATUS */
#define QLW_INT_REQ 0x0002
#define QLW_RISC_INT_REQ 0x0004
/* QLW_SEMA */
#define QLW_SEMA_STATUS 0x0002
#define QLW_SEMA_LOCK 0x0001
/* QLW_NVRAM */
#define QLW_NVRAM_DATA_IN 0x0008
#define QLW_NVRAM_DATA_OUT 0x0004
#define QLW_NVRAM_CHIP_SEL 0x0002
#define QLW_NVRAM_CLOCK 0x0001
#define QLW_NVRAM_CMD_READ 6
/* QLW_CDMA_CFG and QLW_DDMA_CFG */
#define QLW_DMA_BURST_ENABLE 0x0002
/* QLW_HOST_CMD_CTRL write */
#define QLW_HOST_CMD_SHIFT 12
#define QLW_HOST_CMD_NOP 0x0
#define QLW_HOST_CMD_RESET 0x1
#define QLW_HOST_CMD_PAUSE 0x2
#define QLW_HOST_CMD_RELEASE 0x3
#define QLW_HOST_CMD_MASK_PARITY 0x4
#define QLW_HOST_CMD_SET_HOST_INT 0x5
#define QLW_HOST_CMD_CLR_HOST_INT 0x6
#define QLW_HOST_CMD_CLR_RISC_INT 0x7
#define QLW_HOST_CMD_BIOS 0x9
#define QLW_HOST_CMD_ENABLE_PARITY 0xa
#define QLW_HOST_CMD_PARITY_ERROR 0xe
/* QLA_HOST_CMD_CTRL read */
#define QLA_HOST_STATUS_HOST_INT 0x0080
#define QLA_HOST_STATUS_RISC_RESET 0x0040
#define QLA_HOST_STATUS_RISC_PAUSE 0x0020
#define QLA_HOST_STATUS_RISC_EXT 0x0010
/* QLW_MBIX_BASE (reg 0) read */
#define QLW_MBOX_HAS_STATUS 0x4000
#define QLW_MBOX_COMPLETE 0x4000
#define QLW_MBOX_INVALID 0x4001
#define QLW_ASYNC_BUS_RESET 0x8001
#define QLW_ASYNC_SYSTEM_ERROR 0x8002
#define QLW_ASYNC_REQ_XFER_ERROR 0x8003
#define QLW_ASYNC_RSP_XFER_ERROR 0x8004
#define QLW_ASYNC_SCSI_CMD_COMPLETE 0x8020
#define QLW_ASYNC_CTIO_COMPLETE 0x8021
/* QLW_MBOX_BASE (reg 0) write */
#define QLW_MBOX_NOP 0x0000
#define QLW_MBOX_LOAD_RAM 0x0001
#define QLW_MBOX_EXEC_FIRMWARE 0x0002
#define QLW_MBOX_WRITE_RAM_WORD 0x0004
#define QLW_MBOX_REGISTER_TEST 0x0006
#define QLW_MBOX_VERIFY_CSUM 0x0007
#define QLW_MBOX_ABOUT_FIRMWARE 0x0008
#define QLW_MBOX_INIT_REQ_QUEUE 0x0010
#define QLW_MBOX_INIT_RSP_QUEUE 0x0011
#define QLW_MBOX_BUS_RESET 0x0018
#define QLW_MBOX_GET_FIRMWARE_STATUS 0x001F
#define QLW_MBOX_SET_INITIATOR_ID 0x0030
#define QLW_MBOX_SET_SELECTION_TIMEOUT 0x0031
#define QLW_MBOX_SET_RETRY_COUNT 0x0032
#define QLW_MBOX_SET_TAG_AGE_LIMIT 0x0033
#define QLW_MBOX_SET_CLOCK_RATE 0x0034
#define QLW_MBOX_SET_ACTIVE_NEGATION 0x0035
#define QLW_MBOX_SET_ASYNC_DATA_SETUP 0x0036
#define QLW_MBOX_SET_PCI_CONTROL 0x0037
#define QLW_MBOX_SET_TARGET_PARAMETERS 0x0038
#define QLW_MBOX_SET_DEVICE_QUEUE 0x0039
#define QLW_MBOX_SET_SYSTEM_PARAMETER 0x0045
#define QLW_MBOX_SET_FIRMWARE_FEATURES 0x004a
#define QLW_MBOX_INIT_REQ_QUEUE_A64 0x0052
#define QLW_MBOX_INIT_RSP_QUEUE_A64 0x0053
#define QLW_MBOX_SET_DATA_OVERRUN_RECOVERY 0x005a
/* mailbox operation register bitfields */
#define QLW_MBOX_ABOUT_FIRMWARE_IN 0x0001
#define QLW_MBOX_ABOUT_FIRMWARE_OUT 0x004f
#define QLW_MBOX_INIT_FIRMWARE_IN 0x00fd
#define QLW_FW_FEATURE_FAST_POSTING 0x0001
#define QLW_FW_FEATURE_LVD_NOTIFY 0x0002
/* nvram layout */
struct qlw_nvram_target {
u_int8_t parameter;
u_int8_t execution_throttle;
u_int8_t sync_period;
u_int8_t flags;
u_int8_t reserved[2];
} __packed;
struct qlw_nvram_1040 {
u_int8_t id[4];
u_int8_t nvram_version;
u_int8_t config1;
u_int8_t reset_delay;
u_int8_t retry_count;
u_int8_t retry_delay;
u_int8_t config2;
u_int8_t tag_age_limit;
u_int8_t flags1;
u_int16_t selection_timeout;
u_int16_t max_queue_depth;
u_int8_t flags2;
u_int8_t reserved_0[5];
u_int8_t flags3;
u_int8_t reserved_1[5];
struct qlw_nvram_target target[16];
u_int8_t reserved_2[3];
u_int8_t checksum;
} __packed;
struct qlw_nvram_bus {
u_int8_t config1;
u_int8_t reset_delay;
u_int8_t retry_count;
u_int8_t retry_delay;
u_int8_t config2;
u_int8_t reserved_0;
u_int16_t selection_timeout;
u_int16_t max_queue_depth;
u_int8_t reserved_1[6];
struct qlw_nvram_target target[16];
} __packed;
struct qlw_nvram_1080 {
u_int8_t id[4];
u_int8_t nvram_version;
u_int8_t flags1;
u_int16_t flags2;
u_int8_t reserved_0[8];
u_int8_t isp_config;
u_int8_t termination;
u_int16_t isp_parameter;
u_int16_t fw_features;
u_int16_t reserved_1;
struct qlw_nvram_bus bus[2];
u_int8_t reserved_2[2];
u_int16_t subsystem_vendor_id;
u_int16_t subsystem_device_id;
u_int8_t reserved_3;
u_int8_t checksum;
} __packed;
struct qlw_nvram {
u_int8_t id[4];
u_int8_t nvram_version;
u_int8_t data[251];
};
#define QLW_TARGET_PPR 0x0020
#define QLW_TARGET_ASYNC 0x0040
#define QLW_TARGET_NARROW 0x0080
#define QLW_TARGET_RENEG 0x0100
#define QLW_TARGET_QFRZ 0x0200
#define QLW_TARGET_ARQ 0x0400
#define QLW_TARGET_TAGS 0x0800
#define QLW_TARGET_SYNC 0x1000
#define QLW_TARGET_WIDE 0x2000
#define QLW_TARGET_PARITY 0x4000
#define QLW_TARGET_DISC 0x8000
#define QLW_TARGET_SAFE 0xc500
#define QLW_TARGET_DEFAULT 0xfd00
#define QLW_IOCB_CMD_HEAD_OF_QUEUE 0x0002
#define QLW_IOCB_CMD_ORDERED_QUEUE 0x0004
#define QLW_IOCB_CMD_SIMPLE_QUEUE 0x0008
#define QLW_IOCB_CMD_NO_DATA 0x0000
#define QLW_IOCB_CMD_READ_DATA 0x0020
#define QLW_IOCB_CMD_WRITE_DATA 0x0040
#define QLW_IOCB_CMD_NO_FAST_POST 0x0080
struct qlw_iocb_hdr {
u_int8_t entry_type;
u_int8_t entry_count;
u_int8_t seqno;
u_int8_t flags;
} __packed;
#define QLW_IOCB_SEGS_PER_CMD 4
#define QLW_IOCB_SEGS_PER_CONT 7
struct qlw_iocb_seg {
u_int32_t seg_addr;
u_int32_t seg_len;
} __packed;
/* IOCB types */
#define QLW_IOCB_CMD_TYPE_0 0x01
#define QLW_IOCB_CONT_TYPE_0 0x02
#define QLW_IOCB_STATUS 0x03
#define QLW_IOCB_MARKER 0x04
struct qlw_iocb_req0 {
struct qlw_iocb_hdr hdr; /* QLW_IOCB_REQ_TYPE0 */
u_int32_t handle;
u_int16_t device;
u_int16_t ccblen;
u_int16_t flags;
u_int16_t reserved;
u_int16_t timeout;
u_int16_t seg_count;
u_int8_t cdb[12];
struct qlw_iocb_seg segs[4];
} __packed;
struct qlw_iocb_cont0 {
struct qlw_iocb_hdr hdr; /* QLW_IOCB_CONT_TYPE_0 */
u_int32_t reserved;
struct qlw_iocb_seg segs[7];
} __packed;
struct qlw_iocb_status {
struct qlw_iocb_hdr hdr;
u_int32_t handle;
u_int16_t scsi_status;
u_int16_t completion;
u_int16_t state_flags;
u_int16_t status_flags;
u_int16_t rsp_len;
u_int16_t sense_len;
u_int32_t resid;
u_int8_t fcp_rsp[8];
u_int8_t sense_data[32];
} __packed;
/* completion */
#define QLW_IOCB_STATUS_COMPLETE 0x0000
#define QLW_IOCB_STATUS_INCOMPLETE 0x0001
#define QLW_IOCB_STATUS_DMA_ERROR 0x0002
#define QLW_IOCB_STATUS_RESET 0x0004
#define QLW_IOCB_STATUS_ABORTED 0x0005
#define QLW_IOCB_STATUS_TIMEOUT 0x0006
#define QLW_IOCB_STATUS_DATA_OVERRUN 0x0007
#define QLW_IOCB_STATUS_DATA_UNDERRUN 0x0015
#define QLW_IOCB_STATUS_QUEUE_FULL 0x001c
#define QLW_IOCB_STATUS_WIDE_FAILED 0x001f
#define QLW_IOCB_STATUS_SYNCXFER_FAILED 0x0020
#define QLW_STATE_GOT_BUS 0x0100
#define QLW_STATE_GOT_TARGET 0x0200
#define QLW_SCSI_STATUS_SENSE_VALID 0x0200
struct qlw_iocb_marker {
struct qlw_iocb_hdr hdr; /* QLW_IOCB_MARKER */
u_int32_t handle;
u_int16_t device;
u_int16_t modifier;
u_int8_t reserved2[52];
} __packed;
#define QLW_IOCB_MARKER_SYNC_ALL 2
|