xref: /openbsd-src/sys/dev/pci/mpii.c (revision 5054e3e78af0749a9bb00ba9a024b3ee2d90290f)
1 /* $OpenBSD: mpii.c,v 1.3 2009/11/05 03:43:18 marco Exp $ */
2 /*
3  * Copyright (c) James Giannoules
4  * Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
5  * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
6  *
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include "bio.h"
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/buf.h>
26 #include <sys/device.h>
27 #include <sys/ioctl.h>
28 #include <sys/proc.h>
29 #include <sys/malloc.h>
30 #include <sys/kernel.h>
31 #include <sys/rwlock.h>
32 #include <sys/sensors.h>
33 
34 #include <machine/bus.h>
35 
36 #include <dev/pci/pcireg.h>
37 #include <dev/pci/pcivar.h>
38 #include <dev/pci/pcidevs.h>
39 
40 #ifdef __sparc64__
41 #include <dev/ofw/openfirm.h>
42 #endif
43 
44 #include <scsi/scsi_all.h>
45 #include <scsi/scsiconf.h>
46 
47 #include <dev/biovar.h>
48 
49 #define MPII_DOORBELL			0x00
50 /* doorbell read bits */
51 #define MPII_DOORBELL_STATE		(0xf<<28) /* ioc state */
52 #define  MPII_DOORBELL_STATE_RESET	(0x0<<28)
53 #define  MPII_DOORBELL_STATE_READY	(0x1<<28)
54 #define  MPII_DOORBELL_STATE_OPER	(0x2<<28)
55 #define  MPII_DOORBELL_STATE_FAULT	(0x4<<28)
56 #define  MPII_DOORBELL_INUSE		(0x1<<27) /* doorbell used */
57 #define MPII_DOORBELL_WHOINIT		(0x7<<24) /* last to reset ioc */
58 #define  MPII_DOORBELL_WHOINIT_NOONE	(0x0<<24) /* not initialized */
59 #define  MPII_DOORBELL_WHOINIT_SYSBIOS	(0x1<<24) /* system bios */
60 #define  MPII_DOORBELL_WHOINIT_ROMBIOS	(0x2<<24) /* rom bios */
61 #define  MPII_DOORBELL_WHOINIT_PCIPEER	(0x3<<24) /* pci peer */
62 #define  MPII_DOORBELL_WHOINIT_DRIVER	(0x4<<24) /* host driver */
63 #define  MPII_DOORBELL_WHOINIT_MANUFACT	(0x5<<24) /* manufacturing */
64 #define MPII_DOORBELL_FAULT		(0xffff<<0) /* fault code */
65 /* doorbell write bits */
66 #define MPII_DOORBELL_FUNCTION_SHIFT	24
67 #define MPII_DOORBELL_FUNCTION_MASK	(0xff << MPII_DOORBELL_FUNCTION_SHIFT)
68 #define MPII_DOORBELL_FUNCTION(x)	\
69     (((x) << MPII_DOORBELL_FUNCTION_SHIFT) & MPII_DOORBELL_FUNCTION_MASK)
70 #define MPII_DOORBELL_DWORDS_SHIFT	16
71 #define MPII_DOORBELL_DWORDS_MASK	(0xff << MPII_DOORBELL_DWORDS_SHIFT)
72 #define MPII_DOORBELL_DWORDS(x)		\
73     (((x) << MPII_DOORBELL_DWORDS_SHIFT) & MPII_DOORBELL_DWORDS_MASK)
74 #define MPII_DOORBELL_DATA_MASK		0xffff
75 
76 #define MPII_WRITESEQ			0x04
77 #define  MPII_WRITESEQ_KEY_VALUE_MASK	0x0000000f /* key value */
78 #define  MPII_WRITESEQ_FLUSH		0x00
79 #define  MPII_WRITESEQ_1		0x0f
80 #define  MPII_WRITESEQ_2		0x04
81 #define  MPII_WRITESEQ_3		0x0b
82 #define  MPII_WRITESEQ_4		0x03
83 #define  MPII_WRITESEQ_5		0x07
84 #define	 MPII_WRITESEQ_6		0x0d
85 
86 #define MPII_HOSTDIAG			0x08
87 #define  MPII_HOSTDIAG_BDS_MASK		0x00001800 /* boot device select */
88 #define   MPII_HOSTDIAG_BDS_DEFAULT 	(0<<11)	/* default address map, flash */
89 #define   MPII_HOSTDIAG_BDS_HCDW	(1<<11)	/* host code and data window */
90 #define  MPII_HOSTDIAG_CLEARFBS		(1<<10) /* clear flash bad sig */
91 #define  MPII_HOSTDIAG_FORCE_HCB_ONBOOT (1<<9)	/* force host controlled boot */
92 #define  MPII_HOSTDIAG_HCB_MODE		(1<<8)	/* host controlled boot mode */
93 #define  MPII_HOSTDIAG_DWRE		(1<<7) 	/* diag reg write enabled */
94 #define  MPII_HOSTDIAG_FBS		(1<<6) 	/* flash bad sig */
95 #define  MPII_HOSTDIAG_RESET_HIST	(1<<5) 	/* reset history */
96 #define  MPII_HOSTDIAG_DIAGWR_EN	(1<<4) 	/* diagnostic write enabled */
97 #define  MPII_HOSTDIAG_RESET_ADAPTER	(1<<2) 	/* reset adapter */
98 #define  MPII_HOSTDIAG_HOLD_IOC_RESET	(1<<1) 	/* hold ioc in reset */
99 #define  MPII_HOSTDIAG_DIAGMEM_EN	(1<<0) 	/* diag mem enable */
100 
101 #define MPII_DIAGRWDATA			0x10
102 
103 #define MPII_DIAGRWADDRLOW		0x14
104 
105 #define MPII_DIAGRWADDRHIGH		0x18
106 
107 #define MPII_INTR_STATUS		0x30
108 #define  MPII_INTR_STATUS_SYS2IOCDB	(1<<31) /* ioc written to by host */
109 #define  MPII_INTR_STATUS_RESET		(1<<30) /* physical ioc reset */
110 #define  MPII_INTR_STATUS_REPLY		(1<<3)	/* reply message interrupt */
111 #define  MPII_INTR_STATUS_IOC2SYSDB	(1<<0) 	/* ioc write to doorbell */
112 
113 #define MPII_INTR_MASK			0x34
114 #define  MPII_INTR_MASK_RESET		(1<<30) /* ioc reset intr mask */
115 #define  MPII_INTR_MASK_REPLY		(1<<3) 	/* reply message intr mask */
116 #define  MPII_INTR_MASK_DOORBELL	(1<<0) 	/* doorbell interrupt mask */
117 
118 #define MPII_DCR_DATA			0x38
119 
120 #define MPII_DCR_ADDRESS		0x3C
121 
122 #define MPII_REPLY_FREE_HOST_INDEX	0x48
123 
124 #define MPII_REPLY_POST_HOST_INDEX	0x6C
125 
126 #define MPII_HCB_SIZE			0x74
127 
128 #define MPII_HCB_ADDRESS_LOW		0x78
129 #define MPII_HCB_ADDRESS_HIGH		0x7C
130 
131 #define MPII_REQ_DESC_POST_LOW		0xC0
132 #define MPII_REQ_DESC_POST_HIGH		0xC4
133 
134 /*
135  * Scatter Gather Lists
136  */
137 
138 #define MPII_SGE_FL_LAST		(0x1<<31) /* last element in segment */
139 #define MPII_SGE_FL_EOB			(0x1<<30) /* last element of buffer */
140 #define MPII_SGE_FL_TYPE		(0x3<<28) /* element type */
141  #define MPII_SGE_FL_TYPE_SIMPLE	(0x1<<28) /* simple element */
142  #define MPII_SGE_FL_TYPE_CHAIN		(0x3<<28) /* chain element */
143  #define MPII_SGE_FL_TYPE_XACTCTX	(0x0<<28) /* transaction context */
144 #define MPII_SGE_FL_LOCAL		(0x1<<27) /* local address */
145 #define MPII_SGE_FL_DIR			(0x1<<26) /* direction */
146  #define MPII_SGE_FL_DIR_OUT		(0x1<<26)
147  #define MPII_SGE_FL_DIR_IN		(0x0<<26)
148 #define MPII_SGE_FL_SIZE		(0x1<<25) /* address size */
149  #define MPII_SGE_FL_SIZE_32		(0x0<<25)
150  #define MPII_SGE_FL_SIZE_64		(0x1<<25)
151 #define MPII_SGE_FL_EOL			(0x1<<24) /* end of list */
152 
153 struct mpii_sge {
154 	u_int32_t		sg_hdr;
155 	u_int32_t		sg_lo_addr;
156 	u_int32_t		sg_hi_addr;
157 } __packed;
158 
159 struct mpii_fw_tce {
160 	u_int8_t		reserved1;
161 	u_int8_t		context_size;
162 	u_int8_t		details_length;
163 	u_int8_t		flags;
164 
165 	u_int32_t		reserved2;
166 
167 	u_int32_t		image_offset;
168 
169 	u_int32_t		image_size;
170 } __packed;
171 
172 /*
173  * Messages
174  */
175 
176 /* functions */
177 #define MPII_FUNCTION_SCSI_IO_REQUEST			(0x00)
178 #define MPII_FUNCTION_SCSI_TASK_MGMT			(0x01)
179 #define MPII_FUNCTION_IOC_INIT				(0x02)
180 #define MPII_FUNCTION_IOC_FACTS				(0x03)
181 #define MPII_FUNCTION_CONFIG				(0x04)
182 #define MPII_FUNCTION_PORT_FACTS			(0x05)
183 #define MPII_FUNCTION_PORT_ENABLE			(0x06)
184 #define MPII_FUNCTION_EVENT_NOTIFICATION		(0x07)
185 #define MPII_FUNCTION_EVENT_ACK				(0x08)
186 #define MPII_FUNCTION_FW_DOWNLOAD			(0x09)
187 #define MPII_FUNCTION_TARGET_CMD_BUFFER_POST		(0x0A)
188 #define MPII_FUNCTION_TARGET_ASSIST			(0x0B)
189 #define MPII_FUNCTION_TARGET_STATUS_SEND		(0x0C)
190 #define MPII_FUNCTION_TARGET_MODE_ABORT			(0x0D)
191 #define MPII_FUNCTION_FW_UPLOAD				(0x12)
192 
193 #define MPII_FUNCTION_RAID_ACTION			(0x15)
194 #define MPII_FUNCTION_RAID_SCSI_IO_PASSTHROUGH		(0x16)
195 
196 #define MPII_FUNCTION_TOOLBOX				(0x17)
197 
198 #define MPII_FUNCTION_SCSI_ENCLOSURE_PROCESSOR		(0x18)
199 
200 #define MPII_FUNCTION_SMP_PASSTHROUGH			(0x1A)
201 #define MPII_FUNCTION_SAS_IO_UNIT_CONTROL		(0x1B)
202 #define MPII_FUNCTION_SATA_PASSTHROUGH			(0x1C)
203 
204 #define MPII_FUNCTION_DIAG_BUFFER_POST			(0x1D)
205 #define MPII_FUNCTION_DIAG_RELEASE			(0x1E)
206 
207 #define MPII_FUNCTION_TARGET_CMD_BUF_BASE_POST		(0x24)
208 #define MPII_FUNCTION_TARGET_CMD_BUF_LIST_POST		(0x25)
209 
210 #define MPII_FUNCTION_IOC_MESSAGE_UNIT_RESET		(0x40)
211 #define MPII_FUNCTION_IO_UNIT_RESET			(0x41)
212 #define MPII_FUNCTION_HANDSHAKE				(0x42)
213 
214 /* request flags fields for request descriptors */
215 #define MPII_REQ_DESCRIPTOR_FLAGS_TYPE_SHIFT		(0x01)
216 #define MPII_REQ_DESCRIPTOR_FLAGS_TYPE_MASK		(0x07 << \
217 					MPII_REQ_DESCRIPTOR_FLAGS_TYPE_SHIFT)
218 #define MPII_REQ_DESCRIPTOR_FLAGS_SCSI_IO		(0x00)
219 #define MPII_REQ_DESCRIPTOR_FLAGS_SCSI_TARGET		(0x02)
220 #define MPII_REQ_DESCRIPTOR_FLAGS_HIGH_PRIORITY		(0x06)
221 #define MPII_REQ_DESCRIPTOR_FLAGS_DEFAULT		(0x08)
222 
223 #define MPII_REQ_DESCRIPTOR_FLAGS_IOC_FIFO_MARKER	(0x01)
224 
225 /* reply flags */
226 #define MPII_REP_FLAGS_CONT			(1<<7) /* continuation reply */
227 
228 #define MPII_REP_IOCSTATUS_AVAIL		(1<<15) /* logging info available */
229 #define MPII_REP_IOCSTATUS			(0x7fff) /* status */
230 
231 /* Common IOCStatus values for all replies */
232 #define  MPII_IOCSTATUS_SUCCESS				(0x0000)
233 #define  MPII_IOCSTATUS_INVALID_FUNCTION		(0x0001)
234 #define  MPII_IOCSTATUS_BUSY				(0x0002)
235 #define  MPII_IOCSTATUS_INVALID_SGL			(0x0003)
236 #define  MPII_IOCSTATUS_INTERNAL_ERROR			(0x0004)
237 #define  MPII_IOCSTATUS_INVALID_VPID			(0x0005)
238 #define  MPII_IOCSTATUS_INSUFFICIENT_RESOURCES		(0x0006)
239 #define  MPII_IOCSTATUS_INVALID_FIELD			(0x0007)
240 #define  MPII_IOCSTATUS_INVALID_STATE			(0x0008)
241 #define  MPII_IOCSTATUS_OP_STATE_NOT_SUPPORTED		(0x0009)
242 /* Config IOCStatus values */
243 #define  MPII_IOCSTATUS_CONFIG_INVALID_ACTION		(0x0020)
244 #define  MPII_IOCSTATUS_CONFIG_INVALID_TYPE		(0x0021)
245 #define  MPII_IOCSTATUS_CONFIG_INVALID_PAGE		(0x0022)
246 #define  MPII_IOCSTATUS_CONFIG_INVALID_DATA		(0x0023)
247 #define  MPII_IOCSTATUS_CONFIG_NO_DEFAULTS		(0x0024)
248 #define  MPII_IOCSTATUS_CONFIG_CANT_COMMIT		(0x0025)
249 /* SCSIIO Reply initiator values */
250 #define  MPII_IOCSTATUS_SCSI_RECOVERED_ERROR		(0x0040)
251 #define  MPII_IOCSTATUS_SCSI_INVALID_DEVHANDLE		(0x0042)
252 #define  MPII_IOCSTATUS_SCSI_DEVICE_NOT_THERE		(0x0043)
253 #define  MPII_IOCSTATUS_SCSI_DATA_OVERRUN		(0x0044)
254 #define  MPII_IOCSTATUS_SCSI_DATA_UNDERRUN		(0x0045)
255 #define  MPII_IOCSTATUS_SCSI_IO_DATA_ERROR		(0x0046)
256 #define  MPII_IOCSTATUS_SCSI_PROTOCOL_ERROR		(0x0047)
257 #define  MPII_IOCSTATUS_SCSI_TASK_TERMINATED		(0x0048)
258 #define  MPII_IOCSTATUS_SCSI_RESIDUAL_MISMATCH		(0x0049)
259 #define  MPII_IOCSTATUS_SCSI_TASK_MGMT_FAILED		(0x004A)
260 #define  MPII_IOCSTATUS_SCSI_IOC_TERMINATED		(0x004B)
261 #define  MPII_IOCSTATUS_SCSI_EXT_TERMINATED		(0x004C)
262 /* For use by SCSI Initiator and SCSI Target end-to-end data protection */
263 #define  MPII_IOCSTATUS_EEDP_GUARD_ERROR		(0x004D)
264 #define  MPII_IOCSTATUS_EEDP_REF_TAG_ERROR		(0x004E)
265 #define  MPII_IOCSTATUS_EEDP_APP_TAG_ERROR		(0x004F)
266 /* SCSI (SPI & FCP) target values */
267 #define  MPII_IOCSTATUS_TARGET_INVALID_IO_INDEX		(0x0062)
268 #define  MPII_IOCSTATUS_TARGET_ABORTED			(0x0063)
269 #define  MPII_IOCSTATUS_TARGET_NO_CONN_RETRYABLE	(0x0064)
270 #define  MPII_IOCSTATUS_TARGET_NO_CONNECTION		(0x0065)
271 #define  MPII_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH	(0x006A)
272 #define  MPII_IOCSTATUS_TARGET_DATA_OFFSET_ERROR	(0x006D)
273 #define  MPII_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA	(0x006E)
274 #define  MPII_IOCSTATUS_TARGET_IU_TOO_SHORT		(0x006F)
275 #define  MPII_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT		(0x0070)
276 #define  MPII_IOCSTATUS_TARGET_NAK_RECEIVED		(0x0071)
277 /* Serial Attached SCSI values */
278 #define  MPII_IOCSTATUS_SAS_SMP_REQUEST_FAILED		(0x0090)
279 #define  MPII_IOCSTATUS_SAS_SMP_DATA_OVERRUN		(0x0091)
280 /* Diagnostic Tools values */
281 #define  MPII_IOCSTATUS_DIAGNOSTIC_RELEASED		(0x00A0)
282 
283 #define MPII_REP_IOCLOGINFO_TYPE			(0xf<<28) /* logging info type */
284 #define MPII_REP_IOCLOGINFO_TYPE_NONE			(0x0<<28)
285 #define MPII_REP_IOCLOGINFO_TYPE_SCSI			(0x1<<28)
286 #define MPII_REP_IOCLOGINFO_TYPE_FC			(0x2<<28)
287 #define MPII_REP_IOCLOGINFO_TYPE_SAS			(0x3<<28)
288 #define MPII_REP_IOCLOGINFO_TYPE_ISCSI			(0x4<<28)
289 #define MPII_REP_IOCLOGINFO_DATA			(0x0fffffff) /* logging info data */
290 
291 /* event notification types */
292 #define MPII_EVENT_NONE					0x00
293 #define MPII_EVENT_LOG_DATA				0x01
294 #define MPII_EVENT_STATE_CHANGE				0x02
295 #define MPII_EVENT_UNIT_ATTENTION			0x03
296 #define MPII_EVENT_IOC_BUS_RESET			0x04
297 #define MPII_EVENT_EXT_BUS_RESET			0x05
298 #define MPII_EVENT_RESCAN				0x06
299 #define MPII_EVENT_LINK_STATUS_CHANGE			0x07
300 #define MPII_EVENT_LOOP_STATE_CHANGE			0x08
301 #define MPII_EVENT_LOGOUT				0x09
302 #define MPII_EVENT_EVENT_CHANGE				0x0a
303 #define MPII_EVENT_INTEGRATED_RAID			0x0b
304 #define MPII_EVENT_SCSI_DEVICE_STATUS_CHANGE		0x0c
305 #define MPII_EVENT_ON_BUS_TIMER_EXPIRED			0x0d
306 #define MPII_EVENT_QUEUE_FULL				0x0e
307 #define MPII_EVENT_SAS_DEVICE_STATUS_CHANGE		0x0f
308 #define MPII_EVENT_SAS_SES				0x10
309 #define MPII_EVENT_PERSISTENT_TABLE_FULL		0x11
310 #define MPII_EVENT_SAS_PHY_LINK_STATUS			0x12
311 #define MPII_EVENT_SAS_DISCOVERY_ERROR			0x13
312 #define MPII_EVENT_IR_RESYNC_UPDATE			0x14
313 #define MPII_EVENT_IR2					0x15
314 #define MPII_EVENT_SAS_DISCOVERY			0x16
315 #define MPII_EVENT_LOG_ENTRY_ADDED			0x21
316 
317 /* messages */
318 
319 #define MPII_WHOINIT_NOONE				0x00
320 #define MPII_WHOINIT_SYSTEM_BIOS			0x01
321 #define MPII_WHOINIT_ROM_BIOS				0x02
322 #define MPII_WHOINIT_PCI_PEER				0x03
323 #define MPII_WHOINIT_HOST_DRIVER			0x04
324 #define MPII_WHOINIT_MANUFACTURER			0x05
325 
326 /* page address fields */
327 #define MPII_PAGE_ADDRESS_FC_BTID	(1<<24)	/* Bus Target ID */
328 
329 /* default messages */
330 
331 struct mpii_msg_request {
332 	u_int8_t		reserved1;
333 	u_int8_t		reserved2;
334 	u_int8_t		chain_offset;
335 	u_int8_t		function;
336 
337 	u_int8_t		reserved3;
338 	u_int8_t		reserved4;
339 	u_int8_t		reserved5;
340 	u_int8_t		msg_flags;
341 
342 	u_int8_t		vp_id;
343 	u_int8_t		vf_id;
344 	u_int16_t		reserved6;
345 } __packed;
346 
347 struct mpii_msg_reply {
348 	u_int16_t		reserved1;
349 	u_int8_t		msg_length;
350 	u_int8_t		function;
351 
352 	u_int16_t		reserved2;
353 	u_int8_t		reserved3;
354 	u_int8_t		msg_flags;
355 
356 	u_int8_t		vp_id;
357 	u_int8_t		vf_if;
358 	u_int16_t		reserved4;
359 
360 	u_int16_t		reserved5;
361 	u_int16_t		ioc_status;
362 
363 	u_int32_t		ioc_loginfo;
364 } __packed;
365 
366 /* ioc init */
367 
368 struct mpii_msg_iocinit_request {
369 	u_int8_t		whoinit;
370 	u_int8_t		reserved1;
371 	u_int8_t		chain_offset;
372 	u_int8_t		function;
373 
374 	u_int16_t		reserved2;
375 	u_int8_t		reserved3;
376 	u_int8_t		msg_flags;
377 
378 	u_int8_t		vp_id;
379 	u_int8_t		vf_id;
380 	u_int16_t		reserved4;
381 
382 	u_int8_t		msg_version_min;
383 	u_int8_t		msg_version_maj;
384 	u_int8_t		hdr_version_unit;
385 	u_int8_t		hdr_version_dev;
386 
387 	u_int32_t		reserved5;
388 
389 	u_int32_t		reserved6;
390 
391 	u_int16_t		reserved7;
392 	u_int16_t		system_request_frame_size;
393 
394 	u_int16_t		reply_descriptor_post_queue_depth;
395 	u_int16_t		reply_free_queue_depth;
396 
397 	u_int32_t		sense_buffer_address_high;
398 
399 	u_int32_t		system_reply_address_high;
400 
401 	u_int64_t		system_request_frame_base_address;
402 
403 	u_int64_t		reply_descriptor_post_queue_address;
404 
405 	u_int64_t		reply_free_queue_address;
406 
407 	u_int64_t		timestamp;
408 
409 } __packed;
410 
411 struct mpii_msg_iocinit_reply {
412 	u_int8_t		whoinit;
413 	u_int8_t		reserved1;
414 	u_int8_t		msg_length;
415 	u_int8_t		function;
416 
417 	u_int16_t		reserved2;
418 	u_int8_t		reserved3;
419 	u_int8_t		msg_flags;
420 
421 	u_int8_t		vp_id;
422 	u_int8_t		vf_id;
423 	u_int16_t		reserved4;
424 
425 	u_int16_t		reserved5;
426 	u_int16_t		ioc_status;
427 
428 	u_int32_t		ioc_loginfo;
429 } __packed;
430 
431 struct mpii_msg_iocfacts_request {
432 	u_int16_t		reserved1;
433 	u_int8_t		chain_offset;
434 	u_int8_t		function;
435 
436 	u_int16_t		reserved2;
437 	u_int8_t		reserved3;
438 	u_int8_t		msg_flags;
439 
440 	u_int8_t		vp_id;
441 	u_int8_t		vf_id;
442 	u_int16_t		reserved4;
443 } __packed;
444 
445 struct mpii_msg_iocfacts_reply {
446 	u_int8_t		msg_version_min;
447 	u_int8_t		msg_version_maj;
448 	u_int8_t		msg_length;
449 	u_int8_t		function;
450 
451 	u_int8_t		header_version_dev;
452 	u_int8_t		header_version_unit;
453 	u_int8_t		ioc_number;
454 	u_int8_t		msg_flags;
455 
456 	u_int8_t		vp_id;
457 	u_int8_t		vf_id;
458 	u_int16_t		reserved1;
459 
460 	u_int16_t		ioc_exceptions;
461 #define MPII_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL	(1<<0)
462 #define MPII_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID	(1<<1)
463 #define MPII_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL		(1<<2)
464 #define MPII_IOCFACTS_EXCEPT_MANUFACT_CHECKSUM_FAIL	(1<<3)
465 #define MPII_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED	(1<<4)
466 #define MPII_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAC	(1<<8)
467 	/* XXX JPG BOOT_STATUS in bits[7:5] */
468 	/* XXX JPG all these #defines need to be fixed up */
469 	u_int16_t		ioc_status;
470 
471 	u_int32_t		ioc_loginfo;
472 
473 	u_int8_t		max_chain_depth;
474 	u_int8_t		whoinit;
475 	u_int8_t		number_of_ports;
476 	u_int8_t		reserved2;
477 
478 	u_int16_t		request_credit;
479 	u_int16_t		product_id;
480 
481 	u_int32_t		ioc_capabilities;
482 #define MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY           (1<<13)
483 #define MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID        (1<<12)
484 #define MPII_IOCFACTS_CAPABILITY_TLR                    (1<<11)
485 #define MPII_IOCFACTS_CAPABILITY_MULTICAST              (1<<8)
486 #define MPII_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET   (1<<7)
487 #define MPII_IOCFACTS_CAPABILITY_EEDP                   (1<<6)
488 #define MPII_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER        (1<<4)
489 #define MPII_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER      (1<<3)
490 #define MPII_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (1<<2)
491 
492 	u_int8_t		fw_version_dev;
493 	u_int8_t		fw_version_unit;
494 	u_int8_t		fw_version_min;
495 	u_int8_t		fw_version_maj;
496 
497 	u_int16_t		ioc_request_frame_size;
498 	u_int16_t		reserved3;
499 
500 	u_int16_t		max_initiators;
501 	u_int16_t		max_targets;
502 
503 	u_int16_t		max_sas_expanders;
504 	u_int16_t		max_enclosures;
505 
506 	u_int16_t		protocol_flags;
507 	u_int16_t		high_priority_credit;
508 
509 	u_int16_t		max_reply_descriptor_post_queue_depth;
510 	u_int8_t		reply_frame_size;
511 	u_int8_t		max_volumes;
512 
513 	u_int16_t		max_dev_handle;
514 	u_int16_t		max_persistent_entries;
515 
516 	u_int32_t		reserved4;
517 
518 } __packed;
519 
520 struct mpii_msg_portfacts_request {
521 	u_int16_t		reserved1;
522 	u_int8_t		chain_offset;
523 	u_int8_t		function;
524 
525 	u_int16_t		reserved2;
526 	u_int8_t		port_number;
527 	u_int8_t		msg_flags;
528 
529 	u_int8_t		vp_id;
530 	u_int8_t		vf_id;
531 	u_int16_t		reserved3;
532 } __packed;
533 
534 struct mpii_msg_portfacts_reply {
535 	u_int16_t		reserved1;
536 	u_int8_t		msg_length;
537 	u_int8_t		function;
538 
539 	u_int16_t		reserved2;
540 	u_int8_t		port_number;
541 	u_int8_t		msg_flags;
542 
543 	u_int8_t		vp_id;
544 	u_int8_t		vf_id;
545 	u_int16_t		reserved3;
546 
547 	u_int16_t		reserved4;
548 	u_int16_t		ioc_status;
549 
550 	u_int32_t		ioc_loginfo;
551 
552 	u_int8_t		reserved5;
553 	u_int8_t		port_type;
554 #define MPII_PORTFACTS_PORTTYPE_INACTIVE		0x00
555 #define MPII_PORTFACTS_PORTTYPE_FC			0x10
556 #define MPII_PORTFACTS_PORTTYPE_ISCSI			0x20
557 #define MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL		0x30
558 #define MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL		0x31
559 	u_int16_t		reserved6;
560 
561 	u_int16_t		max_posted_cmd_buffers;
562 	u_int16_t		reserved7;
563 } __packed;
564 
565 struct mpii_msg_portenable_request {
566 	u_int16_t		reserved1;
567 	u_int8_t		chain_offset;
568 	u_int8_t		function;
569 
570 	u_int8_t		reserved2;
571 	u_int8_t		port_flags;
572 	u_int8_t		reserved3;
573 	u_int8_t		msg_flags;
574 
575 	u_int8_t		vp_id;
576 	u_int8_t		vf_id;
577 	u_int16_t		reserved4;
578 } __packed;
579 
580 struct mpii_msg_portenable_reply {
581 	u_int16_t		reserved1;
582 	u_int8_t		msg_length;
583 	u_int8_t		function;
584 
585 	u_int8_t		reserved2;
586 	u_int8_t		port_flags;
587 	u_int8_t		reserved3;
588 	u_int8_t		msg_flags;
589 
590 	u_int8_t		vp_id;
591 	u_int8_t		vf_id;
592 	u_int16_t		reserved4;
593 
594 	u_int16_t		reserved5;
595 	u_int16_t		ioc_status;
596 
597 	u_int32_t		ioc_loginfo;
598 } __packed;
599 
600 struct mpii_msg_event_request {
601 	u_int16_t		reserved1;
602 	u_int8_t		chain_offset;
603 	u_int8_t		function;
604 
605 	u_int16_t		reserved2;
606 	u_int8_t		reserved3;
607 	u_int8_t		msg_flags;
608 
609 	u_int8_t		vp_id;
610 	u_int8_t		vf_id;
611 	u_int16_t		reserved4;
612 
613 	u_int32_t		reserved5;
614 
615 	u_int32_t		reserved6;
616 
617 	u_int32_t		event_masks[4];
618 
619 	u_int16_t		sas_broadcase_primitive_masks;
620 	u_int16_t		reserved7;
621 
622 	u_int32_t		reserved8;
623 } __packed;
624 
625 struct mpii_msg_event_reply {
626 	u_int16_t		event_data_length;
627 	u_int8_t		msg_length;
628 	u_int8_t		function;
629 
630 	u_int16_t		reserved1;
631 	u_int8_t		ack_required;
632 #define MPII_EVENT_ACK_REQUIRED				(0x01)
633 	u_int8_t		msg_flags;
634 #define MPII_EVENT_FLAGS_REPLY_KEPT			(1<<7)
635 
636 	u_int8_t		vp_id;
637 	u_int8_t		vf_id;
638 	u_int16_t		reserved2;
639 
640 	u_int16_t		reserved3;
641 	u_int16_t		ioc_status;
642 
643 	u_int32_t		ioc_loginfo;
644 
645 	u_int16_t		event;
646 	u_int16_t		reserved4;
647 
648 	u_int32_t		event_context;
649 
650 	/* event data follows */
651 } __packed;
652 
653 /* XXX JPG */
654 struct mpii_evt_change {
655 	u_int8_t		event_state;
656 	u_int8_t		reserved[3];
657 } __packed;
658 
659 /* XXX JPG */
660 struct mpii_evt_sas_phy {
661 	u_int8_t		phy_num;
662 	u_int8_t		link_rates;
663 #define MPII_EVT_SASPHY_LINK_CUR(x)			(((x) & 0xf0) >> 4)
664 #define MPII_EVT_SASPHY_LINK_PREV(x)			((x) & 0x0f)
665 #define MPII_EVT_SASPHY_LINK_ENABLED			0x0
666 #define MPII_EVT_SASPHY_LINK_DISABLED			0x1
667 #define MPII_EVT_SASPHY_LINK_NEGFAIL			0x2
668 #define MPII_EVT_SASPHY_LINK_SATAOOB			0x3
669 #define MPII_EVT_SASPHY_LINK_1_5GBPS			0x8
670 #define MPII_EVT_SASPHY_LINK_3_0GBPS			0x9
671 	u_int16_t		dev_handle;
672 
673 	u_int64_t		sas_addr;
674 } __packed;
675 
676 struct mpii_evt_sas_change {
677 	u_int16_t		task_tag;
678 	u_int8_t		reason;
679 #define MPII_EVT_SASCH_REASON_SMART_DATA		0x05
680 #define MPII_EVT_SASCH_REASON_UNSUPPORTED		0x07
681 #define MPII_EVT_SASCH_REASON_INTERNAL_RESET		0x08
682 #define MPII_EVT_SASCH_REASON_TASK_ABORT_INTERVAL	0x09
683 #define MPII_EVT_SASCH_REASON_ABORT_TASK_SET_INTERVAL	0x0A
684 #define MPII_EVT_SASCH_REASON_CLEAR_TASK_SET_INTERVAL	0x0B
685 #define MPII_EVT_SASCH_REASON_QUERY_TASK_INTERVAL	0x0C
686 #define MPII_EVT_SASCH_REASON_ASYNC_NOTIFICATION	0x0D
687 #define MPII_EVT_SASCH_REASON_CMP_INTERNAL_DEV_RESET	0x0E
688 #define MPII_EVT_SASCH_REASON_CMP_TASK_ABORT_INTERNAL	0x0F
689 #define MPII_EVT_SASCH_REASON_SATA_INIT_FAILURE		0x10
690 	u_int8_t		reserved1;
691 
692 	u_int8_t		asc;
693 	u_int8_t		ascq;
694 	u_int16_t		dev_handle;
695 
696 	u_int32_t		reserved2;
697 
698 	u_int64_t		sas_addr;
699 
700 	u_int16_t		lun[4];
701 } __packed;
702 
703 struct mpii_msg_eventack_request {
704 	u_int16_t		reserved1;
705 	u_int8_t		chain_offset;
706 	u_int8_t		function;
707 
708 	u_int8_t		reserved2[3];
709 	u_int8_t		msg_flags;
710 
711 	u_int8_t		vp_id;
712 	u_int8_t		vf_id;
713 	u_int16_t		reserved3;
714 
715 	u_int16_t		event;
716 	u_int16_t		reserved4;
717 
718 	u_int32_t		event_context;
719 } __packed;
720 
721 struct mpii_msg_eventack_reply {
722 	u_int16_t		reserved1;
723 	u_int8_t		msg_length;
724 	u_int8_t		function;
725 
726 	u_int8_t		reserved2[3];
727 	u_int8_t		msg_flags;
728 
729 	u_int8_t		vp_id;
730 	u_int8_t		vf_id;
731 	u_int16_t		reserved3;
732 
733 	u_int16_t		reserved4;
734 	u_int16_t		ioc_status;
735 
736 	u_int32_t		ioc_loginfo;
737 } __packed;
738 
739 struct mpii_msg_fwupload_request {
740 	u_int8_t		image_type;
741 #define MPII_FWUPLOAD_IMAGETYPE_IOC_FW			(0x00)
742 #define MPII_FWUPLOAD_IMAGETYPE_NV_FW			(0x01)
743 #define MPII_FWUPLOAD_IMAGETYPE_NV_BACKUP		(0x05)
744 #define MPII_FWUPLOAD_IMAGETYPE_NV_MANUFACTURING	(0x06)
745 #define MPII_FWUPLOAD_IMAGETYPE_NV_CONFIG_1		(0x07)
746 #define MPII_FWUPLOAD_IMAGETYPE_NV_CONFIG_2		(0x08)
747 #define MPII_FWUPLOAD_IMAGETYPE_NV_MEGARAID		(0x09)
748 #define MPII_FWUPLOAD_IMAGETYPE_NV_COMPLETE		(0x0A)
749 #define MPII_FWUPLOAD_IMAGETYPE_COMMON_BOOT_BLOCK	(0x0B)
750 	u_int8_t		reserved1;
751 	u_int8_t		chain_offset;
752 	u_int8_t		function;
753 
754 	u_int8_t		reserved2[3];
755 	u_int8_t		msg_flags;
756 
757 	u_int8_t		vp_id;
758 	u_int8_t		vf_id;
759 	u_int16_t		reserved3;
760 
761 	u_int32_t		reserved4;
762 
763 	u_int32_t		reserved5;
764 
765 	struct mpii_fw_tce	tce;
766 
767 	/* followed by an sgl */
768 } __packed;
769 
770 struct mpii_msg_fwupload_reply {
771 	u_int8_t		image_type;
772 	u_int8_t		reserved1;
773 	u_int8_t		msg_length;
774 	u_int8_t		function;
775 
776 	u_int8_t		reserved2[3];
777 	u_int8_t		msg_flags;
778 
779 	u_int8_t		vp_id;
780 	u_int8_t		vf_id;
781 	u_int16_t		reserved3;
782 
783 	u_int16_t		reserved4;
784 	u_int16_t		ioc_status;
785 
786 	u_int32_t		ioc_loginfo;
787 
788 	u_int32_t		actual_image_size;
789 } __packed;
790 
791 struct mpii_msg_scsi_io {
792 	u_int16_t		dev_handle;
793 	u_int8_t		chain_offset;
794 	u_int8_t		function;
795 
796 	u_int16_t		reserved1;
797 	u_int8_t		reserved2;
798 	u_int8_t		msg_flags;
799 
800 	u_int8_t		vp_id;
801 	u_int8_t		vf_id;
802 	u_int16_t		reserved3;
803 
804 	u_int32_t		sense_buffer_low_address;
805 
806 	u_int16_t		sgl_flags;
807 	u_int8_t		sense_buffer_length;
808 	u_int8_t		reserved4;
809 
810 	u_int8_t		sgl_offset0;
811 	u_int8_t		sgl_offset1;
812 	u_int8_t		sgl_offset2;
813 	u_int8_t		sgl_offset3;
814 
815 	u_int32_t		skip_count;
816 
817 	u_int32_t		data_length;
818 
819 	u_int32_t		bidirectional_data_length;
820 
821 	u_int16_t		io_flags;
822 	u_int16_t		eedp_flags;
823 
824 	u_int32_t		eedp_block_size;
825 
826 	u_int32_t		secondary_reference_tag;
827 
828 	u_int16_t		secondary_application_tag;
829 	u_int16_t		application_tag_translation_mask;
830 
831 	u_int16_t		lun[4];
832 
833 /* the following 16 bits are defined in MPI2 as the control field */
834 	u_int8_t		reserved5;
835 	u_int8_t		tagging;
836 #define MPII_SCSIIO_ATTR_SIMPLE_Q			(0x0)
837 #define MPII_SCSIIO_ATTR_HEAD_OF_Q			(0x1)
838 #define MPII_SCSIIO_ATTR_ORDERED_Q			(0x2)
839 #define MPII_SCSIIO_ATTR_ACA_Q				(0x4)
840 #define MPII_SCSIIO_ATTR_UNTAGGED			(0x5)
841 #define MPII_SCSIIO_ATTR_NO_DISCONNECT			(0x7)
842 	u_int8_t		reserved6;
843 	u_int8_t		direction;
844 #define MPII_SCSIIO_DIR_NONE				(0x0)
845 #define MPII_SCSIIO_DIR_WRITE				(0x1)
846 #define MPII_SCSIIO_DIR_READ				(0x2)
847 
848 #define	MPII_CDB_LEN					32
849 	u_int8_t		cdb[MPII_CDB_LEN];
850 
851 	/* followed by an sgl */
852 } __packed;
853 
854 struct mpii_msg_scsi_io_error {
855 	u_int16_t		dev_handle;
856 	u_int8_t		msg_length;
857 	u_int8_t		function;
858 
859 	u_int16_t		reserved1;
860 	u_int8_t		reserved2;
861 	u_int8_t		msg_flags;
862 
863 	u_int8_t		vp_id;
864 	u_int8_t		vf_id;
865 	u_int16_t		reserved3;
866 
867 	u_int8_t		scsi_status;
868 	/* XXX JPG validate this */
869 #if notyet
870 #define MPII_SCSIIO_ERR_STATUS_SUCCESS
871 #define MPII_SCSIIO_ERR_STATUS_CHECK_COND
872 #define MPII_SCSIIO_ERR_STATUS_BUSY
873 #define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE
874 #define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET
875 #define MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT
876 #define MPII_SCSIIO_ERR_STATUS_CMD_TERM
877 #define MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL
878 #define MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE
879 #endif
880 	u_int8_t		scsi_state;
881 #define MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID		(1<<0)
882 #define MPII_SCSIIO_ERR_STATE_AUTOSENSE_FAILED		(1<<1)
883 #define MPII_SCSIIO_ERR_STATE_NO_SCSI_STATUS		(1<<2)
884 #define MPII_SCSIIO_ERR_STATE_TERMINATED		(1<<3)
885 #define MPII_SCSIIO_ERR_STATE_RESPONSE_INFO_VALID	(1<<4)
886 #define MPII_SCSIIO_ERR_STATE_QUEUE_TAG_REJECTED	(0xffff)
887 	u_int16_t		ioc_status;
888 
889 	u_int32_t		ioc_loginfo;
890 
891 	u_int32_t		transfer_count;
892 
893 	u_int32_t		sense_count;
894 
895 	u_int32_t		response_info;
896 
897 	u_int16_t		task_tag;
898 	u_int16_t		reserved4;
899 
900 	u_int32_t		bidirectional_transfer_count;
901 
902 	u_int32_t		reserved5;
903 
904 	u_int32_t		reserved6;
905 } __packed;
906 
907 struct mpii_request_descriptor {
908 	u_int8_t		request_flags;
909 	u_int8_t		vf_id;
910 	u_int16_t		smid;
911 
912 	u_int16_t		lmid;
913 	/*
914 	 * the following field is descriptor type dependent
915 	 *    default - undefined
916 	 *    scsi io - device handle
917 	 *    high priority - reserved
918 	 */
919 	u_int16_t		type_dependent;
920 } __packed;
921 
922 struct mpii_reply_descriptor {
923 	u_int8_t		reply_flags;
924 #define MPII_REPLY_DESCR_FLAGS_TYPE_MASK               (0x0F)
925 #define MPII_REPLY_DESCR_FLAGS_SCSI_IO_SUCCESS         (0x00)
926 #define MPII_REPLY_DESCR_FLAGS_ADDRESS_REPLY           (0x01)
927 #define MPII_REPLY_DESCR_FLAGS_TARGETASSIST_SUCCESS    (0x02)
928 #define MPII_REPLY_DESCR_FLAGS_TARGET_COMMAND_BUFFER   (0x03)
929 #define MPII_REPLY_DESCR_FLAGS_UNUSED                  (0x0F)
930 	u_int8_t		vf_id;
931 	/*
932 	 * the following field is reply descriptor type dependent
933 	 *     default - undefined
934 	 *     scsi io success - smid
935 	 *     address reply - smid
936 	 */
937 	u_int16_t		type_dependent1;
938 
939 	/*
940 	 * the following field is reply descriptor type dependent
941 	 *     default - undefined
942 	 *     scsi io success - bottom 16 bits is task tag
943 	 *     address reply - reply frame address
944 	 */
945 	u_int32_t		type_dependent2;
946 } __packed;
947 
948 struct mpii_request_header {
949 	u_int16_t		function_dependent1;
950 	u_int8_t		chain_offset;
951 	u_int8_t		function;
952 
953 	u_int16_t		function_dependent2;
954 	u_int8_t		function_dependent3;
955 	u_int8_t		message_flags;
956 
957 	u_int8_t		vp_id;
958 	u_int8_t		vf_id;
959 	u_int16_t		reserved;
960 } __packed;
961 
962 /* XXX JPG delete this? */
963 struct mpii_msg_scsi_task_request {
964 	u_int8_t		target_id;
965 	u_int8_t		bus;
966 	u_int8_t		chain_offset;
967 	u_int8_t		function;
968 
969 	u_int8_t		reserved1;
970 	u_int8_t		task_type;
971 #define MPII_MSG_SCSI_TASK_TYPE_ABORT_TASK		(0x01)
972 #define MPII_MSG_SCSI_TASK_TYPE_ABRT_TASK_SET		(0x02)
973 #define MPII_MSG_SCSI_TASK_TYPE_TARGET_RESET		(0x03)
974 #define MPII_MSG_SCSI_TASK_TYPE_RESET_BUS		(0x04)
975 #define MPII_MSG_SCSI_TASK_TYPE_LOGICAL_UNIT_RESET	(0x05)
976 	u_int8_t		reserved2;
977 	u_int8_t		msg_flags;
978 
979 	u_int32_t		msg_context;
980 
981 	u_int16_t		lun[4];
982 
983 	u_int32_t		reserved3[7];
984 
985 	u_int32_t		target_msg_context;
986 } __packed;
987 
988 /* XXX JPG delete this? */
989 struct mpii_msg_scsi_task_reply {
990 	u_int8_t		target_id;
991 	u_int8_t		bus;
992 	u_int8_t		msg_length;
993 	u_int8_t		function;
994 
995 	u_int8_t		response_code;
996 	u_int8_t		task_type;
997 	u_int8_t		reserved1;
998 	u_int8_t		msg_flags;
999 
1000 	u_int32_t		msg_context;
1001 
1002 	u_int16_t		reserved2;
1003 	u_int16_t		ioc_status;
1004 
1005 	u_int32_t		ioc_loginfo;
1006 
1007 	u_int32_t		termination_count;
1008 } __packed;
1009 
1010 struct mpii_cfg_hdr {
1011 	u_int8_t		page_version;
1012 	u_int8_t		page_length;
1013 	u_int8_t		page_number;
1014 	u_int8_t		page_type;
1015 #define MPII_CONFIG_REQ_PAGE_TYPE_ATTRIBUTE		(0xf0)
1016 #define MPI2_CONFIG_PAGEATTR_READ_ONLY              	(0x00)
1017 #define MPI2_CONFIG_PAGEATTR_CHANGEABLE             	(0x10)
1018 #define MPI2_CONFIG_PAGEATTR_PERSISTENT             	(0x20)
1019 
1020 #define MPII_CONFIG_REQ_PAGE_TYPE_MASK			(0x0f)
1021 #define MPII_CONFIG_REQ_PAGE_TYPE_IO_UNIT		(0x00)
1022 #define MPII_CONFIG_REQ_PAGE_TYPE_IOC			(0x01)
1023 #define MPII_CONFIG_REQ_PAGE_TYPE_BIOS			(0x02)
1024 #define MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL		(0x08)
1025 #define MPII_CONFIG_REQ_PAGE_TYPE_MANUFACTURING		(0x09)
1026 #define MPII_CONFIG_REQ_PAGE_TYPE_RAID_PD		(0x0A)
1027 #define MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED		(0x0F)
1028 } __packed;
1029 
1030 struct mpii_ecfg_hdr {
1031 	u_int8_t		page_version;
1032 	u_int8_t		reserved1;
1033 	u_int8_t		page_number;
1034 	u_int8_t		page_type;
1035 
1036 	u_int16_t		ext_page_length;
1037 	u_int8_t		ext_page_type;
1038 	u_int8_t		reserved2;
1039 } __packed;
1040 
1041 struct mpii_msg_config_request {
1042 	u_int8_t		action;
1043 #define MPII_CONFIG_REQ_ACTION_PAGE_HEADER		(0x00)
1044 #define MPII_CONFIG_REQ_ACTION_PAGE_READ_CURRENT	(0x01)
1045 #define MPII_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT	(0x02)
1046 #define MPII_CONFIG_REQ_ACTION_PAGE_DEFAULT		(0x03)
1047 #define MPII_CONFIG_REQ_ACTION_PAGE_WRITE_NVRAM		(0x04)
1048 #define MPII_CONFIG_REQ_ACTION_PAGE_READ_DEFAULT	(0x05)
1049 #define MPII_CONFIG_REQ_ACTION_PAGE_READ_NVRAM		(0x06)
1050 	u_int8_t		sgl_flags;
1051 	u_int8_t		chain_offset;
1052 	u_int8_t		function;
1053 
1054 	u_int16_t		ext_page_len;
1055 	u_int8_t		ext_page_type;
1056 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_IO_UNIT	(0x10)
1057 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_EXPANDER	(0x11)
1058 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_DEVICE		(0x12)
1059 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_PHY		(0x13)
1060 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_LOG		(0x14)
1061 #define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE            	(0x15)
1062 #define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG         	(0x16)
1063 #define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING      	(0x17)
1064 #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT            	(0x18)
1065 	u_int8_t		msg_flags;
1066 
1067 	u_int8_t		vp_id;
1068 	u_int8_t		vf_id;
1069 	u_int16_t		reserved1;
1070 
1071 	u_int32_t		reserved2[2];
1072 
1073 	struct mpii_cfg_hdr	config_header;
1074 
1075 	u_int32_t		page_address;
1076 /* XXX lots of defns here */
1077 
1078 	struct mpii_sge		page_buffer;
1079 } __packed;
1080 
1081 struct mpii_msg_config_reply {
1082 	u_int8_t		action;
1083 	u_int8_t		sgl_flags;
1084 	u_int8_t		msg_length;
1085 	u_int8_t		function;
1086 
1087 	u_int16_t		ext_page_length;
1088 	u_int8_t		ext_page_type;
1089 	u_int8_t		msg_flags;
1090 
1091 	u_int8_t		vp_id;
1092 	u_int8_t		vf_id;
1093 	u_int16_t		reserved1;
1094 
1095 	u_int16_t		reserved2;
1096 	u_int16_t		ioc_status;
1097 
1098 	u_int32_t		ioc_loginfo;
1099 
1100 	struct mpii_cfg_hdr	config_header;
1101 } __packed;
1102 
1103 struct mpii_cfg_manufacturing_pg0 {
1104 	struct mpii_cfg_hdr	config_header;
1105 
1106 	char			chip_name[16];
1107 	char			chip_revision[8];
1108 	char			board_name[16];
1109 	char			board_assembly[16];
1110 	char			board_tracer_number[16];
1111 } __packed;
1112 
1113 struct mpii_cfg_ioc_pg1 {
1114 	struct mpii_cfg_hdr     config_header;
1115 
1116 	u_int32_t       flags;
1117 
1118 	u_int32_t       coalescing_timeout;
1119 #define	MPII_CFG_IOC_1_REPLY_COALESCING			(1<<0)
1120 
1121 	u_int8_t        coalescing_depth;
1122 	u_int8_t        pci_slot_num;
1123 	u_int8_t        pci_bus_num;
1124 	u_int8_t        pci_domain_segment;
1125 
1126 	u_int32_t       reserved1;
1127 
1128 	u_int32_t       reserved2;
1129 } __packed;
1130 
1131 /*
1132 struct mpii_cfg_raid_vol_pg0 {
1133 	u_int8_t		vol_id;
1134 	u_int8_t		vol_bus;
1135 	u_int8_t		vol_ioc;
1136 	u_int8_t		vol_page;
1137 
1138 	u_int8_t		vol_type;
1139 #define MPII_CFG_RAID_TYPE_RAID_IS			(0x00)
1140 #define MPII_CFG_RAID_TYPE_RAID_IME			(0x01)
1141 #define MPII_CFG_RAID_TYPE_RAID_IM			(0x02)
1142 #define MPII_CFG_RAID_TYPE_RAID_5			(0x03)
1143 #define MPII_CFG_RAID_TYPE_RAID_6			(0x04)
1144 #define MPII_CFG_RAID_TYPE_RAID_10			(0x05)
1145 #define MPII_CFG_RAID_TYPE_RAID_50			(0x06)
1146 	u_int8_t		flags;
1147 #define MPII_CFG_RAID_VOL_INACTIVE	(1<<3)
1148 	u_int16_t		reserved;
1149 } __packed;
1150 */
1151 struct mpii_cfg_ioc_pg3 {
1152 	struct mpii_cfg_hdr	config_header;
1153 
1154 	u_int8_t		no_phys_disks;
1155 	u_int8_t		reserved[3];
1156 
1157 	/* followed by a list of mpii_cfg_raid_physdisk structs */
1158 } __packed;
1159 
1160 struct mpii_cfg_ioc_pg8 {
1161 	struct mpii_cfg_hdr	config_header;
1162 
1163 	u_int8_t		num_devs_per_enclosure;
1164 	u_int8_t		reserved1;
1165 	u_int16_t		reserved2;
1166 
1167 	u_int16_t		max_persistent_entries;
1168 	u_int16_t		max_num_physical_mapped_ids;
1169 
1170 	u_int16_t		flags;
1171 	u_int16_t		reserved3;
1172 
1173 	u_int16_t		ir_volume_mapping_flags;
1174 	u_int16_t		reserved4;
1175 
1176 	u_int32_t		reserved5;
1177 } __packed;
1178 
1179 struct mpii_cfg_raid_physdisk {
1180 	u_int8_t		phys_disk_id;
1181 	u_int8_t		phys_disk_bus;
1182 	u_int8_t		phys_disk_ioc;
1183 	u_int8_t		phys_disk_num;
1184 } __packed;
1185 
1186 struct mpii_cfg_fc_port_pg0 {
1187 	struct mpii_cfg_hdr	config_header;
1188 
1189 	u_int32_t		flags;
1190 
1191 	u_int8_t		mpii_port_nr;
1192 	u_int8_t		link_type;
1193 	u_int8_t		port_state;
1194 	u_int8_t		reserved1;
1195 
1196 	u_int32_t		port_id;
1197 
1198 	u_int64_t		wwnn;
1199 
1200 	u_int64_t		wwpn;
1201 
1202 	u_int32_t		supported_service_class;
1203 
1204 	u_int32_t		supported_speeds;
1205 
1206 	u_int32_t		current_speed;
1207 
1208 	u_int32_t		max_frame_size;
1209 
1210 	u_int64_t		fabric_wwnn;
1211 
1212 	u_int64_t		fabric_wwpn;
1213 
1214 	u_int32_t		discovered_port_count;
1215 
1216 	u_int32_t		max_initiators;
1217 
1218 	u_int8_t		max_aliases_supported;
1219 	u_int8_t		max_hard_aliases_supported;
1220 	u_int8_t		num_current_aliases;
1221 	u_int8_t		reserved2;
1222 } __packed;
1223 
1224 struct mpii_cfg_fc_port_pg1 {
1225 	struct mpii_cfg_hdr	config_header;
1226 
1227 	u_int32_t		flags;
1228 
1229 	u_int64_t		noseepromwwnn;
1230 
1231 	u_int64_t		noseepromwwpn;
1232 
1233 	u_int8_t		hard_alpa;
1234 	u_int8_t		link_config;
1235 	u_int8_t		topology_config;
1236 	u_int8_t		alt_connector;
1237 
1238 	u_int8_t		num_req_aliases;
1239 	u_int8_t		rr_tov;
1240 	u_int8_t		initiator_dev_to;
1241 	u_int8_t		initiator_lo_pend_to;
1242 } __packed;
1243 
1244 struct mpii_cfg_fc_device_pg0 {
1245 	struct mpii_cfg_hdr	config_header;
1246 
1247 	u_int64_t		wwnn;
1248 
1249 	u_int64_t		wwpn;
1250 
1251 	u_int32_t		port_id;
1252 
1253 	u_int8_t		protocol;
1254 	u_int8_t		flags;
1255 	u_int16_t		bb_credit;
1256 
1257 	u_int16_t		max_rx_frame_size;
1258 	u_int8_t		adisc_hard_alpa;
1259 	u_int8_t		port_nr;
1260 
1261 	u_int8_t		fc_ph_low_version;
1262 	u_int8_t		fc_ph_high_version;
1263 	u_int8_t		current_target_id;
1264 	u_int8_t		current_bus;
1265 } __packed;
1266 
1267 struct mpii_cfg_raid_vol_pg0 {
1268 	struct mpii_cfg_hdr	config_header;
1269 
1270 	u_int8_t		volume_id;
1271 	u_int8_t		volume_bus;
1272 	u_int8_t		volume_ioc;
1273 	u_int8_t		volume_type;
1274 
1275 	u_int8_t		volume_status;
1276 #define MPII_CFG_RAID_VOL_0_STATUS_ENABLED		(1<<0)
1277 #define MPII_CFG_RAID_VOL_0_STATUS_QUIESCED		(1<<1)
1278 #define MPII_CFG_RAID_VOL_0_STATUS_RESYNCING		(1<<2)
1279 #define MPII_CFG_RAID_VOL_0_STATUS_ACTIVE		(1<<3)
1280 #define MPII_CFG_RAID_VOL_0_STATUS_BADBLOCK_FULL	(1<<4)
1281 	u_int8_t		volume_state;
1282 #define MPII_CFG_RAID_VOL_0_STATE_OPTIMAL		(0x00)
1283 #define MPII_CFG_RAID_VOL_0_STATE_DEGRADED		(0x01)
1284 #define MPII_CFG_RAID_VOL_0_STATE_FAILED		(0x02)
1285 #define MPII_CFG_RAID_VOL_0_STATE_MISSING		(0x03)
1286 	u_int16_t		reserved1;
1287 
1288 	u_int16_t		volume_settings;
1289 #define MPII_CFG_RAID_VOL_0_SETTINGS_WRITE_CACHE_EN	(1<<0)
1290 #define MPII_CFG_RAID_VOL_0_SETTINGS_OFFLINE_SMART_ERR	(1<<1)
1291 #define MPII_CFG_RAID_VOL_0_SETTINGS_OFFLINE_SMART	(1<<2)
1292 #define MPII_CFG_RAID_VOL_0_SETTINGS_AUTO_SWAP		(1<<3)
1293 #define MPII_CFG_RAID_VOL_0_SETTINGS_HI_PRI_RESYNC	(1<<4)
1294 #define MPII_CFG_RAID_VOL_0_SETTINGS_PROD_SUFFIX	(1<<5)
1295 #define MPII_CFG_RAID_VOL_0_SETTINGS_FAST_SCRUB		(1<<6) /* obsolete */
1296 #define MPII_CFG_RAID_VOL_0_SETTINGS_DEFAULTS		(1<<15)
1297 	u_int8_t		hot_spare_pool;
1298 	u_int8_t		reserved2;
1299 
1300 	u_int32_t		max_lba;
1301 
1302 	u_int32_t		reserved3;
1303 
1304 	u_int32_t		stripe_size;
1305 
1306 	u_int32_t		reserved4;
1307 
1308 	u_int32_t		reserved5;
1309 
1310 	u_int8_t		num_phys_disks;
1311 	u_int8_t		data_scrub_rate;
1312 	u_int8_t		resync_rate;
1313 	u_int8_t		inactive_status;
1314 #define MPII_CFG_RAID_VOL_0_INACTIVE_UNKNOWN		(0x00)
1315 #define MPII_CFG_RAID_VOL_0_INACTIVE_STALE_META		(0x01)
1316 #define MPII_CFG_RAID_VOL_0_INACTIVE_FOREIGN_VOL	(0x02)
1317 #define MPII_CFG_RAID_VOL_0_INACTIVE_NO_RESOURCES	(0x03)
1318 #define MPII_CFG_RAID_VOL_0_INACTIVE_CLONED_VOL		(0x04)
1319 #define MPII_CFG_RAID_VOL_0_INACTIVE_INSUF_META		(0x05)
1320 
1321 	/* followed by a list of mpii_cfg_raid_vol_pg0_physdisk structs */
1322 } __packed;
1323 
1324 struct mpii_cfg_raid_vol_pg0_physdisk {
1325 	u_int16_t		reserved;
1326 	u_int8_t		phys_disk_map;
1327 	u_int8_t		phys_disk_num;
1328 } __packed;
1329 
1330 struct mpii_cfg_raid_vol_pg1 {
1331 	struct mpii_cfg_hdr	config_header;
1332 
1333 	u_int8_t		volume_id;
1334 	u_int8_t		volume_bus;
1335 	u_int8_t		volume_ioc;
1336 	u_int8_t		reserved1;
1337 
1338 	u_int8_t		guid[24];
1339 
1340 	u_int8_t		name[32];
1341 
1342 	u_int64_t		wwid;
1343 
1344 	u_int32_t		reserved2;
1345 
1346 	u_int32_t		reserved3;
1347 } __packed;
1348 
1349 struct mpii_cfg_raid_physdisk_pg0 {
1350 	struct mpii_cfg_hdr	config_header;
1351 
1352 	u_int8_t		phys_disk_id;
1353 	u_int8_t		phys_disk_bus;
1354 	u_int8_t		phys_disk_ioc;
1355 	u_int8_t		phys_disk_num;
1356 
1357 	u_int8_t		enc_id;
1358 	u_int8_t		enc_bus;
1359 	u_int8_t		hot_spare_pool;
1360 	u_int8_t		enc_type;
1361 #define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_NONE		(0x0)
1362 #define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_SAFTE		(0x1)
1363 #define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_SES		(0x2)
1364 
1365 	u_int32_t		reserved1;
1366 
1367 	u_int8_t		ext_disk_id[8];
1368 
1369 	u_int8_t		disk_id[16];
1370 
1371 	u_int8_t		vendor_id[8];
1372 
1373 	u_int8_t		product_id[16];
1374 
1375 	u_int8_t		product_rev[4];
1376 
1377 	u_int8_t		info[32];
1378 
1379 	u_int8_t		phys_disk_status;
1380 #define MPII_CFG_RAID_PHYDISK_0_STATUS_OUTOFSYNC	(1<<0)
1381 #define MPII_CFG_RAID_PHYDISK_0_STATUS_QUIESCED		(1<<1)
1382 	u_int8_t		phys_disk_state;
1383 #define MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE		(0x00)
1384 #define MPII_CFG_RAID_PHYDISK_0_STATE_MISSING		(0x01)
1385 #define MPII_CFG_RAID_PHYDISK_0_STATE_INCOMPAT		(0x02)
1386 #define MPII_CFG_RAID_PHYDISK_0_STATE_FAILED		(0x03)
1387 #define MPII_CFG_RAID_PHYDISK_0_STATE_INIT		(0x04)
1388 #define MPII_CFG_RAID_PHYDISK_0_STATE_OFFLINE		(0x05)
1389 #define MPII_CFG_RAID_PHYDISK_0_STATE_HOSTFAIL		(0x06)
1390 #define MPII_CFG_RAID_PHYDISK_0_STATE_OTHER		(0xff)
1391 	u_int16_t		reserved2;
1392 
1393 	u_int32_t		max_lba;
1394 
1395 	u_int8_t		error_cdb_byte;
1396 	u_int8_t		error_sense_key;
1397 	u_int16_t		reserved3;
1398 
1399 	u_int16_t		error_count;
1400 	u_int8_t		error_asc;
1401 	u_int8_t		error_ascq;
1402 
1403 	u_int16_t		smart_count;
1404 	u_int8_t		smart_asc;
1405 	u_int8_t		smart_ascq;
1406 } __packed;
1407 
1408 struct mpii_cfg_raid_physdisk_pg1 {
1409 	struct mpii_cfg_hdr	config_header;
1410 
1411 	u_int8_t		num_phys_disk_paths;
1412 	u_int8_t		phys_disk_num;
1413 	u_int16_t		reserved1;
1414 
1415 	u_int32_t		reserved2;
1416 
1417 	/* followed by mpii_cfg_raid_physdisk_path structs */
1418 } __packed;
1419 
1420 struct mpii_cfg_raid_physdisk_path {
1421 	u_int8_t		phys_disk_id;
1422 	u_int8_t		phys_disk_bus;
1423 	u_int16_t		reserved1;
1424 
1425 	u_int64_t		wwwid;
1426 
1427 	u_int64_t		owner_wwid;
1428 
1429 	u_int8_t		ownder_id;
1430 	u_int8_t		reserved2;
1431 	u_int16_t		flags;
1432 #define MPII_CFG_RAID_PHYDISK_PATH_INVALID	(1<<0)
1433 #define MPII_CFG_RAID_PHYDISK_PATH_BROKEN	(1<<1)
1434 } __packed;
1435 
1436 #define MPII_CFG_SAS_DEV_ADDR_NEXT		(0<<28)
1437 #define MPII_CFG_SAS_DEV_ADDR_BUS		(1<<28)
1438 #define MPII_CFG_SAS_DEV_ADDR_HANDLE		(2<<28)
1439 
1440 struct mpii_cfg_sas_dev_pg0 {
1441 	struct mpii_ecfg_hdr	config_header;
1442 
1443 	u_int16_t		slot;
1444 	u_int16_t		enc_handle;
1445 
1446 	u_int64_t		sas_addr;
1447 
1448 	u_int16_t		parent_dev_handle;
1449 	u_int8_t		phy_num;
1450 	u_int8_t		access_status;
1451 
1452 	u_int16_t		dev_handle;
1453 	u_int8_t		target;
1454 	u_int8_t		bus;
1455 
1456 	u_int32_t		device_info;
1457 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE			(0x7)
1458 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_NONE		(0x0)
1459 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_END		(0x1)
1460 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_EDGE_EXPANDER	(0x2)
1461 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_FANOUT_EXPANDER	(0x3)
1462 #define MPII_CFG_SAS_DEV_0_DEVINFO_SATA_HOST		(1<<3)
1463 #define MPII_CFG_SAS_DEV_0_DEVINFO_SMP_INITIATOR	(1<<4)
1464 #define MPII_CFG_SAS_DEV_0_DEVINFO_STP_INITIATOR	(1<<5)
1465 #define MPII_CFG_SAS_DEV_0_DEVINFO_SSP_INITIATOR	(1<<6)
1466 #define MPII_CFG_SAS_DEV_0_DEVINFO_SATA_DEVICE		(1<<7)
1467 #define MPII_CFG_SAS_DEV_0_DEVINFO_SMP_TARGET		(1<<8)
1468 #define MPII_CFG_SAS_DEV_0_DEVINFO_STP_TARGET		(1<<9)
1469 #define MPII_CFG_SAS_DEV_0_DEVINFO_SSP_TARGET		(1<<10)
1470 #define MPII_CFG_SAS_DEV_0_DEVINFO_DIRECT_ATTACHED	(1<<11)
1471 #define MPII_CFG_SAS_DEV_0_DEVINFO_LSI_DEVICE		(1<<12)
1472 #define MPII_CFG_SAS_DEV_0_DEVINFO_ATAPI_DEVICE		(1<<13)
1473 #define MPII_CFG_SAS_DEV_0_DEVINFO_SEP_DEVICE		(1<<14)
1474 
1475 	u_int16_t		flags;
1476 #define MPII_CFG_SAS_DEV_0_FLAGS_DEV_PRESENT		(1<<0)
1477 #define MPII_CFG_SAS_DEV_0_FLAGS_DEV_MAPPED		(1<<1)
1478 #define MPII_CFG_SAS_DEV_0_FLAGS_DEV_MAPPED_PERSISTENT	(1<<2)
1479 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_PORT_SELECTOR	(1<<3)
1480 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_FUA		(1<<4)
1481 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_NCQ		(1<<5)
1482 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_SMART		(1<<6)
1483 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_LBA48		(1<<7)
1484 #define MPII_CFG_SAS_DEV_0_FLAGS_UNSUPPORTED		(1<<8)
1485 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_SETTINGS		(1<<9)
1486 	u_int8_t		physical_port;
1487 	u_int8_t		reserved;
1488 } __packed;
1489 
1490 struct mpii_cfg_raid_config_pg0 {
1491 	struct	mpii_ecfg_hdr	config_header;
1492 
1493 	u_int8_t		num_hot_spares;
1494 	u_int8_t		num_phys_disks;
1495 	u_int8_t		num_volumes;
1496 	u_int8_t		config_num;
1497 
1498 	u_int32_t		flags;
1499 #define MPII_CFG_RAID_CONFIG_0_FLAGS_NATIVE		(0<<0)
1500 #define MPII_CFG_RAID_CONFIG_0_FLAGS_FOREIGN		(1<<0)
1501 
1502 	u_int32_t		config_guid[6];
1503 
1504 	u_int32_t		reserved1;
1505 
1506 	u_int8_t		num_elements;
1507 	u_int8_t		reserved2[3];
1508 
1509 	/* followed by struct mpii_raid_config_element structs */
1510 } __packed;
1511 
1512 struct mpii_raid_config_element {
1513 	u_int16_t		element_flags;
1514 #define MPII_RAID_CONFIG_ELEMENT_FLAG_VOLUME		(0x0)
1515 #define MPII_RAID_CONFIG_ELEMENT_FLAG_VOLUME_PHYS_DISK	(0x1)
1516 #define	MPII_RAID_CONFIG_ELEMENT_FLAG_HSP_PHYS_DISK	(0x2)
1517 #define MPII_RAID_CONFIG_ELEMENT_ONLINE_CE_PHYS_DISK	(0x3)
1518 	u_int16_t		vol_dev_handle;
1519 
1520 	u_int8_t		hot_spare_pool;
1521 	u_int8_t		phys_disk_num;
1522 	u_int16_t		phys_disk_dev_handle;
1523 } __packed;
1524 
1525 /*#define MPII_DEBUG*/
1526 #ifdef MPII_DEBUG
1527 #define DPRINTF(x...)		do { if (mpii_debug) printf(x); } while(0)
1528 #define DNPRINTF(n,x...)	do { if (mpii_debug & (n)) printf(x); } while(0)
1529 #define	MPII_D_CMD		0x0001
1530 #define	MPII_D_INTR		0x0002
1531 #define	MPII_D_MISC		0x0004
1532 #define	MPII_D_DMA		0x0008
1533 #define	MPII_D_IOCTL		0x0010
1534 #define	MPII_D_RW		0x0020
1535 #define	MPII_D_MEM		0x0040
1536 #define	MPII_D_CCB		0x0080
1537 #define	MPII_D_PPR		0x0100
1538 #define	MPII_D_RAID		0x0200
1539 #define	MPII_D_EVT		0x0400
1540 #define MPII_D_CFG		0x0800
1541 
1542 uint32_t  mpii_debug = 0
1543 		| MPII_D_CMD
1544 		| MPII_D_INTR
1545 		| MPII_D_MISC
1546 		| MPII_D_DMA
1547 		| MPII_D_IOCTL
1548 		| MPII_D_RW
1549 		| MPII_D_MEM
1550 		| MPII_D_CCB
1551 		| MPII_D_PPR
1552 		| MPII_D_RAID
1553 		| MPII_D_EVT
1554 		| MPII_D_CFG
1555 	;
1556 #else
1557 #define DPRINTF(x...)
1558 #define DNPRINTF(n,x...)
1559 #endif
1560 
1561 #define MPII_REQUEST_SIZE	512
1562 #define MPII_REPLY_SIZE		128
1563 #define MPII_REPLY_COUNT	(PAGE_SIZE / MPII_REPLY_SIZE)
1564 
1565 /*
1566  * this is the max number of sge's we can stuff in a request frame:
1567  * sizeof(scsi_io) + sizeof(sense) + sizeof(sge) * 32 = MPII_REQUEST_SIZE
1568  */
1569 #define MPII_MAX_SGL		32
1570 
1571 #define MPII_MAX_REQUEST_CREDIT	500
1572 #define	MPII_MAX_REPLY_POST_QDEPTH 128
1573 
1574 struct mpii_dmamem {
1575 	bus_dmamap_t		mdm_map;
1576 	bus_dma_segment_t	mdm_seg;
1577 	size_t			mdm_size;
1578 	caddr_t			mdm_kva;
1579 };
1580 #define MPII_DMA_MAP(_mdm)	((_mdm)->mdm_map)
1581 #define MPII_DMA_DVA(_mdm)	((_mdm)->mdm_map->dm_segs[0].ds_addr)
1582 #define MPII_DMA_KVA(_mdm)	((void *)(_mdm)->mdm_kva)
1583 
1584 struct mpii_ccb_bundle {
1585 	struct mpii_msg_scsi_io	mcb_io; /* sgl must follow */
1586 	struct mpii_sge		mcb_sgl[MPII_MAX_SGL];
1587 	struct scsi_sense_data	mcb_sense;
1588 } __packed;
1589 
1590 struct mpii_softc;
1591 
1592 struct mpii_rcb {
1593 	void			*rcb_reply;
1594 	u_int32_t		rcb_reply_dva;
1595 };
1596 
1597 struct mpii_ccb {
1598 	struct mpii_softc	*ccb_sc;
1599 	int			ccb_smid;
1600 
1601 	struct scsi_xfer	*ccb_xs;
1602 	bus_dmamap_t		ccb_dmamap;
1603 
1604 	bus_addr_t		ccb_offset;
1605 	void			*ccb_cmd;
1606 	bus_addr_t		ccb_cmd_dva;
1607 	u_int16_t		ccb_dev_handle;
1608 
1609 	volatile enum {
1610 		MPII_CCB_FREE,
1611 		MPII_CCB_READY,
1612 		MPII_CCB_QUEUED
1613 	}			ccb_state;
1614 
1615 	void			(*ccb_done)(struct mpii_ccb *);
1616 	struct mpii_rcb		*ccb_rcb;
1617 
1618 	TAILQ_ENTRY(mpii_ccb)	ccb_link;
1619 };
1620 
1621 TAILQ_HEAD(mpii_ccb_list, mpii_ccb);
1622 
1623 struct mpii_softc {
1624 	struct device		sc_dev;
1625 	struct scsi_link	sc_link;
1626 
1627 	int			sc_flags;
1628 #define MPII_F_RAID		(1<<1)
1629 
1630 	struct scsibus_softc	*sc_scsibus;
1631 
1632 	bus_space_tag_t		sc_iot;
1633 	bus_space_handle_t	sc_ioh;
1634 	bus_size_t		sc_ios;
1635 	bus_dma_tag_t		sc_dmat;
1636 
1637 	u_int8_t		sc_porttype;
1638 	int			sc_request_depth;
1639 	int			sc_num_reply_frames;
1640 	int			sc_reply_free_qdepth;
1641 	int			sc_reply_post_qdepth;
1642 	int			sc_maxchdepth;
1643 	int			sc_first_sgl_len;
1644 	int			sc_chain_len;
1645 	int			sc_max_sgl_len;
1646 	u_int8_t		sc_ir_firmware;
1647 
1648 	int			sc_buswidth;
1649 	int			sc_target;
1650 	int			sc_ioc_number;
1651 	u_int8_t		sc_vf_id;
1652 	u_int8_t		sc_num_ports;
1653 
1654 	struct mpii_ccb		*sc_ccbs;
1655 	struct mpii_ccb_list	sc_ccb_free;
1656 
1657 	struct mpii_dmamem	*sc_requests;
1658 
1659 	struct mpii_dmamem	*sc_replies;
1660 	struct mpii_rcb		*sc_rcbs;
1661 
1662 	struct mpii_dmamem	*sc_reply_postq;
1663 	struct mpii_reply_descriptor	*sc_reply_postq_kva;
1664 	int			sc_reply_post_host_index;
1665 
1666 	struct mpii_dmamem	*sc_reply_freeq;
1667 	int			sc_reply_free_host_index;
1668 
1669 	size_t			sc_fw_len;
1670 	struct mpii_dmamem	*sc_fw;
1671 
1672 	/* scsi ioctl from sd device */
1673 	int			(*sc_ioctl)(struct device *, u_long, caddr_t);
1674 
1675 	struct rwlock		sc_lock;
1676 	struct mpii_cfg_hdr	sc_cfg_hdr;
1677 	struct mpii_cfg_ioc_pg2	*sc_vol_page;
1678 	struct mpii_cfg_raid_vol	*sc_vol_list;
1679 	struct mpii_cfg_raid_vol_pg0 *sc_rpg0;
1680 
1681 	struct ksensor		*sc_sensors;
1682 	struct ksensordev	sc_sensordev;
1683 };
1684 
1685 int	mpii_attach(struct mpii_softc *);
1686 void	mpii_detach(struct mpii_softc *);
1687 int	mpii_intr(void *);
1688 
1689 int	mpii_pci_match(struct device *, void *, void *);
1690 void	mpii_pci_attach(struct device *, struct device *, void *);
1691 int	mpii_pci_detach(struct device *, int);
1692 
1693 struct mpii_pci_softc {
1694 	struct mpii_softc	psc_mpii;
1695 
1696 	pci_chipset_tag_t	psc_pc;
1697 	pcitag_t		psc_tag;
1698 
1699 	void			*psc_ih;
1700 };
1701 
1702 struct cfattach mpii_pci_ca = {
1703 	sizeof(struct mpii_pci_softc), mpii_pci_match, mpii_pci_attach,
1704 	mpii_pci_detach
1705 };
1706 
1707 #define PREAD(s, r)	pci_conf_read((s)->psc_pc, (s)->psc_tag, (r))
1708 #define PWRITE(s, r, v)	pci_conf_write((s)->psc_pc, (s)->psc_tag, (r), (v))
1709 
1710 static const struct pci_matchid mpii_devices[] = {
1711 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2008 }
1712 };
1713 
1714 int
1715 mpii_pci_match(struct device *parent, void *match, void *aux)
1716 {
1717 	return (pci_matchbyid(aux, mpii_devices, nitems(mpii_devices)));
1718 }
1719 
1720 void
1721 mpii_pci_attach(struct device *parent, struct device *self, void *aux)
1722 {
1723 	struct mpii_pci_softc		*psc = (void *)self;
1724 	struct mpii_softc		*sc = &psc->psc_mpii;
1725 	struct pci_attach_args		*pa = aux;
1726 	pcireg_t			memtype;
1727 	int				r;
1728 	pci_intr_handle_t		ih;
1729 	const char			*intrstr;
1730 #ifdef __sparc64__
1731 	int node;
1732 #endif
1733 
1734 	psc->psc_pc = pa->pa_pc;
1735 	psc->psc_tag = pa->pa_tag;
1736 	psc->psc_ih = NULL;
1737 	sc->sc_dmat = pa->pa_dmat;
1738 	sc->sc_ios = 0;
1739 	sc->sc_target = -1;
1740 
1741 	/* find the appropriate memory base */
1742 	for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) {
1743 		memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, r);
1744 		if ((memtype & PCI_MAPREG_TYPE_MASK) == PCI_MAPREG_TYPE_MEM)
1745 			break;
1746 	}
1747 	if (r >= PCI_MAPREG_END) {
1748 		printf(": unable to locate system interface registers\n");
1749 		return;
1750 	}
1751 
1752 	if (pci_mapreg_map(pa, r, memtype, 0, &sc->sc_iot, &sc->sc_ioh,
1753 	    NULL, &sc->sc_ios, 0xFF) != 0) {
1754 		printf(": unable to map system interface registers\n");
1755 		return;
1756 	}
1757 
1758 	/* disable the expansion rom */
1759 	PWRITE(psc, PCI_ROM_REG, PREAD(psc, PCI_ROM_REG) & ~PCI_ROM_ENABLE);
1760 
1761 	/* hook up the interrupt */
1762 	if (pci_intr_map(pa, &ih)) {
1763 		printf(": unable to map interrupt\n");
1764 		goto unmap;
1765 	}
1766 	intrstr = pci_intr_string(psc->psc_pc, ih);
1767 	psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
1768 	    mpii_intr, sc, sc->sc_dev.dv_xname);
1769 	if (psc->psc_ih == NULL) {
1770 		printf(": unable to map interrupt%s%s\n",
1771 		    intrstr == NULL ? "" : " at ",
1772 		    intrstr == NULL ? "" : intrstr);
1773 		goto unmap;
1774 	}
1775 	printf(": %s", intrstr);
1776 
1777 #ifdef __sparc64__
1778 		/*
1779 		 * Walk up the Open Firmware device tree until we find a
1780 		 * "scsi-initiator-id" property.
1781 		 */
1782 		node = PCITAG_NODE(pa->pa_tag);
1783 		while (node) {
1784 			if (OF_getprop(node, "scsi-initiator-id",
1785 			    &sc->sc_target, sizeof(sc->sc_target)) ==
1786 			    sizeof(sc->sc_target))
1787 				break;
1788 			node = OF_parent(node);
1789 #endif
1790 
1791 	if (mpii_attach(sc) != 0) {
1792 		/* error printed by mpii_attach */
1793 		goto deintr;
1794 	}
1795 
1796 	return;
1797 
1798 deintr:
1799 	pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
1800 	psc->psc_ih = NULL;
1801 unmap:
1802 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
1803 	sc->sc_ios = 0;
1804 }
1805 
1806 int
1807 mpii_pci_detach(struct device *self, int flags)
1808 {
1809 	struct mpii_pci_softc		*psc = (struct mpii_pci_softc *)self;
1810 	struct mpii_softc		*sc = &psc->psc_mpii;
1811 
1812 	mpii_detach(sc);
1813 
1814 	if (psc->psc_ih != NULL) {
1815 		pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
1816 		psc->psc_ih = NULL;
1817 	}
1818 	if (sc->sc_ios != 0) {
1819 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
1820 		sc->sc_ios = 0;
1821 	}
1822 
1823 	return (0);
1824 }
1825 
1826 struct cfdriver mpii_cd = {
1827 	NULL,
1828 	"mpii",
1829 	DV_DULL
1830 };
1831 
1832 int		mpii_scsi_cmd(struct scsi_xfer *);
1833 void		mpii_scsi_cmd_done(struct mpii_ccb *);
1834 void		mpii_minphys(struct buf *bp, struct scsi_link *sl);
1835 int		mpii_scsi_probe(struct scsi_link *);
1836 int		mpii_scsi_ioctl(struct scsi_link *, u_long, caddr_t,
1837 		    int, struct proc *);
1838 
1839 struct scsi_adapter mpii_switch = {
1840 	mpii_scsi_cmd,
1841 	mpii_minphys,
1842 	NULL,
1843 	NULL,
1844 	NULL
1845 };
1846 
1847 struct scsi_device mpii_dev = {
1848 	NULL,
1849 	NULL,
1850 	NULL,
1851 	NULL
1852 };
1853 
1854 struct mpii_dmamem 	*mpii_dmamem_alloc(struct mpii_softc *, size_t);
1855 void		mpii_dmamem_free(struct mpii_softc *,
1856 		    struct mpii_dmamem *);
1857 int		mpii_alloc_ccbs(struct mpii_softc *);
1858 struct mpii_ccb *mpii_get_ccb(struct mpii_softc *);
1859 void		mpii_put_ccb(struct mpii_softc *, struct mpii_ccb *);
1860 int		mpii_alloc_replies(struct mpii_softc *);
1861 int		mpii_alloc_queues(struct mpii_softc *);
1862 void		mpii_push_reply(struct mpii_softc *, u_int32_t);
1863 void		mpii_push_replies(struct mpii_softc *);
1864 
1865 void		mpii_start(struct mpii_softc *, struct mpii_ccb *);
1866 int		mpii_complete(struct mpii_softc *, struct mpii_ccb *, int);
1867 int		mpii_poll(struct mpii_softc *, struct mpii_ccb *, int);
1868 int		mpii_reply(struct mpii_softc *);
1869 
1870 void		mpii_init_queues(struct mpii_softc *);
1871 
1872 void		mpii_timeout_xs(void *);
1873 int		mpii_load_xs(struct mpii_ccb *);
1874 
1875 u_int32_t	mpii_read(struct mpii_softc *, bus_size_t);
1876 void		mpii_write(struct mpii_softc *, bus_size_t, u_int32_t);
1877 int		mpii_wait_eq(struct mpii_softc *, bus_size_t, u_int32_t,
1878 		    u_int32_t);
1879 int		mpii_wait_ne(struct mpii_softc *, bus_size_t, u_int32_t,
1880 		    u_int32_t);
1881 
1882 int		mpii_init(struct mpii_softc *);
1883 int		mpii_reset_soft(struct mpii_softc *);
1884 int		mpii_reset_hard(struct mpii_softc *);
1885 
1886 int		mpii_handshake_send(struct mpii_softc *, void *, size_t);
1887 int		mpii_handshake_recv_dword(struct mpii_softc *,
1888 		    u_int32_t *);
1889 int		mpii_handshake_recv(struct mpii_softc *, void *, size_t);
1890 
1891 void		mpii_empty_done(struct mpii_ccb *);
1892 
1893 int		mpii_iocinit(struct mpii_softc *);
1894 int		mpii_iocfacts(struct mpii_softc *);
1895 int		mpii_portfacts(struct mpii_softc *);
1896 int		mpii_portenable(struct mpii_softc *);
1897 int			mpii_cfg_coalescing(struct mpii_softc *);
1898 /*
1899 void		mpii_get_raid(struct mpii_softc *);
1900 int		mpii_fwupload(struct mpii_softc *);
1901 
1902 int		mpii_eventnotify(struct mpii_softc *);
1903 void		mpii_eventnotify_done(struct mpii_ccb *);
1904 void		mpii_eventack(struct mpii_softc *,
1905 		    struct mpii_msg_event_reply *);
1906 void		mpii_eventack_done(struct mpii_ccb *);
1907 void		mpii_evt_sas(void *, void *);
1908 */
1909 int		mpii_req_cfg_header(struct mpii_softc *, u_int8_t,
1910 		    u_int8_t, u_int32_t, int, void *);
1911 int		mpii_req_cfg_page(struct mpii_softc *, u_int32_t, int,
1912 		    void *, int, void *, size_t);
1913 
1914 void		mpii_get_ioc_pg8(struct mpii_softc *);
1915 void		mpii_get_raid_config_pg0(struct mpii_softc *);
1916 
1917 #if NBIO > 0
1918 int		mpii_bio_get_pg0_raid(struct mpii_softc *, int);
1919 int		mpii_ioctl(struct device *, u_long, caddr_t);
1920 int		mpii_ioctl_inq(struct mpii_softc *, struct bioc_inq *);
1921 int		mpii_ioctl_vol(struct mpii_softc *, struct bioc_vol *);
1922 int		mpii_ioctl_disk(struct mpii_softc *, struct bioc_disk *);
1923 int		mpii_ioctl_setstate(struct mpii_softc *, struct bioc_setstate *);
1924 #ifndef SMALL_KERNEL
1925 int		mpii_create_sensors(struct mpii_softc *);
1926 void		mpii_refresh_sensors(void *);
1927 #endif /* SMALL_KERNEL */
1928 #endif /* NBIO > 0 */
1929 
1930 #define DEVNAME(s)		((s)->sc_dev.dv_xname)
1931 
1932 #define dwordsof(s)		(sizeof(s) / sizeof(u_int32_t))
1933 #define dwordn(p, n)		(((u_int32_t *)(p))[(n)])
1934 
1935 #define mpii_read_db(s)		mpii_read((s), MPII_DOORBELL)
1936 #define mpii_write_db(s, v)	mpii_write((s), MPII_DOORBELL, (v))
1937 #define mpii_read_intr(s)	mpii_read((s), MPII_INTR_STATUS)
1938 #define mpii_write_intr(s, v)	mpii_write((s), MPII_INTR_STATUS, (v))
1939 #define mpii_reply_waiting(s)	((mpii_read_intr((s)) & MPII_INTR_STATUS_REPLY)\
1940 				    == MPII_INTR_STATUS_REPLY)
1941 
1942 #define mpii_read_reply_free(s, v)	mpii_read((s), \
1943 						MPII_REPLY_FREE_HOST_INDEX)
1944 #define mpii_write_reply_free(s, v)	mpii_write((s), \
1945 						MPII_REPLY_FREE_HOST_INDEX, (v))
1946 #define mpii_read_reply_post(s, v)	mpii_read((s), \
1947 						MPII_REPLY_POST_HOST_INDEX)
1948 #define mpii_write_reply_post(s, v)	mpii_write((s), \
1949 						MPII_REPLY_POST_HOST_INDEX, (v))
1950 
1951 #define mpii_wait_db_int(s)	mpii_wait_ne((s), MPII_INTR_STATUS, \
1952 				    MPII_INTR_STATUS_IOC2SYSDB, 0)
1953 #define mpii_wait_db_ack(s)	mpii_wait_eq((s), MPII_INTR_STATUS, \
1954 				    MPII_INTR_STATUS_SYS2IOCDB, 0)
1955 
1956 #define mpii_cfg_header(_s, _t, _n, _a, _h) \
1957     mpii_req_cfg_header((_s), (_t), (_n), (_a), 0, (_h))
1958 #define mpii_ecfg_header(_s, _t, _n, _a, _h) \
1959     mpii_req_cfg_header((_s), (_t), (_n), (_a), 1, (_h))
1960 
1961 #define mpii_cfg_page(_s, _a, _h, _r, _p, _l) \
1962     mpii_req_cfg_page((_s), (_a), 0, (_h), (_r), (_p), (_l))
1963 #define mpii_ecfg_page(_s, _a, _h, _r, _p, _l) \
1964     mpii_req_cfg_page((_s), (_a), 1, (_h), (_r), (_p), (_l))
1965 
1966 int
1967 mpii_attach(struct mpii_softc *sc)
1968 {
1969 	struct scsibus_attach_args	saa;
1970 	struct mpii_ccb			*ccb;
1971 
1972 	printf("\n");
1973 
1974 	/* disable interrupts */
1975 	mpii_write(sc, MPII_INTR_MASK,
1976 	    MPII_INTR_MASK_RESET | MPII_INTR_MASK_REPLY
1977 	    | MPII_INTR_MASK_DOORBELL);
1978 
1979 	if (mpii_init(sc) != 0) {
1980 		printf("%s: unable to initialize ioc\n", DEVNAME(sc));
1981 		return (1);
1982 	}
1983 
1984 	if (mpii_iocfacts(sc) != 0) {
1985 		printf("%s: unable to get iocfacts\n", DEVNAME(sc));
1986 		return (1);
1987 	}
1988 
1989 	if (mpii_alloc_ccbs(sc) != 0) {
1990 		/* error already printed */
1991 		return(1);
1992 	}
1993 
1994 	if (mpii_alloc_replies(sc) != 0) {
1995 		printf("%s: unable to allocated reply space\n", DEVNAME(sc));
1996 		goto free_ccbs;
1997 	}
1998 
1999 	if (mpii_alloc_queues(sc) != 0) {
2000 		printf("%s: unable to allocate reply queues\n", DEVNAME(sc));
2001 		goto free_replies;
2002 	}
2003 
2004 	if (mpii_iocinit(sc) != 0) {
2005 		printf("%s: unable to send iocinit\n", DEVNAME(sc));
2006 		goto free_ccbs;
2007 	}
2008 
2009 	if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2010 	    MPII_DOORBELL_STATE_OPER) != 0) {
2011 		printf("%s: state: 0x%08x\n", DEVNAME(sc),
2012 			mpii_read_db(sc) & MPII_DOORBELL_STATE);
2013 		printf("%s: operational state timeout\n", DEVNAME(sc));
2014 		goto free_ccbs;
2015 	}
2016 
2017 	mpii_push_replies(sc);
2018 	mpii_init_queues(sc);
2019 
2020 	if (mpii_portfacts(sc) != 0) {
2021 		printf("%s: unable to get portfacts\n", DEVNAME(sc));
2022 		goto free_replies;
2023 	}
2024 
2025 	if (mpii_portenable(sc) != 0) {
2026 		printf("%s: unable to enable port\n", DEVNAME(sc));
2027 		goto free_replies;
2028 	}
2029 
2030 	mpii_get_ioc_pg8(sc);
2031 	mpii_get_raid_config_pg0(sc);
2032 
2033 	if (mpii_cfg_coalescing(sc) != 0)
2034 		/* this is fatal in mpi */
2035 		printf("%s: unable to configure coalescing\n", DEVNAME(sc));
2036 
2037 	/* XXX JPG not yet implemented
2038 	if (mpii_fwupload(sc) != 0) {
2039 		printf("%s: unabel to upload firmware\n", DEVNAME(sc));
2040 		goto free_replies;
2041 	}*/
2042 
2043 	rw_init(&sc->sc_lock, "mpii_lock");
2044 
2045 	/* we should be good to go now, attach scsibus */
2046 	sc->sc_link.device = &mpii_dev;
2047 	sc->sc_link.adapter = &mpii_switch;
2048 	sc->sc_link.adapter_softc = sc;
2049 	sc->sc_link.adapter_target = sc->sc_target;
2050 	sc->sc_link.adapter_buswidth = sc->sc_buswidth;
2051 	sc->sc_link.openings = sc->sc_request_depth / sc->sc_buswidth;
2052 
2053 	bzero(&saa, sizeof(saa));
2054 	saa.saa_sc_link = &sc->sc_link;
2055 
2056 	/* config_found() returns the scsibus attached to us */
2057 	sc->sc_scsibus = (struct scsibus_softc *) config_found(&sc->sc_dev,
2058 		&saa, scsiprint);
2059 
2060 	/* XXX JPG here we need to:
2061 	 *
2062 	 *   get raid pages
2063 	 *   do whatever is necessary for MPI2 host mapping
2064 	 *   update our array/RB tree for target -> dev_handle mapping
2065 	 */
2066 
2067 	/* enable interrupts */
2068 	mpii_write(sc, MPII_INTR_MASK, MPII_INTR_MASK_DOORBELL
2069 	    | MPII_INTR_MASK_RESET);
2070 
2071 	return (0);
2072 
2073 free_replies:
2074 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
2075 		0, PAGE_SIZE, BUS_DMASYNC_POSTREAD);
2076 	mpii_dmamem_free(sc, sc->sc_replies);
2077 
2078 free_ccbs:
2079 	while ((ccb = mpii_get_ccb(sc)) != NULL)
2080 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2081 	mpii_dmamem_free(sc, sc->sc_requests);
2082 	free(sc->sc_ccbs, M_DEVBUF);
2083 
2084 	return(1);
2085 }
2086 
2087 void
2088 mpii_detach(struct mpii_softc *sc)
2089 {
2090 
2091 }
2092 
2093 int
2094 mpii_intr(void *arg)
2095 {
2096 	struct mpii_softc	*sc = arg;
2097 
2098 	if (mpii_reply(sc) < 0)
2099 		return (0);
2100 
2101 	while (mpii_reply(sc) >= 0)
2102 		;
2103 
2104 	mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
2105 
2106 	return (1);
2107 }
2108 
2109 void
2110 mpii_timeout_xs(void *arg)
2111 {
2112 /* XXX */
2113 }
2114 
2115 int
2116 mpii_load_xs(struct mpii_ccb *ccb)
2117 {
2118 	struct mpii_softc	*sc = ccb->ccb_sc;
2119 	struct scsi_xfer	*xs = ccb->ccb_xs;
2120 	struct mpii_ccb_bundle	*mcb = ccb->ccb_cmd;
2121 	struct mpii_msg_scsi_io	*io = &mcb->mcb_io;
2122 	struct mpii_sge		*sge, *nsge = &mcb->mcb_sgl[0];
2123 	struct mpii_sge		*ce = NULL, *nce;
2124 	u_int64_t		ce_dva;
2125 	bus_dmamap_t		dmap = ccb->ccb_dmamap;
2126 	u_int32_t		addr, flags;
2127 	int			i, error;
2128 
2129 	/* zero length transfer still requires an SGE */
2130 	if (xs->datalen == 0) {
2131 		nsge->sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
2132 		    MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
2133 		return (0);
2134 	}
2135 
2136 	error = bus_dmamap_load(sc->sc_dmat, dmap,
2137 	    xs->data, xs->datalen, NULL,
2138 	    (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
2139 	if (error) {
2140 		printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
2141 		return (1);
2142 	}
2143 
2144 	/* safe default staring flags */
2145 	flags = MPII_SGE_FL_TYPE_SIMPLE | MPII_SGE_FL_SIZE_64;
2146 	/* if data out */
2147 	if (xs->flags & SCSI_DATA_OUT)
2148 		flags |= MPII_SGE_FL_DIR_OUT;
2149 
2150 	/* we will have to exceed the SGEs we can cram into the request frame */
2151 	if (dmap->dm_nsegs > sc->sc_first_sgl_len) {
2152 		ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1];
2153 		io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4;
2154 	}
2155 
2156 	for (i = 0; i < dmap->dm_nsegs; i++) {
2157 
2158 		if (nsge == ce) {
2159 			nsge++;
2160 			sge->sg_hdr |= htole32(MPII_SGE_FL_LAST);
2161 
2162 			DNPRINTF(MPII_D_DMA, "%s:   - 0x%08x 0x%08x 0x%08x\n",
2163 			    DEVNAME(sc), sge->sg_hdr,
2164 			    sge->sg_hi_addr, sge->sg_lo_addr);
2165 
2166 			if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
2167 				nce = &nsge[sc->sc_chain_len - 1];
2168 				addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
2169 				addr = addr << 16 |
2170 				    sizeof(struct mpii_sge) * sc->sc_chain_len;
2171 			} else {
2172 				nce = NULL;
2173 				addr = sizeof(struct mpii_sge) *
2174 				    (dmap->dm_nsegs - i);
2175 			}
2176 
2177 			ce->sg_hdr = htole32(MPII_SGE_FL_TYPE_CHAIN |
2178 			    MPII_SGE_FL_SIZE_64 | addr);
2179 
2180 			ce_dva = ccb->ccb_cmd_dva +
2181 			    ((u_int8_t *)nsge - (u_int8_t *)mcb);
2182 
2183 			addr = (u_int32_t)(ce_dva >> 32);
2184 			ce->sg_hi_addr = htole32(addr);
2185 			addr = (u_int32_t)ce_dva;
2186 			ce->sg_lo_addr = htole32(addr);
2187 
2188 			DNPRINTF(MPII_D_DMA, "%s:  ce: 0x%08x 0x%08x 0x%08x\n",
2189 			    DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr,
2190 			    ce->sg_lo_addr);
2191 
2192 			ce = nce;
2193 		}
2194 
2195 		DNPRINTF(MPII_D_DMA, "%s:  %d: %d 0x%016llx\n", DEVNAME(sc),
2196 		    i, dmap->dm_segs[i].ds_len,
2197 		    (u_int64_t)dmap->dm_segs[i].ds_addr);
2198 
2199 		sge = nsge;
2200 
2201 		sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len);
2202 		addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32);
2203 		sge->sg_hi_addr = htole32(addr);
2204 		addr = (u_int32_t)dmap->dm_segs[i].ds_addr;
2205 		sge->sg_lo_addr = htole32(addr);
2206 
2207 		DNPRINTF(MPII_D_DMA, "%s:  %d: 0x%08x 0x%08x 0x%08x\n",
2208 		    DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr,
2209 		    sge->sg_lo_addr);
2210 
2211 		nsge = sge + 1;
2212 	}
2213 
2214 	/* terminate list */
2215 	sge->sg_hdr |= htole32(MPII_SGE_FL_LAST | MPII_SGE_FL_EOB |
2216 	    MPII_SGE_FL_EOL);
2217 
2218 	bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
2219 	    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
2220 	    BUS_DMASYNC_PREWRITE);
2221 
2222 	return (0);
2223 }
2224 
2225 void
2226 mpii_minphys(struct buf *bp, struct scsi_link *sl)
2227 {
2228 	/* XXX */
2229 	minphys(bp);
2230 }
2231 
2232 u_int32_t
2233 mpii_read(struct mpii_softc *sc, bus_size_t r)
2234 {
2235 	u_int32_t			rv;
2236 
2237 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2238 	    BUS_SPACE_BARRIER_READ);
2239 	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
2240 
2241 	DNPRINTF(MPII_D_RW, "%s: mpii_read %#x %#x\n", DEVNAME(sc), r, rv);
2242 
2243 	return (rv);
2244 }
2245 
2246 void
2247 mpii_write(struct mpii_softc *sc, bus_size_t r, u_int32_t v)
2248 {
2249 	DNPRINTF(MPII_D_RW, "%s: mpii_write %#x %#x\n", DEVNAME(sc), r, v);
2250 
2251 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
2252 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2253 	    BUS_SPACE_BARRIER_WRITE);
2254 }
2255 
2256 
2257 int
2258 mpii_wait_eq(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
2259     u_int32_t target)
2260 {
2261 	int			i;
2262 
2263 	DNPRINTF(MPII_D_RW, "%s: mpii_wait_eq %#x %#x %#x\n", DEVNAME(sc), r,
2264 	    mask, target);
2265 
2266 	for (i = 0; i < 10000; i++) {
2267 		if ((mpii_read(sc, r) & mask) == target)
2268 			return (0);
2269 		delay(1000);
2270 	}
2271 
2272 	return (1);
2273 }
2274 
2275 int
2276 mpii_wait_ne(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
2277     u_int32_t target)
2278 {
2279 	int			i;
2280 
2281 	DNPRINTF(MPII_D_RW, "%s: mpii_wait_ne %#x %#x %#x\n", DEVNAME(sc), r,
2282 	    mask, target);
2283 
2284 	for (i = 0; i < 10000; i++) {
2285 		if ((mpii_read(sc, r) & mask) != target)
2286 			return (0);
2287 		delay(1000);
2288 	}
2289 
2290 	return (1);
2291 }
2292 
2293 
2294 int
2295 mpii_init(struct mpii_softc *sc)
2296 {
2297 	u_int32_t		db;
2298 	int			i;
2299 
2300 	/* spin until the ioc leaves the reset state */
2301 	if (mpii_wait_ne(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2302 	    MPII_DOORBELL_STATE_RESET) != 0) {
2303 		DNPRINTF(MPII_D_MISC, "%s: mpii_init timeout waiting to leave "
2304 		    "reset state\n", DEVNAME(sc));
2305 		return (1);
2306 	}
2307 
2308 	/* check current ownership */
2309 	db = mpii_read_db(sc);
2310 	if ((db & MPII_DOORBELL_WHOINIT) == MPII_DOORBELL_WHOINIT_PCIPEER) {
2311 		DNPRINTF(MPII_D_MISC, "%s: mpii_init initialised by pci peer\n",
2312 		    DEVNAME(sc));
2313 		return (0);
2314 	}
2315 
2316 	for (i = 0; i < 5; i++) {
2317 		switch (db & MPII_DOORBELL_STATE) {
2318 		case MPII_DOORBELL_STATE_READY:
2319 			DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is ready\n",
2320 			    DEVNAME(sc));
2321 			return (0);
2322 
2323 		case MPII_DOORBELL_STATE_OPER:
2324 		case MPII_DOORBELL_STATE_FAULT:
2325 			DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is being "
2326 			    "reset\n" , DEVNAME(sc));
2327 			if (mpii_reset_soft(sc) != 0)
2328 				mpii_reset_hard(sc);
2329 			break;
2330 
2331 		case MPII_DOORBELL_STATE_RESET:
2332 			DNPRINTF(MPII_D_MISC, "%s: mpii_init waiting to come "
2333 			    "out of reset\n", DEVNAME(sc));
2334 			if (mpii_wait_ne(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2335 			    MPII_DOORBELL_STATE_RESET) != 0)
2336 				return (1);
2337 			break;
2338 		}
2339 		db = mpii_read_db(sc);
2340 	}
2341 
2342 	return (1);
2343 }
2344 
2345 int
2346 mpii_reset_soft(struct mpii_softc *sc)
2347 {
2348 	DNPRINTF(MPII_D_MISC, "%s: mpii_reset_soft\n", DEVNAME(sc));
2349 
2350 	if (mpii_read_db(sc) & MPII_DOORBELL_INUSE) {
2351 		printf("db in use\n");
2352 		return (1);
2353 	}
2354 
2355 	mpii_write_db(sc,
2356 	    MPII_DOORBELL_FUNCTION(MPII_FUNCTION_IOC_MESSAGE_UNIT_RESET));
2357 
2358 	/* XXX LSI waits 15 sec */
2359 	if (mpii_wait_db_ack(sc) != 0)
2360 		return (1);
2361 
2362 	/* XXX LSI waits 15 sec */
2363 	if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2364 	    MPII_DOORBELL_STATE_READY) != 0)
2365 		return (1);
2366 
2367 	/* XXX wait for Sys2IOCDB bit to clear in HIS?? */
2368 
2369 	return (0);
2370 }
2371 
2372 int
2373 mpii_reset_hard(struct mpii_softc *sc)
2374 {
2375 	u_int16_t		i;
2376 
2377 	DNPRINTF(MPII_D_MISC, "%s: mpii_reset_hard\n", DEVNAME(sc));
2378 
2379 	mpii_write_intr(sc, 0);
2380 
2381 	/* enable diagnostic register */
2382 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_FLUSH);
2383 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_1);
2384 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_2);
2385 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_3);
2386 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_4);
2387 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_5);
2388 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_6);
2389 
2390 
2391 	delay(100);
2392 
2393 	if ((mpii_read(sc, MPII_HOSTDIAG) & MPII_HOSTDIAG_DWRE) == 0)
2394 		return(1);
2395 
2396 	/* reset ioc */
2397 	mpii_write(sc, MPII_HOSTDIAG, MPII_HOSTDIAG_RESET_ADAPTER);
2398 
2399 	/* 200 milliseconds */
2400 	delay(200000);
2401 
2402 
2403 	/* XXX this whole function should be more robust */
2404 
2405 	/* XXX  read the host diagnostic reg until reset adapter bit clears ? */
2406 	for (i = 0; i < 30000; i++) {
2407 		if ((mpii_read(sc, MPII_HOSTDIAG) &
2408 		    MPII_HOSTDIAG_RESET_ADAPTER) == 0)
2409 			break;
2410 		delay(10000);
2411 	}
2412 
2413 	/* disable diagnostic register */
2414 	mpii_write(sc, MPII_WRITESEQ, 0xff);
2415 
2416 	/* XXX what else? */
2417 
2418 	DNPRINTF(MPII_D_MISC, "%s: done with mpii_reset_hard\n", DEVNAME(sc));
2419 
2420 	return(0);
2421 }
2422 
2423 int
2424 mpii_handshake_send(struct mpii_softc *sc, void *buf, size_t dwords)
2425 {
2426 	u_int32_t		*query = buf;
2427 	int			i;
2428 
2429 	/* make sure the doorbell is not in use. */
2430 	if (mpii_read_db(sc) & MPII_DOORBELL_INUSE)
2431 		return (1);
2432 
2433 	/* clear pending doorbell interrupts */
2434 	if (mpii_read_intr(sc) & MPII_INTR_STATUS_IOC2SYSDB)
2435 		mpii_write_intr(sc, 0);
2436 
2437 	/*
2438 	 * first write the doorbell with the handshake function and the
2439 	 * dword count.
2440 	 */
2441 	mpii_write_db(sc, MPII_DOORBELL_FUNCTION(MPII_FUNCTION_HANDSHAKE) |
2442 	    MPII_DOORBELL_DWORDS(dwords));
2443 
2444 	/*
2445 	 * the doorbell used bit will be set because a doorbell function has
2446 	 * started. wait for the interrupt and then ack it.
2447 	 */
2448 	if (mpii_wait_db_int(sc) != 0)
2449 		return (1);
2450 	mpii_write_intr(sc, 0);
2451 
2452 	/* poll for the acknowledgement. */
2453 	if (mpii_wait_db_ack(sc) != 0)
2454 		return (1);
2455 
2456 	/* write the query through the doorbell. */
2457 	for (i = 0; i < dwords; i++) {
2458 		mpii_write_db(sc, htole32(query[i]));
2459 		if (mpii_wait_db_ack(sc) != 0)
2460 			return (1);
2461 	}
2462 
2463 	return (0);
2464 }
2465 
2466 int
2467 mpii_handshake_recv_dword(struct mpii_softc *sc, u_int32_t *dword)
2468 {
2469 	u_int16_t		*words = (u_int16_t *)dword;
2470 	int			i;
2471 
2472 	for (i = 0; i < 2; i++) {
2473 		if (mpii_wait_db_int(sc) != 0)
2474 			return (1);
2475 		words[i] = letoh16(mpii_read_db(sc) & MPII_DOORBELL_DATA_MASK);
2476 		mpii_write_intr(sc, 0);
2477 	}
2478 
2479 	return (0);
2480 }
2481 
2482 int
2483 mpii_handshake_recv(struct mpii_softc *sc, void *buf, size_t dwords)
2484 {
2485 	struct mpii_msg_reply	*reply = buf;
2486 	u_int32_t		*dbuf = buf, dummy;
2487 	int			i;
2488 
2489 	/* get the first dword so we can read the length out of the header. */
2490 	if (mpii_handshake_recv_dword(sc, &dbuf[0]) != 0)
2491 		return (1);
2492 
2493 	DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dwords: %d reply: %d\n",
2494 	    DEVNAME(sc), dwords, reply->msg_length);
2495 
2496 	/*
2497 	 * the total length, in dwords, is in the message length field of the
2498 	 * reply header.
2499 	 */
2500 	for (i = 1; i < MIN(dwords, reply->msg_length); i++) {
2501 		if (mpii_handshake_recv_dword(sc, &dbuf[i]) != 0)
2502 			return (1);
2503 	}
2504 
2505 	/* if there's extra stuff to come off the ioc, discard it */
2506 	while (i++ < reply->msg_length) {
2507 		if (mpii_handshake_recv_dword(sc, &dummy) != 0)
2508 			return (1);
2509 		DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dummy read: "
2510 		    "0x%08x\n", DEVNAME(sc), dummy);
2511 	}
2512 
2513 	/* wait for the doorbell used bit to be reset and clear the intr */
2514 	if (mpii_wait_db_int(sc) != 0)
2515 		return (1);
2516 
2517 	if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_INUSE, 0) != 0)
2518 		return (1);
2519 
2520 	mpii_write_intr(sc, 0);
2521 
2522 	return (0);
2523 }
2524 
2525 void
2526 mpii_empty_done(struct mpii_ccb *ccb)
2527 {
2528 	/* nothing to do */
2529 }
2530 
2531 int
2532 mpii_iocfacts(struct mpii_softc *sc)
2533 {
2534 	struct mpii_msg_iocfacts_request	ifq;
2535 	struct mpii_msg_iocfacts_reply		ifp;
2536 
2537 	DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts\n", DEVNAME(sc));
2538 
2539 	bzero(&ifq, sizeof(ifq));
2540 	bzero(&ifp, sizeof(ifp));
2541 
2542 	ifq.function = MPII_FUNCTION_IOC_FACTS;
2543 
2544 	if (mpii_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) {
2545 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts send failed\n",
2546 		    DEVNAME(sc));
2547 		return (1);
2548 	}
2549 
2550 	if (mpii_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) {
2551 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts recv failed\n",
2552 		    DEVNAME(sc));
2553 		return (1);
2554 	}
2555 
2556 	DNPRINTF(MPII_D_MISC, "%s:  func: 0x%02x length: %d msgver: %d.%d\n",
2557 	    DEVNAME(sc), ifp.function, ifp.msg_length,
2558 	    ifp.msg_version_maj, ifp.msg_version_min);
2559 	DNPRINTF(MPII_D_MISC, "%s:  msgflags: 0x%02x iocnumber: 0x%02x "
2560 	    "headerver: %d.%d\n", DEVNAME(sc), ifp.msg_flags,
2561 	    ifp.ioc_number, ifp.header_version_unit,
2562 	    ifp.header_version_dev);
2563 	DNPRINTF(MPII_D_MISC, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
2564 	    ifp.vp_id, ifp.vf_id);
2565 	DNPRINTF(MPII_D_MISC, "%s:  iocstatus: 0x%04x ioexceptions: 0x%04x\n",
2566 	    DEVNAME(sc), letoh16(ifp.ioc_status),
2567 	    letoh16(ifp.ioc_exceptions));
2568 	DNPRINTF(MPII_D_MISC, "%s:  iocloginfo: 0x%08x\n", DEVNAME(sc),
2569 	    letoh32(ifp.ioc_loginfo));
2570 	DNPRINTF(MPII_D_MISC, "%s:  numberofports: 0x%02x whoinit: 0x%02x "
2571 	    "maxchaindepth: %d\n", DEVNAME(sc), ifp.number_of_ports,
2572 	    ifp.whoinit, ifp.max_chain_depth);
2573 	DNPRINTF(MPII_D_MISC, "%s:  productid: 0x%04x requestcredit: 0x%04x\n",
2574 	    DEVNAME(sc), letoh16(ifp.product_id), letoh16(ifp.request_credit));
2575 	DNPRINTF(MPII_D_MISC, "%s:  ioc_capabilities: 0x%08x\n", DEVNAME(sc),
2576 	    letoh32(ifp.ioc_capabilities));
2577 	DNPRINTF(MPII_D_MISC, "%s:  fw_version: %d.%d fw_version_unit: 0x%02x "
2578 	    "fw_version_dev: 0x%02x\n", DEVNAME(sc),
2579 	    ifp.fw_version_maj, ifp.fw_version_min,
2580 	    ifp.fw_version_unit, ifp.fw_version_dev);
2581 	DNPRINTF(MPII_D_MISC, "%s:  iocrequestframesize: 0x%04x\n",
2582 	    DEVNAME(sc), letoh16(ifp.ioc_request_frame_size));
2583 	DNPRINTF(MPII_D_MISC, "%s:  maxtargets: 0x%04x "
2584 	    "maxinitiators: 0x%04x\n", DEVNAME(sc),
2585 	    letoh16(ifp.max_targets), letoh16(ifp.max_initiators));
2586 	DNPRINTF(MPII_D_MISC, "%s:  maxenclosures: 0x%04x "
2587 	    "maxsasexpanders: 0x%04x\n", DEVNAME(sc),
2588 	    letoh16(ifp.max_enclosures), letoh16(ifp.max_sas_expanders));
2589 	DNPRINTF(MPII_D_MISC, "%s:  highprioritycredit: 0x%04x "
2590 	    "protocolflags: 0x%02x\n", DEVNAME(sc),
2591 	    letoh16(ifp.high_priority_credit), letoh16(ifp.protocol_flags));
2592 	DNPRINTF(MPII_D_MISC, "%s:  maxvolumes: 0x%02x replyframesize: 0x%02x "
2593 	    "mrdpqd: 0x%04x\n", DEVNAME(sc), ifp.max_volumes,
2594 	    ifp.reply_frame_size,
2595 	    letoh16(ifp.max_reply_descriptor_post_queue_depth));
2596 	DNPRINTF(MPII_D_MISC, "%s:  maxpersistententries: 0x%04x "
2597 	    "maxdevhandle: 0x%02x\n", DEVNAME(sc),
2598 	    letoh16(ifp.max_persistent_entries), letoh16(ifp.max_dev_handle));
2599 
2600 	sc->sc_maxchdepth = ifp.max_chain_depth;
2601 	sc->sc_ioc_number = ifp.ioc_number;
2602 	sc->sc_vf_id = ifp.vf_id;
2603 
2604 	/* XXX JPG should this be max targets + max vol from cfg page ?? */
2605 	sc->sc_buswidth = (ifp.max_targets == 0) ? 256 :
2606 	    letoh16(ifp.max_targets);
2607 	sc->sc_num_ports = ifp.number_of_ports;
2608 	sc->sc_ir_firmware = (letoh32(ifp.ioc_capabilities) &
2609 	    MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID) ? 1 : 0;
2610 
2611 	sc->sc_request_depth = MIN(letoh16(ifp.request_credit),
2612 	    MPII_MAX_REQUEST_CREDIT);
2613 
2614 	/* should not be multiple of 16 */
2615 	sc->sc_num_reply_frames = sc->sc_request_depth + 32;
2616 	if (!(sc->sc_num_reply_frames % 16))
2617 		sc->sc_num_reply_frames--;
2618 
2619 	/* must be multiple of 16 */
2620 	sc->sc_reply_free_qdepth = sc->sc_num_reply_frames +
2621 	    (16 - (sc->sc_num_reply_frames % 16));
2622 
2623 	sc->sc_reply_post_qdepth = sc->sc_request_depth +
2624 	    sc->sc_num_reply_frames + 1;
2625 
2626 	if (sc->sc_reply_post_qdepth > MPII_MAX_REPLY_POST_QDEPTH)
2627 		sc->sc_reply_post_qdepth = MPII_MAX_REPLY_POST_QDEPTH;
2628 
2629 	if (sc->sc_reply_post_qdepth >
2630 	    ifp.max_reply_descriptor_post_queue_depth)
2631 		sc->sc_reply_post_qdepth =
2632 		    ifp.max_reply_descriptor_post_queue_depth;
2633 
2634 	/* XXX JPG temporary override of calculated values.
2635 	 *         need to think this through as the specs
2636 	 *         and other existing drivers contradict
2637 	 */
2638 	sc->sc_reply_post_qdepth = 128;
2639 	sc->sc_request_depth = 128;
2640 	sc->sc_num_reply_frames = 63;
2641 	sc->sc_reply_free_qdepth = 64;
2642 
2643 	DNPRINTF(MPII_D_MISC, "%s: sc_request_depth: %d "
2644 	    "sc_num_reply_frames: %d sc_reply_free_qdepth: %d "
2645 	    "sc_reply_post_qdepth: %d\n", DEVNAME(sc), sc->sc_request_depth,
2646 	    sc->sc_num_reply_frames, sc->sc_reply_free_qdepth,
2647 	    sc->sc_reply_post_qdepth);
2648 
2649 	/*
2650 	 * you can fit sg elements on the end of the io cmd if they fit in the
2651 	 * request frame size.
2652 	 */
2653 
2654 	sc->sc_first_sgl_len = ((letoh16(ifp.ioc_request_frame_size) * 4) -
2655 	    sizeof(struct mpii_msg_scsi_io)) / sizeof(struct mpii_sge);
2656 	DNPRINTF(MPII_D_MISC, "%s:   first sgl len: %d\n", DEVNAME(sc),
2657 	    sc->sc_first_sgl_len);
2658 
2659 	sc->sc_chain_len = (letoh16(ifp.ioc_request_frame_size) * 4) /
2660 	    sizeof(struct mpii_sge);
2661 	DNPRINTF(MPII_D_MISC, "%s:   chain len: %d\n", DEVNAME(sc),
2662 	    sc->sc_chain_len);
2663 
2664 	/* the sgl tailing the io cmd loses an entry to the chain element. */
2665 	sc->sc_max_sgl_len = MPII_MAX_SGL - 1;
2666 	/* the sgl chains lose an entry for each chain element */
2667 	sc->sc_max_sgl_len -= (MPII_MAX_SGL - sc->sc_first_sgl_len) /
2668 	    sc->sc_chain_len;
2669 	DNPRINTF(MPII_D_MISC, "%s:   max sgl len: %d\n", DEVNAME(sc),
2670 	    sc->sc_max_sgl_len);
2671 
2672 	/* XXX we're ignoring the max chain depth */
2673 
2674 	return(0);
2675 
2676 }
2677 
2678 int
2679 mpii_iocinit(struct mpii_softc *sc)
2680 {
2681 	struct mpii_msg_iocinit_request		iiq;
2682 	struct mpii_msg_iocinit_reply		iip;
2683 	u_int32_t				hi_addr;
2684 
2685 	DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit\n", DEVNAME(sc));
2686 
2687 	bzero(&iiq, sizeof(iiq));
2688 	bzero(&iip, sizeof(iip));
2689 
2690 	iiq.function = MPII_FUNCTION_IOC_INIT;
2691 	iiq.whoinit = MPII_WHOINIT_HOST_DRIVER;
2692 
2693 	/* XXX JPG do something about vf_id */
2694 	iiq.vf_id = 0;
2695 
2696 	iiq.msg_version_maj = 0x02;
2697 	iiq.msg_version_min = 0x00;
2698 
2699 	/* XXX JPG ensure compliance with some level and hard-code? */
2700 	iiq.hdr_version_unit = 0x00;
2701 	iiq.hdr_version_dev = 0x00;
2702 
2703 	iiq.system_request_frame_size = htole16(MPII_REQUEST_SIZE / 4);
2704 
2705 	iiq.reply_descriptor_post_queue_depth =
2706 	    htole16(sc->sc_reply_post_qdepth);
2707 
2708 	iiq.reply_free_queue_depth = htole16(sc->sc_reply_free_qdepth);
2709 
2710 	hi_addr = (u_int32_t)((u_int64_t)MPII_DMA_DVA(sc->sc_requests) >> 32);
2711 	iiq.sense_buffer_address_high = htole32(hi_addr);
2712 
2713 	hi_addr = (u_int32_t)
2714 	    ((u_int64_t)MPII_DMA_DVA(sc->sc_replies) >> 32);
2715 	iiq.system_reply_address_high = hi_addr;
2716 
2717 	iiq.system_request_frame_base_address =
2718 	    (u_int64_t)MPII_DMA_DVA(sc->sc_requests);
2719 
2720 	iiq.reply_descriptor_post_queue_address =
2721 	    (u_int64_t)MPII_DMA_DVA(sc->sc_reply_postq);
2722 
2723 	iiq.reply_free_queue_address =
2724 	    (u_int64_t)MPII_DMA_DVA(sc->sc_reply_freeq);
2725 
2726 	if (mpii_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) {
2727 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit send failed\n",
2728 		    DEVNAME(sc));
2729 		return (1);
2730 	}
2731 
2732 	if (mpii_handshake_recv(sc, &iip, dwordsof(iip)) != 0) {
2733 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit recv failed\n",
2734 		    DEVNAME(sc));
2735 		return (1);
2736 	}
2737 
2738 	DNPRINTF(MPII_D_MISC, "%s:  function: 0x%02x msg_length: %d "
2739 	    "whoinit: 0x%02x\n", DEVNAME(sc), iip.function,
2740 	    iip.msg_length, iip.whoinit);
2741 	DNPRINTF(MPII_D_MISC, "%s:  msg_flags: 0x%02x\n", DEVNAME(sc),
2742 	    iip.msg_flags);
2743 	DNPRINTF(MPII_D_MISC, "%s:  vf_id: 0x%02x vp_id: 0x%02x\n", DEVNAME(sc),
2744 	    iip.vf_id, iip.vp_id);
2745 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2746 	    letoh16(iip.ioc_status));
2747 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2748 	    letoh32(iip.ioc_loginfo));
2749 
2750 	if ((iip.ioc_status != MPII_IOCSTATUS_SUCCESS) || (iip.ioc_loginfo))
2751 		return (1);
2752 
2753 	return (0);
2754 }
2755 
2756 void
2757 mpii_push_reply(struct mpii_softc *sc, u_int32_t rdva)
2758 {
2759 	u_int32_t		*rfp;
2760 
2761 	rfp = MPII_DMA_KVA(sc->sc_reply_freeq);
2762 	rfp[sc->sc_reply_free_host_index] = rdva;
2763 
2764 	sc->sc_reply_free_host_index = (sc->sc_reply_free_host_index + 1) %
2765 	    sc->sc_reply_free_qdepth;
2766 
2767 	mpii_write_reply_free(sc, sc->sc_reply_free_host_index);
2768 }
2769 
2770 int
2771 mpii_portfacts(struct mpii_softc *sc)
2772 {
2773 	struct mpii_msg_portfacts_request	*pfq;
2774 	struct mpii_msg_portfacts_reply		*pfp;
2775 	int			rv = 1, s;
2776 	struct mpii_ccb		*ccb;
2777 
2778 	DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts\n", DEVNAME(sc));
2779 
2780 	s = splbio();
2781 	ccb = mpii_get_ccb(sc);
2782 	splx(s);
2783 	if (ccb == NULL) {
2784 		DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts mpii_get_ccb fail\n",
2785 		    DEVNAME(sc));
2786 		return (rv);
2787 	}
2788 
2789 	ccb->ccb_done = mpii_empty_done;
2790 	pfq = ccb->ccb_cmd;
2791 
2792 	bzero(pfq, sizeof(struct mpii_msg_portfacts_request));
2793 
2794 	pfq->function = MPII_FUNCTION_PORT_FACTS;
2795 	pfq->chain_offset = 0;
2796 	pfq->msg_flags = 0;
2797 	pfq->port_number = 0;
2798 	pfq->vp_id = 0;
2799 	pfq->vf_id = 0;
2800 
2801 	if (mpii_poll(sc, ccb, 50000) != 0) {
2802 		DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts poll\n", DEVNAME(sc));
2803 		goto err;
2804 	}
2805 
2806 	if (ccb->ccb_rcb == NULL) {
2807 		DNPRINTF(MPII_D_MISC, "%s: empty portfacts reply\n",
2808 		    DEVNAME(sc));
2809 		goto err;
2810 	}
2811 
2812 	pfp = ccb->ccb_rcb->rcb_reply;
2813 	DNPRINTF(MPII_D_MISC, "%s   pfp: 0x%04x\n", DEVNAME(sc), pfp);
2814 
2815 	DNPRINTF(MPII_D_MISC, "%s:  function: 0x%02x msg_length: %d\n",
2816 	    DEVNAME(sc), pfp->function, pfp->msg_length);
2817 	DNPRINTF(MPII_D_MISC, "%s:  msg_flags: 0x%02x port_number: %d\n",
2818 	    DEVNAME(sc), pfp->msg_flags, pfp->port_number);
2819 	DNPRINTF(MPII_D_MISC, "%s:  vf_id: 0x%02x vp_id: 0x%02x\n", DEVNAME(sc),
2820 	    pfp->vf_id, pfp->vp_id);
2821 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2822 	    letoh16(pfp->ioc_status));
2823 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2824 	    letoh32(pfp->ioc_loginfo));
2825 	DNPRINTF(MPII_D_MISC, "%s:  port_type: 0x%02x\n", DEVNAME(sc),
2826 	    pfp->port_type);
2827 	DNPRINTF(MPII_D_MISC, "%s:  max_posted_cmd_buffers: %d\n", DEVNAME(sc),
2828 	    letoh16(pfp->max_posted_cmd_buffers));
2829 
2830 	sc->sc_porttype = pfp->port_type;
2831 	/* no such field in MPI2 .... but the dilemma is what
2832 	 * to return to sc_link.adapter_target ... is -1 acceptable? fake 255?
2833 	if (sc->sc_target == -1)
2834 		sc->sc_target = letoh16(pfp->port_scsi_id);
2835 	*/
2836 
2837 	mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2838 	rv = 0;
2839 err:
2840 	mpii_put_ccb(sc, ccb);
2841 
2842 	return (rv);
2843 }
2844 
2845 int
2846 mpii_portenable(struct mpii_softc *sc)
2847 {
2848 	struct mpii_msg_portenable_request	*peq;
2849 	struct mpii_msg_portenable_repy		*pep;
2850 	struct mpii_ccb		*ccb;
2851 	int			s;
2852 
2853 	DNPRINTF(MPII_D_MISC, "%s: mpii_portenable\n", DEVNAME(sc));
2854 
2855 	s = splbio();
2856 	ccb = mpii_get_ccb(sc);
2857 	splx(s);
2858 	if (ccb == NULL) {
2859 		DNPRINTF(MPII_D_MISC, "%s: mpii_portenable ccb_get\n",
2860 		    DEVNAME(sc));
2861 		return (1);
2862 	}
2863 
2864 	ccb->ccb_done = mpii_empty_done;
2865 	peq = ccb->ccb_cmd;
2866 
2867 	peq->function = MPII_FUNCTION_PORT_ENABLE;
2868 	peq->vf_id = sc->sc_vf_id;
2869 
2870 	if (mpii_poll(sc, ccb, 50000) != 0) {
2871 		DNPRINTF(MPII_D_MISC, "%s: mpii_portenable poll\n", DEVNAME(sc));
2872 		return (1);
2873 	}
2874 
2875 	if (ccb->ccb_rcb == NULL) {
2876 		DNPRINTF(MPII_D_MISC, "%s: empty portenable reply\n",
2877 		    DEVNAME(sc));
2878 		return (1);
2879 	}
2880 	pep = ccb->ccb_rcb->rcb_reply;
2881 
2882 	mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2883 	mpii_put_ccb(sc, ccb);
2884 
2885 	return (0);
2886 }
2887 
2888 int
2889 mpii_cfg_coalescing(struct mpii_softc *sc)
2890 {
2891 	struct mpii_cfg_hdr	hdr;
2892 	struct mpii_cfg_ioc_pg1	pg;
2893 	u_int32_t		flags;
2894 
2895 	if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 1, 0, &hdr) != 0) {
2896 		DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1 header\n",
2897 		    DEVNAME(sc));
2898 		return (1);
2899 	}
2900 
2901 	if (mpii_cfg_page(sc, 0, &hdr, 1, &pg, sizeof(pg)) != 0) {
2902 		DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1\n"
2903 		    "page 1\n", DEVNAME(sc));
2904 		return (1);
2905 	}
2906 
2907 	DNPRINTF(MPII_D_MISC, "%s: IOC page 1\n", DEVNAME(sc));
2908 	DNPRINTF(MPII_D_MISC, "%s:  flags: 0x08%x\n", DEVNAME(sc),
2909 	    letoh32(pg.flags));
2910 	DNPRINTF(MPII_D_MISC, "%s:  coalescing_timeout: %d\n", DEVNAME(sc),
2911 	    letoh32(pg.coalescing_timeout));
2912 	DNPRINTF(MPII_D_MISC, "%s:  coalescing_depth: %d pci_slot_num: %d\n",
2913 	    DEVNAME(sc), pg.coalescing_timeout, pg.pci_slot_num);
2914 
2915 	flags = letoh32(pg.flags);
2916 	if (!ISSET(flags, MPII_CFG_IOC_1_REPLY_COALESCING))
2917 		return (0);
2918 
2919 	CLR(pg.flags, htole32(MPII_CFG_IOC_1_REPLY_COALESCING));
2920 	if (mpii_cfg_page(sc, 0, &hdr, 0, &pg, sizeof(pg)) != 0) {
2921 		DNPRINTF(MPII_D_MISC, "%s: unable to clear coalescing\n",
2922 		    DEVNAME(sc));
2923 		return (1);
2924 	}
2925 
2926 	return (0);
2927 }
2928 
2929 void
2930 mpii_get_raid_config_pg0(struct mpii_softc *sc)
2931 {
2932 	struct mpii_cfg_raid_config_pg0	*config_page;
2933 	struct mpii_raid_config_element	*element_list, *element;
2934 	struct mpii_ecfg_hdr	hdr;
2935 	size_t			pagelen;
2936 	struct scsi_link	*link;
2937 	int			i;
2938 
2939 	DNPRINTF(MPII_D_RAID, "%s: mpii_get_raid_config_pg0\n", DEVNAME(sc));
2940 
2941 	if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0, 0, &hdr) != 0) {
2942 		DNPRINTF(MPII_D_RAID, "%s: mpii_get_raid_config_pg0 unable to "
2943 		    "fetch header for IOC page 2\n", DEVNAME(sc));
2944 		return;
2945 	}
2946 
2947 	pagelen = hdr.ext_page_length * 4; /* dwords to bytes */
2948 	config_page = malloc(pagelen, M_TEMP, M_WAITOK|M_CANFAIL);
2949 	if (config_page == NULL) {
2950 		DNPRINTF(MPII_D_RAID, "%s: mpii_get_raid_config_pg0 unable to "
2951 		    "allocate space for raid config page 0\n", DEVNAME(sc));
2952 		return;
2953 	}
2954 	element_list = (struct mpii_raid_config_element *)(config_page + 1);
2955 
2956 	if (mpii_cfg_page(sc, 0, &hdr, 1, config_page, pagelen) != 0) {
2957 		DNPRINTF(MPII_D_RAID, "%s: mpii_get_raid_config_pg0 unable to "
2958 		    "fetch raid config page 0\n", DEVNAME(sc));
2959 		goto out;
2960 	}
2961 
2962 	DNPRINTF(MPII_D_RAID, "%s:  numhotspares: 0x%2x numphysdisks: 0x%02x "
2963 	    "numvolumes: 0x%02x confignum: 0x%02x\n", DEVNAME(sc),
2964 	    config_page->num_hot_spares, config_page->num_phys_disks,
2965 	    config_page->num_volumes, config_page->config_num);
2966 	DNPRINTF(MPII_D_RAID, "%s:  flags: 0x%08x\n", DEVNAME(sc),
2967 	    config_page->flags);
2968 	DNPRINTF(MPII_D_RAID, "%s:  configguid: 0x%08x\n", DEVNAME(sc),
2969 	    config_page->config_guid[0]);
2970 	DNPRINTF(MPII_D_RAID, "%s:              0x%08x\n", DEVNAME(sc),
2971 	    config_page->config_guid[1]);
2972 	DNPRINTF(MPII_D_RAID, "%s:              0x%08x\n", DEVNAME(sc),
2973 	    config_page->config_guid[2]);
2974 	DNPRINTF(MPII_D_RAID, "%s:              0x%08x\n", DEVNAME(sc),
2975 	    config_page->config_guid[3]);
2976 	DNPRINTF(MPII_D_RAID, "%s  numelements: 0x%02x\n", DEVNAME(sc),
2977 	    config_page->num_elements);
2978 
2979 	/* don't walk list if there are no RAID capability */
2980 	/* XXX anything like this for MPI2?
2981 	if (capabilities == 0xdeadbeef) {
2982 		printf("%s: deadbeef in raid configuration\n", DEVNAME(sc));
2983 		goto out;
2984 	}
2985 	*/
2986 
2987 	if (config_page->num_volumes == 0)
2988 		goto out;
2989 
2990 	sc->sc_flags |= MPII_F_RAID;
2991 
2992 	for (i = 0; i < config_page->num_volumes; i++) {
2993 		element = &element_list[i];
2994 
2995 		DNPRINTF(MPII_D_RAID, "%s:   elementflags: 0x%04x voldevhandle: "
2996 		    "0x%04x\n", DEVNAME(sc), letoh16(element->element_flags),
2997 		    letoh16(element->vol_dev_handle));
2998 		DNPRINTF(MPII_D_RAID, "%s:   hotsparepool: 0x%02x physdisknum: "
2999 		    "0x%02x physdiskdevhandle: 0x%04x\n", DEVNAME(sc),
3000 		    element->hot_spare_pool, element->phys_disk_num,
3001 		    letoh16(element->phys_disk_dev_handle));
3002 
3003 		link = sc->sc_scsibus->sc_link[element->vol_dev_handle][0];
3004 		if (link == NULL)
3005 			continue;
3006 
3007 		link->flags |= SDEV_VIRTUAL;
3008 	}
3009 
3010 out:
3011 	free(config_page, M_TEMP);
3012 }
3013 
3014 void
3015 mpii_get_ioc_pg8(struct mpii_softc *sc)
3016 {
3017 	struct mpii_cfg_raid_vol	*vol_list;
3018 	struct mpii_cfg_hdr	hdr;
3019 	struct mpii_cfg_ioc_pg8	*vol_page;
3020 	size_t			pagelen;
3021 
3022 	DNPRINTF(MPII_D_RAID, "%s: mpii_get_ioc_pg8\n", DEVNAME(sc));
3023 
3024 	if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 8, 0, &hdr) != 0) {
3025 		DNPRINTF(MPII_D_RAID, "%s: mpii_get_ioc_pg8 unable to fetch header"
3026 		    "for IOC page 8\n", DEVNAME(sc));
3027 		return;
3028 	}
3029 
3030 	pagelen = hdr.page_length * 4; /* dwords to bytes */
3031 	vol_page = malloc(pagelen, M_TEMP, M_WAITOK|M_CANFAIL);
3032 	if (vol_page == NULL) {
3033 		DNPRINTF(MPII_D_RAID, "%s: mpii_get_ioc_pg8 unable to allocate "
3034 		    "space for ioc config page 8\n", DEVNAME(sc));
3035 		return;
3036 	}
3037 	vol_list = (struct mpii_cfg_raid_vol *)(vol_page + 1);
3038 
3039 	if (mpii_cfg_page(sc, 0, &hdr, 1, vol_page, pagelen) != 0) {
3040 		DNPRINTF(MPII_D_RAID, "%s: mpii_get_raid unable to fetch IOC "
3041 		    "page 8\n", DEVNAME(sc));
3042 		goto out;
3043 	}
3044 
3045 	DNPRINTF(MPII_D_RAID, "%s:  numdevsperenclosure: 0x%02x\n", DEVNAME(sc),
3046 	    vol_page->num_devs_per_enclosure);
3047 	DNPRINTF(MPII_D_RAID, "%s:  maxpersistententries: 0x%04x "
3048 	    "maxnumphysicalmappedids: 0x%04x\n", DEVNAME(sc),
3049 	    letoh16(vol_page->max_persistent_entries),
3050 	    letoh16(vol_page->max_num_physical_mapped_ids));
3051 	DNPRINTF(MPII_D_RAID, "%s:  flags: 0x%04x\n", DEVNAME(sc),
3052 	    letoh16(vol_page->flags));
3053 	DNPRINTF(MPII_D_RAID, "%s:  irvolumemappingflags: 0x%04x\n",
3054 	    DEVNAME(sc), letoh16(vol_page->ir_volume_mapping_flags));
3055 
3056 out:
3057 	free(vol_page, M_TEMP);
3058 }
3059 
3060 int
3061 mpii_req_cfg_header(struct mpii_softc *sc, u_int8_t type, u_int8_t number,
3062     u_int32_t address, int extended, void *p)
3063 {
3064 	struct mpii_msg_config_request	*cq;
3065 	struct mpii_msg_config_reply	*cp;
3066 	struct mpii_ccb		*ccb;
3067 	struct mpii_cfg_hdr	*hdr = p;
3068 	struct mpii_ecfg_hdr	*ehdr = p;
3069 	int			etype = 0;
3070 	int			rv = 0;
3071 	int			s;
3072 
3073 	DNPRINTF(MPII_D_MISC, "%s: mpii_req_cfg_header type: %#x number: %x "
3074 	    "address: 0x%08x extended: %d\n", DEVNAME(sc), type, number,
3075 	    address, extended);
3076 
3077 	s = splbio();
3078 	ccb = mpii_get_ccb(sc);
3079 	splx(s);
3080 	if (ccb == NULL) {
3081 		DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header ccb_get\n",
3082 		    DEVNAME(sc));
3083 		return (1);
3084 	}
3085 
3086 	if (extended) {
3087 		etype = type;
3088 		type = MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED;
3089 	}
3090 
3091 	ccb->ccb_done = mpii_empty_done;
3092 	cq = ccb->ccb_cmd;
3093 
3094 	cq->function = MPII_FUNCTION_CONFIG;
3095 
3096 	cq->action = MPII_CONFIG_REQ_ACTION_PAGE_HEADER;
3097 
3098 	cq->config_header.page_number = number;
3099 	cq->config_header.page_type = type;
3100 	cq->ext_page_type = etype;
3101 	cq->page_address = htole32(address);
3102 	cq->page_buffer.sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
3103 	    MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
3104 
3105 	if (mpii_poll(sc, ccb, 50000) != 0) {
3106 		DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header poll\n", DEVNAME(sc));
3107 		return (1);
3108 	}
3109 
3110 	if (ccb->ccb_rcb == NULL)
3111 		panic("%s: unable to fetch config header\n", DEVNAME(sc));
3112 	cp = ccb->ccb_rcb->rcb_reply;
3113 
3114 	DNPRINTF(MPII_D_MISC, "%s:  action: 0x%02x sgl_flags: 0x%02x "
3115 	    "msg_length: %d function: 0x%02x\n", DEVNAME(sc), cp->action,
3116 	    cp->sgl_flags, cp->msg_length, cp->function);
3117 	DNPRINTF(MPII_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
3118 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
3119 	    letoh16(cp->ext_page_length), cp->ext_page_type,
3120 	    cp->msg_flags);
3121 	DNPRINTF(MPII_D_MISC, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
3122 	    cp->vp_id, cp->vf_id);
3123 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
3124 	    letoh16(cp->ioc_status));
3125 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3126 	    letoh32(cp->ioc_loginfo));
3127 	DNPRINTF(MPII_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
3128 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
3129 	    cp->config_header.page_version,
3130 	    cp->config_header.page_length,
3131 	    cp->config_header.page_number,
3132 	    cp->config_header.page_type);
3133 
3134 	if (letoh16(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
3135 		rv = 1;
3136 	else if (extended) {
3137 		bzero(ehdr, sizeof(*ehdr));
3138 		ehdr->page_version = cp->config_header.page_version;
3139 		ehdr->page_number = cp->config_header.page_number;
3140 		ehdr->page_type = cp->config_header.page_type;
3141 		ehdr->ext_page_length = cp->ext_page_length;
3142 		ehdr->ext_page_type = cp->ext_page_type;
3143 	} else
3144 		*hdr = cp->config_header;
3145 
3146 	mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
3147 	mpii_put_ccb(sc, ccb);
3148 
3149 	return (rv);
3150 }
3151 
3152 int
3153 mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int extended,
3154     void *p, int read, void *page, size_t len)
3155 {
3156 	struct mpii_msg_config_request		*cq;
3157 	struct mpii_msg_config_reply		*cp;
3158 	struct mpii_ccb		*ccb;
3159 	struct mpii_cfg_hdr	*hdr = p;
3160 	struct mpii_ecfg_hdr	*ehdr = p;
3161 	u_int64_t		dva;
3162 	char			*kva;
3163 	int			page_length;
3164 	int			rv = 0;
3165 	int			s;
3166 
3167 	DNPRINTF(MPII_D_MISC, "%s: mpii_req_cfg_page address: %d read: %d type: %x\n",
3168 	    DEVNAME(sc), address, read, hdr->page_type);
3169 
3170 	page_length = extended ?
3171 	    letoh16(ehdr->ext_page_length) : hdr->page_length;
3172 
3173 	if (len > MPII_REQUEST_SIZE - sizeof(struct mpii_msg_config_request) ||
3174 	    len < page_length * 4)
3175 		return (1);
3176 
3177 	s = splbio();
3178 	ccb = mpii_get_ccb(sc);
3179 	splx(s);
3180 	if (ccb == NULL) {
3181 		DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page ccb_get\n", DEVNAME(sc));
3182 		return (1);
3183 	}
3184 
3185 	ccb->ccb_done = mpii_empty_done;
3186 	cq = ccb->ccb_cmd;
3187 
3188 	cq->function = MPII_FUNCTION_CONFIG;
3189 
3190 	cq->action = (read ? MPII_CONFIG_REQ_ACTION_PAGE_READ_CURRENT :
3191 	    MPII_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT);
3192 
3193 	if (extended) {
3194 		cq->config_header.page_version = ehdr->page_version;
3195 		cq->config_header.page_number = ehdr->page_number;
3196 		cq->config_header.page_type = ehdr->page_type;
3197 		cq->ext_page_len = ehdr->ext_page_length;
3198 		cq->ext_page_type = ehdr->ext_page_type;
3199 	} else
3200 		cq->config_header = *hdr;
3201 	cq->config_header.page_type &= MPII_CONFIG_REQ_PAGE_TYPE_MASK;
3202 	cq->page_address = htole32(address);
3203 	cq->page_buffer.sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
3204 	    MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL |
3205 	    (page_length * 4) |
3206 	    (read ? MPII_SGE_FL_DIR_IN : MPII_SGE_FL_DIR_OUT));
3207 
3208 	/* bounce the page via the request space to avoid more bus_dma games */
3209 	dva = ccb->ccb_cmd_dva + sizeof(struct mpii_msg_config_request);
3210 
3211 	cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32));
3212 	cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva);
3213 
3214 	kva = ccb->ccb_cmd;
3215 	kva += sizeof(struct mpii_msg_config_request);
3216 	if (!read)
3217 		bcopy(page, kva, len);
3218 
3219 	if (mpii_poll(sc, ccb, 50000) != 0) {
3220 		DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page poll\n", DEVNAME(sc));
3221 		return (1);
3222 	}
3223 
3224 	if (ccb->ccb_rcb == NULL) {
3225 		mpii_put_ccb(sc, ccb);
3226 		return (1);
3227 	}
3228 	cp = ccb->ccb_rcb->rcb_reply;
3229 
3230 	DNPRINTF(MPII_D_MISC, "%s:  action: 0x%02x sglflags: 0x%02x "
3231 	    "msg_length: %d function: 0x%02x\n", DEVNAME(sc), cp->action,
3232 	    cp->msg_length, cp->function);
3233 	DNPRINTF(MPII_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
3234 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
3235 	    letoh16(cp->ext_page_length), cp->ext_page_type,
3236 	    cp->msg_flags);
3237 	DNPRINTF(MPII_D_MISC, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
3238 	    cp->vp_id, cp->vf_id);
3239 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
3240 	    letoh16(cp->ioc_status));
3241 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3242 	    letoh32(cp->ioc_loginfo));
3243 	DNPRINTF(MPII_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
3244 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
3245 	    cp->config_header.page_version,
3246 	    cp->config_header.page_length,
3247 	    cp->config_header.page_number,
3248 	    cp->config_header.page_type);
3249 
3250 	if (letoh16(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
3251 		rv = 1;
3252 	else if (read)
3253 		bcopy(kva, page, len);
3254 
3255 	mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
3256 	mpii_put_ccb(sc, ccb);
3257 
3258 	return (rv);
3259 }
3260 
3261 int
3262 mpii_reply(struct mpii_softc *sc)
3263 {
3264 	struct mpii_reply_descriptor	*rdp;
3265 	struct mpii_ccb		*ccb;
3266 	struct mpii_rcb		*rcb = NULL;
3267 	struct mpii_msg_reply	*reply = NULL;
3268 	u_int8_t		reply_flags;
3269 	u_int32_t		reply_dva, i;
3270 	int			smid;
3271 
3272 
3273 	DNPRINTF(MPII_D_INTR, "%s: mpii_reply\n", DEVNAME(sc));
3274 
3275 	/* XXX need to change to to be just the reply we expect to read */
3276 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq), 0,
3277 	    8 * sc->sc_reply_post_qdepth, BUS_DMASYNC_POSTWRITE);
3278 
3279 	rdp = &sc->sc_reply_postq_kva[sc->sc_reply_post_host_index];
3280 
3281 	reply_flags = (u_int8_t)(rdp->reply_flags) &
3282 	    MPII_REPLY_DESCR_FLAGS_TYPE_MASK;
3283 
3284 	if ((reply_flags == MPII_REPLY_DESCR_FLAGS_UNUSED))
3285 		return (-1);
3286 
3287 	if (dwordn(rdp, 1) == 0xffffffff)
3288 		/*
3289 		 * ioc is still writing to the reply post queue
3290 		 * race condition - bail!
3291 		 */
3292 		 return (0);
3293 
3294 	DNPRINTF(MPII_D_INTR, "%s:  dword[0]: 0x%08x\n", DEVNAME(sc),
3295 	    letoh32(dwordn(rdp, 0)));
3296 	DNPRINTF(MPII_D_INTR, "%s:  dword[1]: 0x%08x\n", DEVNAME(sc),
3297 	    letoh32(dwordn(rdp, 1)));
3298 
3299 	switch (reply_flags) {
3300 	case MPII_REPLY_DESCR_FLAGS_ADDRESS_REPLY:
3301 		/* reply frame address */
3302 		reply_dva = letoh32(rdp->type_dependent2);
3303 		i = (reply_dva - (u_int32_t)MPII_DMA_DVA(sc->sc_replies)) /
3304 			MPII_REPLY_SIZE;
3305 
3306 		bus_dmamap_sync(sc->sc_dmat,
3307 		    MPII_DMA_MAP(sc->sc_replies), MPII_REPLY_SIZE * i,
3308 		    MPII_REPLY_SIZE, BUS_DMASYNC_POSTREAD);
3309 
3310 		rcb = &sc->sc_rcbs[i];
3311 		reply = rcb->rcb_reply;
3312 		/* fall through */
3313 	default:
3314 		/* smid */
3315 		 smid = letoh16(rdp->type_dependent1);
3316 	}
3317 
3318 	DNPRINTF(MPII_D_INTR, "%s: mpii_reply reply_flags: %d smid: %d reply: %p\n",
3319 	    DEVNAME(sc), reply_flags, smid, reply);
3320 
3321 	if (smid == 0) {
3322 		printf("smid == 0 !!\n");
3323 		goto end;
3324 	}
3325 	ccb = &sc->sc_ccbs[smid - 1];
3326 
3327 	/* XXX why is this necessary ? */
3328 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_requests),
3329 	    ccb->ccb_offset, MPII_REQUEST_SIZE,
3330 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
3331 
3332 	ccb->ccb_state = MPII_CCB_READY;
3333 	ccb->ccb_rcb = rcb;
3334 
3335 	DNPRINTF(MPII_D_INTR, "    rcb: 0x%04x\n", rcb);
3336 
3337 	dwordn(rdp, 0) = 0xffffffff;
3338 	dwordn(rdp, 1) = 0xffffffff;
3339 
3340 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
3341 	    8 * sc->sc_reply_post_host_index, 8,
3342 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
3343 
3344 	sc->sc_reply_post_host_index = (sc->sc_reply_post_host_index + 1) %
3345 	    sc->sc_reply_post_qdepth;
3346 	ccb->ccb_done(ccb);
3347 
3348 end:
3349 
3350 	return (smid);
3351 }
3352 
3353 struct mpii_dmamem *
3354 mpii_dmamem_alloc(struct mpii_softc *sc, size_t size)
3355 {
3356 	struct mpii_dmamem	*mdm;
3357 	int			nsegs;
3358 
3359 	mdm = malloc(sizeof(struct mpii_dmamem), M_DEVBUF, M_NOWAIT | M_ZERO);
3360 	if (mdm == NULL)
3361 		return (NULL);
3362 
3363 	mdm->mdm_size = size;
3364 
3365 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
3366 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0)
3367 		goto mdmfree;
3368 
3369 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mdm->mdm_seg,
3370 	    1, &nsegs, BUS_DMA_NOWAIT) != 0)
3371 		goto destroy;
3372 
3373 	if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size,
3374 	    &mdm->mdm_kva, BUS_DMA_NOWAIT) != 0)
3375 		goto free;
3376 
3377 	if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size,
3378 	    NULL, BUS_DMA_NOWAIT) != 0)
3379 		goto unmap;
3380 
3381 	bzero(mdm->mdm_kva, size);
3382 
3383 	DNPRINTF(MPII_D_MEM, "%s: mpii_dmamem_alloc size: %d mdm: %#x "
3384 	    "map: %#x nsegs: %d segs: %#x kva: %x\n",
3385 	    DEVNAME(sc), size, mdm->mdm_map, nsegs, mdm->mdm_seg, mdm->mdm_kva);
3386 
3387 	return (mdm);
3388 
3389 unmap:
3390 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size);
3391 free:
3392 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
3393 destroy:
3394 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
3395 mdmfree:
3396 	free(mdm, M_DEVBUF);
3397 
3398 	return (NULL);
3399 }
3400 
3401 void
3402 mpii_dmamem_free(struct mpii_softc *sc, struct mpii_dmamem *mdm)
3403 {
3404 	DNPRINTF(MPII_D_MEM, "%s: mpii_dmamem_free %#x\n", DEVNAME(sc), mdm);
3405 
3406 	bus_dmamap_unload(sc->sc_dmat, mdm->mdm_map);
3407 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size);
3408 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
3409 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
3410 	free(mdm, M_DEVBUF);
3411 }
3412 
3413 int
3414 mpii_alloc_ccbs(struct mpii_softc *sc)
3415 {
3416 	struct mpii_ccb		*ccb;
3417 	u_int8_t		*cmd;
3418 	int			i;
3419 
3420 	TAILQ_INIT(&sc->sc_ccb_free);
3421 
3422 	sc->sc_ccbs = malloc(sizeof(struct mpii_ccb) * (sc->sc_request_depth-1),
3423 	    M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO);
3424 	if (sc->sc_ccbs == NULL) {
3425 		printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
3426 		return (1);
3427 	}
3428 
3429 	sc->sc_requests = mpii_dmamem_alloc(sc,
3430 	    MPII_REQUEST_SIZE * sc->sc_request_depth);
3431 	if (sc->sc_requests == NULL) {
3432 		printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
3433 		goto free_ccbs;
3434 	}
3435 	cmd = MPII_DMA_KVA(sc->sc_requests);
3436 	bzero(cmd, MPII_REQUEST_SIZE * sc->sc_request_depth);
3437 
3438 	/*
3439 	 * we have sc->sc_request_depth system request message frames, but
3440 	 * smid zero cannot be used.
3441 	 *
3442 	 * we then have (sc->sc_request_depth - 1) number of ccbs
3443 	 */
3444 	for (i = 1; i < sc->sc_request_depth; i++) {
3445 		ccb = &sc->sc_ccbs[i - 1];
3446 
3447 		if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
3448 		    sc->sc_max_sgl_len, MAXPHYS, 0,
3449 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
3450 		    &ccb->ccb_dmamap) != 0) {
3451 			printf("%s: unable to create dma map\n", DEVNAME(sc));
3452 			goto free_maps;
3453 		}
3454 
3455 		ccb->ccb_sc = sc;
3456 		ccb->ccb_smid = i;
3457 		ccb->ccb_offset = MPII_REQUEST_SIZE * i;
3458 
3459 		ccb->ccb_cmd = &cmd[ccb->ccb_offset];
3460 		ccb->ccb_cmd_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_requests) +
3461 		    ccb->ccb_offset;
3462 
3463 		DNPRINTF(MPII_D_CCB, "%s: mpii_alloc_ccbs(%d) ccb: %#x map: %#x "
3464 		    "sc: %#x smid: %#x offs: %#x cmd: %#x dva: %#x\n",
3465 		    DEVNAME(sc), i, ccb, ccb->ccb_dmamap, ccb->ccb_sc,
3466 		    ccb->ccb_smid, ccb->ccb_offset, ccb->ccb_cmd,
3467 		    ccb->ccb_cmd_dva);
3468 
3469 		mpii_put_ccb(sc, ccb);
3470 	}
3471 
3472 	return (0);
3473 
3474 free_maps:
3475 	while ((ccb = mpii_get_ccb(sc)) != NULL)
3476 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
3477 
3478 	mpii_dmamem_free(sc, sc->sc_requests);
3479 free_ccbs:
3480 	free(sc->sc_ccbs, M_DEVBUF);
3481 
3482 	return (1);
3483 }
3484 
3485 void
3486 mpii_put_ccb(struct mpii_softc *sc, struct mpii_ccb *ccb)
3487 {
3488 	DNPRINTF(MPII_D_CCB, "%s: mpii_put_ccb %#x\n", DEVNAME(sc), ccb);
3489 
3490 	ccb->ccb_state = MPII_CCB_FREE;
3491 	ccb->ccb_xs = NULL;
3492 	ccb->ccb_done = NULL;
3493 	bzero(ccb->ccb_cmd, MPII_REQUEST_SIZE);
3494 	TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link);
3495 }
3496 
3497 struct mpii_ccb *
3498 mpii_get_ccb(struct mpii_softc *sc)
3499 {
3500 	struct mpii_ccb		*ccb;
3501 
3502 	ccb = TAILQ_FIRST(&sc->sc_ccb_free);
3503 	if (ccb == NULL) {
3504 		DNPRINTF(MPII_D_CCB, "%s: mpii_get_ccb == NULL\n", DEVNAME(sc));
3505 		return (NULL);
3506 	}
3507 
3508 	TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link);
3509 
3510 	ccb->ccb_state = MPII_CCB_READY;
3511 
3512 	DNPRINTF(MPII_D_CCB, "%s: mpii_get_ccb %#x\n", DEVNAME(sc), ccb);
3513 
3514 	return (ccb);
3515 }
3516 
3517 int
3518 mpii_alloc_replies(struct mpii_softc *sc)
3519 {
3520 	DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_replies\n", DEVNAME(sc));
3521 
3522 	sc->sc_rcbs = malloc(sc->sc_num_reply_frames * sizeof(struct mpii_rcb),
3523 	    M_DEVBUF, M_WAITOK|M_CANFAIL);
3524 	if (sc->sc_rcbs == NULL)
3525 		return (1);
3526 
3527 	sc->sc_replies = mpii_dmamem_alloc(sc,
3528 	    MPII_REPLY_SIZE * sc->sc_num_reply_frames);
3529 	if (sc->sc_replies == NULL) {
3530 		free(sc->sc_rcbs, M_DEVBUF);
3531 		return (1);
3532 	}
3533 
3534 	return (0);
3535 }
3536 
3537 void
3538 mpii_push_replies(struct mpii_softc *sc)
3539 {
3540 	struct mpii_rcb		*rcb;
3541 	char			*kva = MPII_DMA_KVA(sc->sc_replies);
3542 	int			i;
3543 
3544 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
3545 	    0, MPII_REPLY_SIZE * sc->sc_num_reply_frames, BUS_DMASYNC_PREREAD);
3546 
3547 	for (i = 0; i < sc->sc_num_reply_frames; i++) {
3548 		rcb = &sc->sc_rcbs[i];
3549 
3550 		rcb->rcb_reply = kva + MPII_REPLY_SIZE * i;
3551 		rcb->rcb_reply_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
3552 		    MPII_REPLY_SIZE * i;
3553 		mpii_push_reply(sc, rcb->rcb_reply_dva);
3554 	}
3555 }
3556 void
3557 mpii_start(struct mpii_softc *sc, struct mpii_ccb *ccb)
3558 {
3559 	struct mpii_request_header	*rhp;
3560 	struct mpii_request_descriptor	descriptor;
3561 
3562 	DNPRINTF(MPII_D_RW, "%s: mpii_start %#x\n", DEVNAME(sc),
3563 	    ccb->ccb_cmd_dva);
3564 
3565 	rhp = ccb->ccb_cmd;
3566 
3567 	bzero(&descriptor, sizeof(struct mpii_request_descriptor));
3568 
3569 	switch (rhp->function) {
3570 	case	MPII_FUNCTION_SCSI_IO_REQUEST:
3571 			descriptor.request_flags =
3572 			    MPII_REQ_DESCRIPTOR_FLAGS_SCSI_IO;
3573 			/* device handle */
3574 			descriptor.type_dependent =
3575 			    htole16(ccb->ccb_dev_handle);
3576 			break;
3577 	case	MPII_FUNCTION_SCSI_TASK_MGMT:
3578 			descriptor.request_flags =
3579 			    MPII_REQ_DESCRIPTOR_FLAGS_HIGH_PRIORITY;
3580 			break;
3581 	default:
3582 			descriptor.request_flags =
3583 			    MPII_REQ_DESCRIPTOR_FLAGS_DEFAULT;
3584 	}
3585 
3586 	descriptor.vf_id = sc->sc_vf_id;
3587 	descriptor.smid = htole16(ccb->ccb_smid);
3588 
3589 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_requests),
3590 	    ccb->ccb_offset, MPII_REQUEST_SIZE,
3591 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3592 
3593 	ccb->ccb_state = MPII_CCB_QUEUED;
3594 
3595 	DNPRINTF(MPII_D_RW, "%s:   MPII_REQ_DESC_POST_LOW (0x%08x) write "
3596 	    "0x%08x\n", DEVNAME(sc), MPII_REQ_DESC_POST_LOW,
3597 	    dwordn(&descriptor, 0));
3598 
3599 	DNPRINTF(MPII_D_RW, "%s:   MPII_REQ_DESC_POST_HIGH (0x%08x) write "
3600 	    "0x%08x\n", DEVNAME(sc), MPII_REQ_DESC_POST_HIGH,
3601 	    dwordn(&descriptor, 1));
3602 
3603 	/* XXX make this 64 bit? */
3604 	mpii_write(sc, MPII_REQ_DESC_POST_LOW, htole32(dwordn(&descriptor, 0)));
3605 	mpii_write(sc, MPII_REQ_DESC_POST_HIGH,
3606 	    htole32(dwordn(&descriptor, 1)));
3607 }
3608 
3609 int
3610 mpii_complete(struct mpii_softc *sc, struct mpii_ccb *ccb, int timeout)
3611 {
3612 	int			smid = -1;
3613 
3614 	DNPRINTF(MPII_D_INTR, "%s: mpii_complete timeout %d\n", DEVNAME(sc),
3615 	    timeout);
3616 
3617 	do {
3618 		/* avoid excessive polling */
3619 		if (!mpii_reply_waiting(sc)) {
3620 			if (timeout-- == 0)
3621 				return (1);
3622 
3623 			delay(1000);
3624 			continue;
3625 		}
3626 
3627 		smid = mpii_reply(sc);
3628 
3629 		/* generates PCI write every completed reply, but
3630 		 * prevents deadlock waiting for specific smid
3631 		 */
3632 		mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
3633 
3634 		DNPRINTF(MPII_D_INTR, "%s: mpii_complete call to mpii_reply returned: %d\n",
3635 		    DEVNAME(sc), smid);
3636 
3637 	} while (ccb->ccb_smid != smid);
3638 
3639 	return (0);
3640 }
3641 
3642 int
3643 mpii_alloc_queues(struct mpii_softc *sc)
3644 {
3645 	u_int32_t		*kva;
3646 	u_int64_t		*kva64;
3647 	int			i;
3648 
3649 	DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_queues\n", DEVNAME(sc));
3650 
3651 	sc->sc_reply_freeq = mpii_dmamem_alloc(sc,
3652 	    sc->sc_reply_free_qdepth * 4);
3653 	if (sc->sc_reply_freeq == NULL)
3654 		return (1);
3655 
3656 	kva = MPII_DMA_KVA(sc->sc_reply_freeq);
3657 	for (i = 0; i < sc->sc_num_reply_frames; i++) {
3658 		kva[i] = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
3659 		    MPII_REPLY_SIZE * i;
3660 
3661 		DNPRINTF(MPII_D_MISC, "%s:   %d:  0x%08x = 0x%08x\n",
3662 		    DEVNAME(sc), i,
3663 		    &kva[i], (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
3664 		    MPII_REPLY_SIZE * i);
3665 	}
3666 
3667 	sc->sc_reply_postq =
3668 	    mpii_dmamem_alloc(sc, sc->sc_reply_post_qdepth * 8);
3669 	if (sc->sc_reply_postq == NULL)
3670 		goto free_reply_freeq;
3671 	sc->sc_reply_postq_kva = MPII_DMA_KVA(sc->sc_reply_postq);
3672 
3673 	DNPRINTF(MPII_D_MISC, "%s:  populating reply post descriptor queue\n",
3674 	    DEVNAME(sc));
3675 	kva64 = (u_int64_t *)MPII_DMA_KVA(sc->sc_reply_postq);
3676 	for (i = 0; i < sc->sc_reply_post_qdepth; i++) {
3677 		kva64[i] = 0xffffffffffffffffllu;
3678 		DNPRINTF(MPII_D_MISC, "%s:    %d:  0x%08x = 0x%lx\n",
3679 		    DEVNAME(sc), i, &kva64[i], kva64[i]);
3680 	}
3681 
3682 	return (0);
3683 
3684 free_reply_freeq:
3685 
3686 	mpii_dmamem_free(sc, sc->sc_reply_freeq);
3687 	return (1);
3688 }
3689 
3690 void
3691 mpii_init_queues(struct mpii_softc *sc)
3692 {
3693 	DNPRINTF(MPII_D_MISC, "%s:  mpii_init_queues\n", DEVNAME(sc));
3694 
3695 	sc->sc_reply_free_host_index = sc->sc_reply_free_qdepth - 1;
3696 	sc->sc_reply_post_host_index = 0;
3697 	mpii_write_reply_free(sc, sc->sc_reply_free_host_index);
3698 	mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
3699 }
3700 
3701 
3702 
3703 
3704 int
3705 mpii_poll(struct mpii_softc *sc, struct mpii_ccb *ccb, int timeout)
3706 {
3707 	int			error;
3708 	int			s;
3709 
3710 	DNPRINTF(MPII_D_CMD, "%s: mpii_poll\n", DEVNAME(sc));
3711 
3712 	DNPRINTF(MPII_D_CMD, "   ccb->ccb_cmd: 0x%08x\n", DEVNAME(sc), ccb->ccb_cmd);
3713 	s = splbio();
3714 	mpii_start(sc, ccb);
3715 	error = mpii_complete(sc, ccb, timeout);
3716 	splx(s);
3717 
3718 	return (error);
3719 }
3720 
3721 int
3722 mpii_scsi_cmd(struct scsi_xfer *xs)
3723 {
3724 	struct scsi_link	*link = xs->sc_link;
3725 	struct mpii_softc	*sc = link->adapter_softc;
3726 	struct mpii_ccb		*ccb;
3727 	struct mpii_ccb_bundle	*mcb;
3728 	struct mpii_msg_scsi_io	*io;
3729 	int			s;
3730 
3731 	DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd\n", DEVNAME(sc));
3732 
3733 	if (xs->cmdlen > MPII_CDB_LEN) {
3734 		DNPRINTF(MPII_D_CMD, "%s: CBD too big %d\n",
3735 		    DEVNAME(sc), xs->cmdlen);
3736 		bzero(&xs->sense, sizeof(xs->sense));
3737 		xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
3738 		xs->sense.flags = SKEY_ILLEGAL_REQUEST;
3739 		xs->sense.add_sense_code = 0x20;
3740 		xs->error = XS_SENSE;
3741 		xs->flags |= ITSDONE;
3742 		s = splbio();
3743 		scsi_done(xs);
3744 		splx(s);
3745 		return (COMPLETE);
3746 	}
3747 
3748 	s = splbio();
3749 	ccb = mpii_get_ccb(sc);
3750 	splx(s);
3751 	if (ccb == NULL)
3752 		return (NO_CCB);
3753 
3754 	DNPRINTF(MPII_D_CMD, "%s: ccb_smid: %d xs->flags: 0x%x\n",
3755 	    DEVNAME(sc), ccb->ccb_smid, xs->flags);
3756 
3757 	ccb->ccb_xs = xs;
3758 	ccb->ccb_done = mpii_scsi_cmd_done;
3759 
3760 	mcb = ccb->ccb_cmd;
3761 	io = &mcb->mcb_io;
3762 
3763 	io->function = MPII_FUNCTION_SCSI_IO_REQUEST;
3764 	io->sense_buffer_length = sizeof(xs->sense);
3765 	io->sgl_offset0 = 24; /* XXX fix this */
3766 	io->io_flags = htole16(xs->cmdlen);
3767 	io->dev_handle = htole32(link->target);
3768 	io->lun[0] = htobe16(link->lun);
3769 
3770 	switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
3771 	case SCSI_DATA_IN:
3772 		io->direction = MPII_SCSIIO_DIR_READ;
3773 		break;
3774 	case SCSI_DATA_OUT:
3775 		io->direction = MPII_SCSIIO_DIR_WRITE;
3776 		break;
3777 	default:
3778 		io->direction = MPII_SCSIIO_DIR_NONE;
3779 		break;
3780 	}
3781 
3782 	io->tagging = MPII_SCSIIO_ATTR_SIMPLE_Q;
3783 
3784 	bcopy(xs->cmd, io->cdb, xs->cmdlen);
3785 
3786 	io->data_length = htole32(xs->datalen);
3787 
3788 	io->sense_buffer_low_address = htole32(ccb->ccb_cmd_dva +
3789 	    ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb));
3790 
3791 	if (mpii_load_xs(ccb) != 0) {
3792 		xs->error = XS_DRIVER_STUFFUP;
3793 		xs->flags |= ITSDONE;
3794 		s = splbio();
3795 		mpii_put_ccb(sc, ccb);
3796 		scsi_done(xs);
3797 		splx(s);
3798 		return (COMPLETE);
3799 	}
3800 
3801 	timeout_set(&xs->stimeout, mpii_timeout_xs, ccb);
3802 
3803 	DNPRINTF(MPII_D_CMD, "%s:  sizeof(mpii_msg_scsi_io): %d "
3804 	    "sizeof(mpii_ccb_bundle): %d sge offset: 0x%02x\n",
3805 	    DEVNAME(sc), sizeof(struct mpii_msg_scsi_io),
3806 	    sizeof(struct mpii_ccb_bundle),
3807 	    (u_int8_t *)&mcb->mcb_sgl[0] - (u_int8_t *)mcb);
3808 
3809 	DNPRINTF(MPII_D_CMD, "%s   sgl[0]: 0x%04x 0%04x 0x%04x\n",
3810 	    DEVNAME(sc), mcb->mcb_sgl[0].sg_hdr, mcb->mcb_sgl[0].sg_lo_addr,
3811 	    mcb->mcb_sgl[0].sg_hi_addr);
3812 
3813 	DNPRINTF(MPII_D_CMD, "%s:  Offset0: 0x%02x\n", DEVNAME(sc),
3814 	    io->sgl_offset0);
3815 
3816 	if (xs->flags & SCSI_POLL) {
3817 		if (mpii_poll(sc, ccb, xs->timeout) != 0) {
3818 			xs->error = XS_DRIVER_STUFFUP;
3819 			xs->flags |= ITSDONE;
3820 			s = splbio();
3821 			scsi_done(xs);
3822 			splx(s);
3823 		}
3824 		return (COMPLETE);
3825 	}
3826 
3827 	DNPRINTF(MPII_D_CMD, "%s:    mpii_scsi_cmd(): opcode: %02x datalen: %d "
3828 	    "req_sense_len: %d\n", DEVNAME(sc), xs->cmd->opcode,
3829 	    xs->datalen, xs->req_sense_length);
3830 
3831 	s = splbio();
3832 	mpii_start(sc, ccb);
3833 	splx(s);
3834 	return (SUCCESSFULLY_QUEUED);
3835 }
3836 
3837 void
3838 mpii_scsi_cmd_done(struct mpii_ccb *ccb)
3839 {
3840 	struct mpii_msg_scsi_io_error	*sie;
3841 	struct mpii_softc	*sc = ccb->ccb_sc;
3842 	struct scsi_xfer	*xs = ccb->ccb_xs;
3843 	struct mpii_ccb_bundle	*mcb = ccb->ccb_cmd;
3844 	bus_dmamap_t		dmap = ccb->ccb_dmamap;
3845 
3846 	if (xs->datalen != 0) {
3847 		bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
3848 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
3849 		    BUS_DMASYNC_POSTWRITE);
3850 
3851 		bus_dmamap_unload(sc->sc_dmat, dmap);
3852 	}
3853 
3854 	/* timeout_del */
3855 	xs->error = XS_NOERROR;
3856 	xs->resid = 0;
3857 	xs->flags |= ITSDONE;
3858 
3859 	if (ccb->ccb_rcb == NULL) {
3860 		/* no scsi error, we're ok so drop out early */
3861 		xs->status = SCSI_OK;
3862 		mpii_put_ccb(sc, ccb);
3863 		scsi_done(xs);
3864 		return;
3865 	}
3866 
3867 	sie = ccb->ccb_rcb->rcb_reply;
3868 
3869 	DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd_done xs cmd: 0x%02x len: %d "
3870 	    "flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
3871 	    xs->flags);
3872 	DNPRINTF(MPII_D_CMD, "%s:  dev_handle: %d msg_length: %d "
3873 	    "function: 0x%02x\n", DEVNAME(sc), letoh16(sie->dev_handle),
3874 	    sie->msg_length, sie->function);
3875 	DNPRINTF(MPII_D_CMD, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
3876 	    sie->vp_id, sie->vf_id);
3877 	DNPRINTF(MPII_D_CMD, "%s:  scsi_status: 0x%02x scsi_state: 0x%02x "
3878 	    "ioc_status: 0x%04x\n", DEVNAME(sc), sie->scsi_status,
3879 	    sie->scsi_state, letoh16(sie->ioc_status));
3880 	DNPRINTF(MPII_D_CMD, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3881 	    letoh32(sie->ioc_loginfo));
3882 	DNPRINTF(MPII_D_CMD, "%s:  transfer_count: %d\n", DEVNAME(sc),
3883 	    letoh32(sie->transfer_count));
3884 	DNPRINTF(MPII_D_CMD, "%s:  sense_count: %d\n", DEVNAME(sc),
3885 	    letoh32(sie->sense_count));
3886 	DNPRINTF(MPII_D_CMD, "%s:  response_info: 0x%08x\n", DEVNAME(sc),
3887 	    letoh32(sie->response_info));
3888 	DNPRINTF(MPII_D_CMD, "%s:  task_tag: 0x%04x\n", DEVNAME(sc),
3889 	    letoh16(sie->task_tag));
3890 	DNPRINTF(MPII_D_CMD, "%s:  bidirectional_transfer_count: 0x%08x\n",
3891 	    DEVNAME(sc), letoh32(sie->bidirectional_transfer_count));
3892 
3893 	xs->status = sie->scsi_status;
3894 	switch (letoh16(sie->ioc_status)) {
3895 	case MPII_IOCSTATUS_SCSI_DATA_UNDERRUN:
3896 		xs->resid = xs->datalen - letoh32(sie->transfer_count);
3897 		if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_NO_SCSI_STATUS) {
3898 			xs->error = XS_DRIVER_STUFFUP;
3899 			break;
3900 		}
3901 		/* FALLTHROUGH */
3902 	case MPII_IOCSTATUS_SUCCESS:
3903 	case MPII_IOCSTATUS_SCSI_RECOVERED_ERROR:
3904 		switch (xs->status) {
3905 		case SCSI_OK:
3906 			xs->resid = 0;
3907 			break;
3908 
3909 		case SCSI_CHECK:
3910 			xs->error = XS_SENSE;
3911 			break;
3912 
3913 		case SCSI_BUSY:
3914 		case SCSI_QUEUE_FULL:
3915 			xs->error = XS_BUSY;
3916 			break;
3917 
3918 		default:
3919 			xs->error = XS_DRIVER_STUFFUP;
3920 			break;
3921 		}
3922 		break;
3923 
3924 	case MPII_IOCSTATUS_BUSY:
3925 	case MPII_IOCSTATUS_INSUFFICIENT_RESOURCES:
3926 		xs->error = XS_BUSY;
3927 		break;
3928 
3929 	case MPII_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
3930 	case MPII_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
3931 		xs->error = XS_SELTIMEOUT;
3932 		break;
3933 
3934 	default:
3935 		xs->error = XS_DRIVER_STUFFUP;
3936 		break;
3937 	}
3938 
3939 	if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID)
3940 		bcopy(&mcb->mcb_sense, &xs->sense, sizeof(xs->sense));
3941 
3942 
3943 	DNPRINTF(MPII_D_CMD, "%s:  xs err: 0x%02x status: %d\n", DEVNAME(sc),
3944 	    xs->error, xs->status);
3945 
3946 	mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
3947 	mpii_put_ccb(sc, ccb);
3948 	scsi_done(xs);
3949 }
3950