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