xref: /openbsd-src/sys/dev/pci/mpii.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: mpii.c,v 1.51 2012/04/11 13:29:14 naddy Exp $	*/
2 /*
3  * Copyright (c) 2010 Mike Belopuhov <mkb@crypt.org.ru>
4  * Copyright (c) 2009 James Giannoules
5  * Copyright (c) 2005 - 2010 David Gwynne <dlg@openbsd.org>
6  * Copyright (c) 2005 - 2010 Marco Peereboom <marco@openbsd.org>
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/malloc.h>
29 #include <sys/kernel.h>
30 #include <sys/rwlock.h>
31 #include <sys/sensors.h>
32 #include <sys/dkio.h>
33 #include <sys/tree.h>
34 
35 #include <machine/bus.h>
36 
37 #include <dev/pci/pcireg.h>
38 #include <dev/pci/pcivar.h>
39 #include <dev/pci/pcidevs.h>
40 
41 #include <scsi/scsi_all.h>
42 #include <scsi/scsiconf.h>
43 
44 #include <dev/biovar.h>
45 
46 #define MPII_DOORBELL			(0x00)
47 /* doorbell read bits */
48 #define MPII_DOORBELL_STATE		(0xf<<28) /* ioc state */
49 #define  MPII_DOORBELL_STATE_RESET	(0x0<<28)
50 #define  MPII_DOORBELL_STATE_READY	(0x1<<28)
51 #define  MPII_DOORBELL_STATE_OPER	(0x2<<28)
52 #define  MPII_DOORBELL_STATE_FAULT	(0x4<<28)
53 #define  MPII_DOORBELL_INUSE		(0x1<<27) /* doorbell used */
54 #define MPII_DOORBELL_WHOINIT		(0x7<<24) /* last to reset ioc */
55 #define  MPII_DOORBELL_WHOINIT_NOONE	(0x0<<24) /* not initialized */
56 #define  MPII_DOORBELL_WHOINIT_SYSBIOS	(0x1<<24) /* system bios */
57 #define  MPII_DOORBELL_WHOINIT_ROMBIOS	(0x2<<24) /* rom bios */
58 #define  MPII_DOORBELL_WHOINIT_PCIPEER	(0x3<<24) /* pci peer */
59 #define  MPII_DOORBELL_WHOINIT_DRIVER	(0x4<<24) /* host driver */
60 #define  MPII_DOORBELL_WHOINIT_MANUFACT	(0x5<<24) /* manufacturing */
61 #define MPII_DOORBELL_FAULT		(0xffff<<0) /* fault code */
62 /* doorbell write bits */
63 #define MPII_DOORBELL_FUNCTION_SHIFT	(24)
64 #define MPII_DOORBELL_FUNCTION_MASK	(0xff << MPII_DOORBELL_FUNCTION_SHIFT)
65 #define MPII_DOORBELL_FUNCTION(x)	\
66     (((x) << MPII_DOORBELL_FUNCTION_SHIFT) & MPII_DOORBELL_FUNCTION_MASK)
67 #define MPII_DOORBELL_DWORDS_SHIFT	16
68 #define MPII_DOORBELL_DWORDS_MASK	(0xff << MPII_DOORBELL_DWORDS_SHIFT)
69 #define MPII_DOORBELL_DWORDS(x)		\
70     (((x) << MPII_DOORBELL_DWORDS_SHIFT) & MPII_DOORBELL_DWORDS_MASK)
71 #define MPII_DOORBELL_DATA_MASK		(0xffff)
72 
73 #define MPII_WRITESEQ			(0x04)
74 #define  MPII_WRITESEQ_KEY_VALUE_MASK	(0x0000000f) /* key value */
75 #define  MPII_WRITESEQ_FLUSH		(0x00)
76 #define  MPII_WRITESEQ_1		(0x0f)
77 #define  MPII_WRITESEQ_2		(0x04)
78 #define  MPII_WRITESEQ_3		(0x0b)
79 #define  MPII_WRITESEQ_4		(0x02)
80 #define  MPII_WRITESEQ_5		(0x07)
81 #define  MPII_WRITESEQ_6		(0x0d)
82 
83 #define MPII_HOSTDIAG			(0x08)
84 #define  MPII_HOSTDIAG_BDS_MASK		(0x00001800) /* boot device select */
85 #define   MPII_HOSTDIAG_BDS_DEFAULT 	(0<<11)	/* default address map, flash */
86 #define   MPII_HOSTDIAG_BDS_HCDW	(1<<11)	/* host code and data window */
87 #define  MPII_HOSTDIAG_CLEARFBS		(1<<10) /* clear flash bad sig */
88 #define  MPII_HOSTDIAG_FORCE_HCB_ONBOOT (1<<9)	/* force host controlled boot */
89 #define  MPII_HOSTDIAG_HCB_MODE		(1<<8)	/* host controlled boot mode */
90 #define  MPII_HOSTDIAG_DWRE		(1<<7) 	/* diag reg write enabled */
91 #define  MPII_HOSTDIAG_FBS		(1<<6) 	/* flash bad sig */
92 #define  MPII_HOSTDIAG_RESET_HIST	(1<<5) 	/* reset history */
93 #define  MPII_HOSTDIAG_DIAGWR_EN	(1<<4) 	/* diagnostic write enabled */
94 #define  MPII_HOSTDIAG_RESET_ADAPTER	(1<<2) 	/* reset adapter */
95 #define  MPII_HOSTDIAG_HOLD_IOC_RESET	(1<<1) 	/* hold ioc in reset */
96 #define  MPII_HOSTDIAG_DIAGMEM_EN	(1<<0) 	/* diag mem enable */
97 
98 #define MPII_DIAGRWDATA			(0x10)
99 
100 #define MPII_DIAGRWADDRLOW		(0x14)
101 
102 #define MPII_DIAGRWADDRHIGH		(0x18)
103 
104 #define MPII_INTR_STATUS		(0x30)
105 #define  MPII_INTR_STATUS_SYS2IOCDB	(1<<31) /* ioc written to by host */
106 #define  MPII_INTR_STATUS_RESET		(1<<30) /* physical ioc reset */
107 #define  MPII_INTR_STATUS_REPLY		(1<<3)	/* reply message interrupt */
108 #define  MPII_INTR_STATUS_IOC2SYSDB	(1<<0) 	/* ioc write to doorbell */
109 
110 #define MPII_INTR_MASK			(0x34)
111 #define  MPII_INTR_MASK_RESET		(1<<30) /* ioc reset intr mask */
112 #define  MPII_INTR_MASK_REPLY		(1<<3) 	/* reply message intr mask */
113 #define  MPII_INTR_MASK_DOORBELL	(1<<0) 	/* doorbell interrupt mask */
114 
115 #define MPII_DCR_DATA			(0x38)
116 
117 #define MPII_DCR_ADDRESS		(0x3c)
118 
119 #define MPII_REPLY_FREE_HOST_INDEX	(0x48)
120 
121 #define MPII_REPLY_POST_HOST_INDEX	(0x6c)
122 
123 #define MPII_HCB_SIZE			(0x74)
124 
125 #define MPII_HCB_ADDRESS_LOW		(0x78)
126 #define MPII_HCB_ADDRESS_HIGH		(0x7c)
127 
128 #define MPII_REQ_DESCR_POST_LOW		(0xc0)
129 #define MPII_REQ_DESCR_POST_HIGH	(0xc4)
130 
131 /*
132  * Scatter Gather Lists
133  */
134 
135 #define MPII_SGE_FL_LAST		(0x1<<31) /* last element in segment */
136 #define MPII_SGE_FL_EOB			(0x1<<30) /* last element of buffer */
137 #define MPII_SGE_FL_TYPE		(0x3<<28) /* element type */
138  #define MPII_SGE_FL_TYPE_SIMPLE	(0x1<<28) /* simple element */
139  #define MPII_SGE_FL_TYPE_CHAIN		(0x3<<28) /* chain element */
140  #define MPII_SGE_FL_TYPE_XACTCTX	(0x0<<28) /* transaction context */
141 #define MPII_SGE_FL_LOCAL		(0x1<<27) /* local address */
142 #define MPII_SGE_FL_DIR			(0x1<<26) /* direction */
143  #define MPII_SGE_FL_DIR_OUT		(0x1<<26)
144  #define MPII_SGE_FL_DIR_IN		(0x0<<26)
145 #define MPII_SGE_FL_SIZE		(0x1<<25) /* address size */
146  #define MPII_SGE_FL_SIZE_32		(0x0<<25)
147  #define MPII_SGE_FL_SIZE_64		(0x1<<25)
148 #define MPII_SGE_FL_EOL			(0x1<<24) /* end of list */
149 
150 struct mpii_sge {
151 	u_int32_t		sg_hdr;
152 	u_int32_t		sg_lo_addr;
153 	u_int32_t		sg_hi_addr;
154 } __packed;
155 
156 struct mpii_fw_tce {
157 	u_int8_t		reserved1;
158 	u_int8_t		context_size;
159 	u_int8_t		details_length;
160 	u_int8_t		flags;
161 
162 	u_int32_t		reserved2;
163 
164 	u_int32_t		image_offset;
165 
166 	u_int32_t		image_size;
167 } __packed;
168 
169 /*
170  * Messages
171  */
172 
173 /* functions */
174 #define MPII_FUNCTION_SCSI_IO_REQUEST			(0x00)
175 #define MPII_FUNCTION_SCSI_TASK_MGMT			(0x01)
176 #define MPII_FUNCTION_IOC_INIT				(0x02)
177 #define MPII_FUNCTION_IOC_FACTS				(0x03)
178 #define MPII_FUNCTION_CONFIG				(0x04)
179 #define MPII_FUNCTION_PORT_FACTS			(0x05)
180 #define MPII_FUNCTION_PORT_ENABLE			(0x06)
181 #define MPII_FUNCTION_EVENT_NOTIFICATION		(0x07)
182 #define MPII_FUNCTION_EVENT_ACK				(0x08)
183 #define MPII_FUNCTION_FW_DOWNLOAD			(0x09)
184 #define MPII_FUNCTION_TARGET_CMD_BUFFER_POST		(0x0a)
185 #define MPII_FUNCTION_TARGET_ASSIST			(0x0b)
186 #define MPII_FUNCTION_TARGET_STATUS_SEND		(0x0c)
187 #define MPII_FUNCTION_TARGET_MODE_ABORT			(0x0d)
188 #define MPII_FUNCTION_FW_UPLOAD				(0x12)
189 
190 #define MPII_FUNCTION_RAID_ACTION			(0x15)
191 #define MPII_FUNCTION_RAID_SCSI_IO_PASSTHROUGH		(0x16)
192 
193 #define MPII_FUNCTION_TOOLBOX				(0x17)
194 
195 #define MPII_FUNCTION_SCSI_ENCLOSURE_PROCESSOR		(0x18)
196 
197 #define MPII_FUNCTION_SMP_PASSTHROUGH			(0x1a)
198 #define MPII_FUNCTION_SAS_IO_UNIT_CONTROL		(0x1b)
199 #define MPII_FUNCTION_SATA_PASSTHROUGH			(0x1c)
200 
201 #define MPII_FUNCTION_DIAG_BUFFER_POST			(0x1d)
202 #define MPII_FUNCTION_DIAG_RELEASE			(0x1e)
203 
204 #define MPII_FUNCTION_TARGET_CMD_BUF_BASE_POST		(0x24)
205 #define MPII_FUNCTION_TARGET_CMD_BUF_LIST_POST		(0x25)
206 
207 #define MPII_FUNCTION_IOC_MESSAGE_UNIT_RESET		(0x40)
208 #define MPII_FUNCTION_IO_UNIT_RESET			(0x41)
209 #define MPII_FUNCTION_HANDSHAKE				(0x42)
210 
211 /* Common IOCStatus values for all replies */
212 #define MPII_IOCSTATUS_MASK				(0x7fff)
213 #define  MPII_IOCSTATUS_SUCCESS				(0x0000)
214 #define  MPII_IOCSTATUS_INVALID_FUNCTION		(0x0001)
215 #define  MPII_IOCSTATUS_BUSY				(0x0002)
216 #define  MPII_IOCSTATUS_INVALID_SGL			(0x0003)
217 #define  MPII_IOCSTATUS_INTERNAL_ERROR			(0x0004)
218 #define  MPII_IOCSTATUS_INVALID_VPID			(0x0005)
219 #define  MPII_IOCSTATUS_INSUFFICIENT_RESOURCES		(0x0006)
220 #define  MPII_IOCSTATUS_INVALID_FIELD			(0x0007)
221 #define  MPII_IOCSTATUS_INVALID_STATE			(0x0008)
222 #define  MPII_IOCSTATUS_OP_STATE_NOT_SUPPORTED		(0x0009)
223 /* Config IOCStatus values */
224 #define  MPII_IOCSTATUS_CONFIG_INVALID_ACTION		(0x0020)
225 #define  MPII_IOCSTATUS_CONFIG_INVALID_TYPE		(0x0021)
226 #define  MPII_IOCSTATUS_CONFIG_INVALID_PAGE		(0x0022)
227 #define  MPII_IOCSTATUS_CONFIG_INVALID_DATA		(0x0023)
228 #define  MPII_IOCSTATUS_CONFIG_NO_DEFAULTS		(0x0024)
229 #define  MPII_IOCSTATUS_CONFIG_CANT_COMMIT		(0x0025)
230 /* SCSIIO Reply initiator values */
231 #define  MPII_IOCSTATUS_SCSI_RECOVERED_ERROR		(0x0040)
232 #define  MPII_IOCSTATUS_SCSI_INVALID_DEVHANDLE		(0x0042)
233 #define  MPII_IOCSTATUS_SCSI_DEVICE_NOT_THERE		(0x0043)
234 #define  MPII_IOCSTATUS_SCSI_DATA_OVERRUN		(0x0044)
235 #define  MPII_IOCSTATUS_SCSI_DATA_UNDERRUN		(0x0045)
236 #define  MPII_IOCSTATUS_SCSI_IO_DATA_ERROR		(0x0046)
237 #define  MPII_IOCSTATUS_SCSI_PROTOCOL_ERROR		(0x0047)
238 #define  MPII_IOCSTATUS_SCSI_TASK_TERMINATED		(0x0048)
239 #define  MPII_IOCSTATUS_SCSI_RESIDUAL_MISMATCH		(0x0049)
240 #define  MPII_IOCSTATUS_SCSI_TASK_MGMT_FAILED		(0x004a)
241 #define  MPII_IOCSTATUS_SCSI_IOC_TERMINATED		(0x004b)
242 #define  MPII_IOCSTATUS_SCSI_EXT_TERMINATED		(0x004c)
243 /* For use by SCSI Initiator and SCSI Target end-to-end data protection */
244 #define  MPII_IOCSTATUS_EEDP_GUARD_ERROR		(0x004d)
245 #define  MPII_IOCSTATUS_EEDP_REF_TAG_ERROR		(0x004e)
246 #define  MPII_IOCSTATUS_EEDP_APP_TAG_ERROR		(0x004f)
247 /* SCSI (SPI & FCP) target values */
248 #define  MPII_IOCSTATUS_TARGET_INVALID_IO_INDEX		(0x0062)
249 #define  MPII_IOCSTATUS_TARGET_ABORTED			(0x0063)
250 #define  MPII_IOCSTATUS_TARGET_NO_CONN_RETRYABLE	(0x0064)
251 #define  MPII_IOCSTATUS_TARGET_NO_CONNECTION		(0x0065)
252 #define  MPII_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH	(0x006a)
253 #define  MPII_IOCSTATUS_TARGET_DATA_OFFSET_ERROR	(0x006d)
254 #define  MPII_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA	(0x006e)
255 #define  MPII_IOCSTATUS_TARGET_IU_TOO_SHORT		(0x006f)
256 #define  MPII_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT		(0x0070)
257 #define  MPII_IOCSTATUS_TARGET_NAK_RECEIVED		(0x0071)
258 /* Serial Attached SCSI values */
259 #define  MPII_IOCSTATUS_SAS_SMP_REQUEST_FAILED		(0x0090)
260 #define  MPII_IOCSTATUS_SAS_SMP_DATA_OVERRUN		(0x0091)
261 /* Diagnostic Tools values */
262 #define  MPII_IOCSTATUS_DIAGNOSTIC_RELEASED		(0x00a0)
263 
264 #define MPII_REP_IOCLOGINFO_TYPE			(0xf<<28)
265 #define MPII_REP_IOCLOGINFO_TYPE_NONE			(0x0<<28)
266 #define MPII_REP_IOCLOGINFO_TYPE_SCSI			(0x1<<28)
267 #define MPII_REP_IOCLOGINFO_TYPE_FC			(0x2<<28)
268 #define MPII_REP_IOCLOGINFO_TYPE_SAS			(0x3<<28)
269 #define MPII_REP_IOCLOGINFO_TYPE_ISCSI			(0x4<<28)
270 #define MPII_REP_IOCLOGINFO_DATA			(0x0fffffff)
271 
272 /* event notification types */
273 #define MPII_EVENT_NONE					(0x00)
274 #define MPII_EVENT_LOG_DATA				(0x01)
275 #define MPII_EVENT_STATE_CHANGE				(0x02)
276 #define MPII_EVENT_HARD_RESET_RECEIVED			(0x05)
277 #define MPII_EVENT_EVENT_CHANGE				(0x0a)
278 #define MPII_EVENT_TASK_SET_FULL			(0x0e)
279 #define MPII_EVENT_SAS_DEVICE_STATUS_CHANGE		(0x0f)
280 #define MPII_EVENT_IR_OPERATION_STATUS			(0x14)
281 #define MPII_EVENT_SAS_DISCOVERY			(0x16)
282 #define MPII_EVENT_SAS_BROADCAST_PRIMITIVE		(0x17)
283 #define MPII_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE	(0x18)
284 #define MPII_EVENT_SAS_INIT_TABLE_OVERFLOW		(0x19)
285 #define MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST		(0x1c)
286 #define MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE	(0x1d)
287 #define MPII_EVENT_IR_VOLUME				(0x1e)
288 #define MPII_EVENT_IR_PHYSICAL_DISK			(0x1f)
289 #define MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST		(0x20)
290 #define MPII_EVENT_LOG_ENTRY_ADDED			(0x21)
291 
292 /* messages */
293 
294 #define MPII_WHOINIT_NOONE				(0x00)
295 #define MPII_WHOINIT_SYSTEM_BIOS			(0x01)
296 #define MPII_WHOINIT_ROM_BIOS				(0x02)
297 #define MPII_WHOINIT_PCI_PEER				(0x03)
298 #define MPII_WHOINIT_HOST_DRIVER			(0x04)
299 #define MPII_WHOINIT_MANUFACTURER			(0x05)
300 
301 /* default messages */
302 
303 struct mpii_msg_request {
304 	u_int8_t		reserved1;
305 	u_int8_t		reserved2;
306 	u_int8_t		chain_offset;
307 	u_int8_t		function;
308 
309 	u_int8_t		reserved3;
310 	u_int8_t		reserved4;
311 	u_int8_t		reserved5;
312 	u_int8_t		msg_flags;
313 
314 	u_int8_t		vp_id;
315 	u_int8_t		vf_id;
316 	u_int16_t		reserved6;
317 } __packed;
318 
319 struct mpii_msg_reply {
320 	u_int16_t		reserved1;
321 	u_int8_t		msg_length;
322 	u_int8_t		function;
323 
324 	u_int16_t		reserved2;
325 	u_int8_t		reserved3;
326 	u_int8_t		msg_flags;
327 
328 	u_int8_t		vp_id;
329 	u_int8_t		vf_if;
330 	u_int16_t		reserved4;
331 
332 	u_int16_t		reserved5;
333 	u_int16_t		ioc_status;
334 
335 	u_int32_t		ioc_loginfo;
336 } __packed;
337 
338 /* ioc init */
339 
340 struct mpii_msg_iocinit_request {
341 	u_int8_t		whoinit;
342 	u_int8_t		reserved1;
343 	u_int8_t		chain_offset;
344 	u_int8_t		function;
345 
346 	u_int16_t		reserved2;
347 	u_int8_t		reserved3;
348 	u_int8_t		msg_flags;
349 
350 	u_int8_t		vp_id;
351 	u_int8_t		vf_id;
352 	u_int16_t		reserved4;
353 
354 	u_int8_t		msg_version_min;
355 	u_int8_t		msg_version_maj;
356 	u_int8_t		hdr_version_unit;
357 	u_int8_t		hdr_version_dev;
358 
359 	u_int32_t		reserved5;
360 
361 	u_int32_t		reserved6;
362 
363 	u_int16_t		reserved7;
364 	u_int16_t		system_request_frame_size;
365 
366 	u_int16_t		reply_descriptor_post_queue_depth;
367 	u_int16_t		reply_free_queue_depth;
368 
369 	u_int32_t		sense_buffer_address_high;
370 
371 	u_int32_t		system_reply_address_high;
372 
373 	u_int64_t		system_request_frame_base_address;
374 
375 	u_int64_t		reply_descriptor_post_queue_address;
376 
377 	u_int64_t		reply_free_queue_address;
378 
379 	u_int64_t		timestamp;
380 } __packed;
381 
382 struct mpii_msg_iocinit_reply {
383 	u_int8_t		whoinit;
384 	u_int8_t		reserved1;
385 	u_int8_t		msg_length;
386 	u_int8_t		function;
387 
388 	u_int16_t		reserved2;
389 	u_int8_t		reserved3;
390 	u_int8_t		msg_flags;
391 
392 	u_int8_t		vp_id;
393 	u_int8_t		vf_id;
394 	u_int16_t		reserved4;
395 
396 	u_int16_t		reserved5;
397 	u_int16_t		ioc_status;
398 
399 	u_int32_t		ioc_loginfo;
400 } __packed;
401 
402 struct mpii_msg_iocfacts_request {
403 	u_int16_t		reserved1;
404 	u_int8_t		chain_offset;
405 	u_int8_t		function;
406 
407 	u_int16_t		reserved2;
408 	u_int8_t		reserved3;
409 	u_int8_t		msg_flags;
410 
411 	u_int8_t		vp_id;
412 	u_int8_t		vf_id;
413 	u_int16_t		reserved4;
414 } __packed;
415 
416 struct mpii_msg_iocfacts_reply {
417 	u_int8_t		msg_version_min;
418 	u_int8_t		msg_version_maj;
419 	u_int8_t		msg_length;
420 	u_int8_t		function;
421 
422 	u_int8_t		header_version_dev;
423 	u_int8_t		header_version_unit;
424 	u_int8_t		ioc_number;
425 	u_int8_t		msg_flags;
426 
427 	u_int8_t		vp_id;
428 	u_int8_t		vf_id;
429 	u_int16_t		reserved1;
430 
431 	u_int16_t		ioc_exceptions;
432 #define MPII_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL	(1<<0)
433 #define MPII_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID	(1<<1)
434 #define MPII_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL		(1<<2)
435 #define MPII_IOCFACTS_EXCEPT_MANUFACT_CHECKSUM_FAIL	(1<<3)
436 #define MPII_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED	(1<<4)
437 #define MPII_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAC	(1<<8)
438 	/* XXX JPG BOOT_STATUS in bits[7:5] */
439 	/* XXX JPG all these #defines need to be fixed up */
440 	u_int16_t		ioc_status;
441 
442 	u_int32_t		ioc_loginfo;
443 
444 	u_int8_t		max_chain_depth;
445 	u_int8_t		whoinit;
446 	u_int8_t		number_of_ports;
447 	u_int8_t		reserved2;
448 
449 	u_int16_t		request_credit;
450 	u_int16_t		product_id;
451 
452 	u_int32_t		ioc_capabilities;
453 #define MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY           (1<<13)
454 #define MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID        (1<<12)
455 #define MPII_IOCFACTS_CAPABILITY_TLR                    (1<<11)
456 #define MPII_IOCFACTS_CAPABILITY_MULTICAST              (1<<8)
457 #define MPII_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET   (1<<7)
458 #define MPII_IOCFACTS_CAPABILITY_EEDP                   (1<<6)
459 #define MPII_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER        (1<<4)
460 #define MPII_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER      (1<<3)
461 #define MPII_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (1<<2)
462 
463 	u_int8_t		fw_version_dev;
464 	u_int8_t		fw_version_unit;
465 	u_int8_t		fw_version_min;
466 	u_int8_t		fw_version_maj;
467 
468 	u_int16_t		ioc_request_frame_size;
469 	u_int16_t		reserved3;
470 
471 	u_int16_t		max_initiators;
472 	u_int16_t		max_targets;
473 
474 	u_int16_t		max_sas_expanders;
475 	u_int16_t		max_enclosures;
476 
477 	u_int16_t		protocol_flags;
478 	u_int16_t		high_priority_credit;
479 
480 	u_int16_t		max_reply_descriptor_post_queue_depth;
481 	u_int8_t		reply_frame_size;
482 	u_int8_t		max_volumes;
483 
484 	u_int16_t		max_dev_handle;
485 	u_int16_t		max_persistent_entries;
486 
487 	u_int32_t		reserved4;
488 } __packed;
489 
490 struct mpii_msg_portfacts_request {
491 	u_int16_t		reserved1;
492 	u_int8_t		chain_offset;
493 	u_int8_t		function;
494 
495 	u_int16_t		reserved2;
496 	u_int8_t		port_number;
497 	u_int8_t		msg_flags;
498 
499 	u_int8_t		vp_id;
500 	u_int8_t		vf_id;
501 	u_int16_t		reserved3;
502 } __packed;
503 
504 struct mpii_msg_portfacts_reply {
505 	u_int16_t		reserved1;
506 	u_int8_t		msg_length;
507 	u_int8_t		function;
508 
509 	u_int16_t		reserved2;
510 	u_int8_t		port_number;
511 	u_int8_t		msg_flags;
512 
513 	u_int8_t		vp_id;
514 	u_int8_t		vf_id;
515 	u_int16_t		reserved3;
516 
517 	u_int16_t		reserved4;
518 	u_int16_t		ioc_status;
519 
520 	u_int32_t		ioc_loginfo;
521 
522 	u_int8_t		reserved5;
523 	u_int8_t		port_type;
524 #define MPII_PORTFACTS_PORTTYPE_INACTIVE		(0x00)
525 #define MPII_PORTFACTS_PORTTYPE_FC			(0x10)
526 #define MPII_PORTFACTS_PORTTYPE_ISCSI			(0x20)
527 #define MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL		(0x30)
528 #define MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL		(0x31)
529 	u_int16_t		reserved6;
530 
531 	u_int16_t		max_posted_cmd_buffers;
532 	u_int16_t		reserved7;
533 } __packed;
534 
535 struct mpii_msg_portenable_request {
536 	u_int16_t		reserved1;
537 	u_int8_t		chain_offset;
538 	u_int8_t		function;
539 
540 	u_int8_t		reserved2;
541 	u_int8_t		port_flags;
542 	u_int8_t		reserved3;
543 	u_int8_t		msg_flags;
544 
545 	u_int8_t		vp_id;
546 	u_int8_t		vf_id;
547 	u_int16_t		reserved4;
548 } __packed;
549 
550 struct mpii_msg_portenable_reply {
551 	u_int16_t		reserved1;
552 	u_int8_t		msg_length;
553 	u_int8_t		function;
554 
555 	u_int8_t		reserved2;
556 	u_int8_t		port_flags;
557 	u_int8_t		reserved3;
558 	u_int8_t		msg_flags;
559 
560 	u_int8_t		vp_id;
561 	u_int8_t		vf_id;
562 	u_int16_t		reserved4;
563 
564 	u_int16_t		reserved5;
565 	u_int16_t		ioc_status;
566 
567 	u_int32_t		ioc_loginfo;
568 } __packed;
569 
570 struct mpii_msg_event_request {
571 	u_int16_t		reserved1;
572 	u_int8_t		chain_offset;
573 	u_int8_t		function;
574 
575 	u_int16_t		reserved2;
576 	u_int8_t		reserved3;
577 	u_int8_t		msg_flags;
578 
579 	u_int8_t		vp_id;
580 	u_int8_t		vf_id;
581 	u_int16_t		reserved4;
582 
583 	u_int32_t		reserved5;
584 
585 	u_int32_t		reserved6;
586 
587 	u_int32_t		event_masks[4];
588 
589 	u_int16_t		sas_broadcase_primitive_masks;
590 	u_int16_t		reserved7;
591 
592 	u_int32_t		reserved8;
593 } __packed;
594 
595 struct mpii_msg_event_reply {
596 	u_int16_t		event_data_length;
597 	u_int8_t		msg_length;
598 	u_int8_t		function;
599 
600 	u_int16_t		reserved1;
601 	u_int8_t		ack_required;
602 #define MPII_EVENT_ACK_REQUIRED				(0x01)
603 	u_int8_t		msg_flags;
604 #define MPII_EVENT_FLAGS_REPLY_KEPT			(1<<7)
605 
606 	u_int8_t		vp_id;
607 	u_int8_t		vf_id;
608 	u_int16_t		reserved2;
609 
610 	u_int16_t		reserved3;
611 	u_int16_t		ioc_status;
612 
613 	u_int32_t		ioc_loginfo;
614 
615 	u_int16_t		event;
616 	u_int16_t		reserved4;
617 
618 	u_int32_t		event_context;
619 
620 	/* event data follows */
621 } __packed;
622 
623 struct mpii_msg_eventack_request {
624 	u_int16_t		reserved1;
625 	u_int8_t		chain_offset;
626 	u_int8_t		function;
627 
628 	u_int8_t		reserved2[3];
629 	u_int8_t		msg_flags;
630 
631 	u_int8_t		vp_id;
632 	u_int8_t		vf_id;
633 	u_int16_t		reserved3;
634 
635 	u_int16_t		event;
636 	u_int16_t		reserved4;
637 
638 	u_int32_t		event_context;
639 } __packed;
640 
641 struct mpii_msg_eventack_reply {
642 	u_int16_t		reserved1;
643 	u_int8_t		msg_length;
644 	u_int8_t		function;
645 
646 	u_int8_t		reserved2[3];
647 	u_int8_t		msg_flags;
648 
649 	u_int8_t		vp_id;
650 	u_int8_t		vf_id;
651 	u_int16_t		reserved3;
652 
653 	u_int16_t		reserved4;
654 	u_int16_t		ioc_status;
655 
656 	u_int32_t		ioc_loginfo;
657 } __packed;
658 
659 struct mpii_msg_fwupload_request {
660 	u_int8_t		image_type;
661 #define MPII_FWUPLOAD_IMAGETYPE_IOC_FW			(0x00)
662 #define MPII_FWUPLOAD_IMAGETYPE_NV_FW			(0x01)
663 #define MPII_FWUPLOAD_IMAGETYPE_NV_BACKUP		(0x05)
664 #define MPII_FWUPLOAD_IMAGETYPE_NV_MANUFACTURING	(0x06)
665 #define MPII_FWUPLOAD_IMAGETYPE_NV_CONFIG_1		(0x07)
666 #define MPII_FWUPLOAD_IMAGETYPE_NV_CONFIG_2		(0x08)
667 #define MPII_FWUPLOAD_IMAGETYPE_NV_MEGARAID		(0x09)
668 #define MPII_FWUPLOAD_IMAGETYPE_NV_COMPLETE		(0x0a)
669 #define MPII_FWUPLOAD_IMAGETYPE_COMMON_BOOT_BLOCK	(0x0b)
670 	u_int8_t		reserved1;
671 	u_int8_t		chain_offset;
672 	u_int8_t		function;
673 
674 	u_int8_t		reserved2[3];
675 	u_int8_t		msg_flags;
676 
677 	u_int8_t		vp_id;
678 	u_int8_t		vf_id;
679 	u_int16_t		reserved3;
680 
681 	u_int32_t		reserved4;
682 
683 	u_int32_t		reserved5;
684 
685 	struct mpii_fw_tce	tce;
686 
687 	/* followed by an sgl */
688 } __packed;
689 
690 struct mpii_msg_fwupload_reply {
691 	u_int8_t		image_type;
692 	u_int8_t		reserved1;
693 	u_int8_t		msg_length;
694 	u_int8_t		function;
695 
696 	u_int8_t		reserved2[3];
697 	u_int8_t		msg_flags;
698 
699 	u_int8_t		vp_id;
700 	u_int8_t		vf_id;
701 	u_int16_t		reserved3;
702 
703 	u_int16_t		reserved4;
704 	u_int16_t		ioc_status;
705 
706 	u_int32_t		ioc_loginfo;
707 
708 	u_int32_t		actual_image_size;
709 } __packed;
710 
711 struct mpii_msg_scsi_io {
712 	u_int16_t		dev_handle;
713 	u_int8_t		chain_offset;
714 	u_int8_t		function;
715 
716 	u_int16_t		reserved1;
717 	u_int8_t		reserved2;
718 	u_int8_t		msg_flags;
719 
720 	u_int8_t		vp_id;
721 	u_int8_t		vf_id;
722 	u_int16_t		reserved3;
723 
724 	u_int32_t		sense_buffer_low_address;
725 
726 	u_int16_t		sgl_flags;
727 	u_int8_t		sense_buffer_length;
728 	u_int8_t		reserved4;
729 
730 	u_int8_t		sgl_offset0;
731 	u_int8_t		sgl_offset1;
732 	u_int8_t		sgl_offset2;
733 	u_int8_t		sgl_offset3;
734 
735 	u_int32_t		skip_count;
736 
737 	u_int32_t		data_length;
738 
739 	u_int32_t		bidirectional_data_length;
740 
741 	u_int16_t		io_flags;
742 	u_int16_t		eedp_flags;
743 
744 	u_int32_t		eedp_block_size;
745 
746 	u_int32_t		secondary_reference_tag;
747 
748 	u_int16_t		secondary_application_tag;
749 	u_int16_t		application_tag_translation_mask;
750 
751 	u_int16_t		lun[4];
752 
753 /* the following 16 bits are defined in MPI2 as the control field */
754 	u_int8_t		reserved5;
755 	u_int8_t		tagging;
756 #define MPII_SCSIIO_ATTR_SIMPLE_Q			(0x0)
757 #define MPII_SCSIIO_ATTR_HEAD_OF_Q			(0x1)
758 #define MPII_SCSIIO_ATTR_ORDERED_Q			(0x2)
759 #define MPII_SCSIIO_ATTR_ACA_Q				(0x4)
760 #define MPII_SCSIIO_ATTR_UNTAGGED			(0x5)
761 #define MPII_SCSIIO_ATTR_NO_DISCONNECT			(0x7)
762 	u_int8_t		reserved6;
763 	u_int8_t		direction;
764 #define MPII_SCSIIO_DIR_NONE				(0x0)
765 #define MPII_SCSIIO_DIR_WRITE				(0x1)
766 #define MPII_SCSIIO_DIR_READ				(0x2)
767 
768 #define	MPII_CDB_LEN					(32)
769 	u_int8_t		cdb[MPII_CDB_LEN];
770 
771 	/* followed by an sgl */
772 } __packed;
773 
774 struct mpii_msg_scsi_io_error {
775 	u_int16_t		dev_handle;
776 	u_int8_t		msg_length;
777 	u_int8_t		function;
778 
779 	u_int16_t		reserved1;
780 	u_int8_t		reserved2;
781 	u_int8_t		msg_flags;
782 
783 	u_int8_t		vp_id;
784 	u_int8_t		vf_id;
785 	u_int16_t		reserved3;
786 
787 	u_int8_t		scsi_status;
788 	/* XXX JPG validate this */
789 #if notyet
790 #define MPII_SCSIIO_ERR_STATUS_SUCCESS
791 #define MPII_SCSIIO_ERR_STATUS_CHECK_COND
792 #define MPII_SCSIIO_ERR_STATUS_BUSY
793 #define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE
794 #define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET
795 #define MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT
796 #define MPII_SCSIIO_ERR_STATUS_CMD_TERM
797 #define MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL
798 #define MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE
799 #endif
800 	u_int8_t		scsi_state;
801 #define MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID		(1<<0)
802 #define MPII_SCSIIO_ERR_STATE_AUTOSENSE_FAILED		(1<<1)
803 #define MPII_SCSIIO_ERR_STATE_NO_SCSI_STATUS		(1<<2)
804 #define MPII_SCSIIO_ERR_STATE_TERMINATED		(1<<3)
805 #define MPII_SCSIIO_ERR_STATE_RESPONSE_INFO_VALID	(1<<4)
806 #define MPII_SCSIIO_ERR_STATE_QUEUE_TAG_REJECTED	(0xffff)
807 	u_int16_t		ioc_status;
808 
809 	u_int32_t		ioc_loginfo;
810 
811 	u_int32_t		transfer_count;
812 
813 	u_int32_t		sense_count;
814 
815 	u_int32_t		response_info;
816 
817 	u_int16_t		task_tag;
818 	u_int16_t		reserved4;
819 
820 	u_int32_t		bidirectional_transfer_count;
821 
822 	u_int32_t		reserved5;
823 
824 	u_int32_t		reserved6;
825 } __packed;
826 
827 struct mpii_request_descr {
828 	u_int8_t		request_flags;
829 #define MPII_REQ_DESCR_TYPE_MASK			(0x0e)
830 #define MPII_REQ_DESCR_SCSI_IO				(0x00)
831 #define MPII_REQ_DESCR_SCSI_TARGET			(0x02)
832 #define MPII_REQ_DESCR_HIGH_PRIORITY			(0x06)
833 #define MPII_REQ_DESCR_DEFAULT				(0x08)
834 	u_int8_t		vf_id;
835 	u_int16_t		smid;
836 
837 	u_int16_t		lmid;
838 	u_int16_t		dev_handle;
839 } __packed;
840 
841 struct mpii_reply_descr {
842 	u_int8_t		reply_flags;
843 #define MPII_REPLY_DESCR_TYPE_MASK               	(0x0f)
844 #define MPII_REPLY_DESCR_SCSI_IO_SUCCESS         	(0x00)
845 #define MPII_REPLY_DESCR_ADDRESS_REPLY           	(0x01)
846 #define MPII_REPLY_DESCR_TARGET_ASSIST_SUCCESS    	(0x02)
847 #define MPII_REPLY_DESCR_TARGET_COMMAND_BUFFER   	(0x03)
848 #define MPII_REPLY_DESCR_UNUSED                  	(0x0f)
849 	u_int8_t		vf_id;
850 	u_int16_t		smid;
851 
852 	union {
853 		u_int32_t	data;
854 		u_int32_t	frame_addr;	/* Address Reply */
855 	};
856 } __packed;
857 
858 struct mpii_request_header {
859 	u_int16_t		function_dependent1;
860 	u_int8_t		chain_offset;
861 	u_int8_t		function;
862 
863 	u_int16_t		function_dependent2;
864 	u_int8_t		function_dependent3;
865 	u_int8_t		message_flags;
866 
867 	u_int8_t		vp_id;
868 	u_int8_t		vf_id;
869 	u_int16_t		reserved;
870 } __packed;
871 
872 struct mpii_msg_scsi_task_request {
873 	u_int16_t		dev_handle;
874 	u_int8_t		chain_offset;
875 	u_int8_t		function;
876 
877 	u_int8_t		reserved1;
878 	u_int8_t		task_type;
879 #define MPII_SCSI_TASK_ABORT_TASK			(0x01)
880 #define MPII_SCSI_TASK_ABRT_TASK_SET			(0x02)
881 #define MPII_SCSI_TASK_TARGET_RESET			(0x03)
882 #define MPII_SCSI_TASK_RESET_BUS			(0x04)
883 #define MPII_SCSI_TASK_LOGICAL_UNIT_RESET		(0x05)
884 	u_int8_t		reserved2;
885 	u_int8_t		msg_flags;
886 
887 	u_int8_t		vp_id;
888 	u_int8_t		vf_id;
889 	u_int16_t		reserved3;
890 
891 	u_int16_t		lun[4];
892 
893 	u_int32_t		reserved4[7];
894 
895 	u_int16_t		task_mid;
896 	u_int16_t		reserved5;
897 } __packed;
898 
899 struct mpii_msg_scsi_task_reply {
900 	u_int16_t		dev_handle;
901 	u_int8_t		msg_length;
902 	u_int8_t		function;
903 
904 	u_int8_t		response_code;
905 	u_int8_t		task_type;
906 	u_int8_t		reserved1;
907 	u_int8_t		msg_flags;
908 
909 	u_int8_t		vp_id;
910 	u_int8_t		vf_id;
911 	u_int16_t		reserved2;
912 
913 	u_int16_t		reserved3;
914 	u_int16_t		ioc_status;
915 
916 	u_int32_t		ioc_loginfo;
917 
918 	u_int32_t		termination_count;
919 } __packed;
920 
921 struct mpii_msg_sas_oper_request {
922 	u_int8_t		operation;
923 #define MPII_SAS_OP_CLEAR_PERSISTENT		(0x02)
924 #define MPII_SAS_OP_PHY_LINK_RESET		(0x06)
925 #define MPII_SAS_OP_PHY_HARD_RESET		(0x07)
926 #define MPII_SAS_OP_PHY_CLEAR_ERROR_LOG		(0x08)
927 #define MPII_SAS_OP_SEND_PRIMITIVE		(0x0a)
928 #define MPII_SAS_OP_FORCE_FULL_DISCOVERY	(0x0b)
929 #define MPII_SAS_OP_TRANSMIT_PORT_SELECT	(0x0c)
930 #define MPII_SAS_OP_REMOVE_DEVICE		(0x0d)
931 #define MPII_SAS_OP_LOOKUP_MAPPING		(0x0e)
932 #define MPII_SAS_OP_SET_IOC_PARAM		(0x0f)
933 	u_int8_t		reserved1;
934 	u_int8_t		chain_offset;
935 	u_int8_t		function;
936 
937 	u_int16_t		dev_handle;
938 	u_int8_t		ioc_param;
939 	u_int8_t		msg_flags;
940 
941 	u_int8_t		vp_id;
942 	u_int8_t		vf_id;
943 	u_int16_t		reserved2;
944 
945 	u_int16_t		reserved3;
946 	u_int8_t		phy_num;
947 	u_int8_t		prim_flags;
948 
949 	u_int32_t		primitive;
950 
951 	u_int8_t		lookup_method;
952 #define MPII_SAS_LOOKUP_METHOD_SAS_ADDR		(0x01)
953 #define MPII_SAS_LOOKUP_METHOD_SAS_ENCL		(0x02)
954 #define MPII_SAS_LOOKUP_METHOD_SAS_DEVNAME	(0x03)
955 	u_int8_t		reserved4;
956 	u_int16_t		slot_num;
957 
958 	u_int64_t		lookup_addr;
959 
960 	u_int32_t		ioc_param_value;
961 
962 	u_int64_t		reserved5;
963 } __packed;
964 
965 struct mpii_msg_sas_oper_reply {
966 	u_int8_t		operation;
967 	u_int8_t		reserved1;
968 	u_int8_t		chain_offset;
969 	u_int8_t		function;
970 
971 	u_int16_t		dev_handle;
972 	u_int8_t		ioc_param;
973 	u_int8_t		msg_flags;
974 
975 	u_int8_t		vp_id;
976 	u_int8_t		vf_id;
977 	u_int16_t		reserved2;
978 
979 	u_int16_t		reserved3;
980 	u_int16_t		ioc_status;
981 
982 	u_int32_t		ioc_loginfo;
983 } __packed;
984 
985 struct mpii_msg_raid_action_request {
986 	u_int8_t	action;
987 #define MPII_RAID_ACTION_CHANGE_VOL_WRITE_CACHE	(0x17)
988 	u_int8_t	reserved1;
989 	u_int8_t	chain_offset;
990 	u_int8_t	function;
991 
992 	u_int16_t	vol_dev_handle;
993 	u_int8_t	phys_disk_num;
994 	u_int8_t	msg_flags;
995 
996 	u_int8_t	vp_id;
997 	u_int8_t	vf_if;
998 	u_int16_t	reserved2;
999 
1000 	u_int32_t	reserved3;
1001 
1002 	u_int32_t	action_data;
1003 #define MPII_RAID_VOL_WRITE_CACHE_MASK			(0x03)
1004 #define MPII_RAID_VOL_WRITE_CACHE_DISABLE		(0x01)
1005 #define MPII_RAID_VOL_WRITE_CACHE_ENABLE		(0x02)
1006 
1007 	struct mpii_sge	action_sge;
1008 } __packed;
1009 
1010 struct mpii_msg_raid_action_reply {
1011 	u_int8_t	action;
1012 	u_int8_t	reserved1;
1013 	u_int8_t	chain_offset;
1014 	u_int8_t	function;
1015 
1016 	u_int16_t	vol_dev_handle;
1017 	u_int8_t	phys_disk_num;
1018 	u_int8_t	msg_flags;
1019 
1020 	u_int8_t	vp_id;
1021 	u_int8_t	vf_if;
1022 	u_int16_t	reserved2;
1023 
1024 	u_int16_t	reserved3;
1025 	u_int16_t	ioc_status;
1026 
1027 	u_int32_t	action_data[5];
1028 } __packed;
1029 
1030 struct mpii_cfg_hdr {
1031 	u_int8_t		page_version;
1032 	u_int8_t		page_length;
1033 	u_int8_t		page_number;
1034 	u_int8_t		page_type;
1035 #define MPII_CONFIG_REQ_PAGE_TYPE_ATTRIBUTE		(0xf0)
1036 #define MPI2_CONFIG_PAGEATTR_READ_ONLY              	(0x00)
1037 #define MPI2_CONFIG_PAGEATTR_CHANGEABLE             	(0x10)
1038 #define MPI2_CONFIG_PAGEATTR_PERSISTENT             	(0x20)
1039 
1040 #define MPII_CONFIG_REQ_PAGE_TYPE_MASK			(0x0f)
1041 #define MPII_CONFIG_REQ_PAGE_TYPE_IO_UNIT		(0x00)
1042 #define MPII_CONFIG_REQ_PAGE_TYPE_IOC			(0x01)
1043 #define MPII_CONFIG_REQ_PAGE_TYPE_BIOS			(0x02)
1044 #define MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL		(0x08)
1045 #define MPII_CONFIG_REQ_PAGE_TYPE_MANUFACTURING		(0x09)
1046 #define MPII_CONFIG_REQ_PAGE_TYPE_RAID_PD		(0x0a)
1047 #define MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED		(0x0f)
1048 } __packed;
1049 
1050 struct mpii_ecfg_hdr {
1051 	u_int8_t		page_version;
1052 	u_int8_t		reserved1;
1053 	u_int8_t		page_number;
1054 	u_int8_t		page_type;
1055 
1056 	u_int16_t		ext_page_length;
1057 	u_int8_t		ext_page_type;
1058 #define MPII_CONFIG_REQ_PAGE_TYPE_SAS_DEVICE		(0x12)
1059 #define MPII_CONFIG_REQ_PAGE_TYPE_RAID_CONFIG		(0x16)
1060 #define MPII_CONFIG_REQ_PAGE_TYPE_DRIVER_MAPPING	(0x17)
1061 	u_int8_t		reserved2;
1062 } __packed;
1063 
1064 struct mpii_msg_config_request {
1065 	u_int8_t		action;
1066 #define MPII_CONFIG_REQ_ACTION_PAGE_HEADER		(0x00)
1067 #define MPII_CONFIG_REQ_ACTION_PAGE_READ_CURRENT	(0x01)
1068 #define MPII_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT	(0x02)
1069 #define MPII_CONFIG_REQ_ACTION_PAGE_DEFAULT		(0x03)
1070 #define MPII_CONFIG_REQ_ACTION_PAGE_WRITE_NVRAM		(0x04)
1071 #define MPII_CONFIG_REQ_ACTION_PAGE_READ_DEFAULT	(0x05)
1072 #define MPII_CONFIG_REQ_ACTION_PAGE_READ_NVRAM		(0x06)
1073 	u_int8_t		sgl_flags;
1074 	u_int8_t		chain_offset;
1075 	u_int8_t		function;
1076 
1077 	u_int16_t		ext_page_len;
1078 	u_int8_t		ext_page_type;
1079 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_IO_UNIT	(0x10)
1080 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_EXPANDER	(0x11)
1081 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_DEVICE		(0x12)
1082 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_PHY		(0x13)
1083 #define MPII_CONFIG_REQ_EXTPAGE_TYPE_LOG		(0x14)
1084 #define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE            	(0x15)
1085 #define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG         	(0x16)
1086 #define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING      	(0x17)
1087 #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT            	(0x18)
1088 	u_int8_t		msg_flags;
1089 
1090 	u_int8_t		vp_id;
1091 	u_int8_t		vf_id;
1092 	u_int16_t		reserved1;
1093 
1094 	u_int32_t		reserved2[2];
1095 
1096 	struct mpii_cfg_hdr	config_header;
1097 
1098 	u_int32_t		page_address;
1099 /* XXX lots of defns here */
1100 
1101 	struct mpii_sge		page_buffer;
1102 } __packed;
1103 
1104 struct mpii_msg_config_reply {
1105 	u_int8_t		action;
1106 	u_int8_t		sgl_flags;
1107 	u_int8_t		msg_length;
1108 	u_int8_t		function;
1109 
1110 	u_int16_t		ext_page_length;
1111 	u_int8_t		ext_page_type;
1112 	u_int8_t		msg_flags;
1113 
1114 	u_int8_t		vp_id;
1115 	u_int8_t		vf_id;
1116 	u_int16_t		reserved1;
1117 
1118 	u_int16_t		reserved2;
1119 	u_int16_t		ioc_status;
1120 
1121 	u_int32_t		ioc_loginfo;
1122 
1123 	struct mpii_cfg_hdr	config_header;
1124 } __packed;
1125 
1126 struct mpii_cfg_manufacturing_pg0 {
1127 	struct mpii_cfg_hdr	config_header;
1128 
1129 	char			chip_name[16];
1130 	char			chip_revision[8];
1131 	char			board_name[16];
1132 	char			board_assembly[16];
1133 	char			board_tracer_number[16];
1134 } __packed;
1135 
1136 struct mpii_cfg_ioc_pg1 {
1137 	struct mpii_cfg_hdr     config_header;
1138 
1139 	u_int32_t       flags;
1140 
1141 	u_int32_t       coalescing_timeout;
1142 #define	MPII_CFG_IOC_1_REPLY_COALESCING			(1<<0)
1143 
1144 	u_int8_t        coalescing_depth;
1145 	u_int8_t        pci_slot_num;
1146 	u_int8_t        pci_bus_num;
1147 	u_int8_t        pci_domain_segment;
1148 
1149 	u_int32_t       reserved1;
1150 
1151 	u_int32_t       reserved2;
1152 } __packed;
1153 
1154 struct mpii_cfg_ioc_pg3 {
1155 	struct mpii_cfg_hdr	config_header;
1156 
1157 	u_int8_t		no_phys_disks;
1158 	u_int8_t		reserved[3];
1159 
1160 	/* followed by a list of mpii_cfg_raid_physdisk structs */
1161 } __packed;
1162 
1163 struct mpii_cfg_ioc_pg8 {
1164 	struct mpii_cfg_hdr	config_header;
1165 
1166 	u_int8_t		num_devs_per_enclosure;
1167 	u_int8_t		reserved1;
1168 	u_int16_t		reserved2;
1169 
1170 	u_int16_t		max_persistent_entries;
1171 	u_int16_t		max_num_physical_mapped_ids;
1172 
1173 	u_int16_t		flags;
1174 #define	MPII_IOC_PG8_FLAGS_DA_START_SLOT_1		(1<<5)
1175 #define MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0		(1<<4)
1176 #define MPII_IOC_PG8_FLAGS_MAPPING_MODE_MASK		(0x0000000e)
1177 #define MPII_IOC_PG8_FLAGS_DEVICE_PERSISTENCE_MAPPING	(0<<1)
1178 #define MPII_IOC_PG8_FLAGS_ENCLOSURE_SLOT_MAPPING	(1<<1)
1179 #define MPII_IOC_PG8_FLAGS_DISABLE_PERSISTENT_MAPPING	(1<<0)
1180 #define	MPII_IOC_PG8_FLAGS_ENABLE_PERSISTENT_MAPPING	(0<<0)
1181 	u_int16_t		reserved3;
1182 
1183 	u_int16_t		ir_volume_mapping_flags;
1184 #define	MPII_IOC_PG8_IRFLAGS_VOLUME_MAPPING_MODE_MASK	(0x00000003)
1185 #define	MPII_IOC_PG8_IRFLAGS_LOW_VOLUME_MAPPING		(0<<0)
1186 #define	MPII_IOC_PG8_IRFLAGS_HIGH_VOLUME_MAPPING	(1<<0)
1187 	u_int16_t		reserved4;
1188 
1189 	u_int32_t		reserved5;
1190 } __packed;
1191 
1192 struct mpii_cfg_raid_physdisk {
1193 	u_int8_t		phys_disk_id;
1194 	u_int8_t		phys_disk_bus;
1195 	u_int8_t		phys_disk_ioc;
1196 	u_int8_t		phys_disk_num;
1197 } __packed;
1198 
1199 struct mpii_cfg_fc_port_pg0 {
1200 	struct mpii_cfg_hdr	config_header;
1201 
1202 	u_int32_t		flags;
1203 
1204 	u_int8_t		mpii_port_nr;
1205 	u_int8_t		link_type;
1206 	u_int8_t		port_state;
1207 	u_int8_t		reserved1;
1208 
1209 	u_int32_t		port_id;
1210 
1211 	u_int64_t		wwnn;
1212 
1213 	u_int64_t		wwpn;
1214 
1215 	u_int32_t		supported_service_class;
1216 
1217 	u_int32_t		supported_speeds;
1218 
1219 	u_int32_t		current_speed;
1220 
1221 	u_int32_t		max_frame_size;
1222 
1223 	u_int64_t		fabric_wwnn;
1224 
1225 	u_int64_t		fabric_wwpn;
1226 
1227 	u_int32_t		discovered_port_count;
1228 
1229 	u_int32_t		max_initiators;
1230 
1231 	u_int8_t		max_aliases_supported;
1232 	u_int8_t		max_hard_aliases_supported;
1233 	u_int8_t		num_current_aliases;
1234 	u_int8_t		reserved2;
1235 } __packed;
1236 
1237 struct mpii_cfg_fc_port_pg1 {
1238 	struct mpii_cfg_hdr	config_header;
1239 
1240 	u_int32_t		flags;
1241 
1242 	u_int64_t		noseepromwwnn;
1243 
1244 	u_int64_t		noseepromwwpn;
1245 
1246 	u_int8_t		hard_alpa;
1247 	u_int8_t		link_config;
1248 	u_int8_t		topology_config;
1249 	u_int8_t		alt_connector;
1250 
1251 	u_int8_t		num_req_aliases;
1252 	u_int8_t		rr_tov;
1253 	u_int8_t		initiator_dev_to;
1254 	u_int8_t		initiator_lo_pend_to;
1255 } __packed;
1256 
1257 struct mpii_cfg_fc_device_pg0 {
1258 	struct mpii_cfg_hdr	config_header;
1259 
1260 	u_int64_t		wwnn;
1261 
1262 	u_int64_t		wwpn;
1263 
1264 	u_int32_t		port_id;
1265 
1266 	u_int8_t		protocol;
1267 	u_int8_t		flags;
1268 	u_int16_t		bb_credit;
1269 
1270 	u_int16_t		max_rx_frame_size;
1271 	u_int8_t		adisc_hard_alpa;
1272 	u_int8_t		port_nr;
1273 
1274 	u_int8_t		fc_ph_low_version;
1275 	u_int8_t		fc_ph_high_version;
1276 	u_int8_t		current_target_id;
1277 	u_int8_t		current_bus;
1278 } __packed;
1279 
1280 #define MPII_CFG_RAID_VOL_ADDR_HANDLE		(1<<28)
1281 
1282 struct mpii_cfg_raid_vol_pg0 {
1283 	struct mpii_cfg_hdr	config_header;
1284 
1285 	u_int16_t		volume_handle;
1286 	u_int8_t		volume_state;
1287 #define MPII_CFG_RAID_VOL_0_STATE_MISSING		(0x00)
1288 #define MPII_CFG_RAID_VOL_0_STATE_FAILED		(0x01)
1289 #define MPII_CFG_RAID_VOL_0_STATE_INITIALIZING		(0x02)
1290 #define MPII_CFG_RAID_VOL_0_STATE_ONLINE		(0x03)
1291 #define MPII_CFG_RAID_VOL_0_STATE_DEGRADED		(0x04)
1292 #define MPII_CFG_RAID_VOL_0_STATE_OPTIMAL		(0x05)
1293 	u_int8_t		volume_type;
1294 #define MPII_CFG_RAID_VOL_0_TYPE_RAID0			(0x00)
1295 #define MPII_CFG_RAID_VOL_0_TYPE_RAID1E			(0x01)
1296 #define MPII_CFG_RAID_VOL_0_TYPE_RAID1			(0x02)
1297 #define MPII_CFG_RAID_VOL_0_TYPE_RAID10			(0x05)
1298 #define MPII_CFG_RAID_VOL_0_TYPE_UNKNOWN		(0xff)
1299 
1300 	u_int32_t		volume_status;
1301 #define MPII_CFG_RAID_VOL_0_STATUS_SCRUB		(1<<20)
1302 #define MPII_CFG_RAID_VOL_0_STATUS_RESYNC		(1<<16)
1303 
1304 	u_int16_t		volume_settings;
1305 #define MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_MASK		(0x3<<0)
1306 #define MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_UNCHANGED	(0x0<<0)
1307 #define MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_DISABLED	(0x1<<0)
1308 #define MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_ENABLED	(0x2<<0)
1309 
1310 	u_int8_t		hot_spare_pool;
1311 	u_int8_t		reserved1;
1312 
1313 	u_int64_t		max_lba;
1314 
1315 	u_int32_t		stripe_size;
1316 
1317 	u_int16_t		block_size;
1318 	u_int16_t		reserved2;
1319 
1320 	u_int8_t		phys_disk_types;
1321 	u_int8_t		resync_rate;
1322 	u_int16_t		data_scrub_rate;
1323 
1324 	u_int8_t		num_phys_disks;
1325 	u_int16_t		reserved3;
1326 	u_int8_t		inactive_status;
1327 #define MPII_CFG_RAID_VOL_0_INACTIVE_UNKNOWN		(0x00)
1328 #define MPII_CFG_RAID_VOL_0_INACTIVE_STALE_META		(0x01)
1329 #define MPII_CFG_RAID_VOL_0_INACTIVE_FOREIGN_VOL	(0x02)
1330 #define MPII_CFG_RAID_VOL_0_INACTIVE_NO_RESOURCES	(0x03)
1331 #define MPII_CFG_RAID_VOL_0_INACTIVE_CLONED_VOL		(0x04)
1332 #define MPII_CFG_RAID_VOL_0_INACTIVE_INSUF_META		(0x05)
1333 
1334 	/* followed by a list of mpii_cfg_raid_vol_pg0_physdisk structs */
1335 } __packed;
1336 
1337 struct mpii_cfg_raid_vol_pg0_physdisk {
1338 	u_int8_t		raid_set_num;
1339 	u_int8_t		phys_disk_map;
1340 	u_int8_t		phys_disk_num;
1341 	u_int8_t		reserved;
1342 } __packed;
1343 
1344 struct mpii_cfg_raid_vol_pg1 {
1345 	struct mpii_cfg_hdr	config_header;
1346 
1347 	u_int8_t		volume_id;
1348 	u_int8_t		volume_bus;
1349 	u_int8_t		volume_ioc;
1350 	u_int8_t		reserved1;
1351 
1352 	u_int8_t		guid[24];
1353 
1354 	u_int8_t		name[32];
1355 
1356 	u_int64_t		wwid;
1357 
1358 	u_int32_t		reserved2;
1359 
1360 	u_int32_t		reserved3;
1361 } __packed;
1362 
1363 #define MPII_CFG_RAID_PHYS_DISK_ADDR_NUMBER		(1<<28)
1364 
1365 struct mpii_cfg_raid_physdisk_pg0 {
1366 	struct mpii_cfg_hdr	config_header;
1367 
1368 	u_int16_t		dev_handle;
1369 	u_int8_t		reserved1;
1370 	u_int8_t		phys_disk_num;
1371 
1372 	u_int8_t		enc_id;
1373 	u_int8_t		enc_bus;
1374 	u_int8_t		hot_spare_pool;
1375 	u_int8_t		enc_type;
1376 #define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_NONE		(0x0)
1377 #define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_SAFTE		(0x1)
1378 #define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_SES		(0x2)
1379 
1380 	u_int32_t		reserved2;
1381 
1382 	u_int8_t		vendor_id[8];
1383 
1384 	u_int8_t		product_id[16];
1385 
1386 	u_int8_t		product_rev[4];
1387 
1388 	u_int8_t		serial[32];
1389 
1390 	u_int32_t		reserved3;
1391 
1392 	u_int8_t		phys_disk_state;
1393 #define MPII_CFG_RAID_PHYDISK_0_STATE_NOTCONFIGURED	(0x00)
1394 #define MPII_CFG_RAID_PHYDISK_0_STATE_NOTCOMPATIBLE	(0x01)
1395 #define MPII_CFG_RAID_PHYDISK_0_STATE_OFFLINE		(0x02)
1396 #define MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE		(0x03)
1397 #define MPII_CFG_RAID_PHYDISK_0_STATE_HOTSPARE		(0x04)
1398 #define MPII_CFG_RAID_PHYDISK_0_STATE_DEGRADED		(0x05)
1399 #define MPII_CFG_RAID_PHYDISK_0_STATE_REBUILDING	(0x06)
1400 #define MPII_CFG_RAID_PHYDISK_0_STATE_OPTIMAL		(0x07)
1401 	u_int8_t		offline_reason;
1402 #define MPII_CFG_RAID_PHYDISK_0_OFFLINE_MISSING		(0x01)
1403 #define MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILED		(0x03)
1404 #define MPII_CFG_RAID_PHYDISK_0_OFFLINE_INITIALIZING	(0x04)
1405 #define MPII_CFG_RAID_PHYDISK_0_OFFLINE_REQUESTED	(0x05)
1406 #define MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILEDREQ	(0x06)
1407 #define MPII_CFG_RAID_PHYDISK_0_OFFLINE_OTHER		(0xff)
1408 
1409 	u_int8_t		incompat_reason;
1410 	u_int8_t		phys_disk_attrs;
1411 
1412 	u_int32_t		phys_disk_status;
1413 #define MPII_CFG_RAID_PHYDISK_0_STATUS_OUTOFSYNC	(1<<0)
1414 #define MPII_CFG_RAID_PHYDISK_0_STATUS_QUIESCED		(1<<1)
1415 
1416 	u_int64_t		dev_max_lba;
1417 
1418 	u_int64_t		host_max_lba;
1419 
1420 	u_int64_t		coerced_max_lba;
1421 
1422 	u_int16_t		block_size;
1423 	u_int16_t		reserved4;
1424 
1425 	u_int32_t		reserved5;
1426 } __packed;
1427 
1428 struct mpii_cfg_raid_physdisk_pg1 {
1429 	struct mpii_cfg_hdr	config_header;
1430 
1431 	u_int8_t		num_phys_disk_paths;
1432 	u_int8_t		phys_disk_num;
1433 	u_int16_t		reserved1;
1434 
1435 	u_int32_t		reserved2;
1436 
1437 	/* followed by mpii_cfg_raid_physdisk_path structs */
1438 } __packed;
1439 
1440 struct mpii_cfg_raid_physdisk_path {
1441 	u_int8_t		phys_disk_id;
1442 	u_int8_t		phys_disk_bus;
1443 	u_int16_t		reserved1;
1444 
1445 	u_int64_t		wwwid;
1446 
1447 	u_int64_t		owner_wwid;
1448 
1449 	u_int8_t		ownder_id;
1450 	u_int8_t		reserved2;
1451 	u_int16_t		flags;
1452 #define MPII_CFG_RAID_PHYDISK_PATH_INVALID	(1<<0)
1453 #define MPII_CFG_RAID_PHYDISK_PATH_BROKEN	(1<<1)
1454 } __packed;
1455 
1456 #define MPII_CFG_SAS_DEV_ADDR_NEXT		(0<<28)
1457 #define MPII_CFG_SAS_DEV_ADDR_BUS		(1<<28)
1458 #define MPII_CFG_SAS_DEV_ADDR_HANDLE		(2<<28)
1459 
1460 struct mpii_cfg_sas_dev_pg0 {
1461 	struct mpii_ecfg_hdr	config_header;
1462 
1463 	u_int16_t		slot;
1464 	u_int16_t		enc_handle;
1465 
1466 	u_int64_t		sas_addr;
1467 
1468 	u_int16_t		parent_dev_handle;
1469 	u_int8_t		phy_num;
1470 	u_int8_t		access_status;
1471 
1472 	u_int16_t		dev_handle;
1473 	u_int8_t		target;
1474 	u_int8_t		bus;
1475 
1476 	u_int32_t		device_info;
1477 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE			(0x7)
1478 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_NONE		(0x0)
1479 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_END		(0x1)
1480 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_EDGE_EXPANDER	(0x2)
1481 #define MPII_CFG_SAS_DEV_0_DEVINFO_TYPE_FANOUT_EXPANDER	(0x3)
1482 #define MPII_CFG_SAS_DEV_0_DEVINFO_SATA_HOST		(1<<3)
1483 #define MPII_CFG_SAS_DEV_0_DEVINFO_SMP_INITIATOR	(1<<4)
1484 #define MPII_CFG_SAS_DEV_0_DEVINFO_STP_INITIATOR	(1<<5)
1485 #define MPII_CFG_SAS_DEV_0_DEVINFO_SSP_INITIATOR	(1<<6)
1486 #define MPII_CFG_SAS_DEV_0_DEVINFO_SATA_DEVICE		(1<<7)
1487 #define MPII_CFG_SAS_DEV_0_DEVINFO_SMP_TARGET		(1<<8)
1488 #define MPII_CFG_SAS_DEV_0_DEVINFO_STP_TARGET		(1<<9)
1489 #define MPII_CFG_SAS_DEV_0_DEVINFO_SSP_TARGET		(1<<10)
1490 #define MPII_CFG_SAS_DEV_0_DEVINFO_DIRECT_ATTACHED	(1<<11)
1491 #define MPII_CFG_SAS_DEV_0_DEVINFO_LSI_DEVICE		(1<<12)
1492 #define MPII_CFG_SAS_DEV_0_DEVINFO_ATAPI_DEVICE		(1<<13)
1493 #define MPII_CFG_SAS_DEV_0_DEVINFO_SEP_DEVICE		(1<<14)
1494 
1495 	u_int16_t		flags;
1496 #define MPII_CFG_SAS_DEV_0_FLAGS_DEV_PRESENT		(1<<0)
1497 #define MPII_CFG_SAS_DEV_0_FLAGS_DEV_MAPPED		(1<<1)
1498 #define MPII_CFG_SAS_DEV_0_FLAGS_DEV_MAPPED_PERSISTENT	(1<<2)
1499 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_PORT_SELECTOR	(1<<3)
1500 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_FUA		(1<<4)
1501 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_NCQ		(1<<5)
1502 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_SMART		(1<<6)
1503 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_LBA48		(1<<7)
1504 #define MPII_CFG_SAS_DEV_0_FLAGS_UNSUPPORTED		(1<<8)
1505 #define MPII_CFG_SAS_DEV_0_FLAGS_SATA_SETTINGS		(1<<9)
1506 	u_int8_t		physical_port;
1507 	u_int8_t		max_port_conn;
1508 
1509 	u_int64_t		device_name;
1510 
1511 	u_int8_t		port_groups;
1512 	u_int8_t		dma_group;
1513 	u_int8_t		ctrl_group;
1514 	u_int8_t		reserved1;
1515 
1516 	u_int64_t		reserved2;
1517 } __packed;
1518 
1519 #define MPII_CFG_RAID_CONFIG_ACTIVE_CONFIG		(2<<28)
1520 
1521 struct mpii_cfg_raid_config_pg0 {
1522 	struct	mpii_ecfg_hdr	config_header;
1523 
1524 	u_int8_t		num_hot_spares;
1525 	u_int8_t		num_phys_disks;
1526 	u_int8_t		num_volumes;
1527 	u_int8_t		config_num;
1528 
1529 	u_int32_t		flags;
1530 #define MPII_CFG_RAID_CONFIG_0_FLAGS_NATIVE		(0<<0)
1531 #define MPII_CFG_RAID_CONFIG_0_FLAGS_FOREIGN		(1<<0)
1532 
1533 	u_int32_t		config_guid[6];
1534 
1535 	u_int32_t		reserved1;
1536 
1537 	u_int8_t		num_elements;
1538 	u_int8_t		reserved2[3];
1539 
1540 	/* followed by struct mpii_raid_config_element structs */
1541 } __packed;
1542 
1543 struct mpii_raid_config_element {
1544 	u_int16_t		element_flags;
1545 #define MPII_RAID_CONFIG_ELEMENT_FLAG_VOLUME		(0x0)
1546 #define MPII_RAID_CONFIG_ELEMENT_FLAG_VOLUME_PHYS_DISK	(0x1)
1547 #define	MPII_RAID_CONFIG_ELEMENT_FLAG_HSP_PHYS_DISK	(0x2)
1548 #define MPII_RAID_CONFIG_ELEMENT_ONLINE_CE_PHYS_DISK	(0x3)
1549 	u_int16_t		vol_dev_handle;
1550 
1551 	u_int8_t		hot_spare_pool;
1552 	u_int8_t		phys_disk_num;
1553 	u_int16_t		phys_disk_dev_handle;
1554 } __packed;
1555 
1556 struct mpii_cfg_dpm_pg0 {
1557 	struct mpii_ecfg_hdr	config_header;
1558 #define MPII_DPM_ADDRESS_FORM_MASK			(0xf0000000)
1559 #define MPII_DPM_ADDRESS_FORM_ENTRY_RANGE		(0x00000000)
1560 #define MPII_DPM_ADDRESS_ENTRY_COUNT_MASK		(0x0fff0000)
1561 #define MPII_DPM_ADDRESS_ENTRY_COUNT_SHIFT		(16)
1562 #define MPII_DPM_ADDRESS_START_ENTRY_MASK		(0x0000ffff)
1563 
1564 	/* followed by struct mpii_dpm_entry structs */
1565 } __packed;
1566 
1567 struct mpii_dpm_entry {
1568 	u_int64_t		physical_identifier;
1569 
1570 	u_int16_t		mapping_information;
1571 	u_int16_t		device_index;
1572 
1573 	u_int32_t		physical_bits_mapping;
1574 
1575 	u_int32_t		reserved1;
1576 } __packed;
1577 
1578 struct mpii_evt_sas_discovery {
1579 	u_int8_t		flags;
1580 #define	MPII_EVENT_SAS_DISC_FLAGS_DEV_CHANGE_MASK	(1<<1)
1581 #define MPII_EVENT_SAS_DISC_FLAGS_DEV_CHANGE_NO_CHANGE	(0<<1)
1582 #define MPII_EVENT_SAS_DISC_FLAGS_DEV_CHANGE_CHANGE	(1<<1)
1583 #define MPII_EVENT_SAS_DISC_FLAGS_DISC_IN_PROG_MASK	(1<<0)
1584 #define MPII_EVENT_SAS_DISC_FLAGS_DISC_NOT_IN_PROGRESS	(1<<0)
1585 #define MPII_EVENT_SAS_DISC_FLAGS_DISC_IN_PROGRESS	(0<<0)
1586 	u_int8_t		reason_code;
1587 #define MPII_EVENT_SAS_DISC_REASON_CODE_STARTED		(0x01)
1588 #define	MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED	(0x02)
1589 	u_int8_t		physical_port;
1590 	u_int8_t		reserved1;
1591 
1592 	u_int32_t		discovery_status;
1593 } __packed;
1594 
1595 struct mpii_evt_ir_status {
1596 	u_int16_t		vol_dev_handle;
1597 	u_int16_t		reserved1;
1598 
1599 	u_int8_t		operation;
1600 #define MPII_EVENT_IR_RAIDOP_RESYNC			(0x00)
1601 #define MPII_EVENT_IR_RAIDOP_OCE			(0x01)
1602 #define MPII_EVENT_IR_RAIDOP_CONS_CHECK			(0x02)
1603 #define MPII_EVENT_IR_RAIDOP_BG_INIT			(0x03)
1604 #define MPII_EVENT_IR_RAIDOP_MAKE_CONS			(0x04)
1605 	u_int8_t		percent;
1606 	u_int16_t		reserved2;
1607 
1608 	u_int32_t		reserved3;
1609 };
1610 
1611 struct mpii_evt_ir_volume {
1612 	u_int16_t		vol_dev_handle;
1613 	u_int8_t		reason_code;
1614 #define MPII_EVENT_IR_VOL_RC_SETTINGS_CHANGED		(0x01)
1615 #define MPII_EVENT_IR_VOL_RC_STATUS_CHANGED		(0x02)
1616 #define MPII_EVENT_IR_VOL_RC_STATE_CHANGED		(0x03)
1617 	u_int8_t		reserved1;
1618 
1619 	u_int32_t		new_value;
1620 	u_int32_t		prev_value;
1621 } __packed;
1622 
1623 struct mpii_evt_ir_physical_disk {
1624 	u_int16_t		reserved1;
1625 	u_int8_t		reason_code;
1626 #define MPII_EVENT_IR_PD_RC_SETTINGS_CHANGED		(0x01)
1627 #define MPII_EVENT_IR_PD_RC_STATUS_FLAGS_CHANGED	(0x02)
1628 #define MPII_EVENT_IR_PD_RC_STATUS_CHANGED		(0x03)
1629 	u_int8_t		phys_disk_num;
1630 
1631 	u_int16_t		phys_disk_dev_handle;
1632 	u_int16_t		reserved2;
1633 
1634 	u_int16_t		slot;
1635 	u_int16_t		enclosure_handle;
1636 
1637 	u_int32_t		new_value;
1638 	u_int32_t		previous_value;
1639 } __packed;
1640 
1641 struct mpii_evt_sas_tcl {
1642 	u_int16_t		enclosure_handle;
1643 	u_int16_t		expander_handle;
1644 
1645 	u_int8_t		num_phys;
1646 	u_int8_t		reserved1[3];
1647 
1648 	u_int8_t		num_entries;
1649 	u_int8_t		start_phy_num;
1650 	u_int8_t		expn_status;
1651 #define	MPII_EVENT_SAS_TOPO_ES_ADDED			(0x01)
1652 #define MPII_EVENT_SAS_TOPO_ES_NOT_RESPONDING		(0x02)
1653 #define MPII_EVENT_SAS_TOPO_ES_RESPONDING		(0x03)
1654 #define MPII_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING	(0x04)
1655 	u_int8_t		physical_port;
1656 
1657 	/* followed by num_entries number of struct mpii_evt_phy_entry */
1658 } __packed;
1659 
1660 struct mpii_evt_phy_entry {
1661 	u_int16_t		dev_handle;
1662 	u_int8_t		link_rate;
1663 	u_int8_t		phy_status;
1664 #define MPII_EVENT_SAS_TOPO_PS_RC_MASK			(0x0f)
1665 #define MPII_EVENT_SAS_TOPO_PS_RC_ADDED			(0x01)
1666 #define MPII_EVENT_SAS_TOPO_PS_RC_MISSING		(0x02)
1667 } __packed;
1668 
1669 struct mpii_evt_ir_cfg_change_list {
1670 	u_int8_t		num_elements;
1671 	u_int16_t		reserved;
1672 	u_int8_t		config_num;
1673 
1674 	u_int32_t		flags;
1675 #define MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN		(0x1)
1676 
1677 	/* followed by num_elements struct mpii_evt_ir_cfg_elements */
1678 } __packed;
1679 
1680 struct mpii_evt_ir_cfg_element {
1681 	u_int16_t		element_flags;
1682 #define MPII_EVT_IR_CFG_ELEMENT_TYPE_MASK		(0xf)
1683 #define MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME		(0x0)
1684 #define MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME_DISK	(0x1)
1685 #define MPII_EVT_IR_CFG_ELEMENT_TYPE_HOT_SPARE		(0x2)
1686 	u_int16_t		vol_dev_handle;
1687 
1688 	u_int8_t		reason_code;
1689 #define MPII_EVT_IR_CFG_ELEMENT_RC_ADDED		(0x01)
1690 #define MPII_EVT_IR_CFG_ELEMENT_RC_REMOVED		(0x02)
1691 #define MPII_EVT_IR_CFG_ELEMENT_RC_NO_CHANGE		(0x03)
1692 #define MPII_EVT_IR_CFG_ELEMENT_RC_HIDE			(0x04)
1693 #define MPII_EVT_IR_CFG_ELEMENT_RC_UNHIDE		(0x05)
1694 #define MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_CREATED	(0x06)
1695 #define MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_DELETED	(0x07)
1696 #define MPII_EVT_IR_CFG_ELEMENT_RC_PD_CREATED		(0x08)
1697 #define MPII_EVT_IR_CFG_ELEMENT_RC_PD_DELETED		(0x09)
1698 	u_int8_t		phys_disk_num;
1699 	u_int16_t		phys_disk_dev_handle;
1700 } __packed;
1701 
1702 /* #define MPII_DEBUG */
1703 #ifdef MPII_DEBUG
1704 #define DPRINTF(x...)		do { if (mpii_debug) printf(x); } while(0)
1705 #define DNPRINTF(n,x...)	do { if (mpii_debug & (n)) printf(x); } while(0)
1706 #define	MPII_D_CMD		(0x0001)
1707 #define	MPII_D_INTR		(0x0002)
1708 #define	MPII_D_MISC		(0x0004)
1709 #define	MPII_D_DMA		(0x0008)
1710 #define	MPII_D_IOCTL		(0x0010)
1711 #define	MPII_D_RW		(0x0020)
1712 #define	MPII_D_MEM		(0x0040)
1713 #define	MPII_D_CCB		(0x0080)
1714 #define	MPII_D_PPR		(0x0100)
1715 #define	MPII_D_RAID		(0x0200)
1716 #define	MPII_D_EVT		(0x0400)
1717 #define MPII_D_CFG		(0x0800)
1718 #define MPII_D_MAP		(0x1000)
1719 
1720 u_int32_t  mpii_debug = 0
1721 		| MPII_D_CMD
1722 		| MPII_D_INTR
1723 		| MPII_D_MISC
1724 		| MPII_D_DMA
1725 		| MPII_D_IOCTL
1726 		| MPII_D_RW
1727 		| MPII_D_MEM
1728 		| MPII_D_CCB
1729 		| MPII_D_PPR
1730 		| MPII_D_RAID
1731 		| MPII_D_EVT
1732 		| MPII_D_CFG
1733 		| MPII_D_MAP
1734 	;
1735 #else
1736 #define DPRINTF(x...)
1737 #define DNPRINTF(n,x...)
1738 #endif
1739 
1740 #define MPII_REQUEST_SIZE	(512)
1741 #define MPII_REPLY_SIZE		(128)
1742 #define MPII_REPLY_COUNT	PAGE_SIZE / MPII_REPLY_SIZE
1743 
1744 /*
1745  * this is the max number of sge's we can stuff in a request frame:
1746  * sizeof(scsi_io) + sizeof(sense) + sizeof(sge) * 32 = MPII_REQUEST_SIZE
1747  */
1748 #define MPII_MAX_SGL			(32)
1749 
1750 #define MPII_MAX_REQUEST_CREDIT		(128)
1751 
1752 struct mpii_dmamem {
1753 	bus_dmamap_t		mdm_map;
1754 	bus_dma_segment_t	mdm_seg;
1755 	size_t			mdm_size;
1756 	caddr_t			mdm_kva;
1757 };
1758 #define MPII_DMA_MAP(_mdm)	(_mdm)->mdm_map
1759 #define MPII_DMA_DVA(_mdm)	(_mdm)->mdm_map->dm_segs[0].ds_addr
1760 #define MPII_DMA_KVA(_mdm)	(void *)(_mdm)->mdm_kva
1761 
1762 struct mpii_ccb_bundle {
1763 	struct mpii_msg_scsi_io	mcb_io; /* sgl must follow */
1764 	struct mpii_sge		mcb_sgl[MPII_MAX_SGL];
1765 	struct scsi_sense_data	mcb_sense;
1766 } __packed;
1767 
1768 struct mpii_softc;
1769 
1770 struct mpii_rcb {
1771 	SIMPLEQ_ENTRY(mpii_rcb)	rcb_link;
1772 	void			*rcb_reply;
1773 	u_int32_t		rcb_reply_dva;
1774 };
1775 
1776 SIMPLEQ_HEAD(mpii_rcb_list, mpii_rcb);
1777 
1778 struct mpii_device {
1779 	int			flags;
1780 #define MPII_DF_ATTACH		(0x0001)
1781 #define MPII_DF_DETACH		(0x0002)
1782 #define MPII_DF_HIDDEN		(0x0004)
1783 #define MPII_DF_UNUSED		(0x0008)
1784 #define MPII_DF_VOLUME		(0x0010)
1785 #define MPII_DF_VOLUME_DISK	(0x0020)
1786 #define MPII_DF_HOT_SPARE	(0x0040)
1787 	short			slot;
1788 	short			percent;
1789 	u_int16_t		dev_handle;
1790 	u_int16_t		enclosure;
1791 	u_int16_t		expander;
1792 	u_int8_t		phy_num;
1793 	u_int8_t		physical_port;
1794 };
1795 
1796 struct mpii_ccb {
1797 	struct mpii_softc	*ccb_sc;
1798 	int			ccb_smid;
1799 
1800 	void *			ccb_cookie;
1801 	bus_dmamap_t		ccb_dmamap;
1802 
1803 	bus_addr_t		ccb_offset;
1804 	void			*ccb_cmd;
1805 	bus_addr_t		ccb_cmd_dva;
1806 	u_int16_t		ccb_dev_handle;
1807 
1808 	volatile enum {
1809 		MPII_CCB_FREE,
1810 		MPII_CCB_READY,
1811 		MPII_CCB_QUEUED,
1812 		MPII_CCB_TIMEOUT
1813 	}			ccb_state;
1814 
1815 	void			(*ccb_done)(struct mpii_ccb *);
1816 	struct mpii_rcb		*ccb_rcb;
1817 
1818 	SIMPLEQ_ENTRY(mpii_ccb)	ccb_link;
1819 };
1820 
1821 SIMPLEQ_HEAD(mpii_ccb_list, mpii_ccb);
1822 
1823 struct mpii_softc {
1824 	struct device		sc_dev;
1825 
1826 	pci_chipset_tag_t	sc_pc;
1827 	pcitag_t		sc_tag;
1828 
1829 	void			*sc_ih;
1830 
1831 	struct scsi_link	sc_link;
1832 
1833 	int			sc_flags;
1834 #define MPII_F_RAID		(1<<1)
1835 
1836 	struct scsibus_softc	*sc_scsibus;
1837 
1838 	struct mpii_device	**sc_devs;
1839 
1840 	bus_space_tag_t		sc_iot;
1841 	bus_space_handle_t	sc_ioh;
1842 	bus_size_t		sc_ios;
1843 	bus_dma_tag_t		sc_dmat;
1844 
1845 	struct mutex		sc_req_mtx;
1846 	struct mutex		sc_rep_mtx;
1847 
1848 	u_int8_t		sc_porttype;
1849 	int			sc_request_depth;
1850 	int			sc_num_reply_frames;
1851 	int			sc_reply_free_qdepth;
1852 	int			sc_reply_post_qdepth;
1853 	int			sc_maxchdepth;
1854 	int			sc_first_sgl_len;
1855 	int			sc_chain_len;
1856 	int			sc_max_sgl_len;
1857 
1858 	u_int8_t		sc_ioc_event_replay;
1859 	u_int16_t		sc_max_enclosures;
1860 	u_int16_t		sc_max_expanders;
1861 	u_int8_t		sc_max_volumes;
1862 	u_int16_t		sc_max_devices;
1863 	u_int16_t		sc_max_dpm_entries;
1864 	u_int16_t		sc_vd_count;
1865 	u_int16_t		sc_vd_id_low;
1866 	u_int16_t		sc_pd_id_start;
1867 	u_int8_t		sc_num_channels;
1868 	int			sc_ioc_number;
1869 	u_int8_t		sc_vf_id;
1870 	u_int8_t		sc_num_ports;
1871 
1872 	struct mpii_ccb		*sc_ccbs;
1873 	struct mpii_ccb_list	sc_ccb_free;
1874 	struct mutex		sc_ccb_free_mtx;
1875 
1876 	struct mutex		sc_ccb_mtx;
1877 				/*
1878 				 * this protects the ccb state and list entry
1879 				 * between mpii_scsi_cmd and scsidone.
1880 				 */
1881 
1882 	struct mpii_ccb_list	sc_ccb_tmos;
1883 	struct scsi_iohandler	sc_ccb_tmo_handler;
1884 
1885 	struct scsi_iopool	sc_iopool;
1886 
1887 	struct mpii_dmamem	*sc_requests;
1888 
1889 	struct mpii_dmamem	*sc_replies;
1890 	struct mpii_rcb		*sc_rcbs;
1891 
1892 	struct mpii_dmamem	*sc_reply_postq;
1893 	struct mpii_reply_descr	*sc_reply_postq_kva;
1894 	int			sc_reply_post_host_index;
1895 
1896 	struct mpii_dmamem	*sc_reply_freeq;
1897 	int			sc_reply_free_host_index;
1898 
1899 	struct mpii_rcb_list	sc_evt_ack_queue;
1900 	struct mutex		sc_evt_ack_mtx;
1901 	struct scsi_iohandler	sc_evt_ack_handler;
1902 
1903 	/* scsi ioctl from sd device */
1904 	int			(*sc_ioctl)(struct device *, u_long, caddr_t);
1905 
1906 	int			sc_nsensors;
1907 	struct ksensor		*sc_sensors;
1908 	struct ksensordev	sc_sensordev;
1909 };
1910 
1911 int	mpii_match(struct device *, void *, void *);
1912 void	mpii_attach(struct device *, struct device *, void *);
1913 int	mpii_detach(struct device *, int);
1914 
1915 int	mpii_intr(void *);
1916 
1917 struct cfattach mpii_ca = {
1918 	sizeof(struct mpii_softc),
1919 	mpii_match,
1920 	mpii_attach,
1921 	mpii_detach
1922 };
1923 
1924 struct cfdriver mpii_cd = {
1925 	NULL,
1926 	"mpii",
1927 	DV_DULL
1928 };
1929 
1930 #define PREAD(s, r)	pci_conf_read((s)->sc_pc, (s)->sc_tag, (r))
1931 #define PWRITE(s, r, v)	pci_conf_write((s)->sc_pc, (s)->sc_tag, (r), (v))
1932 
1933 void		mpii_scsi_cmd(struct scsi_xfer *);
1934 void		mpii_scsi_cmd_done(struct mpii_ccb *);
1935 int		mpii_scsi_probe(struct scsi_link *);
1936 int		mpii_scsi_ioctl(struct scsi_link *, u_long, caddr_t, int);
1937 
1938 struct scsi_adapter mpii_switch = {
1939 	mpii_scsi_cmd,
1940 	scsi_minphys,
1941 	mpii_scsi_probe,
1942 	NULL,
1943 	mpii_scsi_ioctl
1944 };
1945 
1946 struct mpii_dmamem 	*mpii_dmamem_alloc(struct mpii_softc *, size_t);
1947 void		mpii_dmamem_free(struct mpii_softc *,
1948 		    struct mpii_dmamem *);
1949 int		mpii_alloc_ccbs(struct mpii_softc *);
1950 void *		mpii_get_ccb(void *);
1951 void		mpii_put_ccb(void *, void *);
1952 int		mpii_alloc_replies(struct mpii_softc *);
1953 int		mpii_alloc_queues(struct mpii_softc *);
1954 void		mpii_push_reply(struct mpii_softc *, struct mpii_rcb *);
1955 void		mpii_push_replies(struct mpii_softc *);
1956 
1957 void		mpii_scsi_cmd_tmo(void *);
1958 void		mpii_scsi_cmd_tmo_handler(void *, void *);
1959 void		mpii_scsi_cmd_tmo_done(struct mpii_ccb *);
1960 
1961 int		mpii_alloc_dev(struct mpii_softc *);
1962 int		mpii_insert_dev(struct mpii_softc *, struct mpii_device *);
1963 int		mpii_remove_dev(struct mpii_softc *, struct mpii_device *);
1964 struct mpii_device *mpii_find_dev(struct mpii_softc *, u_int16_t);
1965 
1966 void		mpii_start(struct mpii_softc *, struct mpii_ccb *);
1967 int		mpii_poll(struct mpii_softc *, struct mpii_ccb *);
1968 void		mpii_poll_done(struct mpii_ccb *);
1969 struct mpii_rcb *mpii_reply(struct mpii_softc *, struct mpii_reply_descr *);
1970 
1971 void		mpii_wait(struct mpii_softc *, struct mpii_ccb *);
1972 void		mpii_wait_done(struct mpii_ccb *);
1973 
1974 void		mpii_init_queues(struct mpii_softc *);
1975 
1976 int		mpii_load_xs(struct mpii_ccb *);
1977 
1978 u_int32_t	mpii_read(struct mpii_softc *, bus_size_t);
1979 void		mpii_write(struct mpii_softc *, bus_size_t, u_int32_t);
1980 int		mpii_wait_eq(struct mpii_softc *, bus_size_t, u_int32_t,
1981 		    u_int32_t);
1982 int		mpii_wait_ne(struct mpii_softc *, bus_size_t, u_int32_t,
1983 		    u_int32_t);
1984 
1985 int		mpii_init(struct mpii_softc *);
1986 int		mpii_reset_soft(struct mpii_softc *);
1987 int		mpii_reset_hard(struct mpii_softc *);
1988 
1989 int		mpii_handshake_send(struct mpii_softc *, void *, size_t);
1990 int		mpii_handshake_recv_dword(struct mpii_softc *,
1991 		    u_int32_t *);
1992 int		mpii_handshake_recv(struct mpii_softc *, void *, size_t);
1993 
1994 void		mpii_empty_done(struct mpii_ccb *);
1995 
1996 int		mpii_iocinit(struct mpii_softc *);
1997 int		mpii_iocfacts(struct mpii_softc *);
1998 int		mpii_portfacts(struct mpii_softc *);
1999 int		mpii_portenable(struct mpii_softc *);
2000 int		mpii_cfg_coalescing(struct mpii_softc *);
2001 
2002 int		mpii_eventnotify(struct mpii_softc *);
2003 void		mpii_eventnotify_done(struct mpii_ccb *);
2004 void		mpii_eventack(void *, void *);
2005 void		mpii_eventack_done(struct mpii_ccb *);
2006 void		mpii_event_process(struct mpii_softc *, struct mpii_rcb *);
2007 void		mpii_event_sas(struct mpii_softc *,
2008 		    struct mpii_msg_event_reply *);
2009 void		mpii_event_raid(struct mpii_softc *,
2010 		    struct mpii_msg_event_reply *);
2011 void		mpii_event_defer(void *, void *);
2012 
2013 void		mpii_sas_remove_device(struct mpii_softc *, u_int16_t);
2014 
2015 int		mpii_req_cfg_header(struct mpii_softc *, u_int8_t,
2016 		    u_int8_t, u_int32_t, int, void *);
2017 int		mpii_req_cfg_page(struct mpii_softc *, u_int32_t, int,
2018 		    void *, int, void *, size_t);
2019 
2020 int		mpii_get_ioc_pg8(struct mpii_softc *);
2021 
2022 int		mpii_ioctl_cache(struct scsi_link *, u_long, struct dk_cache *);
2023 
2024 #if NBIO > 0
2025 int		mpii_ioctl(struct device *, u_long, caddr_t);
2026 int		mpii_ioctl_inq(struct mpii_softc *, struct bioc_inq *);
2027 int		mpii_ioctl_vol(struct mpii_softc *, struct bioc_vol *);
2028 int		mpii_ioctl_disk(struct mpii_softc *, struct bioc_disk *);
2029 int		mpii_bio_hs(struct mpii_softc *, struct bioc_disk *, int,
2030 		    int, int *);
2031 int		mpii_bio_disk(struct mpii_softc *, struct bioc_disk *,
2032 		    u_int8_t);
2033 struct mpii_device *mpii_find_vol(struct mpii_softc *, int);
2034 #ifndef SMALL_KERNEL
2035  int		mpii_bio_volstate(struct mpii_softc *, struct bioc_vol *);
2036 int		mpii_create_sensors(struct mpii_softc *);
2037 void		mpii_refresh_sensors(void *);
2038 #endif /* SMALL_KERNEL */
2039 #endif /* NBIO > 0 */
2040 
2041 #define DEVNAME(s)		((s)->sc_dev.dv_xname)
2042 
2043 #define dwordsof(s)		(sizeof(s) / sizeof(u_int32_t))
2044 #define dwordn(p, n)		(((u_int32_t *)(p))[(n)])
2045 
2046 #define mpii_read_db(s)		mpii_read((s), MPII_DOORBELL)
2047 #define mpii_write_db(s, v)	mpii_write((s), MPII_DOORBELL, (v))
2048 #define mpii_read_intr(s)	mpii_read((s), MPII_INTR_STATUS)
2049 #define mpii_write_intr(s, v)	mpii_write((s), MPII_INTR_STATUS, (v))
2050 #define mpii_reply_waiting(s)	((mpii_read_intr((s)) & MPII_INTR_STATUS_REPLY)\
2051 				    == MPII_INTR_STATUS_REPLY)
2052 
2053 #define mpii_read_reply_free(s)		mpii_read((s), \
2054 						MPII_REPLY_FREE_HOST_INDEX)
2055 #define mpii_write_reply_free(s, v)	mpii_write((s), \
2056 						MPII_REPLY_FREE_HOST_INDEX, (v))
2057 #define mpii_read_reply_post(s)		mpii_read((s), \
2058 						MPII_REPLY_POST_HOST_INDEX)
2059 #define mpii_write_reply_post(s, v)	mpii_write((s), \
2060 						MPII_REPLY_POST_HOST_INDEX, (v))
2061 
2062 #define mpii_wait_db_int(s)	mpii_wait_ne((s), MPII_INTR_STATUS, \
2063 				    MPII_INTR_STATUS_IOC2SYSDB, 0)
2064 #define mpii_wait_db_ack(s)	mpii_wait_eq((s), MPII_INTR_STATUS, \
2065 				    MPII_INTR_STATUS_SYS2IOCDB, 0)
2066 
2067 #define MPII_PG_EXTENDED	(1<<0)
2068 #define MPII_PG_POLL		(1<<1)
2069 #define MPII_PG_FMT		"\020" "\002POLL" "\001EXTENDED"
2070 
2071 #define mpii_cfg_header(_s, _t, _n, _a, _h) \
2072 	mpii_req_cfg_header((_s), (_t), (_n), (_a), \
2073 	    MPII_PG_POLL, (_h))
2074 #define mpii_ecfg_header(_s, _t, _n, _a, _h) \
2075 	mpii_req_cfg_header((_s), (_t), (_n), (_a), \
2076 	    MPII_PG_POLL|MPII_PG_EXTENDED, (_h))
2077 
2078 #define mpii_cfg_page(_s, _a, _h, _r, _p, _l) \
2079 	mpii_req_cfg_page((_s), (_a), MPII_PG_POLL, \
2080 	    (_h), (_r), (_p), (_l))
2081 #define mpii_ecfg_page(_s, _a, _h, _r, _p, _l) \
2082 	mpii_req_cfg_page((_s), (_a), MPII_PG_POLL|MPII_PG_EXTENDED, \
2083 	    (_h), (_r), (_p), (_l))
2084 
2085 static const struct pci_matchid mpii_devices[] = {
2086 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2004 },
2087 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2008 },
2088 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2108_3 },
2089 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2108_4 },
2090 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2108_5 },
2091 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2116_1 },
2092 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2116_2 },
2093 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2208_1 },
2094 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2208_2 },
2095 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2208_3 },
2096 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2208_4 },
2097 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2208_5 },
2098 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2208_6 },
2099 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2308_1 },
2100 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2308_2 },
2101 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2308_3 }
2102 };
2103 
2104 int
2105 mpii_match(struct device *parent, void *match, void *aux)
2106 {
2107 	return (pci_matchbyid(aux, mpii_devices, nitems(mpii_devices)));
2108 }
2109 
2110 void
2111 mpii_attach(struct device *parent, struct device *self, void *aux)
2112 {
2113 	struct mpii_softc		*sc = (struct mpii_softc *)self;
2114 	struct pci_attach_args		*pa = aux;
2115 	pcireg_t			memtype;
2116 	int				r;
2117 	pci_intr_handle_t		ih;
2118 	struct scsibus_attach_args	saa;
2119 	struct mpii_ccb			*ccb;
2120 
2121 	sc->sc_pc = pa->pa_pc;
2122 	sc->sc_tag = pa->pa_tag;
2123 	sc->sc_dmat = pa->pa_dmat;
2124 
2125 	mtx_init(&sc->sc_req_mtx, IPL_BIO);
2126 	mtx_init(&sc->sc_rep_mtx, IPL_BIO);
2127 
2128 	/* find the appropriate memory base */
2129 	for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) {
2130 		memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, r);
2131 		if ((memtype & PCI_MAPREG_TYPE_MASK) == PCI_MAPREG_TYPE_MEM)
2132 			break;
2133 	}
2134 	if (r >= PCI_MAPREG_END) {
2135 		printf(": unable to locate system interface registers\n");
2136 		return;
2137 	}
2138 
2139 	if (pci_mapreg_map(pa, r, memtype, 0, &sc->sc_iot, &sc->sc_ioh,
2140 	    NULL, &sc->sc_ios, 0xFF) != 0) {
2141 		printf(": unable to map system interface registers\n");
2142 		return;
2143 	}
2144 
2145 	/* disable the expansion rom */
2146 	PWRITE(sc, PCI_ROM_REG, PREAD(sc, PCI_ROM_REG) & ~PCI_ROM_ENABLE);
2147 
2148 	/* disable interrupts */
2149 	mpii_write(sc, MPII_INTR_MASK,
2150 	    MPII_INTR_MASK_RESET | MPII_INTR_MASK_REPLY |
2151 	    MPII_INTR_MASK_DOORBELL);
2152 
2153 	/* hook up the interrupt */
2154 	if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
2155 		printf(": unable to map interrupt\n");
2156 		goto unmap;
2157 	}
2158 	printf(": %s\n", pci_intr_string(sc->sc_pc, ih));
2159 
2160 	if (mpii_init(sc) != 0) {
2161 		printf("%s: unable to initialize ioc\n", DEVNAME(sc));
2162 		goto unmap;
2163 	}
2164 
2165 	if (mpii_iocfacts(sc) != 0) {
2166 		printf("%s: unable to get iocfacts\n", DEVNAME(sc));
2167 		goto unmap;
2168 	}
2169 
2170 	if (mpii_alloc_ccbs(sc) != 0) {
2171 		/* error already printed */
2172 		goto unmap;
2173 	}
2174 
2175 	if (mpii_alloc_replies(sc) != 0) {
2176 		printf("%s: unable to allocated reply space\n", DEVNAME(sc));
2177 		goto free_ccbs;
2178 	}
2179 
2180 	if (mpii_alloc_queues(sc) != 0) {
2181 		printf("%s: unable to allocate reply queues\n", DEVNAME(sc));
2182 		goto free_replies;
2183 	}
2184 
2185 	if (mpii_iocinit(sc) != 0) {
2186 		printf("%s: unable to send iocinit\n", DEVNAME(sc));
2187 		goto free_queues;
2188 	}
2189 
2190 	if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2191 	    MPII_DOORBELL_STATE_OPER) != 0) {
2192 		printf("%s: state: 0x%08x\n", DEVNAME(sc),
2193 			mpii_read_db(sc) & MPII_DOORBELL_STATE);
2194 		printf("%s: operational state timeout\n", DEVNAME(sc));
2195 		goto free_queues;
2196 	}
2197 
2198 	mpii_push_replies(sc);
2199 	mpii_init_queues(sc);
2200 
2201 	if (mpii_portfacts(sc) != 0) {
2202 		printf("%s: unable to get portfacts\n", DEVNAME(sc));
2203 		goto free_queues;
2204 	}
2205 
2206 	if (mpii_get_ioc_pg8(sc) != 0) {
2207 		printf("%s: unable to get ioc page 8\n", DEVNAME(sc));
2208 		goto free_queues;
2209 	}
2210 
2211 	if (mpii_cfg_coalescing(sc) != 0) {
2212 		printf("%s: unable to configure coalescing\n", DEVNAME(sc));
2213 		goto free_queues;
2214 	}
2215 
2216 	/* XXX bail on unsupported porttype? */
2217 	if ((sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) ||
2218 	    (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL)) {
2219 		if (mpii_eventnotify(sc) != 0) {
2220 			printf("%s: unable to enable events\n", DEVNAME(sc));
2221 			goto free_queues;
2222 		}
2223 	}
2224 
2225 	if (mpii_alloc_dev(sc) != 0) {
2226 		printf("%s: unable to allocate memory for mpii_device\n",
2227 		    DEVNAME(sc));
2228 		goto free_queues;
2229 	}
2230 
2231 	if (mpii_portenable(sc) != 0) {
2232 		printf("%s: unable to enable port\n", DEVNAME(sc));
2233 		goto free_dev;
2234 	}
2235 
2236 	/* we should be good to go now, attach scsibus */
2237 	sc->sc_link.adapter = &mpii_switch;
2238 	sc->sc_link.adapter_softc = sc;
2239 	sc->sc_link.adapter_target = -1;
2240 	sc->sc_link.adapter_buswidth = sc->sc_max_devices;
2241 	sc->sc_link.luns = 1;
2242 	sc->sc_link.openings = sc->sc_request_depth - 1;
2243 	sc->sc_link.pool = &sc->sc_iopool;
2244 
2245 	bzero(&saa, sizeof(saa));
2246 	saa.saa_sc_link = &sc->sc_link;
2247 
2248 	sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_BIO,
2249 	    mpii_intr, sc, sc->sc_dev.dv_xname);
2250 	if (sc->sc_ih == NULL)
2251 		goto free_dev;
2252 
2253 	/* config_found() returns the scsibus attached to us */
2254 	sc->sc_scsibus = (struct scsibus_softc *) config_found(&sc->sc_dev,
2255 	    &saa, scsiprint);
2256 
2257 	/* enable interrupts */
2258 	mpii_write(sc, MPII_INTR_MASK, MPII_INTR_MASK_DOORBELL
2259 	    | MPII_INTR_MASK_RESET);
2260 
2261 #if NBIO > 0
2262 	if (ISSET(sc->sc_flags, MPII_F_RAID)) {
2263 		if (bio_register(&sc->sc_dev, mpii_ioctl) != 0)
2264 			panic("%s: controller registration failed",
2265 			    DEVNAME(sc));
2266 		else
2267 			sc->sc_ioctl = mpii_ioctl;
2268 
2269 #ifndef SMALL_KERNEL
2270 		if (mpii_create_sensors(sc) != 0)
2271 			printf("%s: unable to create sensors\n", DEVNAME(sc));
2272 #endif
2273 	}
2274 #endif
2275 
2276 	return;
2277 
2278 free_dev:
2279 	if (sc->sc_devs)
2280 		free(sc->sc_devs, M_DEVBUF);
2281 
2282 free_queues:
2283 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_freeq),
2284      	    0, sc->sc_reply_free_qdepth * 4, BUS_DMASYNC_POSTREAD);
2285 	mpii_dmamem_free(sc, sc->sc_reply_freeq);
2286 
2287 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
2288 	    0, sc->sc_reply_post_qdepth * 8, BUS_DMASYNC_POSTREAD);
2289 	mpii_dmamem_free(sc, sc->sc_reply_postq);
2290 
2291 free_replies:
2292 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
2293 		0, PAGE_SIZE, BUS_DMASYNC_POSTREAD);
2294 	mpii_dmamem_free(sc, sc->sc_replies);
2295 
2296 free_ccbs:
2297 	while ((ccb = mpii_get_ccb(sc)) != NULL)
2298 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2299 	mpii_dmamem_free(sc, sc->sc_requests);
2300 	free(sc->sc_ccbs, M_DEVBUF);
2301 
2302 unmap:
2303 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
2304 	sc->sc_ios = 0;
2305 }
2306 
2307 int
2308 mpii_detach(struct device *self, int flags)
2309 {
2310 	struct mpii_softc		*sc = (struct mpii_softc *)self;
2311 
2312 	if (sc->sc_ih != NULL) {
2313 		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
2314 		sc->sc_ih = NULL;
2315 	}
2316 	if (sc->sc_ios != 0) {
2317 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
2318 		sc->sc_ios = 0;
2319 	}
2320 
2321 	return (0);
2322 }
2323 
2324 int
2325 mpii_intr(void *arg)
2326 {
2327 	struct mpii_rcb_list		evts = SIMPLEQ_HEAD_INITIALIZER(evts);
2328 	struct mpii_ccb_list		ccbs = SIMPLEQ_HEAD_INITIALIZER(ccbs);
2329 	struct mpii_softc		*sc = arg;
2330 	struct mpii_reply_descr		*postq = sc->sc_reply_postq_kva, *rdp;
2331 	struct mpii_ccb			*ccb;
2332 	struct mpii_rcb			*rcb;
2333 	int				smid;
2334 	int				rv = 0;
2335 
2336 	mtx_enter(&sc->sc_rep_mtx);
2337 	bus_dmamap_sync(sc->sc_dmat,
2338 	    MPII_DMA_MAP(sc->sc_reply_postq),
2339 	    0, 8 * sc->sc_reply_post_qdepth,
2340 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2341 
2342 	for (;;) {
2343 		rdp = &postq[sc->sc_reply_post_host_index];
2344 		if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
2345 		    MPII_REPLY_DESCR_UNUSED)
2346 			break;
2347 		if (rdp->data == 0xffffffff) {
2348 			/*
2349 			 * ioc is still writing to the reply post queue
2350 			 * race condition - bail!
2351 			 */
2352 			break;
2353 		}
2354 
2355 		smid = letoh16(rdp->smid);
2356 		rcb = mpii_reply(sc, rdp);
2357 
2358 		if (smid) {
2359 			ccb = &sc->sc_ccbs[smid - 1];
2360 			ccb->ccb_state = MPII_CCB_READY;
2361 			ccb->ccb_rcb = rcb;
2362 			SIMPLEQ_INSERT_TAIL(&ccbs, ccb, ccb_link);
2363 		} else
2364 			SIMPLEQ_INSERT_TAIL(&evts, rcb, rcb_link);
2365 
2366 		sc->sc_reply_post_host_index++;
2367 		sc->sc_reply_post_host_index %= sc->sc_reply_post_qdepth;
2368 		rv = 1;
2369 	}
2370 
2371 	bus_dmamap_sync(sc->sc_dmat,
2372 	    MPII_DMA_MAP(sc->sc_reply_postq),
2373 	    0, 8 * sc->sc_reply_post_qdepth,
2374 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2375 
2376 	if (rv)
2377 		mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
2378 
2379 	mtx_leave(&sc->sc_rep_mtx);
2380 
2381 	if (rv == 0)
2382 		return (0);
2383 
2384 	while ((ccb = SIMPLEQ_FIRST(&ccbs)) != NULL) {
2385 		SIMPLEQ_REMOVE_HEAD(&ccbs, ccb_link);
2386 		ccb->ccb_done(ccb);
2387 	}
2388 	while ((rcb = SIMPLEQ_FIRST(&evts)) != NULL) {
2389 		SIMPLEQ_REMOVE_HEAD(&evts, rcb_link);
2390 		mpii_event_process(sc, rcb);
2391 	}
2392 
2393 	return (1);
2394 }
2395 
2396 int
2397 mpii_load_xs(struct mpii_ccb *ccb)
2398 {
2399 	struct mpii_softc	*sc = ccb->ccb_sc;
2400 	struct scsi_xfer	*xs = ccb->ccb_cookie;
2401 	struct mpii_ccb_bundle	*mcb = ccb->ccb_cmd;
2402 	struct mpii_msg_scsi_io	*io = &mcb->mcb_io;
2403 	struct mpii_sge		*sge = NULL, *nsge = &mcb->mcb_sgl[0];
2404 	struct mpii_sge		*ce = NULL, *nce = NULL;
2405 	u_int64_t		ce_dva;
2406 	bus_dmamap_t		dmap = ccb->ccb_dmamap;
2407 	u_int32_t		addr, flags;
2408 	int			i, error;
2409 
2410 	/* zero length transfer still requires an SGE */
2411 	if (xs->datalen == 0) {
2412 		nsge->sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
2413 		    MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
2414 		return (0);
2415 	}
2416 
2417 	error = bus_dmamap_load(sc->sc_dmat, dmap,
2418 	    xs->data, xs->datalen, NULL,
2419 	    (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
2420 	if (error) {
2421 		printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
2422 		return (1);
2423 	}
2424 
2425 	/* safe default staring flags */
2426 	flags = MPII_SGE_FL_TYPE_SIMPLE | MPII_SGE_FL_SIZE_64;
2427 	/* if data out */
2428 	if (xs->flags & SCSI_DATA_OUT)
2429 		flags |= MPII_SGE_FL_DIR_OUT;
2430 
2431 	/* we will have to exceed the SGEs we can cram into the request frame */
2432 	if (dmap->dm_nsegs > sc->sc_first_sgl_len) {
2433 		ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1];
2434 		io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4;
2435 	}
2436 
2437 	for (i = 0; i < dmap->dm_nsegs; i++) {
2438 		if (nsge == ce) {
2439 			nsge++;
2440 			sge->sg_hdr |= htole32(MPII_SGE_FL_LAST);
2441 
2442 			DNPRINTF(MPII_D_DMA, "%s:   - 0x%08x 0x%08x 0x%08x\n",
2443 			    DEVNAME(sc), sge->sg_hdr,
2444 			    sge->sg_hi_addr, sge->sg_lo_addr);
2445 
2446 			if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
2447 				nce = &nsge[sc->sc_chain_len - 1];
2448 				addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
2449 				addr = addr << 16 |
2450 				    sizeof(struct mpii_sge) * sc->sc_chain_len;
2451 			} else {
2452 				nce = NULL;
2453 				addr = sizeof(struct mpii_sge) *
2454 				    (dmap->dm_nsegs - i);
2455 			}
2456 
2457 			ce->sg_hdr = htole32(MPII_SGE_FL_TYPE_CHAIN |
2458 			    MPII_SGE_FL_SIZE_64 | addr);
2459 
2460 			ce_dva = ccb->ccb_cmd_dva +
2461 			    ((u_int8_t *)nsge - (u_int8_t *)mcb);
2462 
2463 			addr = (u_int32_t)(ce_dva >> 32);
2464 			ce->sg_hi_addr = htole32(addr);
2465 			addr = (u_int32_t)ce_dva;
2466 			ce->sg_lo_addr = htole32(addr);
2467 
2468 			DNPRINTF(MPII_D_DMA, "%s:  ce: 0x%08x 0x%08x 0x%08x\n",
2469 			    DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr,
2470 			    ce->sg_lo_addr);
2471 
2472 			ce = nce;
2473 		}
2474 
2475 		DNPRINTF(MPII_D_DMA, "%s:  %d: %d 0x%016llx\n", DEVNAME(sc),
2476 		    i, dmap->dm_segs[i].ds_len,
2477 		    (u_int64_t)dmap->dm_segs[i].ds_addr);
2478 
2479 		sge = nsge;
2480 
2481 		sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len);
2482 		addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32);
2483 		sge->sg_hi_addr = htole32(addr);
2484 		addr = (u_int32_t)dmap->dm_segs[i].ds_addr;
2485 		sge->sg_lo_addr = htole32(addr);
2486 
2487 		DNPRINTF(MPII_D_DMA, "%s:  %d: 0x%08x 0x%08x 0x%08x\n",
2488 		    DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr,
2489 		    sge->sg_lo_addr);
2490 
2491 		nsge = sge + 1;
2492 	}
2493 
2494 	/* terminate list */
2495 	sge->sg_hdr |= htole32(MPII_SGE_FL_LAST | MPII_SGE_FL_EOB |
2496 	    MPII_SGE_FL_EOL);
2497 
2498 	bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
2499 	    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
2500 	    BUS_DMASYNC_PREWRITE);
2501 
2502 	return (0);
2503 }
2504 
2505 int
2506 mpii_scsi_probe(struct scsi_link *link)
2507 {
2508 	struct mpii_softc	*sc = link->adapter_softc;
2509 	int			flags;
2510 
2511 	if ((sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) &&
2512 	    (sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL))
2513 		return (1);
2514 
2515 	if (sc->sc_devs[link->target] == NULL)
2516 		return (1);
2517 
2518 	flags = sc->sc_devs[link->target]->flags;
2519 	if (ISSET(flags, MPII_DF_HIDDEN) || ISSET(flags, MPII_DF_UNUSED))
2520 		return (1);
2521 
2522 	return (0);
2523 }
2524 
2525 u_int32_t
2526 mpii_read(struct mpii_softc *sc, bus_size_t r)
2527 {
2528 	u_int32_t			rv;
2529 
2530 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2531 	    BUS_SPACE_BARRIER_READ);
2532 	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
2533 
2534 	DNPRINTF(MPII_D_RW, "%s: mpii_read %#x %#x\n", DEVNAME(sc), r, rv);
2535 
2536 	return (rv);
2537 }
2538 
2539 void
2540 mpii_write(struct mpii_softc *sc, bus_size_t r, u_int32_t v)
2541 {
2542 	DNPRINTF(MPII_D_RW, "%s: mpii_write %#x %#x\n", DEVNAME(sc), r, v);
2543 
2544 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
2545 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2546 	    BUS_SPACE_BARRIER_WRITE);
2547 }
2548 
2549 
2550 int
2551 mpii_wait_eq(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
2552     u_int32_t target)
2553 {
2554 	int			i;
2555 
2556 	DNPRINTF(MPII_D_RW, "%s: mpii_wait_eq %#x %#x %#x\n", DEVNAME(sc), r,
2557 	    mask, target);
2558 
2559 	for (i = 0; i < 15000; i++) {
2560 		if ((mpii_read(sc, r) & mask) == target)
2561 			return (0);
2562 		delay(1000);
2563 	}
2564 
2565 	return (1);
2566 }
2567 
2568 int
2569 mpii_wait_ne(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
2570     u_int32_t target)
2571 {
2572 	int			i;
2573 
2574 	DNPRINTF(MPII_D_RW, "%s: mpii_wait_ne %#x %#x %#x\n", DEVNAME(sc), r,
2575 	    mask, target);
2576 
2577 	for (i = 0; i < 15000; i++) {
2578 		if ((mpii_read(sc, r) & mask) != target)
2579 			return (0);
2580 		delay(1000);
2581 	}
2582 
2583 	return (1);
2584 }
2585 
2586 
2587 int
2588 mpii_init(struct mpii_softc *sc)
2589 {
2590 	u_int32_t		db;
2591 	int			i;
2592 
2593 	/* spin until the ioc leaves the reset state */
2594 	if (mpii_wait_ne(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2595 	    MPII_DOORBELL_STATE_RESET) != 0) {
2596 		DNPRINTF(MPII_D_MISC, "%s: mpii_init timeout waiting to leave "
2597 		    "reset state\n", DEVNAME(sc));
2598 		return (1);
2599 	}
2600 
2601 	/* check current ownership */
2602 	db = mpii_read_db(sc);
2603 	if ((db & MPII_DOORBELL_WHOINIT) == MPII_DOORBELL_WHOINIT_PCIPEER) {
2604 		DNPRINTF(MPII_D_MISC, "%s: mpii_init initialised by pci peer\n",
2605 		    DEVNAME(sc));
2606 		return (0);
2607 	}
2608 
2609 	for (i = 0; i < 5; i++) {
2610 		switch (db & MPII_DOORBELL_STATE) {
2611 		case MPII_DOORBELL_STATE_READY:
2612 			DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is ready\n",
2613 			    DEVNAME(sc));
2614 			return (0);
2615 
2616 		case MPII_DOORBELL_STATE_OPER:
2617 			DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is oper\n",
2618 			    DEVNAME(sc));
2619 			if (sc->sc_ioc_event_replay)
2620 				mpii_reset_soft(sc);
2621 			else
2622 				mpii_reset_hard(sc);
2623 			break;
2624 
2625 		case MPII_DOORBELL_STATE_FAULT:
2626 			DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is being "
2627 			    "reset hard\n" , DEVNAME(sc));
2628 			mpii_reset_hard(sc);
2629 			break;
2630 
2631 		case MPII_DOORBELL_STATE_RESET:
2632 			DNPRINTF(MPII_D_MISC, "%s: mpii_init waiting to come "
2633 			    "out of reset\n", DEVNAME(sc));
2634 			if (mpii_wait_ne(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2635 			    MPII_DOORBELL_STATE_RESET) != 0)
2636 				return (1);
2637 			break;
2638 		}
2639 		db = mpii_read_db(sc);
2640 	}
2641 
2642 	return (1);
2643 }
2644 
2645 int
2646 mpii_reset_soft(struct mpii_softc *sc)
2647 {
2648 	DNPRINTF(MPII_D_MISC, "%s: mpii_reset_soft\n", DEVNAME(sc));
2649 
2650 	if (mpii_read_db(sc) & MPII_DOORBELL_INUSE) {
2651 		return (1);
2652 	}
2653 
2654 	mpii_write_db(sc,
2655 	    MPII_DOORBELL_FUNCTION(MPII_FUNCTION_IOC_MESSAGE_UNIT_RESET));
2656 
2657 	/* XXX LSI waits 15 sec */
2658 	if (mpii_wait_db_ack(sc) != 0)
2659 		return (1);
2660 
2661 	/* XXX LSI waits 15 sec */
2662 	if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2663 	    MPII_DOORBELL_STATE_READY) != 0)
2664 		return (1);
2665 
2666 	/* XXX wait for Sys2IOCDB bit to clear in HIS?? */
2667 
2668 	return (0);
2669 }
2670 
2671 int
2672 mpii_reset_hard(struct mpii_softc *sc)
2673 {
2674 	u_int16_t		i;
2675 
2676 	DNPRINTF(MPII_D_MISC, "%s: mpii_reset_hard\n", DEVNAME(sc));
2677 
2678 	mpii_write_intr(sc, 0);
2679 
2680 	/* enable diagnostic register */
2681 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_FLUSH);
2682 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_1);
2683 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_2);
2684 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_3);
2685 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_4);
2686 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_5);
2687 	mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_6);
2688 
2689 	delay(100);
2690 
2691 	if ((mpii_read(sc, MPII_HOSTDIAG) & MPII_HOSTDIAG_DWRE) == 0) {
2692 		DNPRINTF(MPII_D_MISC, "%s: mpii_reset_hard failure to enable "
2693 		    "diagnostic read/write\n", DEVNAME(sc));
2694 		return(1);
2695 	}
2696 
2697 	/* reset ioc */
2698 	mpii_write(sc, MPII_HOSTDIAG, MPII_HOSTDIAG_RESET_ADAPTER);
2699 
2700 	/* 240 milliseconds */
2701 	delay(240000);
2702 
2703 
2704 	/* XXX this whole function should be more robust */
2705 
2706 	/* XXX  read the host diagnostic reg until reset adapter bit clears ? */
2707 	for (i = 0; i < 30000; i++) {
2708 		if ((mpii_read(sc, MPII_HOSTDIAG) &
2709 		    MPII_HOSTDIAG_RESET_ADAPTER) == 0)
2710 			break;
2711 		delay(10000);
2712 	}
2713 
2714 	/* disable diagnostic register */
2715 	mpii_write(sc, MPII_WRITESEQ, 0xff);
2716 
2717 	/* XXX what else? */
2718 
2719 	DNPRINTF(MPII_D_MISC, "%s: done with mpii_reset_hard\n", DEVNAME(sc));
2720 
2721 	return(0);
2722 }
2723 
2724 int
2725 mpii_handshake_send(struct mpii_softc *sc, void *buf, size_t dwords)
2726 {
2727 	u_int32_t		*query = buf;
2728 	int			i;
2729 
2730 	/* make sure the doorbell is not in use. */
2731 	if (mpii_read_db(sc) & MPII_DOORBELL_INUSE)
2732 		return (1);
2733 
2734 	/* clear pending doorbell interrupts */
2735 	if (mpii_read_intr(sc) & MPII_INTR_STATUS_IOC2SYSDB)
2736 		mpii_write_intr(sc, 0);
2737 
2738 	/*
2739 	 * first write the doorbell with the handshake function and the
2740 	 * dword count.
2741 	 */
2742 	mpii_write_db(sc, MPII_DOORBELL_FUNCTION(MPII_FUNCTION_HANDSHAKE) |
2743 	    MPII_DOORBELL_DWORDS(dwords));
2744 
2745 	/*
2746 	 * the doorbell used bit will be set because a doorbell function has
2747 	 * started. wait for the interrupt and then ack it.
2748 	 */
2749 	if (mpii_wait_db_int(sc) != 0)
2750 		return (1);
2751 	mpii_write_intr(sc, 0);
2752 
2753 	/* poll for the acknowledgement. */
2754 	if (mpii_wait_db_ack(sc) != 0)
2755 		return (1);
2756 
2757 	/* write the query through the doorbell. */
2758 	for (i = 0; i < dwords; i++) {
2759 		mpii_write_db(sc, htole32(query[i]));
2760 		if (mpii_wait_db_ack(sc) != 0)
2761 			return (1);
2762 	}
2763 
2764 	return (0);
2765 }
2766 
2767 int
2768 mpii_handshake_recv_dword(struct mpii_softc *sc, u_int32_t *dword)
2769 {
2770 	u_int16_t		*words = (u_int16_t *)dword;
2771 	int			i;
2772 
2773 	for (i = 0; i < 2; i++) {
2774 		if (mpii_wait_db_int(sc) != 0)
2775 			return (1);
2776 		words[i] = letoh16(mpii_read_db(sc) & MPII_DOORBELL_DATA_MASK);
2777 		mpii_write_intr(sc, 0);
2778 	}
2779 
2780 	return (0);
2781 }
2782 
2783 int
2784 mpii_handshake_recv(struct mpii_softc *sc, void *buf, size_t dwords)
2785 {
2786 	struct mpii_msg_reply	*reply = buf;
2787 	u_int32_t		*dbuf = buf, dummy;
2788 	int			i;
2789 
2790 	/* get the first dword so we can read the length out of the header. */
2791 	if (mpii_handshake_recv_dword(sc, &dbuf[0]) != 0)
2792 		return (1);
2793 
2794 	DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dwords: %d reply: %d\n",
2795 	    DEVNAME(sc), dwords, reply->msg_length);
2796 
2797 	/*
2798 	 * the total length, in dwords, is in the message length field of the
2799 	 * reply header.
2800 	 */
2801 	for (i = 1; i < MIN(dwords, reply->msg_length); i++) {
2802 		if (mpii_handshake_recv_dword(sc, &dbuf[i]) != 0)
2803 			return (1);
2804 	}
2805 
2806 	/* if there's extra stuff to come off the ioc, discard it */
2807 	while (i++ < reply->msg_length) {
2808 		if (mpii_handshake_recv_dword(sc, &dummy) != 0)
2809 			return (1);
2810 		DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dummy read: "
2811 		    "0x%08x\n", DEVNAME(sc), dummy);
2812 	}
2813 
2814 	/* wait for the doorbell used bit to be reset and clear the intr */
2815 	if (mpii_wait_db_int(sc) != 0)
2816 		return (1);
2817 
2818 	if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_INUSE, 0) != 0)
2819 		return (1);
2820 
2821 	mpii_write_intr(sc, 0);
2822 
2823 	return (0);
2824 }
2825 
2826 void
2827 mpii_empty_done(struct mpii_ccb *ccb)
2828 {
2829 	/* nothing to do */
2830 }
2831 
2832 int
2833 mpii_iocfacts(struct mpii_softc *sc)
2834 {
2835 	struct mpii_msg_iocfacts_request	ifq;
2836 	struct mpii_msg_iocfacts_reply		ifp;
2837 
2838 	DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts\n", DEVNAME(sc));
2839 
2840 	bzero(&ifq, sizeof(ifq));
2841 	bzero(&ifp, sizeof(ifp));
2842 
2843 	ifq.function = MPII_FUNCTION_IOC_FACTS;
2844 
2845 	if (mpii_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) {
2846 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts send failed\n",
2847 		    DEVNAME(sc));
2848 		return (1);
2849 	}
2850 
2851 	if (mpii_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) {
2852 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts recv failed\n",
2853 		    DEVNAME(sc));
2854 		return (1);
2855 	}
2856 
2857 	DNPRINTF(MPII_D_MISC, "%s:  func: 0x%02x length: %d msgver: %d.%d\n",
2858 	    DEVNAME(sc), ifp.function, ifp.msg_length,
2859 	    ifp.msg_version_maj, ifp.msg_version_min);
2860 	DNPRINTF(MPII_D_MISC, "%s:  msgflags: 0x%02x iocnumber: 0x%02x "
2861 	    "headerver: %d.%d\n", DEVNAME(sc), ifp.msg_flags,
2862 	    ifp.ioc_number, ifp.header_version_unit,
2863 	    ifp.header_version_dev);
2864 	DNPRINTF(MPII_D_MISC, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
2865 	    ifp.vp_id, ifp.vf_id);
2866 	DNPRINTF(MPII_D_MISC, "%s:  iocstatus: 0x%04x ioexceptions: 0x%04x\n",
2867 	    DEVNAME(sc), letoh16(ifp.ioc_status),
2868 	    letoh16(ifp.ioc_exceptions));
2869 	DNPRINTF(MPII_D_MISC, "%s:  iocloginfo: 0x%08x\n", DEVNAME(sc),
2870 	    letoh32(ifp.ioc_loginfo));
2871 	DNPRINTF(MPII_D_MISC, "%s:  numberofports: 0x%02x whoinit: 0x%02x "
2872 	    "maxchaindepth: %d\n", DEVNAME(sc), ifp.number_of_ports,
2873 	    ifp.whoinit, ifp.max_chain_depth);
2874 	DNPRINTF(MPII_D_MISC, "%s:  productid: 0x%04x requestcredit: 0x%04x\n",
2875 	    DEVNAME(sc), letoh16(ifp.product_id), letoh16(ifp.request_credit));
2876 	DNPRINTF(MPII_D_MISC, "%s:  ioc_capabilities: 0x%08x\n", DEVNAME(sc),
2877 	    letoh32(ifp.ioc_capabilities));
2878 	DNPRINTF(MPII_D_MISC, "%s:  fw_version: %d.%d fw_version_unit: 0x%02x "
2879 	    "fw_version_dev: 0x%02x\n", DEVNAME(sc),
2880 	    ifp.fw_version_maj, ifp.fw_version_min,
2881 	    ifp.fw_version_unit, ifp.fw_version_dev);
2882 	DNPRINTF(MPII_D_MISC, "%s:  iocrequestframesize: 0x%04x\n",
2883 	    DEVNAME(sc), letoh16(ifp.ioc_request_frame_size));
2884 	DNPRINTF(MPII_D_MISC, "%s:  maxtargets: 0x%04x "
2885 	    "maxinitiators: 0x%04x\n", DEVNAME(sc),
2886 	    letoh16(ifp.max_targets), letoh16(ifp.max_initiators));
2887 	DNPRINTF(MPII_D_MISC, "%s:  maxenclosures: 0x%04x "
2888 	    "maxsasexpanders: 0x%04x\n", DEVNAME(sc),
2889 	    letoh16(ifp.max_enclosures), letoh16(ifp.max_sas_expanders));
2890 	DNPRINTF(MPII_D_MISC, "%s:  highprioritycredit: 0x%04x "
2891 	    "protocolflags: 0x%02x\n", DEVNAME(sc),
2892 	    letoh16(ifp.high_priority_credit), letoh16(ifp.protocol_flags));
2893 	DNPRINTF(MPII_D_MISC, "%s:  maxvolumes: 0x%02x replyframesize: 0x%02x "
2894 	    "mrdpqd: 0x%04x\n", DEVNAME(sc), ifp.max_volumes,
2895 	    ifp.reply_frame_size,
2896 	    letoh16(ifp.max_reply_descriptor_post_queue_depth));
2897 	DNPRINTF(MPII_D_MISC, "%s:  maxpersistententries: 0x%04x "
2898 	    "maxdevhandle: 0x%02x\n", DEVNAME(sc),
2899 	    letoh16(ifp.max_persistent_entries), letoh16(ifp.max_dev_handle));
2900 
2901 	sc->sc_maxchdepth = ifp.max_chain_depth;
2902 	sc->sc_ioc_number = ifp.ioc_number;
2903 	sc->sc_vf_id = ifp.vf_id;
2904 
2905 	sc->sc_num_ports = ifp.number_of_ports;
2906 	sc->sc_ioc_event_replay = (letoh32(ifp.ioc_capabilities) &
2907 	    MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY) ? 1 : 0;
2908 	sc->sc_max_enclosures = letoh16(ifp.max_enclosures);
2909 	sc->sc_max_expanders = letoh16(ifp.max_sas_expanders);
2910 	sc->sc_max_volumes = ifp.max_volumes;
2911 	sc->sc_max_devices = ifp.max_volumes + letoh16(ifp.max_targets);
2912 	sc->sc_num_channels = 1;
2913 
2914 	if (ISSET(letoh32(ifp.ioc_capabilities),
2915 	    MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID))
2916 		SET(sc->sc_flags, MPII_F_RAID);
2917 
2918 	sc->sc_request_depth = MIN(letoh16(ifp.request_credit),
2919 	    MPII_MAX_REQUEST_CREDIT);
2920 
2921 	/* should not be multiple of 16 */
2922 	sc->sc_num_reply_frames = sc->sc_request_depth + 32;
2923 	if (!(sc->sc_num_reply_frames % 16))
2924 		sc->sc_num_reply_frames--;
2925 
2926 	/* must be multiple of 16 */
2927 	sc->sc_reply_free_qdepth = sc->sc_num_reply_frames +
2928 	    (16 - (sc->sc_num_reply_frames % 16));
2929 	sc->sc_reply_post_qdepth = ((sc->sc_request_depth +
2930 	    sc->sc_num_reply_frames + 1 + 15) / 16) * 16;
2931 
2932 	if (sc->sc_reply_post_qdepth >
2933 	    ifp.max_reply_descriptor_post_queue_depth)
2934 		sc->sc_reply_post_qdepth =
2935 		    ifp.max_reply_descriptor_post_queue_depth;
2936 
2937 	DNPRINTF(MPII_D_MISC, "%s: sc_request_depth: %d "
2938 	    "sc_num_reply_frames: %d sc_reply_free_qdepth: %d "
2939 	    "sc_reply_post_qdepth: %d\n", DEVNAME(sc), sc->sc_request_depth,
2940 	    sc->sc_num_reply_frames, sc->sc_reply_free_qdepth,
2941 	    sc->sc_reply_post_qdepth);
2942 
2943 	/*
2944 	 * you can fit sg elements on the end of the io cmd if they fit in the
2945 	 * request frame size.
2946 	 */
2947 
2948 	sc->sc_first_sgl_len = ((letoh16(ifp.ioc_request_frame_size) * 4) -
2949 	    sizeof(struct mpii_msg_scsi_io)) / sizeof(struct mpii_sge);
2950 	DNPRINTF(MPII_D_MISC, "%s:   first sgl len: %d\n", DEVNAME(sc),
2951 	    sc->sc_first_sgl_len);
2952 
2953 	sc->sc_chain_len = (letoh16(ifp.ioc_request_frame_size) * 4) /
2954 	    sizeof(struct mpii_sge);
2955 	DNPRINTF(MPII_D_MISC, "%s:   chain len: %d\n", DEVNAME(sc),
2956 	    sc->sc_chain_len);
2957 
2958 	/* the sgl tailing the io cmd loses an entry to the chain element. */
2959 	sc->sc_max_sgl_len = MPII_MAX_SGL - 1;
2960 	/* the sgl chains lose an entry for each chain element */
2961 	sc->sc_max_sgl_len -= (MPII_MAX_SGL - sc->sc_first_sgl_len) /
2962 	    sc->sc_chain_len;
2963 	DNPRINTF(MPII_D_MISC, "%s:   max sgl len: %d\n", DEVNAME(sc),
2964 	    sc->sc_max_sgl_len);
2965 
2966 	/* XXX we're ignoring the max chain depth */
2967 
2968 	return(0);
2969 
2970 }
2971 
2972 int
2973 mpii_iocinit(struct mpii_softc *sc)
2974 {
2975 	struct mpii_msg_iocinit_request		iiq;
2976 	struct mpii_msg_iocinit_reply		iip;
2977 	u_int32_t				hi_addr;
2978 
2979 	DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit\n", DEVNAME(sc));
2980 
2981 	bzero(&iiq, sizeof(iiq));
2982 	bzero(&iip, sizeof(iip));
2983 
2984 	iiq.function = MPII_FUNCTION_IOC_INIT;
2985 	iiq.whoinit = MPII_WHOINIT_HOST_DRIVER;
2986 
2987 	/* XXX JPG do something about vf_id */
2988 	iiq.vf_id = 0;
2989 
2990 	iiq.msg_version_maj = 0x02;
2991 	iiq.msg_version_min = 0x00;
2992 
2993 	/* XXX JPG ensure compliance with some level and hard-code? */
2994 	iiq.hdr_version_unit = 0x00;
2995 	iiq.hdr_version_dev = 0x00;
2996 
2997 	iiq.system_request_frame_size = htole16(MPII_REQUEST_SIZE / 4);
2998 
2999 	iiq.reply_descriptor_post_queue_depth =
3000 	    htole16(sc->sc_reply_post_qdepth);
3001 
3002 	iiq.reply_free_queue_depth = htole16(sc->sc_reply_free_qdepth);
3003 
3004 	hi_addr = (u_int32_t)((u_int64_t)MPII_DMA_DVA(sc->sc_requests) >> 32);
3005 	iiq.sense_buffer_address_high = htole32(hi_addr);
3006 
3007 	hi_addr = (u_int32_t)
3008 	    ((u_int64_t)MPII_DMA_DVA(sc->sc_replies) >> 32);
3009 	iiq.system_reply_address_high = htole32(hi_addr);
3010 
3011 	iiq.system_request_frame_base_address =
3012 	    (u_int64_t)MPII_DMA_DVA(sc->sc_requests);
3013 
3014 	iiq.reply_descriptor_post_queue_address =
3015 	    (u_int64_t)MPII_DMA_DVA(sc->sc_reply_postq);
3016 
3017 	iiq.reply_free_queue_address =
3018 	    (u_int64_t)MPII_DMA_DVA(sc->sc_reply_freeq);
3019 
3020 	if (mpii_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) {
3021 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit send failed\n",
3022 		    DEVNAME(sc));
3023 		return (1);
3024 	}
3025 
3026 	if (mpii_handshake_recv(sc, &iip, dwordsof(iip)) != 0) {
3027 		DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit recv failed\n",
3028 		    DEVNAME(sc));
3029 		return (1);
3030 	}
3031 
3032 	DNPRINTF(MPII_D_MISC, "%s:  function: 0x%02x msg_length: %d "
3033 	    "whoinit: 0x%02x\n", DEVNAME(sc), iip.function,
3034 	    iip.msg_length, iip.whoinit);
3035 	DNPRINTF(MPII_D_MISC, "%s:  msg_flags: 0x%02x\n", DEVNAME(sc),
3036 	    iip.msg_flags);
3037 	DNPRINTF(MPII_D_MISC, "%s:  vf_id: 0x%02x vp_id: 0x%02x\n", DEVNAME(sc),
3038 	    iip.vf_id, iip.vp_id);
3039 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
3040 	    letoh16(iip.ioc_status));
3041 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3042 	    letoh32(iip.ioc_loginfo));
3043 
3044 	if ((iip.ioc_status != MPII_IOCSTATUS_SUCCESS) || (iip.ioc_loginfo))
3045 		return (1);
3046 
3047 	return (0);
3048 }
3049 
3050 void
3051 mpii_push_reply(struct mpii_softc *sc, struct mpii_rcb *rcb)
3052 {
3053 	u_int32_t		*rfp;
3054 
3055 	if (rcb == NULL)
3056 		return;
3057 
3058 	rfp = MPII_DMA_KVA(sc->sc_reply_freeq);
3059 	rfp[sc->sc_reply_free_host_index] = rcb->rcb_reply_dva;
3060 
3061 	sc->sc_reply_free_host_index = (sc->sc_reply_free_host_index + 1) %
3062 	    sc->sc_reply_free_qdepth;
3063 
3064 	mpii_write_reply_free(sc, sc->sc_reply_free_host_index);
3065 }
3066 
3067 int
3068 mpii_portfacts(struct mpii_softc *sc)
3069 {
3070 	struct mpii_msg_portfacts_request	*pfq;
3071 	struct mpii_msg_portfacts_reply		*pfp;
3072 	struct mpii_ccb				*ccb;
3073 	int					rv = 1;
3074 
3075 	DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts\n", DEVNAME(sc));
3076 
3077 	ccb = scsi_io_get(&sc->sc_iopool, 0);
3078 	if (ccb == NULL) {
3079 		DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts mpii_get_ccb fail\n",
3080 		    DEVNAME(sc));
3081 		return (rv);
3082 	}
3083 
3084 	ccb->ccb_done = mpii_empty_done;
3085 	pfq = ccb->ccb_cmd;
3086 
3087 	bzero(pfq, sizeof(*pfq));
3088 
3089 	pfq->function = MPII_FUNCTION_PORT_FACTS;
3090 	pfq->chain_offset = 0;
3091 	pfq->msg_flags = 0;
3092 	pfq->port_number = 0;
3093 	pfq->vp_id = 0;
3094 	pfq->vf_id = 0;
3095 
3096 	if (mpii_poll(sc, ccb) != 0) {
3097 		DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts poll\n",
3098 		    DEVNAME(sc));
3099 		goto err;
3100 	}
3101 
3102 	if (ccb->ccb_rcb == NULL) {
3103 		DNPRINTF(MPII_D_MISC, "%s: empty portfacts reply\n",
3104 		    DEVNAME(sc));
3105 		goto err;
3106 	}
3107 
3108 	pfp = ccb->ccb_rcb->rcb_reply;
3109 	DNPRINTF(MPII_D_MISC, "%s   pfp: 0x%04x\n", DEVNAME(sc), pfp);
3110 
3111 	DNPRINTF(MPII_D_MISC, "%s:  function: 0x%02x msg_length: %d\n",
3112 	    DEVNAME(sc), pfp->function, pfp->msg_length);
3113 	DNPRINTF(MPII_D_MISC, "%s:  msg_flags: 0x%02x port_number: %d\n",
3114 	    DEVNAME(sc), pfp->msg_flags, pfp->port_number);
3115 	DNPRINTF(MPII_D_MISC, "%s:  vf_id: 0x%02x vp_id: 0x%02x\n",
3116 	    DEVNAME(sc), pfp->vf_id, pfp->vp_id);
3117 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
3118 	    letoh16(pfp->ioc_status));
3119 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3120 	    letoh32(pfp->ioc_loginfo));
3121 	DNPRINTF(MPII_D_MISC, "%s:  port_type: 0x%02x\n", DEVNAME(sc),
3122 	    pfp->port_type);
3123 	DNPRINTF(MPII_D_MISC, "%s:  max_posted_cmd_buffers: %d\n", DEVNAME(sc),
3124 	    letoh16(pfp->max_posted_cmd_buffers));
3125 
3126 	sc->sc_porttype = pfp->port_type;
3127 
3128 	mpii_push_reply(sc, ccb->ccb_rcb);
3129 	rv = 0;
3130 err:
3131 	scsi_io_put(&sc->sc_iopool, ccb);
3132 
3133 	return (rv);
3134 }
3135 
3136 void
3137 mpii_eventack(void *cookie, void *io)
3138 {
3139 	struct mpii_softc			*sc = cookie;
3140 	struct mpii_ccb				*ccb = io;
3141 	struct mpii_rcb				*rcb, *next;
3142 	struct mpii_msg_event_reply		*enp;
3143 	struct mpii_msg_eventack_request	*eaq;
3144 
3145 	mtx_enter(&sc->sc_evt_ack_mtx);
3146 	rcb = SIMPLEQ_FIRST(&sc->sc_evt_ack_queue);
3147 	if (rcb != NULL) {
3148 		next = SIMPLEQ_NEXT(rcb, rcb_link);
3149 		SIMPLEQ_REMOVE_HEAD(&sc->sc_evt_ack_queue, rcb_link);
3150 	}
3151 	mtx_leave(&sc->sc_evt_ack_mtx);
3152 
3153 	if (rcb == NULL) {
3154 		scsi_io_put(&sc->sc_iopool, ccb);
3155 		return;
3156 	}
3157 
3158 	enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
3159 
3160 	ccb->ccb_done = mpii_eventack_done;
3161 	eaq = ccb->ccb_cmd;
3162 
3163 	eaq->function = MPII_FUNCTION_EVENT_ACK;
3164 
3165 	eaq->event = enp->event;
3166 	eaq->event_context = enp->event_context;
3167 
3168 	mpii_push_reply(sc, rcb);
3169 
3170 	mpii_start(sc, ccb);
3171 
3172 	if (next != NULL)
3173 		scsi_ioh_add(&sc->sc_evt_ack_handler);
3174 }
3175 
3176 void
3177 mpii_eventack_done(struct mpii_ccb *ccb)
3178 {
3179 	struct mpii_softc			*sc = ccb->ccb_sc;
3180 
3181 	DNPRINTF(MPII_D_EVT, "%s: event ack done\n", DEVNAME(sc));
3182 
3183 	mpii_push_reply(sc, ccb->ccb_rcb);
3184 	scsi_io_put(&sc->sc_iopool, ccb);
3185 }
3186 
3187 int
3188 mpii_portenable(struct mpii_softc *sc)
3189 {
3190 	struct mpii_msg_portenable_request	*peq;
3191 	struct mpii_msg_portenable_repy		*pep;
3192 	struct mpii_ccb				*ccb;
3193 
3194 	DNPRINTF(MPII_D_MISC, "%s: mpii_portenable\n", DEVNAME(sc));
3195 
3196 	ccb = scsi_io_get(&sc->sc_iopool, 0);
3197 	if (ccb == NULL) {
3198 		DNPRINTF(MPII_D_MISC, "%s: mpii_portenable ccb_get\n",
3199 		    DEVNAME(sc));
3200 		return (1);
3201 	}
3202 
3203 	ccb->ccb_done = mpii_empty_done;
3204 	peq = ccb->ccb_cmd;
3205 
3206 	peq->function = MPII_FUNCTION_PORT_ENABLE;
3207 	peq->vf_id = sc->sc_vf_id;
3208 
3209 	if (mpii_poll(sc, ccb) != 0) {
3210 		DNPRINTF(MPII_D_MISC, "%s: mpii_portenable poll\n",
3211 		    DEVNAME(sc));
3212 		return (1);
3213 	}
3214 
3215 	if (ccb->ccb_rcb == NULL) {
3216 		DNPRINTF(MPII_D_MISC, "%s: empty portenable reply\n",
3217 		    DEVNAME(sc));
3218 		return (1);
3219 	}
3220 	pep = ccb->ccb_rcb->rcb_reply;
3221 
3222 	mpii_push_reply(sc, ccb->ccb_rcb);
3223 	scsi_io_put(&sc->sc_iopool, ccb);
3224 
3225 	return (0);
3226 }
3227 
3228 int
3229 mpii_cfg_coalescing(struct mpii_softc *sc)
3230 {
3231 	struct mpii_cfg_hdr		hdr;
3232 	struct mpii_cfg_ioc_pg1		pg;
3233 
3234 	if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 1, 0,
3235 	    &hdr) != 0) {
3236 		DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1 "
3237 		    "header\n", DEVNAME(sc));
3238 		return (1);
3239 	}
3240 
3241 	if (mpii_cfg_page(sc, 0, &hdr, 1, &pg, sizeof(pg)) != 0) {
3242 		DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1\n"
3243 		    "page 1\n", DEVNAME(sc));
3244 		return (1);
3245 	}
3246 
3247 	DNPRINTF(MPII_D_MISC, "%s: IOC page 1\n", DEVNAME(sc));
3248 	DNPRINTF(MPII_D_MISC, "%s:  flags: 0x08%x\n", DEVNAME(sc),
3249 	    letoh32(pg.flags));
3250 	DNPRINTF(MPII_D_MISC, "%s:  coalescing_timeout: %d\n", DEVNAME(sc),
3251 	    letoh32(pg.coalescing_timeout));
3252 	DNPRINTF(MPII_D_MISC, "%s:  coalescing_depth: %d pci_slot_num: %d\n",
3253 	    DEVNAME(sc), pg.coalescing_timeout, pg.pci_slot_num);
3254 
3255 	if (!ISSET(letoh32(pg.flags), MPII_CFG_IOC_1_REPLY_COALESCING))
3256 		return (0);
3257 
3258 	CLR(pg.flags, htole32(MPII_CFG_IOC_1_REPLY_COALESCING));
3259 	if (mpii_cfg_page(sc, 0, &hdr, 0, &pg, sizeof(pg)) != 0) {
3260 		DNPRINTF(MPII_D_MISC, "%s: unable to clear coalescing\n",
3261 		    DEVNAME(sc));
3262 		return (1);
3263 	}
3264 
3265 	return (0);
3266 }
3267 
3268 #define MPII_EVENT_MASKALL(enq)		do {			\
3269 		enq->event_masks[0] = 0xffffffff;		\
3270 		enq->event_masks[1] = 0xffffffff;		\
3271 		enq->event_masks[2] = 0xffffffff;		\
3272 		enq->event_masks[3] = 0xffffffff;		\
3273 	} while (0)
3274 
3275 #define MPII_EVENT_UNMASK(enq, evt)	do {			\
3276 		enq->event_masks[evt / 32] &=			\
3277 		    htole32(~(1 << (evt % 32)));		\
3278 	} while (0)
3279 
3280 int
3281 mpii_eventnotify(struct mpii_softc *sc)
3282 {
3283 	struct mpii_msg_event_request		*enq;
3284 	struct mpii_ccb				*ccb;
3285 
3286 	ccb = scsi_io_get(&sc->sc_iopool, 0);
3287 	if (ccb == NULL) {
3288 		DNPRINTF(MPII_D_MISC, "%s: mpii_eventnotify ccb_get\n",
3289 		    DEVNAME(sc));
3290 		return (1);
3291 	}
3292 
3293 	SIMPLEQ_INIT(&sc->sc_evt_ack_queue);
3294 	mtx_init(&sc->sc_evt_ack_mtx, IPL_BIO);
3295 	scsi_ioh_set(&sc->sc_evt_ack_handler, &sc->sc_iopool,
3296 	    mpii_eventack, sc);
3297 
3298 	ccb->ccb_done = mpii_eventnotify_done;
3299 	enq = ccb->ccb_cmd;
3300 
3301 	enq->function = MPII_FUNCTION_EVENT_NOTIFICATION;
3302 
3303 	/*
3304 	 * Enable reporting of the following events:
3305 	 *
3306 	 * MPII_EVENT_SAS_DISCOVERY
3307 	 * MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST
3308 	 * MPII_EVENT_SAS_DEVICE_STATUS_CHANGE
3309 	 * MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE
3310 	 * MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST
3311 	 * MPII_EVENT_IR_VOLUME
3312 	 * MPII_EVENT_IR_PHYSICAL_DISK
3313 	 * MPII_EVENT_IR_OPERATION_STATUS
3314 	 */
3315 
3316 	MPII_EVENT_MASKALL(enq);
3317 	MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_DISCOVERY);
3318 	MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
3319 	MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_DEVICE_STATUS_CHANGE);
3320 	MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE);
3321 	MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST);
3322 	MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_VOLUME);
3323 	MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_PHYSICAL_DISK);
3324 	MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_OPERATION_STATUS);
3325 
3326 	mpii_start(sc, ccb);
3327 
3328 	return (0);
3329 }
3330 
3331 void
3332 mpii_eventnotify_done(struct mpii_ccb *ccb)
3333 {
3334 	struct mpii_softc			*sc = ccb->ccb_sc;
3335 	struct mpii_rcb				*rcb = ccb->ccb_rcb;
3336 
3337 	DNPRINTF(MPII_D_EVT, "%s: mpii_eventnotify_done\n", DEVNAME(sc));
3338 
3339 	scsi_io_put(&sc->sc_iopool, ccb);
3340 	mpii_event_process(sc, rcb);
3341 }
3342 
3343 void
3344 mpii_event_raid(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
3345 {
3346 	struct mpii_evt_ir_cfg_change_list	*ccl;
3347 	struct mpii_evt_ir_cfg_element		*ce;
3348 	struct mpii_device			*dev;
3349 	u_int16_t				type;
3350 	int					i;
3351 
3352 	ccl = (struct mpii_evt_ir_cfg_change_list *)(enp + 1);
3353 
3354 	if (ccl->num_elements == 0)
3355 		return;
3356 	if (ISSET(letoh32(ccl->flags), MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN))
3357 		/* bail on foreign configurations */
3358 		return;
3359 
3360 	ce = (struct mpii_evt_ir_cfg_element *)(ccl + 1);
3361 
3362 	for (i = 0; i < ccl->num_elements; i++, ce++) {
3363 		type = (letoh16(ce->element_flags) &
3364 		    MPII_EVT_IR_CFG_ELEMENT_TYPE_MASK);
3365 
3366 		switch (type) {
3367 		case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME:
3368 			switch (ce->reason_code) {
3369 			case MPII_EVT_IR_CFG_ELEMENT_RC_ADDED:
3370 			case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_CREATED:
3371 				if (mpii_find_dev(sc,
3372 				    letoh16(ce->vol_dev_handle))) {
3373 					printf("%s: device %#x is already "
3374 					    "configured\n", DEVNAME(sc),
3375 					    letoh16(ce->vol_dev_handle));
3376 					break;
3377 				}
3378 				dev = malloc(sizeof(*dev), M_DEVBUF,
3379 				    M_NOWAIT | M_ZERO);
3380 				if (!dev) {
3381 					printf("%s: failed to allocate a "
3382 				    	    "device structure\n", DEVNAME(sc));
3383 					break;
3384 				}
3385 				SET(dev->flags, MPII_DF_VOLUME);
3386 				dev->slot = sc->sc_vd_id_low;
3387 				dev->dev_handle = letoh16(ce->vol_dev_handle);
3388 				if (mpii_insert_dev(sc, dev)) {
3389 					free(dev, M_DEVBUF);
3390 					break;
3391 				}
3392 				sc->sc_vd_count++;
3393 				break;
3394 			case MPII_EVT_IR_CFG_ELEMENT_RC_REMOVED:
3395 			case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_DELETED:
3396 				if (!(dev = mpii_find_dev(sc,
3397 				    letoh16(ce->vol_dev_handle))))
3398 					break;
3399 				mpii_remove_dev(sc, dev);
3400 				sc->sc_vd_count--;
3401 				break;
3402 			}
3403 			break;
3404 		case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME_DISK:
3405 			if (ce->reason_code ==
3406 			    MPII_EVT_IR_CFG_ELEMENT_RC_PD_CREATED ||
3407 			    ce->reason_code ==
3408 			    MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
3409 				/* there should be an underlying sas drive */
3410 				if (!(dev = mpii_find_dev(sc,
3411 				    letoh16(ce->phys_disk_dev_handle))))
3412 					break;
3413 				/* promoted from a hot spare? */
3414 				CLR(dev->flags, MPII_DF_HOT_SPARE);
3415 				SET(dev->flags, MPII_DF_VOLUME_DISK |
3416 				    MPII_DF_HIDDEN);
3417 			}
3418 			break;
3419 		case MPII_EVT_IR_CFG_ELEMENT_TYPE_HOT_SPARE:
3420 			if (ce->reason_code ==
3421 			    MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
3422 				/* there should be an underlying sas drive */
3423 				if (!(dev = mpii_find_dev(sc,
3424 				    letoh16(ce->phys_disk_dev_handle))))
3425 					break;
3426 				SET(dev->flags, MPII_DF_HOT_SPARE |
3427 				    MPII_DF_HIDDEN);
3428 			}
3429 			break;
3430 		}
3431 	}
3432 }
3433 
3434 void
3435 mpii_event_sas(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
3436 {
3437 	struct mpii_evt_sas_tcl		*tcl;
3438 	struct mpii_evt_phy_entry	*pe;
3439 	struct mpii_device		*dev;
3440 	int				i;
3441 
3442 	tcl = (struct mpii_evt_sas_tcl *)(enp + 1);
3443 
3444 	if (tcl->num_entries == 0)
3445 		return;
3446 
3447 	pe = (struct mpii_evt_phy_entry *)(tcl + 1);
3448 
3449 	for (i = 0; i < tcl->num_entries; i++, pe++) {
3450 		switch (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK) {
3451 		case MPII_EVENT_SAS_TOPO_PS_RC_ADDED:
3452 			if (mpii_find_dev(sc, letoh16(pe->dev_handle))) {
3453 				printf("%s: device %#x is already "
3454 				    "configured\n", DEVNAME(sc),
3455 				    letoh16(pe->dev_handle));
3456 				break;
3457 			}
3458 			dev = malloc(sizeof(*dev), M_DEVBUF, M_NOWAIT | M_ZERO);
3459 			if (!dev) {
3460 				printf("%s: failed to allocate a "
3461 				    "device structure\n", DEVNAME(sc));
3462 				break;
3463 			}
3464 			dev->slot = sc->sc_pd_id_start + tcl->start_phy_num + i;
3465 			dev->dev_handle = letoh16(pe->dev_handle);
3466 			dev->phy_num = tcl->start_phy_num + i;
3467 			if (tcl->enclosure_handle)
3468 				dev->physical_port = tcl->physical_port;
3469 			dev->enclosure = letoh16(tcl->enclosure_handle);
3470 			dev->expander = letoh16(tcl->expander_handle);
3471 			if (mpii_insert_dev(sc, dev)) {
3472 				free(dev, M_DEVBUF);
3473 				break;
3474 			}
3475 			if (sc->sc_scsibus) {
3476 				SET(dev->flags, MPII_DF_ATTACH);
3477 				if (scsi_task(mpii_event_defer, sc,
3478 				    dev, 0) != 0)
3479 					printf("%s: unable to run device "
3480 					    "attachment routine\n",
3481 					    DEVNAME(sc));
3482 			}
3483 			break;
3484 		case MPII_EVENT_SAS_TOPO_PS_RC_MISSING:
3485 			if (!(dev = mpii_find_dev(sc,
3486 			    letoh16(pe->dev_handle))))
3487 				break;
3488 			mpii_remove_dev(sc, dev);
3489 			if (sc->sc_scsibus) {
3490 				SET(dev->flags, MPII_DF_DETACH);
3491 				scsi_activate(sc->sc_scsibus, dev->slot, -1,
3492 				    DVACT_DEACTIVATE);
3493 				if (scsi_task(mpii_event_defer, sc,
3494 				    dev, 0) != 0)
3495 					printf("%s: unable to run device "
3496 					    "detachment routine\n",
3497 					    DEVNAME(sc));
3498 			}
3499 			break;
3500 		}
3501 	}
3502 }
3503 
3504 void
3505 mpii_event_process(struct mpii_softc *sc, struct mpii_rcb *rcb)
3506 {
3507 	struct mpii_msg_event_reply		*enp;
3508 
3509 	enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
3510 
3511 	DNPRINTF(MPII_D_EVT, "%s: mpii_event_process: %#x\n", DEVNAME(sc),
3512 	    letoh32(enp->event));
3513 
3514 	switch (letoh32(enp->event)) {
3515 	case MPII_EVENT_EVENT_CHANGE:
3516 		/* should be properly ignored */
3517 		break;
3518 	case MPII_EVENT_SAS_DISCOVERY: {
3519 		struct mpii_evt_sas_discovery	*esd =
3520 		    (struct mpii_evt_sas_discovery *)(enp + 1);
3521 
3522 		if (esd->reason_code ==
3523 		    MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED &&
3524 		    esd->discovery_status != 0)
3525 			printf("%s: sas discovery completed with status %#x\n",
3526 			    DEVNAME(sc), esd->discovery_status);
3527 		}
3528 		break;
3529 	case MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
3530 		mpii_event_sas(sc, enp);
3531 		break;
3532 	case MPII_EVENT_SAS_DEVICE_STATUS_CHANGE:
3533 		break;
3534 	case MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
3535 		break;
3536 	case MPII_EVENT_IR_VOLUME: {
3537 		struct mpii_evt_ir_volume	*evd =
3538 		    (struct mpii_evt_ir_volume *)(enp + 1);
3539 		struct mpii_device		*dev;
3540 #if NBIO > 0
3541 		const char *vol_states[] = {
3542 			BIOC_SVINVALID_S,
3543 			BIOC_SVOFFLINE_S,
3544 			BIOC_SVBUILDING_S,
3545 			BIOC_SVONLINE_S,
3546 			BIOC_SVDEGRADED_S,
3547 			BIOC_SVONLINE_S,
3548 		};
3549 #endif
3550 
3551 		if (cold)
3552 			break;
3553 		if (!(dev = mpii_find_dev(sc, letoh16(evd->vol_dev_handle))))
3554 			break;
3555 #if NBIO > 0
3556 		if (evd->reason_code == MPII_EVENT_IR_VOL_RC_STATE_CHANGED)
3557 			printf("%s: volume %d state changed from %s to %s\n",
3558 			    DEVNAME(sc), dev->slot - sc->sc_vd_id_low,
3559 			    vol_states[evd->prev_value],
3560 			    vol_states[evd->new_value]);
3561 #endif
3562 		if (evd->reason_code == MPII_EVENT_IR_VOL_RC_STATUS_CHANGED &&
3563 		    ISSET(evd->new_value, MPII_CFG_RAID_VOL_0_STATUS_RESYNC) &&
3564 		    !ISSET(evd->prev_value, MPII_CFG_RAID_VOL_0_STATUS_RESYNC))
3565 			printf("%s: started resync on a volume %d\n",
3566 			    DEVNAME(sc), dev->slot - sc->sc_vd_id_low);
3567 		}
3568 		break;
3569 	case MPII_EVENT_IR_PHYSICAL_DISK:
3570 		break;
3571 	case MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST:
3572 		mpii_event_raid(sc, enp);
3573 		break;
3574 	case MPII_EVENT_IR_OPERATION_STATUS: {
3575 		struct mpii_evt_ir_status	*evs =
3576 		    (struct mpii_evt_ir_status *)(enp + 1);
3577 		struct mpii_device		*dev;
3578 
3579 		if (!(dev = mpii_find_dev(sc, letoh16(evs->vol_dev_handle))))
3580 			break;
3581 		if (evs->operation == MPII_EVENT_IR_RAIDOP_RESYNC)
3582 			dev->percent = evs->percent;
3583 		break;
3584 		}
3585 	default:
3586 		DNPRINTF(MPII_D_EVT, "%s:  unhandled event 0x%02x\n",
3587 		    DEVNAME(sc), letoh32(enp->event));
3588 	}
3589 
3590 	if (enp->ack_required) {
3591 		mtx_enter(&sc->sc_evt_ack_mtx);
3592 		SIMPLEQ_INSERT_TAIL(&sc->sc_evt_ack_queue, rcb, rcb_link);
3593 		mtx_leave(&sc->sc_evt_ack_mtx);
3594 		scsi_ioh_add(&sc->sc_evt_ack_handler);
3595 	} else
3596 		mpii_push_reply(sc, rcb);
3597 }
3598 
3599 void
3600 mpii_event_defer(void *xsc, void *arg)
3601 {
3602 	struct mpii_softc	*sc = xsc;
3603 	struct mpii_device	*dev = arg;
3604 
3605 	if (ISSET(dev->flags, MPII_DF_DETACH)) {
3606 		mpii_sas_remove_device(sc, dev->dev_handle);
3607 		if (!ISSET(dev->flags, MPII_DF_HIDDEN)) {
3608 			scsi_detach_target(sc->sc_scsibus, dev->slot,
3609 			    DETACH_FORCE);
3610 		}
3611 		free(dev, M_DEVBUF);
3612 
3613 	} else if (ISSET(dev->flags, MPII_DF_ATTACH)) {
3614 		CLR(dev->flags, MPII_DF_ATTACH);
3615 		if (!ISSET(dev->flags, MPII_DF_HIDDEN))
3616 			scsi_probe_target(sc->sc_scsibus, dev->slot);
3617 	}
3618 }
3619 
3620 void
3621 mpii_sas_remove_device(struct mpii_softc *sc, u_int16_t handle)
3622 {
3623  	struct mpii_msg_scsi_task_request	*stq;
3624 	struct mpii_msg_sas_oper_request	*soq;
3625 	struct mpii_ccb				*ccb;
3626 
3627 	ccb = scsi_io_get(&sc->sc_iopool, 0);
3628 	if (ccb == NULL)
3629 		return;
3630 
3631 	stq = ccb->ccb_cmd;
3632 	stq->function = MPII_FUNCTION_SCSI_TASK_MGMT;
3633 	stq->task_type = MPII_SCSI_TASK_TARGET_RESET;
3634 	stq->dev_handle = htole16(handle);
3635 
3636 	ccb->ccb_done = mpii_empty_done;
3637 	mpii_wait(sc, ccb);
3638 
3639 	if (ccb->ccb_rcb != NULL)
3640 		mpii_push_reply(sc, ccb->ccb_rcb);
3641 
3642 	/* reuse a ccb */
3643 	ccb->ccb_state = MPII_CCB_READY;
3644 	ccb->ccb_rcb = NULL;
3645 
3646 	soq = ccb->ccb_cmd;
3647 	bzero(soq, sizeof(*soq));
3648 	soq->function = MPII_FUNCTION_SAS_IO_UNIT_CONTROL;
3649 	soq->operation = MPII_SAS_OP_REMOVE_DEVICE;
3650 	soq->dev_handle = htole16(handle);
3651 
3652 	ccb->ccb_done = mpii_empty_done;
3653 	mpii_wait(sc, ccb);
3654 	if (ccb->ccb_rcb != NULL)
3655 		mpii_push_reply(sc, ccb->ccb_rcb);
3656 }
3657 
3658 int
3659 mpii_get_ioc_pg8(struct mpii_softc *sc)
3660 {
3661 	struct mpii_cfg_hdr	hdr;
3662 	struct mpii_cfg_ioc_pg8	*page;
3663 	size_t			pagelen;
3664 	u_int16_t		flags;
3665 	int			pad = 0, rv = 0;
3666 
3667 	DNPRINTF(MPII_D_RAID, "%s: mpii_get_ioc_pg8\n", DEVNAME(sc));
3668 
3669 	if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 8, 0,
3670 	    &hdr) != 0) {
3671 		DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to fetch "
3672 		    "header for IOC page 8\n", DEVNAME(sc));
3673 		return (1);
3674 	}
3675 
3676 	pagelen = hdr.page_length * 4; /* dwords to bytes */
3677 
3678 	page = malloc(pagelen, M_TEMP, M_NOWAIT);
3679 	if (page == NULL) {
3680 		DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to allocate "
3681 		    "space for ioc config page 8\n", DEVNAME(sc));
3682 		return (1);
3683 	}
3684 
3685 	if (mpii_cfg_page(sc, 0, &hdr, 1, page, pagelen) != 0) {
3686 		DNPRINTF(MPII_D_CFG, "%s: mpii_get_raid unable to fetch IOC "
3687 		    "page 8\n", DEVNAME(sc));
3688 		rv = 1;
3689 		goto out;
3690 	}
3691 
3692 	DNPRINTF(MPII_D_CFG, "%s:  numdevsperenclosure: 0x%02x\n", DEVNAME(sc),
3693 	    page->num_devs_per_enclosure);
3694 	DNPRINTF(MPII_D_CFG, "%s:  maxpersistententries: 0x%04x "
3695 	    "maxnumphysicalmappedids: 0x%04x\n", DEVNAME(sc),
3696 	    letoh16(page->max_persistent_entries),
3697 	    letoh16(page->max_num_physical_mapped_ids));
3698 	DNPRINTF(MPII_D_CFG, "%s:  flags: 0x%04x\n", DEVNAME(sc),
3699 	    letoh16(page->flags));
3700 	DNPRINTF(MPII_D_CFG, "%s:  irvolumemappingflags: 0x%04x\n",
3701 	    DEVNAME(sc), letoh16(page->ir_volume_mapping_flags));
3702 
3703 	if (page->flags & MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0)
3704 		pad = 1;
3705 
3706 	flags = page->ir_volume_mapping_flags &
3707 	    MPII_IOC_PG8_IRFLAGS_VOLUME_MAPPING_MODE_MASK;
3708 	if (ISSET(sc->sc_flags, MPII_F_RAID)) {
3709 		if (flags == MPII_IOC_PG8_IRFLAGS_LOW_VOLUME_MAPPING) {
3710 			sc->sc_vd_id_low += pad;
3711 			pad = sc->sc_max_volumes; /* for sc_pd_id_start */
3712 		} else
3713 			sc->sc_vd_id_low = sc->sc_max_devices -
3714 			    sc->sc_max_volumes;
3715 	}
3716 
3717 	sc->sc_pd_id_start += pad;
3718 
3719 	DNPRINTF(MPII_D_MAP, "%s: mpii_get_ioc_pg8 mapping: sc_pd_id_start: %d "
3720 	    "sc_vd_id_low: %d sc_max_volumes: %d\n", DEVNAME(sc),
3721 	    sc->sc_pd_id_start, sc->sc_vd_id_low, sc->sc_max_volumes);
3722 
3723 out:
3724 	free(page, M_TEMP);
3725 
3726 	return(rv);
3727 }
3728 
3729 int
3730 mpii_req_cfg_header(struct mpii_softc *sc, u_int8_t type, u_int8_t number,
3731     u_int32_t address, int flags, void *p)
3732 {
3733 	struct mpii_msg_config_request		*cq;
3734 	struct mpii_msg_config_reply		*cp;
3735 	struct mpii_cfg_hdr	*hdr = p;
3736 	struct mpii_ccb		*ccb;
3737 	struct mpii_ecfg_hdr	*ehdr = p;
3738 	int			etype = 0;
3739 	int			rv = 0;
3740 
3741 	DNPRINTF(MPII_D_MISC, "%s: mpii_req_cfg_header type: %#x number: %x "
3742 	    "address: 0x%08x flags: 0x%b\n", DEVNAME(sc), type, number,
3743 	    address, flags, MPII_PG_FMT);
3744 
3745 	ccb = scsi_io_get(&sc->sc_iopool,
3746 	    ISSET(flags, MPII_PG_POLL) ? SCSI_NOSLEEP : 0);
3747 	if (ccb == NULL) {
3748 		DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header ccb_get\n",
3749 		    DEVNAME(sc));
3750 		return (1);
3751 	}
3752 
3753 	if (ISSET(flags, MPII_PG_EXTENDED)) {
3754 		etype = type;
3755 		type = MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED;
3756 	}
3757 
3758 	cq = ccb->ccb_cmd;
3759 
3760 	cq->function = MPII_FUNCTION_CONFIG;
3761 
3762 	cq->action = MPII_CONFIG_REQ_ACTION_PAGE_HEADER;
3763 
3764 	cq->config_header.page_number = number;
3765 	cq->config_header.page_type = type;
3766 	cq->ext_page_type = etype;
3767 	cq->page_address = htole32(address);
3768 	cq->page_buffer.sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
3769 	    MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
3770 
3771 	ccb->ccb_done = mpii_empty_done;
3772 	if (ISSET(flags, MPII_PG_POLL)) {
3773 		if (mpii_poll(sc, ccb) != 0) {
3774 			DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header poll\n",
3775 			    DEVNAME(sc));
3776 			return (1);
3777 		}
3778 	} else
3779 		mpii_wait(sc, ccb);
3780 
3781 	if (ccb->ccb_rcb == NULL) {
3782 		scsi_io_put(&sc->sc_iopool, ccb);
3783 		return (1);
3784 	}
3785 	cp = ccb->ccb_rcb->rcb_reply;
3786 
3787 	DNPRINTF(MPII_D_MISC, "%s:  action: 0x%02x sgl_flags: 0x%02x "
3788 	    "msg_length: %d function: 0x%02x\n", DEVNAME(sc), cp->action,
3789 	    cp->sgl_flags, cp->msg_length, cp->function);
3790 	DNPRINTF(MPII_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
3791 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
3792 	    letoh16(cp->ext_page_length), cp->ext_page_type,
3793 	    cp->msg_flags);
3794 	DNPRINTF(MPII_D_MISC, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
3795 	    cp->vp_id, cp->vf_id);
3796 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
3797 	    letoh16(cp->ioc_status));
3798 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3799 	    letoh32(cp->ioc_loginfo));
3800 	DNPRINTF(MPII_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
3801 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
3802 	    cp->config_header.page_version,
3803 	    cp->config_header.page_length,
3804 	    cp->config_header.page_number,
3805 	    cp->config_header.page_type);
3806 
3807 	if (letoh16(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
3808 		rv = 1;
3809 	else if (ISSET(flags, MPII_PG_EXTENDED)) {
3810 		bzero(ehdr, sizeof(*ehdr));
3811 		ehdr->page_version = cp->config_header.page_version;
3812 		ehdr->page_number = cp->config_header.page_number;
3813 		ehdr->page_type = cp->config_header.page_type;
3814 		ehdr->ext_page_length = cp->ext_page_length;
3815 		ehdr->ext_page_type = cp->ext_page_type;
3816 	} else
3817 		*hdr = cp->config_header;
3818 
3819 	mpii_push_reply(sc, ccb->ccb_rcb);
3820 	scsi_io_put(&sc->sc_iopool, ccb);
3821 
3822 	return (rv);
3823 }
3824 
3825 int
3826 mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int flags,
3827     void *p, int read, void *page, size_t len)
3828 {
3829 	struct mpii_msg_config_request		*cq;
3830 	struct mpii_msg_config_reply		*cp;
3831 	struct mpii_cfg_hdr	*hdr = p;
3832 	struct mpii_ccb		*ccb;
3833 	struct mpii_ecfg_hdr	*ehdr = p;
3834 	u_int64_t		dva;
3835 	char			*kva;
3836 	int			page_length;
3837 	int			rv = 0;
3838 
3839 	DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page address: %d read: %d "
3840 	    "type: %x\n", DEVNAME(sc), address, read, hdr->page_type);
3841 
3842 	page_length = ISSET(flags, MPII_PG_EXTENDED) ?
3843 	    letoh16(ehdr->ext_page_length) : hdr->page_length;
3844 
3845 	if (len > MPII_REQUEST_SIZE - sizeof(struct mpii_msg_config_request) ||
3846     	    len < page_length * 4)
3847 		return (1);
3848 
3849 	ccb = scsi_io_get(&sc->sc_iopool,
3850 	    ISSET(flags, MPII_PG_POLL) ? SCSI_NOSLEEP : 0);
3851 	if (ccb == NULL) {
3852 		DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page ccb_get\n",
3853 		    DEVNAME(sc));
3854 		return (1);
3855 	}
3856 
3857 	cq = ccb->ccb_cmd;
3858 
3859 	cq->function = MPII_FUNCTION_CONFIG;
3860 
3861 	cq->action = (read ? MPII_CONFIG_REQ_ACTION_PAGE_READ_CURRENT :
3862 	    MPII_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT);
3863 
3864 	if (ISSET(flags, MPII_PG_EXTENDED)) {
3865 		cq->config_header.page_version = ehdr->page_version;
3866 		cq->config_header.page_number = ehdr->page_number;
3867 		cq->config_header.page_type = ehdr->page_type;
3868 		cq->ext_page_len = ehdr->ext_page_length;
3869 		cq->ext_page_type = ehdr->ext_page_type;
3870 	} else
3871 		cq->config_header = *hdr;
3872 	cq->config_header.page_type &= MPII_CONFIG_REQ_PAGE_TYPE_MASK;
3873 	cq->page_address = htole32(address);
3874 	cq->page_buffer.sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
3875 	    MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL |
3876 	    MPII_SGE_FL_SIZE_64 | (page_length * 4) |
3877 	    (read ? MPII_SGE_FL_DIR_IN : MPII_SGE_FL_DIR_OUT));
3878 
3879 	/* bounce the page via the request space to avoid more bus_dma games */
3880 	dva = ccb->ccb_cmd_dva + sizeof(struct mpii_msg_config_request);
3881 
3882 	cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32));
3883 	cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva);
3884 
3885 	kva = ccb->ccb_cmd;
3886 	kva += sizeof(struct mpii_msg_config_request);
3887 
3888 	if (!read)
3889 		bcopy(page, kva, len);
3890 
3891 	ccb->ccb_done = mpii_empty_done;
3892 	if (ISSET(flags, MPII_PG_POLL)) {
3893 		if (mpii_poll(sc, ccb) != 0) {
3894 			DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header poll\n",
3895 			    DEVNAME(sc));
3896 			return (1);
3897 		}
3898 	} else
3899 		mpii_wait(sc, ccb);
3900 
3901 	if (ccb->ccb_rcb == NULL) {
3902 		scsi_io_put(&sc->sc_iopool, ccb);
3903 		return (1);
3904 	}
3905 	cp = ccb->ccb_rcb->rcb_reply;
3906 
3907 	DNPRINTF(MPII_D_MISC, "%s:  action: 0x%02x sglflags: 0x%02x "
3908 	    "msg_length: %d function: 0x%02x\n", DEVNAME(sc), cp->action,
3909 	    cp->msg_length, cp->function);
3910 	DNPRINTF(MPII_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
3911 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
3912 	    letoh16(cp->ext_page_length), cp->ext_page_type,
3913 	    cp->msg_flags);
3914 	DNPRINTF(MPII_D_MISC, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
3915 	    cp->vp_id, cp->vf_id);
3916 	DNPRINTF(MPII_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
3917 	    letoh16(cp->ioc_status));
3918 	DNPRINTF(MPII_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3919 	    letoh32(cp->ioc_loginfo));
3920 	DNPRINTF(MPII_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
3921 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
3922 	    cp->config_header.page_version,
3923 	    cp->config_header.page_length,
3924 	    cp->config_header.page_number,
3925 	    cp->config_header.page_type);
3926 
3927 	if (letoh16(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
3928 		rv = 1;
3929 	else if (read)
3930 		bcopy(kva, page, len);
3931 
3932 	mpii_push_reply(sc, ccb->ccb_rcb);
3933 	scsi_io_put(&sc->sc_iopool, ccb);
3934 
3935 	return (rv);
3936 }
3937 
3938 struct mpii_rcb *
3939 mpii_reply(struct mpii_softc *sc, struct mpii_reply_descr *rdp)
3940 {
3941 	struct mpii_rcb		*rcb = NULL;
3942 	u_int32_t		rfid;
3943 
3944 	DNPRINTF(MPII_D_INTR, "%s: mpii_reply\n", DEVNAME(sc));
3945 
3946 	if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
3947 	    MPII_REPLY_DESCR_ADDRESS_REPLY) {
3948 		rfid = (letoh32(rdp->frame_addr) -
3949 		    (u_int32_t)MPII_DMA_DVA(sc->sc_replies)) / MPII_REPLY_SIZE;
3950 
3951 		bus_dmamap_sync(sc->sc_dmat,
3952 		    MPII_DMA_MAP(sc->sc_replies), MPII_REPLY_SIZE * rfid,
3953 		    MPII_REPLY_SIZE, BUS_DMASYNC_POSTREAD);
3954 
3955 		rcb = &sc->sc_rcbs[rfid];
3956 	}
3957 
3958 	memset(rdp, 0xff, sizeof(*rdp));
3959 
3960 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
3961 	    8 * sc->sc_reply_post_host_index, 8,
3962 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
3963 
3964 	return (rcb);
3965 }
3966 
3967 struct mpii_dmamem *
3968 mpii_dmamem_alloc(struct mpii_softc *sc, size_t size)
3969 {
3970 	struct mpii_dmamem	*mdm;
3971 	int			nsegs;
3972 
3973 	mdm = malloc(sizeof(*mdm), M_DEVBUF, M_NOWAIT | M_ZERO);
3974 	if (mdm == NULL)
3975 	return (NULL);
3976 
3977 	mdm->mdm_size = size;
3978 
3979 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
3980 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0)
3981 		goto mdmfree;
3982 
3983 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mdm->mdm_seg,
3984 	    1, &nsegs, BUS_DMA_NOWAIT) != 0)
3985 		goto destroy;
3986 
3987 	if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size,
3988 	    &mdm->mdm_kva, BUS_DMA_NOWAIT) != 0)
3989 		goto free;
3990 
3991 	if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size,
3992 	    NULL, BUS_DMA_NOWAIT) != 0)
3993 		goto unmap;
3994 
3995 	DNPRINTF(MPII_D_MEM, "  kva: %p  dva: %p  map: %p  size: %d\n",
3996 	    mdm->mdm_kva, mdm->mdm_map->dm_segs[0].ds_addr, mdm->mdm_map,
3997 	    size);
3998 
3999 	bzero(mdm->mdm_kva, size);
4000 
4001 	return (mdm);
4002 
4003 unmap:
4004 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size);
4005 free:
4006 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
4007 destroy:
4008 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
4009 mdmfree:
4010 	free(mdm, M_DEVBUF);
4011 
4012 	return (NULL);
4013 }
4014 
4015 void
4016 mpii_dmamem_free(struct mpii_softc *sc, struct mpii_dmamem *mdm)
4017 {
4018 	DNPRINTF(MPII_D_MEM, "%s: mpii_dmamem_free %#x\n", DEVNAME(sc), mdm);
4019 
4020 	bus_dmamap_unload(sc->sc_dmat, mdm->mdm_map);
4021 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size);
4022 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
4023 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
4024 	free(mdm, M_DEVBUF);
4025 }
4026 
4027 int
4028 mpii_alloc_dev(struct mpii_softc *sc)
4029 {
4030 	sc->sc_devs = malloc(sc->sc_max_devices *
4031 	    sizeof(struct mpii_device *), M_DEVBUF, M_NOWAIT | M_ZERO);
4032 	if (sc->sc_devs == NULL)
4033 		return (1);
4034 	return (0);
4035 }
4036 
4037 int
4038 mpii_insert_dev(struct mpii_softc *sc, struct mpii_device *dev)
4039 {
4040 	int slot = dev->slot; 	/* initial hint */
4041 
4042 	if (!dev || slot < 0)
4043 		return (1);
4044 	while (slot < sc->sc_max_devices && sc->sc_devs[slot] != NULL)
4045 		slot++;
4046 	if (slot >= sc->sc_max_devices)
4047 		return (1);
4048 	dev->slot = slot;
4049 	sc->sc_devs[slot] = dev;
4050 	return (0);
4051 }
4052 
4053 int
4054 mpii_remove_dev(struct mpii_softc *sc, struct mpii_device *dev)
4055 {
4056 	int			i;
4057 
4058 	if (!dev)
4059 		return (1);
4060 	for (i = 0; i < sc->sc_max_devices;  i++)
4061 		if (sc->sc_devs[i] &&
4062 		    sc->sc_devs[i]->dev_handle == dev->dev_handle) {
4063 			sc->sc_devs[i] = NULL;
4064 			return (0);
4065 		}
4066 	return (1);
4067 }
4068 
4069 struct mpii_device *
4070 mpii_find_dev(struct mpii_softc *sc, u_int16_t handle)
4071 {
4072 	int			i;
4073 
4074 	for (i = 0; i < sc->sc_max_devices;  i++)
4075 		if (sc->sc_devs[i] && sc->sc_devs[i]->dev_handle == handle)
4076 			return (sc->sc_devs[i]);
4077 	return (NULL);
4078 }
4079 
4080 int
4081 mpii_alloc_ccbs(struct mpii_softc *sc)
4082 {
4083 	struct mpii_ccb		*ccb;
4084 	u_int8_t		*cmd;
4085 	int			i;
4086 
4087 	SIMPLEQ_INIT(&sc->sc_ccb_free);
4088 	SIMPLEQ_INIT(&sc->sc_ccb_tmos);
4089 	mtx_init(&sc->sc_ccb_free_mtx, IPL_BIO);
4090 	mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
4091 	scsi_ioh_set(&sc->sc_ccb_tmo_handler, &sc->sc_iopool,
4092 	    mpii_scsi_cmd_tmo_handler, sc);
4093 
4094 	sc->sc_ccbs = malloc(sizeof(*ccb) * (sc->sc_request_depth-1),
4095 	    M_DEVBUF, M_NOWAIT | M_ZERO);
4096 	if (sc->sc_ccbs == NULL) {
4097 		printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
4098 		return (1);
4099 	}
4100 
4101 	sc->sc_requests = mpii_dmamem_alloc(sc,
4102 	    MPII_REQUEST_SIZE * sc->sc_request_depth);
4103 	if (sc->sc_requests == NULL) {
4104 		printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
4105 		goto free_ccbs;
4106 	}
4107 	cmd = MPII_DMA_KVA(sc->sc_requests);
4108 	bzero(cmd, MPII_REQUEST_SIZE * sc->sc_request_depth);
4109 
4110 	/*
4111 	 * we have sc->sc_request_depth system request message
4112 	 * frames, but smid zero cannot be used. so we then
4113 	 * have (sc->sc_request_depth - 1) number of ccbs
4114 	 */
4115 	for (i = 1; i < sc->sc_request_depth; i++) {
4116 		ccb = &sc->sc_ccbs[i - 1];
4117 
4118 		if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
4119 		    sc->sc_max_sgl_len, MAXPHYS, 0,
4120 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
4121 		    &ccb->ccb_dmamap) != 0) {
4122 			printf("%s: unable to create dma map\n", DEVNAME(sc));
4123 			goto free_maps;
4124 		}
4125 
4126 		ccb->ccb_sc = sc;
4127 		ccb->ccb_smid = i;
4128 		ccb->ccb_offset = MPII_REQUEST_SIZE * i;
4129 
4130 		ccb->ccb_cmd = &cmd[ccb->ccb_offset];
4131 		ccb->ccb_cmd_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_requests) +
4132 		    ccb->ccb_offset;
4133 
4134 		DNPRINTF(MPII_D_CCB, "%s: mpii_alloc_ccbs(%d) ccb: %#x map: %#x "
4135 		    "sc: %#x smid: %#x offs: %#x cmd: %#x dva: %#x\n",
4136 		    DEVNAME(sc), i, ccb, ccb->ccb_dmamap, ccb->ccb_sc,
4137 		    ccb->ccb_smid, ccb->ccb_offset, ccb->ccb_cmd,
4138 		    ccb->ccb_cmd_dva);
4139 
4140 		mpii_put_ccb(sc, ccb);
4141 	}
4142 
4143 	scsi_iopool_init(&sc->sc_iopool, sc, mpii_get_ccb, mpii_put_ccb);
4144 
4145 	return (0);
4146 
4147 free_maps:
4148 	while ((ccb = mpii_get_ccb(sc)) != NULL)
4149 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
4150 
4151 	mpii_dmamem_free(sc, sc->sc_requests);
4152 free_ccbs:
4153 	free(sc->sc_ccbs, M_DEVBUF);
4154 
4155 	return (1);
4156 }
4157 
4158 void
4159 mpii_put_ccb(void *cookie, void *io)
4160 {
4161 	struct mpii_softc	*sc = cookie;
4162 	struct mpii_ccb		*ccb = io;
4163 
4164 	DNPRINTF(MPII_D_CCB, "%s: mpii_put_ccb %#x\n", DEVNAME(sc), ccb);
4165 
4166 	ccb->ccb_state = MPII_CCB_FREE;
4167 	ccb->ccb_cookie = NULL;
4168 	ccb->ccb_done = NULL;
4169 	ccb->ccb_rcb = NULL;
4170 	bzero(ccb->ccb_cmd, MPII_REQUEST_SIZE);
4171 
4172 	mtx_enter(&sc->sc_ccb_free_mtx);
4173 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_link);
4174 	mtx_leave(&sc->sc_ccb_free_mtx);
4175 }
4176 
4177 void *
4178 mpii_get_ccb(void *cookie)
4179 {
4180 	struct mpii_softc	*sc = cookie;
4181 	struct mpii_ccb		*ccb;
4182 
4183 	mtx_enter(&sc->sc_ccb_free_mtx);
4184 	ccb = SIMPLEQ_FIRST(&sc->sc_ccb_free);
4185 	if (ccb != NULL) {
4186 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ccb_link);
4187 		ccb->ccb_state = MPII_CCB_READY;
4188 	}
4189 	mtx_leave(&sc->sc_ccb_free_mtx);
4190 
4191 	DNPRINTF(MPII_D_CCB, "%s: mpii_get_ccb %#x\n", DEVNAME(sc), ccb);
4192 
4193 	return (ccb);
4194 }
4195 
4196 int
4197 mpii_alloc_replies(struct mpii_softc *sc)
4198 {
4199 	DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_replies\n", DEVNAME(sc));
4200 
4201 	sc->sc_rcbs = malloc(sc->sc_num_reply_frames * sizeof(struct mpii_rcb),
4202 	    M_DEVBUF, M_NOWAIT);
4203 	if (sc->sc_rcbs == NULL)
4204 		return (1);
4205 
4206 	sc->sc_replies = mpii_dmamem_alloc(sc, MPII_REPLY_SIZE *
4207 	    sc->sc_num_reply_frames);
4208 	if (sc->sc_replies == NULL) {
4209 		free(sc->sc_rcbs, M_DEVBUF);
4210 		return (1);
4211 	}
4212 
4213 	return (0);
4214 }
4215 
4216 void
4217 mpii_push_replies(struct mpii_softc *sc)
4218 {
4219 	struct mpii_rcb		*rcb;
4220 	char			*kva = MPII_DMA_KVA(sc->sc_replies);
4221 	int			i;
4222 
4223 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
4224 	    0, MPII_REPLY_SIZE * sc->sc_num_reply_frames, BUS_DMASYNC_PREREAD);
4225 
4226 	for (i = 0; i < sc->sc_num_reply_frames; i++) {
4227 		rcb = &sc->sc_rcbs[i];
4228 
4229 		rcb->rcb_reply = kva + MPII_REPLY_SIZE * i;
4230 		rcb->rcb_reply_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
4231 		    MPII_REPLY_SIZE * i;
4232 		mpii_push_reply(sc, rcb);
4233 	}
4234 }
4235 
4236 void
4237 mpii_start(struct mpii_softc *sc, struct mpii_ccb *ccb)
4238 {
4239 	struct mpii_request_header	*rhp;
4240 	struct mpii_request_descr	descr;
4241 	u_int32_t			*rdp = (u_int32_t *)&descr;
4242 
4243 	DNPRINTF(MPII_D_RW, "%s: mpii_start %#x\n", DEVNAME(sc),
4244 	    ccb->ccb_cmd_dva);
4245 
4246 	rhp = ccb->ccb_cmd;
4247 
4248 	bzero(&descr, sizeof(descr));
4249 
4250 	switch (rhp->function) {
4251 	case MPII_FUNCTION_SCSI_IO_REQUEST:
4252 		descr.request_flags = MPII_REQ_DESCR_SCSI_IO;
4253 		descr.dev_handle = htole16(ccb->ccb_dev_handle);
4254 		break;
4255 	case MPII_FUNCTION_SCSI_TASK_MGMT:
4256 		descr.request_flags = MPII_REQ_DESCR_HIGH_PRIORITY;
4257 		break;
4258 	default:
4259 		descr.request_flags = MPII_REQ_DESCR_DEFAULT;
4260 	}
4261 
4262 	descr.vf_id = sc->sc_vf_id;
4263 	descr.smid = htole16(ccb->ccb_smid);
4264 
4265 	bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_requests),
4266 	    ccb->ccb_offset, MPII_REQUEST_SIZE,
4267 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
4268 
4269 	ccb->ccb_state = MPII_CCB_QUEUED;
4270 
4271 	DNPRINTF(MPII_D_RW, "%s:   MPII_REQ_DESCR_POST_LOW (0x%08x) write "
4272 	    "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_LOW, *rdp);
4273 
4274 	DNPRINTF(MPII_D_RW, "%s:   MPII_REQ_DESCR_POST_HIGH (0x%08x) write "
4275 	    "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_HIGH, *(rdp+1));
4276 
4277 	mtx_enter(&sc->sc_req_mtx);
4278 	mpii_write(sc, MPII_REQ_DESCR_POST_LOW, htole32(*rdp));
4279 	mpii_write(sc, MPII_REQ_DESCR_POST_HIGH, htole32(*(rdp+1)));
4280 	mtx_leave(&sc->sc_req_mtx);
4281 }
4282 
4283 int
4284 mpii_poll(struct mpii_softc *sc, struct mpii_ccb *ccb)
4285 {
4286 	void				(*done)(struct mpii_ccb *);
4287 	void				*cookie;
4288 	int				rv = 1;
4289 
4290 	DNPRINTF(MPII_D_INTR, "%s: mpii_complete %d\n", DEVNAME(sc));
4291 
4292 	done = ccb->ccb_done;
4293 	cookie = ccb->ccb_cookie;
4294 
4295 	ccb->ccb_done = mpii_poll_done;
4296 	ccb->ccb_cookie = &rv;
4297 
4298 	mpii_start(sc, ccb);
4299 
4300 	while (rv == 1) {
4301 		/* avoid excessive polling */
4302 		if (mpii_reply_waiting(sc))
4303 			mpii_intr(sc);
4304 		else
4305 			delay(10);
4306 	}
4307 
4308 	ccb->ccb_cookie = cookie;
4309 	done(ccb);
4310 
4311 	return (0);
4312 }
4313 
4314 void
4315 mpii_poll_done(struct mpii_ccb *ccb)
4316 {
4317 	int				*rv = ccb->ccb_cookie;
4318 
4319 	*rv = 0;
4320 }
4321 
4322 int
4323 mpii_alloc_queues(struct mpii_softc *sc)
4324 {
4325 	u_int32_t		*kva;
4326 	u_int64_t		*kva64;
4327 	int			i;
4328 
4329 	DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_queues\n", DEVNAME(sc));
4330 
4331 	sc->sc_reply_freeq = mpii_dmamem_alloc(sc,
4332 	    sc->sc_reply_free_qdepth * 4);
4333 	if (sc->sc_reply_freeq == NULL)
4334 		return (1);
4335 
4336 	kva = MPII_DMA_KVA(sc->sc_reply_freeq);
4337 	for (i = 0; i < sc->sc_num_reply_frames; i++) {
4338 		kva[i] = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
4339 		    MPII_REPLY_SIZE * i;
4340 
4341 		DNPRINTF(MPII_D_MISC, "%s:   %d:  0x%08x = 0x%08x\n",
4342 		    DEVNAME(sc), i,
4343 		    &kva[i], (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
4344 		    MPII_REPLY_SIZE * i);
4345 	}
4346 
4347 	sc->sc_reply_postq =
4348 	    mpii_dmamem_alloc(sc, sc->sc_reply_post_qdepth * 8);
4349 	if (sc->sc_reply_postq == NULL)
4350 		goto free_reply_freeq;
4351 	sc->sc_reply_postq_kva = MPII_DMA_KVA(sc->sc_reply_postq);
4352 
4353 	DNPRINTF(MPII_D_MISC, "%s:  populating reply post descriptor queue\n",
4354 	    DEVNAME(sc));
4355 	kva64 = (u_int64_t *)MPII_DMA_KVA(sc->sc_reply_postq);
4356 	for (i = 0; i < sc->sc_reply_post_qdepth; i++) {
4357 		kva64[i] = 0xffffffffffffffffllu;
4358 		DNPRINTF(MPII_D_MISC, "%s:    %d:  0x%08x = 0x%lx\n",
4359 		    DEVNAME(sc), i, &kva64[i], kva64[i]);
4360 	}
4361 
4362 	return (0);
4363 
4364 free_reply_freeq:
4365 
4366 	mpii_dmamem_free(sc, sc->sc_reply_freeq);
4367 	return (1);
4368 }
4369 
4370 void
4371 mpii_init_queues(struct mpii_softc *sc)
4372 {
4373 	DNPRINTF(MPII_D_MISC, "%s:  mpii_init_queues\n", DEVNAME(sc));
4374 
4375 	sc->sc_reply_free_host_index = sc->sc_reply_free_qdepth - 1;
4376 	sc->sc_reply_post_host_index = 0;
4377 	mpii_write_reply_free(sc, sc->sc_reply_free_host_index);
4378 	mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
4379 }
4380 
4381 void
4382 mpii_wait(struct mpii_softc *sc, struct mpii_ccb *ccb)
4383 {
4384 	struct mutex		mtx = MUTEX_INITIALIZER(IPL_BIO);
4385 	void			(*done)(struct mpii_ccb *);
4386 	void			*cookie;
4387 
4388 	done = ccb->ccb_done;
4389 	cookie = ccb->ccb_cookie;
4390 
4391 	ccb->ccb_done = mpii_wait_done;
4392 	ccb->ccb_cookie = &mtx;
4393 
4394 	/* XXX this will wait forever for the ccb to complete */
4395 
4396 	mpii_start(sc, ccb);
4397 
4398 	mtx_enter(&mtx);
4399 	while (ccb->ccb_cookie != NULL)
4400 		msleep(ccb, &mtx, PRIBIO, "mpiiwait", 0);
4401 	mtx_leave(&mtx);
4402 
4403 	ccb->ccb_cookie = cookie;
4404 	done(ccb);
4405 }
4406 
4407 void
4408 mpii_wait_done(struct mpii_ccb *ccb)
4409 {
4410 	struct mutex		*mtx = ccb->ccb_cookie;
4411 
4412 	mtx_enter(mtx);
4413 	ccb->ccb_cookie = NULL;
4414 	wakeup_one(ccb);
4415 	mtx_leave(mtx);
4416 }
4417 
4418 void
4419 mpii_scsi_cmd(struct scsi_xfer *xs)
4420 {
4421 	struct scsi_link	*link = xs->sc_link;
4422 	struct mpii_softc	*sc = link->adapter_softc;
4423 	struct mpii_ccb		*ccb = xs->io;
4424 	struct mpii_ccb_bundle	*mcb;
4425 	struct mpii_msg_scsi_io	*io;
4426 	struct mpii_device	*dev;
4427 
4428 	DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd\n", DEVNAME(sc));
4429 
4430 	if (xs->cmdlen > MPII_CDB_LEN) {
4431 		DNPRINTF(MPII_D_CMD, "%s: CBD too big %d\n",
4432 		    DEVNAME(sc), xs->cmdlen);
4433 		bzero(&xs->sense, sizeof(xs->sense));
4434 		xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
4435 		xs->sense.flags = SKEY_ILLEGAL_REQUEST;
4436 		xs->sense.add_sense_code = 0x20;
4437 		xs->error = XS_SENSE;
4438 		scsi_done(xs);
4439 		return;
4440 	}
4441 
4442 	if ((dev = sc->sc_devs[link->target]) == NULL) {
4443 		/* device no longer exists */
4444 		xs->error = XS_SELTIMEOUT;
4445 		scsi_done(xs);
4446 		return;
4447 	}
4448 
4449 	DNPRINTF(MPII_D_CMD, "%s: ccb_smid: %d xs->flags: 0x%x\n",
4450 	    DEVNAME(sc), ccb->ccb_smid, xs->flags);
4451 
4452 	ccb->ccb_cookie = xs;
4453 	ccb->ccb_done = mpii_scsi_cmd_done;
4454 	ccb->ccb_dev_handle = dev->dev_handle;
4455 
4456 	mcb = ccb->ccb_cmd;
4457 	io = &mcb->mcb_io;
4458 
4459 	io->function = MPII_FUNCTION_SCSI_IO_REQUEST;
4460 	io->sense_buffer_length = sizeof(xs->sense);
4461 	io->sgl_offset0 = 24; /* XXX fix this */
4462 	io->io_flags = htole16(xs->cmdlen);
4463 	io->dev_handle = htole16(ccb->ccb_dev_handle);
4464 	io->lun[0] = htobe16(link->lun);
4465 
4466 	switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
4467 	case SCSI_DATA_IN:
4468 		io->direction = MPII_SCSIIO_DIR_READ;
4469 		break;
4470 	case SCSI_DATA_OUT:
4471 		io->direction = MPII_SCSIIO_DIR_WRITE;
4472 		break;
4473 	default:
4474 		io->direction = MPII_SCSIIO_DIR_NONE;
4475 	}
4476 
4477 	io->tagging = MPII_SCSIIO_ATTR_SIMPLE_Q;
4478 
4479 	bcopy(xs->cmd, io->cdb, xs->cmdlen);
4480 
4481 	io->data_length = htole32(xs->datalen);
4482 
4483 	io->sense_buffer_low_address = htole32(ccb->ccb_cmd_dva +
4484 	    ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb));
4485 
4486 	if (mpii_load_xs(ccb) != 0) {
4487 		xs->error = XS_DRIVER_STUFFUP;
4488 		scsi_done(xs);
4489 		return;
4490 	}
4491 
4492 	DNPRINTF(MPII_D_CMD, "%s:  sizeof(mpii_msg_scsi_io): %d "
4493 	    "sizeof(mpii_ccb_bundle): %d sge offset: 0x%02x\n",
4494 	    DEVNAME(sc), sizeof(struct mpii_msg_scsi_io),
4495 	    sizeof(struct mpii_ccb_bundle),
4496 	    (u_int8_t *)&mcb->mcb_sgl[0] - (u_int8_t *)mcb);
4497 
4498 	DNPRINTF(MPII_D_CMD, "%s   sgl[0]: 0x%04x 0%04x 0x%04x\n",
4499 	    DEVNAME(sc), mcb->mcb_sgl[0].sg_hdr, mcb->mcb_sgl[0].sg_lo_addr,
4500 	    mcb->mcb_sgl[0].sg_hi_addr);
4501 
4502 	DNPRINTF(MPII_D_CMD, "%s:  Offset0: 0x%02x\n", DEVNAME(sc),
4503 	    io->sgl_offset0);
4504 
4505 	timeout_set(&xs->stimeout, mpii_scsi_cmd_tmo, ccb);
4506 	if (xs->flags & SCSI_POLL) {
4507 		if (mpii_poll(sc, ccb) != 0) {
4508 			xs->error = XS_DRIVER_STUFFUP;
4509 			scsi_done(xs);
4510 		}
4511 		return;
4512 	}
4513 
4514 	DNPRINTF(MPII_D_CMD, "%s:    mpii_scsi_cmd(): opcode: %02x "
4515 	    "datalen: %d\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen);
4516 
4517 	timeout_add_msec(&xs->stimeout, xs->timeout);
4518 	mpii_start(sc, ccb);
4519 }
4520 
4521 void
4522 mpii_scsi_cmd_tmo(void *xccb)
4523 {
4524 	struct mpii_ccb		*ccb = xccb;
4525 	struct mpii_softc	*sc = ccb->ccb_sc;
4526 
4527 	printf("%s: mpii_scsi_cmd_tmo\n", DEVNAME(sc));
4528 
4529 	mtx_enter(&sc->sc_ccb_mtx);
4530 	if (ccb->ccb_state == MPII_CCB_QUEUED) {
4531 		ccb->ccb_state = MPII_CCB_TIMEOUT;
4532 		SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_tmos, ccb, ccb_link);
4533 	}
4534 	mtx_leave(&sc->sc_ccb_mtx);
4535 
4536 	scsi_ioh_add(&sc->sc_ccb_tmo_handler);
4537 }
4538 
4539 void
4540 mpii_scsi_cmd_tmo_handler(void *cookie, void *io)
4541 {
4542 	struct mpii_softc			*sc = cookie;
4543 	struct mpii_ccb				*tccb = io;
4544 	struct mpii_ccb				*ccb;
4545 	struct mpii_msg_scsi_task_request	*stq;
4546 
4547 	mtx_enter(&sc->sc_ccb_mtx);
4548 	ccb = SIMPLEQ_FIRST(&sc->sc_ccb_tmos);
4549 	if (ccb != NULL) {
4550 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_tmos, ccb_link);
4551 		ccb->ccb_state = MPII_CCB_QUEUED;
4552 	}
4553 	/* should remove any other ccbs for the same dev handle */
4554 	mtx_leave(&sc->sc_ccb_mtx);
4555 
4556 	if (ccb == NULL) {
4557 		scsi_io_put(&sc->sc_iopool, tccb);
4558 		return;
4559 	}
4560 
4561 	stq = tccb->ccb_cmd;
4562 	stq->function = MPII_FUNCTION_SCSI_TASK_MGMT;
4563 	stq->task_type = MPII_SCSI_TASK_TARGET_RESET;
4564 	stq->dev_handle = htole16(ccb->ccb_dev_handle);
4565 
4566 	tccb->ccb_done = mpii_scsi_cmd_tmo_done;
4567 	mpii_start(sc, tccb);
4568 }
4569 
4570 void
4571 mpii_scsi_cmd_tmo_done(struct mpii_ccb *tccb)
4572 {
4573 	mpii_scsi_cmd_tmo_handler(tccb->ccb_sc, tccb);
4574 }
4575 
4576 void
4577 mpii_scsi_cmd_done(struct mpii_ccb *ccb)
4578 {
4579 	struct mpii_ccb		*tccb;
4580 	struct mpii_msg_scsi_io_error	*sie;
4581 	struct mpii_softc	*sc = ccb->ccb_sc;
4582 	struct scsi_xfer	*xs = ccb->ccb_cookie;
4583 	struct mpii_ccb_bundle	*mcb = ccb->ccb_cmd;
4584 	bus_dmamap_t		dmap = ccb->ccb_dmamap;
4585 
4586 	timeout_del(&xs->stimeout);
4587 	mtx_enter(&sc->sc_ccb_mtx);
4588 	if (ccb->ccb_state == MPII_CCB_TIMEOUT) {
4589 		/* ENOSIMPLEQ_REMOVE :( */
4590 		if (ccb == SIMPLEQ_FIRST(&sc->sc_ccb_tmos))
4591 			SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_tmos, ccb_link);
4592 		else {
4593 			SIMPLEQ_FOREACH(tccb, &sc->sc_ccb_tmos, ccb_link) {
4594 				if (SIMPLEQ_NEXT(tccb, ccb_link) == ccb) {
4595 					SIMPLEQ_REMOVE_AFTER(&sc->sc_ccb_tmos,
4596 					    tccb, ccb_link);
4597 					break;
4598 				}
4599 			}
4600 		}
4601 	}
4602 
4603 	ccb->ccb_state = MPII_CCB_READY;
4604 	mtx_leave(&sc->sc_ccb_mtx);
4605 
4606 	if (xs->datalen != 0) {
4607 		bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
4608 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
4609 		    BUS_DMASYNC_POSTWRITE);
4610 
4611 		bus_dmamap_unload(sc->sc_dmat, dmap);
4612 	}
4613 
4614 	xs->error = XS_NOERROR;
4615 	xs->resid = 0;
4616 
4617 	if (ccb->ccb_rcb == NULL) {
4618 		/* no scsi error, we're ok so drop out early */
4619 		xs->status = SCSI_OK;
4620 		scsi_done(xs);
4621 		return;
4622 	}
4623 
4624 	sie = ccb->ccb_rcb->rcb_reply;
4625 
4626 	DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd_done xs cmd: 0x%02x len: %d "
4627 	    "flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
4628 	    xs->flags);
4629 	DNPRINTF(MPII_D_CMD, "%s:  dev_handle: %d msg_length: %d "
4630 	    "function: 0x%02x\n", DEVNAME(sc), letoh16(sie->dev_handle),
4631 	    sie->msg_length, sie->function);
4632 	DNPRINTF(MPII_D_CMD, "%s:  vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
4633 	    sie->vp_id, sie->vf_id);
4634 	DNPRINTF(MPII_D_CMD, "%s:  scsi_status: 0x%02x scsi_state: 0x%02x "
4635 	    "ioc_status: 0x%04x\n", DEVNAME(sc), sie->scsi_status,
4636 	    sie->scsi_state, letoh16(sie->ioc_status));
4637 	DNPRINTF(MPII_D_CMD, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
4638 	    letoh32(sie->ioc_loginfo));
4639 	DNPRINTF(MPII_D_CMD, "%s:  transfer_count: %d\n", DEVNAME(sc),
4640 	    letoh32(sie->transfer_count));
4641 	DNPRINTF(MPII_D_CMD, "%s:  sense_count: %d\n", DEVNAME(sc),
4642 	    letoh32(sie->sense_count));
4643 	DNPRINTF(MPII_D_CMD, "%s:  response_info: 0x%08x\n", DEVNAME(sc),
4644 	    letoh32(sie->response_info));
4645 	DNPRINTF(MPII_D_CMD, "%s:  task_tag: 0x%04x\n", DEVNAME(sc),
4646 	    letoh16(sie->task_tag));
4647 	DNPRINTF(MPII_D_CMD, "%s:  bidirectional_transfer_count: 0x%08x\n",
4648 	    DEVNAME(sc), letoh32(sie->bidirectional_transfer_count));
4649 
4650 	xs->status = sie->scsi_status;
4651 	switch (letoh16(sie->ioc_status) & MPII_IOCSTATUS_MASK) {
4652 	case MPII_IOCSTATUS_SCSI_DATA_UNDERRUN:
4653 		switch (xs->status) {
4654 		case SCSI_OK:
4655 			xs->resid = xs->datalen - letoh32(sie->transfer_count);
4656 			break;
4657 		default:
4658 			xs->error = XS_DRIVER_STUFFUP;
4659 			break;
4660 		}
4661 		break;
4662 	case MPII_IOCSTATUS_SUCCESS:
4663 	case MPII_IOCSTATUS_SCSI_RECOVERED_ERROR:
4664 		switch (xs->status) {
4665 		case SCSI_OK:
4666 			xs->resid = 0;
4667 			break;
4668 
4669 		case SCSI_CHECK:
4670 			xs->error = XS_SENSE;
4671 			break;
4672 
4673 		case SCSI_BUSY:
4674 		case SCSI_QUEUE_FULL:
4675 			xs->error = XS_BUSY;
4676 			break;
4677 
4678 		default:
4679 			xs->error = XS_DRIVER_STUFFUP;
4680 		}
4681 		break;
4682 
4683 	case MPII_IOCSTATUS_BUSY:
4684 	case MPII_IOCSTATUS_INSUFFICIENT_RESOURCES:
4685 		xs->error = XS_BUSY;
4686 		break;
4687 
4688 	case MPII_IOCSTATUS_SCSI_IOC_TERMINATED:
4689 	case MPII_IOCSTATUS_SCSI_TASK_TERMINATED:
4690 		xs->error = XS_RESET;
4691 		break;
4692 
4693 	case MPII_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
4694 	case MPII_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
4695 		xs->error = XS_SELTIMEOUT;
4696 		break;
4697 
4698 	default:
4699 		xs->error = XS_DRIVER_STUFFUP;
4700 		break;
4701 	}
4702 
4703 	if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID)
4704 		bcopy(&mcb->mcb_sense, &xs->sense, sizeof(xs->sense));
4705 
4706 	DNPRINTF(MPII_D_CMD, "%s:  xs err: %d status: %#x\n", DEVNAME(sc),
4707 	    xs->error, xs->status);
4708 
4709 	mpii_push_reply(sc, ccb->ccb_rcb);
4710 	scsi_done(xs);
4711 }
4712 
4713 int
4714 mpii_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag)
4715 {
4716 	struct mpii_softc	*sc = (struct mpii_softc *)link->adapter_softc;
4717 	struct mpii_device	*dev = sc->sc_devs[link->target];
4718 
4719 	DNPRINTF(MPII_D_IOCTL, "%s: mpii_scsi_ioctl\n", DEVNAME(sc));
4720 
4721 	switch (cmd) {
4722 	case DIOCGCACHE:
4723 	case DIOCSCACHE:
4724 		if (dev != NULL && ISSET(dev->flags, MPII_DF_VOLUME)) {
4725 			return (mpii_ioctl_cache(link, cmd,
4726 			    (struct dk_cache *)addr));
4727 		}
4728 		break;
4729 
4730 	default:
4731 		if (sc->sc_ioctl)
4732 			return (sc->sc_ioctl(link->adapter_softc, cmd, addr));
4733 
4734 		break;
4735 	}
4736 
4737 	return (ENOTTY);
4738 }
4739 
4740 int
4741 mpii_ioctl_cache(struct scsi_link *link, u_long cmd, struct dk_cache *dc)
4742 {
4743 	struct mpii_softc *sc = (struct mpii_softc *)link->adapter_softc;
4744 	struct mpii_device *dev = sc->sc_devs[link->target];
4745 	struct mpii_cfg_raid_vol_pg0 *vpg;
4746 	struct mpii_msg_raid_action_request *req;
4747  	struct mpii_msg_raid_action_reply *rep;
4748 	struct mpii_cfg_hdr hdr;
4749 	struct mpii_ccb	*ccb;
4750 	u_int32_t addr = MPII_CFG_RAID_VOL_ADDR_HANDLE | dev->dev_handle;
4751 	size_t pagelen;
4752 	int rv = 0;
4753 	int enabled;
4754 
4755 	if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
4756 	    addr, MPII_PG_POLL, &hdr) != 0)
4757 		return (EINVAL);
4758 
4759 	pagelen = hdr.page_length * 4;
4760 	vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
4761 	if (vpg == NULL)
4762 		return (ENOMEM);
4763 
4764 	if (mpii_req_cfg_page(sc, addr, MPII_PG_POLL, &hdr, 1,
4765 	    vpg, pagelen) != 0) {
4766 		rv = EINVAL;
4767 		goto done;
4768 		free(vpg, M_TEMP);
4769 		return (EINVAL);
4770 	}
4771 
4772 	enabled = ((letoh16(vpg->volume_settings) &
4773 	    MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_MASK) ==
4774 	    MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_ENABLED) ? 1 : 0;
4775 
4776 	if (cmd == DIOCGCACHE) {
4777 		dc->wrcache = enabled;
4778 		dc->rdcache = 0;
4779 		goto done;
4780 	} /* else DIOCSCACHE */
4781 
4782 	if (dc->rdcache) {
4783 		rv = EOPNOTSUPP;
4784 		goto done;
4785 	}
4786 
4787 	if (((dc->wrcache) ? 1 : 0) == enabled)
4788 		goto done;
4789 
4790 	ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL);
4791 	if (ccb == NULL) {
4792 		rv = ENOMEM;
4793 		goto done;
4794 	}
4795 
4796 	ccb->ccb_done = mpii_empty_done;
4797 
4798 	req = ccb->ccb_cmd;
4799 	bzero(req, sizeof(*req));
4800 	req->function = MPII_FUNCTION_RAID_ACTION;
4801 	req->action = MPII_RAID_ACTION_CHANGE_VOL_WRITE_CACHE;
4802 	req->vol_dev_handle = htole16(dev->dev_handle);
4803 	req->action_data = htole32(dc->wrcache ?
4804 	    MPII_RAID_VOL_WRITE_CACHE_ENABLE :
4805 	    MPII_RAID_VOL_WRITE_CACHE_DISABLE);
4806 
4807 	if (mpii_poll(sc, ccb) != 0) {
4808 		rv = EIO;
4809 		goto done;
4810 	}
4811 
4812 	if (ccb->ccb_rcb != NULL) {
4813 		rep = ccb->ccb_rcb->rcb_reply;
4814 		if ((rep->ioc_status != MPII_IOCSTATUS_SUCCESS) ||
4815 		    ((rep->action_data[0] &
4816 		     MPII_RAID_VOL_WRITE_CACHE_MASK) !=
4817 		    (dc->wrcache ? MPII_RAID_VOL_WRITE_CACHE_ENABLE :
4818 		     MPII_RAID_VOL_WRITE_CACHE_DISABLE)))
4819 			rv = EINVAL;
4820 		mpii_push_reply(sc, ccb->ccb_rcb);
4821 	}
4822 
4823 	scsi_io_put(&sc->sc_iopool, ccb);
4824 
4825 done:
4826 	free(vpg, M_TEMP);
4827 	return (rv);
4828 }
4829 
4830 #if NBIO > 0
4831 int
4832 mpii_ioctl(struct device *dev, u_long cmd, caddr_t addr)
4833 {
4834 	struct mpii_softc	*sc = (struct mpii_softc *)dev;
4835 	int			error = 0;
4836 
4837 	DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl ", DEVNAME(sc));
4838 
4839 	switch (cmd) {
4840 	case BIOCINQ:
4841 		DNPRINTF(MPII_D_IOCTL, "inq\n");
4842 		error = mpii_ioctl_inq(sc, (struct bioc_inq *)addr);
4843 		break;
4844 	case BIOCVOL:
4845 		DNPRINTF(MPII_D_IOCTL, "vol\n");
4846 		error = mpii_ioctl_vol(sc, (struct bioc_vol *)addr);
4847 		break;
4848 	case BIOCDISK:
4849 		DNPRINTF(MPII_D_IOCTL, "disk\n");
4850 		error = mpii_ioctl_disk(sc, (struct bioc_disk *)addr);
4851 		break;
4852 	default:
4853 		DNPRINTF(MPII_D_IOCTL, " invalid ioctl\n");
4854 		error = EINVAL;
4855 	}
4856 
4857 	return (error);
4858 }
4859 
4860 int
4861 mpii_ioctl_inq(struct mpii_softc *sc, struct bioc_inq *bi)
4862 {
4863 	int			i;
4864 
4865 	DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_inq\n", DEVNAME(sc));
4866 
4867 	strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
4868 	for (i = 0; i < sc->sc_max_devices; i++)
4869 		if (sc->sc_devs[i] &&
4870 		    ISSET(sc->sc_devs[i]->flags, MPII_DF_VOLUME))
4871 			bi->bi_novol++;
4872 	return (0);
4873 }
4874 
4875 int
4876 mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
4877 {
4878 	struct mpii_cfg_raid_vol_pg0	*vpg;
4879 	struct mpii_cfg_hdr		hdr;
4880 	struct mpii_device		*dev;
4881 	struct scsi_link		*lnk;
4882 	struct device			*scdev;
4883 	size_t				pagelen;
4884 	u_int16_t			volh;
4885 	int				rv, hcnt = 0;
4886 
4887 	DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_vol %d\n",
4888 	    DEVNAME(sc), bv->bv_volid);
4889 
4890 	if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
4891 		return (ENODEV);
4892 	volh = dev->dev_handle;
4893 
4894 	if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
4895 	    MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
4896 		printf("%s: unable to fetch header for raid volume page 0\n",
4897 		    DEVNAME(sc));
4898 		return (EINVAL);
4899 	}
4900 
4901 	pagelen = hdr.page_length * 4;
4902 	vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
4903 	if (vpg == NULL) {
4904 		printf("%s: unable to allocate space for raid "
4905 		    "volume page 0\n", DEVNAME(sc));
4906 		return (ENOMEM);
4907 	}
4908 
4909 	if (mpii_req_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0,
4910 	    &hdr, 1, vpg, pagelen) != 0) {
4911 		printf("%s: unable to fetch raid volume page 0\n",
4912 		    DEVNAME(sc));
4913 		free(vpg, M_TEMP);
4914 		return (EINVAL);
4915 	}
4916 
4917 	switch (vpg->volume_state) {
4918 	case MPII_CFG_RAID_VOL_0_STATE_ONLINE:
4919 	case MPII_CFG_RAID_VOL_0_STATE_OPTIMAL:
4920 		bv->bv_status = BIOC_SVONLINE;
4921 		break;
4922 	case MPII_CFG_RAID_VOL_0_STATE_DEGRADED:
4923 		if (ISSET(letoh32(vpg->volume_status),
4924 		    MPII_CFG_RAID_VOL_0_STATUS_RESYNC)) {
4925 			bv->bv_status = BIOC_SVREBUILD;
4926 			bv->bv_percent = dev->percent;
4927 		} else
4928 			bv->bv_status = BIOC_SVDEGRADED;
4929 		break;
4930 	case MPII_CFG_RAID_VOL_0_STATE_FAILED:
4931 		bv->bv_status = BIOC_SVOFFLINE;
4932 		break;
4933 	case MPII_CFG_RAID_VOL_0_STATE_INITIALIZING:
4934 		bv->bv_status = BIOC_SVBUILDING;
4935 		break;
4936 	case MPII_CFG_RAID_VOL_0_STATE_MISSING:
4937 	default:
4938 		bv->bv_status = BIOC_SVINVALID;
4939 		break;
4940 	}
4941 
4942 	switch (vpg->volume_type) {
4943 	case MPII_CFG_RAID_VOL_0_TYPE_RAID0:
4944 		bv->bv_level = 0;
4945 		break;
4946 	case MPII_CFG_RAID_VOL_0_TYPE_RAID1:
4947 		bv->bv_level = 1;
4948 		break;
4949 	case MPII_CFG_RAID_VOL_0_TYPE_RAID1E:
4950 	case MPII_CFG_RAID_VOL_0_TYPE_RAID10:
4951 		bv->bv_level = 10;
4952 		break;
4953 	default:
4954 		bv->bv_level = -1;
4955 	}
4956 
4957 	if ((rv = mpii_bio_hs(sc, NULL, 0, vpg->hot_spare_pool, &hcnt)) != 0) {
4958 		free(vpg, M_TEMP);
4959 		return (rv);
4960 	}
4961 
4962 	bv->bv_nodisk = vpg->num_phys_disks + hcnt;
4963 
4964 	bv->bv_size = letoh64(vpg->max_lba) * letoh16(vpg->block_size);
4965 
4966 	lnk = scsi_get_link(sc->sc_scsibus, dev->slot, 0);
4967 	if (lnk != NULL) {
4968 		scdev = lnk->device_softc;
4969 		strlcpy(bv->bv_dev, scdev->dv_xname, sizeof(bv->bv_dev));
4970 	}
4971 
4972 	free(vpg, M_TEMP);
4973 	return (0);
4974 }
4975 
4976 int
4977 mpii_ioctl_disk(struct mpii_softc *sc, struct bioc_disk *bd)
4978 {
4979 	struct mpii_cfg_raid_vol_pg0		*vpg;
4980 	struct mpii_cfg_raid_vol_pg0_physdisk	*pd;
4981 	struct mpii_cfg_hdr			hdr;
4982 	struct mpii_device			*dev;
4983 	size_t					pagelen;
4984 	u_int16_t				volh;
4985 	u_int8_t				dn;
4986 
4987 	DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_disk %d/%d\n",
4988 	    DEVNAME(sc), bd->bd_volid, bd->bd_diskid);
4989 
4990 	if ((dev = mpii_find_vol(sc, bd->bd_volid)) == NULL)
4991 		return (ENODEV);
4992 	volh = dev->dev_handle;
4993 
4994 	if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
4995 	    MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
4996 		printf("%s: unable to fetch header for raid volume page 0\n",
4997 		    DEVNAME(sc));
4998 		return (EINVAL);
4999 	}
5000 
5001 	pagelen = hdr.page_length * 4;
5002 	vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
5003 	if (vpg == NULL) {
5004 		printf("%s: unable to allocate space for raid "
5005 		    "volume page 0\n", DEVNAME(sc));
5006 		return (ENOMEM);
5007 	}
5008 
5009 	if (mpii_req_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0,
5010 	    &hdr, 1, vpg, pagelen) != 0) {
5011 		printf("%s: unable to fetch raid volume page 0\n",
5012 		    DEVNAME(sc));
5013 		free(vpg, M_TEMP);
5014 		return (EINVAL);
5015 	}
5016 
5017 	if (bd->bd_diskid >= vpg->num_phys_disks) {
5018 		int		nvdsk = vpg->num_phys_disks;
5019 		int		hsmap = vpg->hot_spare_pool;
5020 
5021 		free(vpg, M_TEMP);
5022 		return (mpii_bio_hs(sc, bd, nvdsk, hsmap, NULL));
5023 	}
5024 
5025 	pd = (struct mpii_cfg_raid_vol_pg0_physdisk *)(vpg + 1) +
5026 	    bd->bd_diskid;
5027 	dn = pd->phys_disk_num;
5028 
5029 	free(vpg, M_TEMP);
5030 	return (mpii_bio_disk(sc, bd, dn));
5031 }
5032 
5033 int
5034 mpii_bio_hs(struct mpii_softc *sc, struct bioc_disk *bd, int nvdsk,
5035      int hsmap, int *hscnt)
5036 {
5037 	struct mpii_cfg_raid_config_pg0	*cpg;
5038 	struct mpii_raid_config_element	*el;
5039 	struct mpii_ecfg_hdr		ehdr;
5040 	size_t				pagelen;
5041 	int				i, nhs = 0;
5042 
5043 	if (bd)
5044 		DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_hs %d\n", DEVNAME(sc),
5045 		    bd->bd_diskid - nvdsk);
5046 	else
5047 		DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_hs\n", DEVNAME(sc));
5048 
5049 	if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_CONFIG,
5050 	    0, MPII_CFG_RAID_CONFIG_ACTIVE_CONFIG, MPII_PG_EXTENDED,
5051 	    &ehdr) != 0) {
5052 		printf("%s: unable to fetch header for raid config page 0\n",
5053 		    DEVNAME(sc));
5054 		return (EINVAL);
5055 	}
5056 
5057 	pagelen = letoh16(ehdr.ext_page_length) * 4;
5058 	cpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
5059 	if (cpg == NULL) {
5060 		printf("%s: unable to allocate space for raid config page 0\n",
5061 		    DEVNAME(sc));
5062 		return (ENOMEM);
5063 	}
5064 
5065 	if (mpii_req_cfg_page(sc, MPII_CFG_RAID_CONFIG_ACTIVE_CONFIG,
5066 	    MPII_PG_EXTENDED, &ehdr, 1, cpg, pagelen) != 0) {
5067 		printf("%s: unable to fetch raid config page 0\n",
5068 		    DEVNAME(sc));
5069 		free(cpg, M_TEMP);
5070 		return (EINVAL);
5071 	}
5072 
5073 	el = (struct mpii_raid_config_element *)(cpg + 1);
5074 	for (i = 0; i < cpg->num_elements; i++, el++) {
5075 		if (ISSET(letoh16(el->element_flags),
5076 		    MPII_RAID_CONFIG_ELEMENT_FLAG_HSP_PHYS_DISK) &&
5077 		    el->hot_spare_pool == hsmap) {
5078 			/*
5079 			 * diskid comparison is based on the idea that all
5080 			 * disks are counted by the bio(4) in sequence, thus
5081 			 * substracting the number of disks in the volume
5082 			 * from the diskid yields us a "relative" hotspare
5083 			 * number, which is good enough for us.
5084 			 */
5085 			if (bd != NULL && bd->bd_diskid == nhs + nvdsk) {
5086 				u_int8_t dn = el->phys_disk_num;
5087 
5088 				free(cpg, M_TEMP);
5089 				return (mpii_bio_disk(sc, bd, dn));
5090 			}
5091 			nhs++;
5092 		}
5093 	}
5094 
5095 	if (hscnt)
5096 		*hscnt = nhs;
5097 
5098 	free(cpg, M_TEMP);
5099 	return (0);
5100 }
5101 
5102 int
5103 mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk *bd, u_int8_t dn)
5104 {
5105 	struct mpii_cfg_raid_physdisk_pg0	*ppg;
5106 	struct mpii_cfg_hdr			hdr;
5107 	struct mpii_device			*dev;
5108 	int					len;
5109 
5110 	DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_disk %d\n", DEVNAME(sc),
5111 	    bd->bd_diskid);
5112 
5113 	ppg = malloc(sizeof(*ppg), M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
5114 	if (ppg == NULL) {
5115 		printf("%s: unable to allocate space for raid physical disk "
5116 		    "page 0\n", DEVNAME(sc));
5117 		return (ENOMEM);
5118 	}
5119 
5120 	hdr.page_version = 0;
5121 	hdr.page_length = sizeof(*ppg) / 4;
5122 	hdr.page_number = 0;
5123 	hdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_RAID_PD;
5124 
5125 	if (mpii_req_cfg_page(sc, MPII_CFG_RAID_PHYS_DISK_ADDR_NUMBER | dn, 0,
5126 	    &hdr, 1, ppg, sizeof(*ppg)) != 0) {
5127 		printf("%s: unable to fetch raid drive page 0\n",
5128 		    DEVNAME(sc));
5129 		free(ppg, M_TEMP);
5130 		return (EINVAL);
5131 	}
5132 
5133 	bd->bd_target = ppg->phys_disk_num;
5134 
5135 	if ((dev = mpii_find_dev(sc, letoh16(ppg->dev_handle))) == NULL) {
5136 		bd->bd_status = BIOC_SDINVALID;
5137 		free(ppg, M_TEMP);
5138 		return (0);
5139 	}
5140 
5141 	switch (ppg->phys_disk_state) {
5142 	case MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE:
5143 	case MPII_CFG_RAID_PHYDISK_0_STATE_OPTIMAL:
5144 		bd->bd_status = BIOC_SDONLINE;
5145 		break;
5146 	case MPII_CFG_RAID_PHYDISK_0_STATE_OFFLINE:
5147 		if (ppg->offline_reason ==
5148 		    MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILED ||
5149 		    ppg->offline_reason ==
5150 		    MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILEDREQ)
5151 			bd->bd_status = BIOC_SDFAILED;
5152 		else
5153 			bd->bd_status = BIOC_SDOFFLINE;
5154 		break;
5155 	case MPII_CFG_RAID_PHYDISK_0_STATE_DEGRADED:
5156 		bd->bd_status = BIOC_SDFAILED;
5157 		break;
5158 	case MPII_CFG_RAID_PHYDISK_0_STATE_REBUILDING:
5159 		bd->bd_status = BIOC_SDREBUILD;
5160 		break;
5161 	case MPII_CFG_RAID_PHYDISK_0_STATE_HOTSPARE:
5162 		bd->bd_status = BIOC_SDHOTSPARE;
5163 		break;
5164 	case MPII_CFG_RAID_PHYDISK_0_STATE_NOTCONFIGURED:
5165 		bd->bd_status = BIOC_SDUNUSED;
5166 		break;
5167 	case MPII_CFG_RAID_PHYDISK_0_STATE_NOTCOMPATIBLE:
5168 	default:
5169 		bd->bd_status = BIOC_SDINVALID;
5170 		break;
5171 	}
5172 
5173 	bd->bd_size = letoh64(ppg->dev_max_lba) * letoh16(ppg->block_size);
5174 
5175 	scsi_strvis(bd->bd_vendor, ppg->vendor_id, sizeof(ppg->vendor_id));
5176 	len = strlen(bd->bd_vendor);
5177 	bd->bd_vendor[len] = ' ';
5178 	scsi_strvis(&bd->bd_vendor[len + 1], ppg->product_id,
5179 	    sizeof(ppg->product_id));
5180 	scsi_strvis(bd->bd_serial, ppg->serial, sizeof(ppg->serial));
5181 
5182 	free(ppg, M_TEMP);
5183 	return (0);
5184 }
5185 
5186 struct mpii_device *
5187 mpii_find_vol(struct mpii_softc *sc, int volid)
5188 {
5189 	struct mpii_device	*dev = NULL;
5190 
5191 	if (sc->sc_vd_id_low + volid >= sc->sc_max_devices)
5192 		return (NULL);
5193 	dev = sc->sc_devs[sc->sc_vd_id_low + volid];
5194 	if (dev && ISSET(dev->flags, MPII_DF_VOLUME))
5195 		return (dev);
5196 	return (NULL);
5197 }
5198 
5199 #ifndef SMALL_KERNEL
5200 /*
5201  * Non-sleeping lightweight version of the mpii_ioctl_vol
5202  */
5203 int
5204 mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
5205 {
5206 	struct mpii_cfg_raid_vol_pg0	*vpg;
5207 	struct mpii_cfg_hdr		hdr;
5208 	struct mpii_device		*dev = NULL;
5209 	size_t				pagelen;
5210 	u_int16_t			volh;
5211 
5212 	if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
5213 		return (ENODEV);
5214 	volh = dev->dev_handle;
5215 
5216 	if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
5217 	    MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, &hdr) != 0) {
5218 		DNPRINTF(MPII_D_MISC, "%s: unable to fetch header for raid "
5219 		    "volume page 0\n", DEVNAME(sc));
5220 		return (EINVAL);
5221 	}
5222 
5223 	pagelen = hdr.page_length * 4;
5224 	vpg = malloc(pagelen, M_TEMP, M_NOWAIT | M_ZERO);
5225 	if (vpg == NULL) {
5226 		DNPRINTF(MPII_D_MISC, "%s: unable to allocate space for raid "
5227 		    "volume page 0\n", DEVNAME(sc));
5228 		return (ENOMEM);
5229 	}
5230 
5231 	if (mpii_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh,
5232 	    &hdr, 1, vpg, pagelen) != 0) {
5233 		DNPRINTF(MPII_D_MISC, "%s: unable to fetch raid volume "
5234 		    "page 0\n", DEVNAME(sc));
5235 		free(vpg, M_TEMP);
5236 		return (EINVAL);
5237 	}
5238 
5239 	switch (vpg->volume_state) {
5240 	case MPII_CFG_RAID_VOL_0_STATE_ONLINE:
5241 	case MPII_CFG_RAID_VOL_0_STATE_OPTIMAL:
5242 		bv->bv_status = BIOC_SVONLINE;
5243 		break;
5244 	case MPII_CFG_RAID_VOL_0_STATE_DEGRADED:
5245 		if (ISSET(letoh32(vpg->volume_status),
5246 		    MPII_CFG_RAID_VOL_0_STATUS_RESYNC))
5247 			bv->bv_status = BIOC_SVREBUILD;
5248 		else
5249 			bv->bv_status = BIOC_SVDEGRADED;
5250 		break;
5251 	case MPII_CFG_RAID_VOL_0_STATE_FAILED:
5252 		bv->bv_status = BIOC_SVOFFLINE;
5253 		break;
5254 	case MPII_CFG_RAID_VOL_0_STATE_INITIALIZING:
5255 		bv->bv_status = BIOC_SVBUILDING;
5256 		break;
5257 	case MPII_CFG_RAID_VOL_0_STATE_MISSING:
5258 	default:
5259 		bv->bv_status = BIOC_SVINVALID;
5260 		break;
5261 	}
5262 
5263 	free(vpg, M_TEMP);
5264 	return (0);
5265 }
5266 
5267 int
5268 mpii_create_sensors(struct mpii_softc *sc)
5269 {
5270 	struct scsibus_softc	*ssc = sc->sc_scsibus;
5271 	struct device		*dev;
5272 	struct scsi_link	*link;
5273 	int			i;
5274 
5275 	sc->sc_sensors = malloc(sizeof(struct ksensor) * sc->sc_vd_count,
5276 	    M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO);
5277 	if (sc->sc_sensors == NULL)
5278 		return (1);
5279 	sc->sc_nsensors = sc->sc_vd_count;
5280 
5281 	strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
5282 	    sizeof(sc->sc_sensordev.xname));
5283 
5284 	for (i = 0; i < sc->sc_vd_count; i++) {
5285 		link = scsi_get_link(ssc, i + sc->sc_vd_id_low, 0);
5286 		if (link == NULL)
5287 			goto bad;
5288 
5289 		dev = link->device_softc;
5290 
5291 		sc->sc_sensors[i].type = SENSOR_DRIVE;
5292 		sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
5293 
5294 		strlcpy(sc->sc_sensors[i].desc, dev->dv_xname,
5295 		    sizeof(sc->sc_sensors[i].desc));
5296 
5297 		sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
5298 	}
5299 
5300 	if (sensor_task_register(sc, mpii_refresh_sensors, 10) == NULL)
5301 		goto bad;
5302 
5303 	sensordev_install(&sc->sc_sensordev);
5304 
5305 	return (0);
5306 
5307 bad:
5308 	free(sc->sc_sensors, M_DEVBUF);
5309 
5310 	return (1);
5311 }
5312 
5313 void
5314 mpii_refresh_sensors(void *arg)
5315 {
5316 	struct mpii_softc	*sc = arg;
5317 	struct bioc_vol		bv;
5318 	int			i;
5319 
5320 	for (i = 0; i < sc->sc_nsensors; i++) {
5321 		bzero(&bv, sizeof(bv));
5322 		bv.bv_volid = i;
5323 		if (mpii_bio_volstate(sc, &bv))
5324 			return;
5325 		switch(bv.bv_status) {
5326 		case BIOC_SVOFFLINE:
5327 			sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL;
5328 			sc->sc_sensors[i].status = SENSOR_S_CRIT;
5329 			break;
5330 		case BIOC_SVDEGRADED:
5331 			sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL;
5332 			sc->sc_sensors[i].status = SENSOR_S_WARN;
5333 			break;
5334 		case BIOC_SVREBUILD:
5335 			sc->sc_sensors[i].value = SENSOR_DRIVE_REBUILD;
5336 			sc->sc_sensors[i].status = SENSOR_S_WARN;
5337 			break;
5338 		case BIOC_SVONLINE:
5339 			sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE;
5340 			sc->sc_sensors[i].status = SENSOR_S_OK;
5341 			break;
5342 		case BIOC_SVINVALID:
5343 			/* FALLTHROUGH */
5344 		default:
5345 			sc->sc_sensors[i].value = 0; /* unknown */
5346 			sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
5347 		}
5348 	}
5349 }
5350 #endif /* SMALL_KERNEL */
5351 #endif /* NBIO > 0 */
5352