mpii.c revision 1.1 1 /* $NetBSD: mpii.c,v 1.1 2012/04/19 17:50:51 bouyer Exp $ */
2 /* OpenBSD: mpii.c,v 1.51 2012/04/11 13:29:14 naddy Exp */
3 /*
4 * Copyright (c) 2010 Mike Belopuhov <mkb (at) crypt.org.ru>
5 * Copyright (c) 2009 James Giannoules
6 * Copyright (c) 2005 - 2010 David Gwynne <dlg (at) openbsd.org>
7 * Copyright (c) 2005 - 2010 Marco Peereboom <marco (at) 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.1 2012/04/19 17:50:51 bouyer 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 /* XXX JPG validate this */
794 #if notyet
795 #define MPII_SCSIIO_ERR_STATUS_SUCCESS
796 #define MPII_SCSIIO_ERR_STATUS_CHECK_COND
797 #define MPII_SCSIIO_ERR_STATUS_BUSY
798 #define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE
799 #define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET
800 #define MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT
801 #define MPII_SCSIIO_ERR_STATUS_CMD_TERM
802 #define MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL
803 #define MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE
804 #endif
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
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
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
2138 pci_aprint_devinfo(pa, NULL);
2139
2140 sc->sc_pc = pa->pa_pc;
2141 sc->sc_tag = pa->pa_tag;
2142 sc->sc_dmat = pa->pa_dmat;
2143 sc->sc_dev = self;
2144
2145 mutex_init(&sc->sc_req_mtx, MUTEX_DEFAULT, IPL_BIO);
2146 mutex_init(&sc->sc_rep_mtx, MUTEX_DEFAULT, IPL_BIO);
2147 mutex_init(&sc->sc_ccb_free_mtx, MUTEX_DEFAULT, IPL_BIO);
2148 cv_init(&sc->sc_ccb_free_cv, "mpii_ccbs");
2149 mutex_init(&sc->sc_ccb_mtx, MUTEX_DEFAULT, IPL_BIO);
2150
2151 snprintf(wkname, sizeof(wkname), "%s_tmo", DEVNAME(sc));
2152 if (workqueue_create(&sc->sc_ssb_tmowk, wkname,
2153 mpii_scsi_cmd_tmo_handler, sc, PRI_NONE, IPL_BIO, WQ_MPSAFE) != 0) {
2154 aprint_error_dev(self, "can't create %s workqueue\n", wkname);
2155 return;
2156 }
2157
2158 snprintf(wkname, sizeof(wkname), "%s_evt", DEVNAME(sc));
2159 if (workqueue_create(&sc->sc_ssb_evt_ackwk, wkname,
2160 mpii_eventack, sc, PRI_NONE, IPL_BIO, WQ_MPSAFE) != 0) {
2161 aprint_error_dev(self, "can't create %s workqueue\n", wkname);
2162 return;
2163 }
2164
2165 /* find the appropriate memory base */
2166 for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) {
2167 memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, r);
2168 if ((memtype & PCI_MAPREG_TYPE_MASK) == PCI_MAPREG_TYPE_MEM)
2169 break;
2170 }
2171 if (r >= PCI_MAPREG_END) {
2172 aprint_error_dev(self,
2173 "unable to locate system interface registers\n");
2174 return;
2175 }
2176
2177 if (pci_mapreg_map(pa, r, memtype, 0, &sc->sc_iot, &sc->sc_ioh,
2178 NULL, &sc->sc_ios) != 0) {
2179 aprint_error_dev(self,
2180 "unable to map system interface registers\n");
2181 return;
2182 }
2183
2184 /* disable the expansion rom */
2185 PWRITE(sc, PCI_MAPREG_ROM,
2186 PREAD(sc, PCI_MAPREG_ROM) & ~PCI_MAPREG_ROM_ENABLE);
2187
2188 /* disable interrupts */
2189 mpii_write(sc, MPII_INTR_MASK,
2190 MPII_INTR_MASK_RESET | MPII_INTR_MASK_REPLY |
2191 MPII_INTR_MASK_DOORBELL);
2192
2193 /* hook up the interrupt */
2194 if (pci_intr_map(pa, &ih) != 0) {
2195 aprint_error_dev(self, "unable to map interrupt\n");
2196 goto unmap;
2197 }
2198 intrstr = pci_intr_string(pa->pa_pc, ih);
2199
2200 if (mpii_init(sc) != 0) {
2201 aprint_error_dev(self, "unable to initialize ioc\n");
2202 goto unmap;
2203 }
2204
2205 if (mpii_iocfacts(sc) != 0) {
2206 aprint_error_dev(self, "unable to get iocfacts\n");
2207 goto unmap;
2208 }
2209
2210 if (mpii_alloc_ccbs(sc) != 0) {
2211 /* error already printed */
2212 goto unmap;
2213 }
2214
2215 if (mpii_alloc_replies(sc) != 0) {
2216 aprint_error_dev(self, "unable to allocated reply space\n");
2217 goto free_ccbs;
2218 }
2219
2220 if (mpii_alloc_queues(sc) != 0) {
2221 aprint_error_dev(self, "unable to allocate reply queues\n");
2222 goto free_replies;
2223 }
2224
2225 if (mpii_iocinit(sc) != 0) {
2226 aprint_error_dev(self, "unable to send iocinit\n");
2227 goto free_queues;
2228 }
2229
2230 if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2231 MPII_DOORBELL_STATE_OPER) != 0) {
2232 aprint_error_dev(self, "state: 0x%08x\n",
2233 mpii_read_db(sc) & MPII_DOORBELL_STATE);
2234 aprint_error_dev(self, "operational state timeout\n");
2235 goto free_queues;
2236 }
2237
2238 mpii_push_replies(sc);
2239 mpii_init_queues(sc);
2240
2241 if (mpii_portfacts(sc) != 0) {
2242 aprint_error_dev(self, "unable to get portfacts\n");
2243 goto free_queues;
2244 }
2245
2246 if (mpii_get_ioc_pg8(sc) != 0) {
2247 aprint_error_dev(self, "unable to get ioc page 8\n");
2248 goto free_queues;
2249 }
2250
2251 if (mpii_cfg_coalescing(sc) != 0) {
2252 aprint_error_dev(self, "unable to configure coalescing\n");
2253 goto free_queues;
2254 }
2255
2256 /* XXX bail on unsupported porttype? */
2257 if ((sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) ||
2258 (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL)) {
2259 if (mpii_eventnotify(sc) != 0) {
2260 aprint_error_dev(self, "unable to enable events\n");
2261 goto free_queues;
2262 }
2263 }
2264
2265 if (mpii_alloc_dev(sc) != 0) {
2266 aprint_error_dev(self,
2267 "unable to allocate memory for mpii_device\n");
2268 goto free_queues;
2269 }
2270
2271 if (mpii_portenable(sc) != 0) {
2272 aprint_error_dev(self, "unable to enable port\n");
2273 goto free_dev;
2274 }
2275
2276 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_BIO,
2277 mpii_intr, sc);
2278 if (sc->sc_ih == NULL) {
2279 aprint_error_dev(self, "can't establish interrupt");
2280 if (intrstr)
2281 aprint_error(" at %s", intrstr);
2282 aprint_error("\n");
2283 goto free_dev;
2284 }
2285
2286 memset(adapt, 0, sizeof(*adapt));
2287 adapt->adapt_dev = sc->sc_dev;
2288 adapt->adapt_nchannels = 1;
2289 adapt->adapt_openings = sc->sc_request_depth - 1;
2290 adapt->adapt_max_periph = adapt->adapt_openings;
2291 adapt->adapt_request = mpii_scsipi_request;
2292 adapt->adapt_minphys = mpii_minphys;
2293
2294 memset(chan, 0, sizeof(*chan));
2295 chan->chan_adapter = adapt;
2296 chan->chan_bustype = &scsi_sas_bustype;
2297 chan->chan_channel = 0;
2298 chan->chan_flags = 0;
2299 chan->chan_nluns = 1;
2300 chan->chan_ntargets = sc->sc_max_devices;
2301 chan->chan_id = -1;
2302
2303 mpii_rescan(self, "scsi", NULL);
2304
2305 /* enable interrupts */
2306 mpii_write(sc, MPII_INTR_MASK, MPII_INTR_MASK_DOORBELL
2307 | MPII_INTR_MASK_RESET);
2308
2309 #if NBIO > 0
2310 if (ISSET(sc->sc_flags, MPII_F_RAID)) {
2311 if (bio_register(sc->sc_dev, mpii_ioctl) != 0)
2312 panic("%s: controller registration failed",
2313 DEVNAME(sc));
2314
2315 if (mpii_create_sensors(sc) != 0)
2316 aprint_error_dev(self, "unable to create sensors\n");
2317 }
2318 #endif
2319
2320 return;
2321
2322 free_dev:
2323 if (sc->sc_devs)
2324 free(sc->sc_devs, M_DEVBUF);
2325
2326 free_queues:
2327 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_freeq),
2328 0, sc->sc_reply_free_qdepth * 4, BUS_DMASYNC_POSTREAD);
2329 mpii_dmamem_free(sc, sc->sc_reply_freeq);
2330
2331 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
2332 0, sc->sc_reply_post_qdepth * 8, BUS_DMASYNC_POSTREAD);
2333 mpii_dmamem_free(sc, sc->sc_reply_postq);
2334
2335 free_replies:
2336 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
2337 0, PAGE_SIZE, BUS_DMASYNC_POSTREAD);
2338 mpii_dmamem_free(sc, sc->sc_replies);
2339
2340 free_ccbs:
2341 while ((ccb = mpii_get_ccb(sc, MPII_NOSLEEP)) != NULL)
2342 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2343 mpii_dmamem_free(sc, sc->sc_requests);
2344 free(sc->sc_ccbs, M_DEVBUF);
2345
2346 unmap:
2347 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
2348 sc->sc_ios = 0;
2349 }
2350
2351 static int
2352 mpii_detach(device_t self, int flags)
2353 {
2354 struct mpii_softc *sc = device_private(self);
2355 int error;
2356 struct mpii_ccb *ccb;
2357
2358 if ((error = config_detach_children(sc->sc_dev, flags)) != 0)
2359 return error;
2360
2361 #if NBIO > 0
2362 mpii_destroy_sensors(sc);
2363 bio_unregister(sc->sc_dev);
2364 #endif /* NBIO > 0 */
2365
2366 if (sc->sc_ih != NULL) {
2367 if (sc->sc_devs)
2368 free(sc->sc_devs, M_DEVBUF);
2369
2370 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_freeq),
2371 0, sc->sc_reply_free_qdepth * 4, BUS_DMASYNC_POSTREAD);
2372 mpii_dmamem_free(sc, sc->sc_reply_freeq);
2373
2374 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
2375 0, sc->sc_reply_post_qdepth * 8, BUS_DMASYNC_POSTREAD);
2376 mpii_dmamem_free(sc, sc->sc_reply_postq);
2377
2378 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
2379 0, PAGE_SIZE, BUS_DMASYNC_POSTREAD);
2380 mpii_dmamem_free(sc, sc->sc_replies);
2381
2382 while ((ccb = mpii_get_ccb(sc, MPII_NOSLEEP)) != NULL)
2383 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2384 mpii_dmamem_free(sc, sc->sc_requests);
2385 free(sc->sc_ccbs, M_DEVBUF);
2386
2387 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
2388 sc->sc_ih = NULL;
2389 }
2390 if (sc->sc_ios != 0) {
2391 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
2392 sc->sc_ios = 0;
2393 }
2394
2395 return (0);
2396 }
2397
2398 static int
2399 mpii_rescan(device_t self, const char *ifattr, const int *locators)
2400 {
2401 struct mpii_softc *sc = device_private(self);
2402
2403 if (sc->sc_child != NULL)
2404 return 0;
2405
2406 sc->sc_child = config_found_sm_loc(self, ifattr, locators, &sc->sc_chan,
2407 scsiprint, NULL);
2408
2409 return 0;
2410 }
2411
2412 static void
2413 mpii_childdetached(device_t self, device_t child)
2414 {
2415 struct mpii_softc *sc = device_private(self);
2416
2417 KASSERT(self == sc->sc_dev);
2418 KASSERT(child == sc->sc_child);
2419
2420 if (child == sc->sc_child)
2421 sc->sc_child = NULL;
2422 }
2423
2424 static int
2425 mpii_intr(void *arg)
2426 {
2427 struct mpii_rcb_list evts = SIMPLEQ_HEAD_INITIALIZER(evts);
2428 struct mpii_ccb_list ccbs = SIMPLEQ_HEAD_INITIALIZER(ccbs);
2429 struct mpii_softc *sc = arg;
2430 struct mpii_reply_descr *postq = sc->sc_reply_postq_kva, *rdp;
2431 struct mpii_ccb *ccb;
2432 struct mpii_rcb *rcb;
2433 int smid;
2434 int rv = 0;
2435
2436 mutex_enter(&sc->sc_rep_mtx);
2437 bus_dmamap_sync(sc->sc_dmat,
2438 MPII_DMA_MAP(sc->sc_reply_postq),
2439 0, 8 * sc->sc_reply_post_qdepth,
2440 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2441
2442 for (;;) {
2443 rdp = &postq[sc->sc_reply_post_host_index];
2444 if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
2445 MPII_REPLY_DESCR_UNUSED)
2446 break;
2447 if (rdp->data == 0xffffffff) {
2448 /*
2449 * ioc is still writing to the reply post queue
2450 * race condition - bail!
2451 */
2452 break;
2453 }
2454
2455 smid = le16toh(rdp->smid);
2456 rcb = mpii_reply(sc, rdp);
2457
2458 if (smid) {
2459 ccb = &sc->sc_ccbs[smid - 1];
2460 ccb->ccb_state = MPII_CCB_READY;
2461 ccb->ccb_rcb = rcb;
2462 SIMPLEQ_INSERT_TAIL(&ccbs, ccb, u.ccb_link);
2463 } else
2464 SIMPLEQ_INSERT_TAIL(&evts, rcb, u.rcb_link);
2465
2466 sc->sc_reply_post_host_index++;
2467 sc->sc_reply_post_host_index %= sc->sc_reply_post_qdepth;
2468 rv = 1;
2469 }
2470
2471 bus_dmamap_sync(sc->sc_dmat,
2472 MPII_DMA_MAP(sc->sc_reply_postq),
2473 0, 8 * sc->sc_reply_post_qdepth,
2474 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2475
2476 if (rv)
2477 mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
2478
2479 mutex_exit(&sc->sc_rep_mtx);
2480
2481 if (rv == 0)
2482 return (0);
2483
2484 while ((ccb = SIMPLEQ_FIRST(&ccbs)) != NULL) {
2485 SIMPLEQ_REMOVE_HEAD(&ccbs, u.ccb_link);
2486 ccb->ccb_done(ccb);
2487 }
2488 while ((rcb = SIMPLEQ_FIRST(&evts)) != NULL) {
2489 SIMPLEQ_REMOVE_HEAD(&evts, u.rcb_link);
2490 mpii_event_process(sc, rcb);
2491 }
2492
2493 return (1);
2494 }
2495
2496 static int
2497 mpii_load_xs(struct mpii_ccb *ccb)
2498 {
2499 struct mpii_softc *sc = ccb->ccb_sc;
2500 struct scsipi_xfer *xs = ccb->ccb_cookie;
2501 struct mpii_ccb_bundle *mcb = ccb->ccb_cmd;
2502 struct mpii_msg_scsi_io *io = &mcb->mcb_io;
2503 struct mpii_sge *sge = NULL, *nsge = &mcb->mcb_sgl[0];
2504 struct mpii_sge *ce = NULL, *nce = NULL;
2505 u_int64_t ce_dva;
2506 bus_dmamap_t dmap = ccb->ccb_dmamap;
2507 u_int32_t addr, flags;
2508 int i, error;
2509
2510 /* zero length transfer still requires an SGE */
2511 if (xs->datalen == 0) {
2512 nsge->sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
2513 MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
2514 return (0);
2515 }
2516
2517 error = bus_dmamap_load(sc->sc_dmat, dmap,
2518 xs->data, xs->datalen, NULL, (xs->xs_control & XS_CTL_NOSLEEP) ?
2519 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
2520 if (error) {
2521 aprint_error_dev(sc->sc_dev, "error %d loading dmamap\n",
2522 error);
2523 return (1);
2524 }
2525
2526 /* safe default staring flags */
2527 flags = MPII_SGE_FL_TYPE_SIMPLE | MPII_SGE_FL_SIZE_64;
2528 /* if data out */
2529 if (xs->xs_control & XS_CTL_DATA_OUT)
2530 flags |= MPII_SGE_FL_DIR_OUT;
2531
2532 /* we will have to exceed the SGEs we can cram into the request frame */
2533 if (dmap->dm_nsegs > sc->sc_first_sgl_len) {
2534 ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1];
2535 io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4;
2536 }
2537
2538 for (i = 0; i < dmap->dm_nsegs; i++) {
2539 if (nsge == ce) {
2540 nsge++;
2541 sge->sg_hdr |= htole32(MPII_SGE_FL_LAST);
2542
2543 DNPRINTF(MPII_D_DMA, "%s: - 0x%08x 0x%08x 0x%08x\n",
2544 DEVNAME(sc), sge->sg_hdr,
2545 sge->sg_hi_addr, sge->sg_lo_addr);
2546
2547 if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
2548 nce = &nsge[sc->sc_chain_len - 1];
2549 addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
2550 addr = addr << 16 |
2551 sizeof(struct mpii_sge) * sc->sc_chain_len;
2552 } else {
2553 nce = NULL;
2554 addr = sizeof(struct mpii_sge) *
2555 (dmap->dm_nsegs - i);
2556 }
2557
2558 ce->sg_hdr = htole32(MPII_SGE_FL_TYPE_CHAIN |
2559 MPII_SGE_FL_SIZE_64 | addr);
2560
2561 ce_dva = ccb->ccb_cmd_dva +
2562 ((u_int8_t *)nsge - (u_int8_t *)mcb);
2563
2564 addr = (u_int32_t)(ce_dva >> 32);
2565 ce->sg_hi_addr = htole32(addr);
2566 addr = (u_int32_t)ce_dva;
2567 ce->sg_lo_addr = htole32(addr);
2568
2569 DNPRINTF(MPII_D_DMA, "%s: ce: 0x%08x 0x%08x 0x%08x\n",
2570 DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr,
2571 ce->sg_lo_addr);
2572
2573 ce = nce;
2574 }
2575
2576 DNPRINTF(MPII_D_DMA, "%s: %d: %" PRId64 " 0x%016" PRIx64 "\n",
2577 DEVNAME(sc), i, (int64_t)dmap->dm_segs[i].ds_len,
2578 (u_int64_t)dmap->dm_segs[i].ds_addr);
2579
2580 sge = nsge;
2581
2582 sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len);
2583 addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32);
2584 sge->sg_hi_addr = htole32(addr);
2585 addr = (u_int32_t)dmap->dm_segs[i].ds_addr;
2586 sge->sg_lo_addr = htole32(addr);
2587
2588 DNPRINTF(MPII_D_DMA, "%s: %d: 0x%08x 0x%08x 0x%08x\n",
2589 DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr,
2590 sge->sg_lo_addr);
2591
2592 nsge = sge + 1;
2593 }
2594
2595 /* terminate list */
2596 sge->sg_hdr |= htole32(MPII_SGE_FL_LAST | MPII_SGE_FL_EOB |
2597 MPII_SGE_FL_EOL);
2598
2599 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
2600 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
2601 BUS_DMASYNC_PREWRITE);
2602
2603 return (0);
2604 }
2605
2606 static u_int32_t
2607 mpii_read(struct mpii_softc *sc, bus_size_t r)
2608 {
2609 u_int32_t rv;
2610
2611 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2612 BUS_SPACE_BARRIER_READ);
2613 rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
2614
2615 DNPRINTF(MPII_D_RW, "%s: mpii_read %#" PRIx64 " %#x\n", DEVNAME(sc),
2616 (uint64_t)r, rv);
2617
2618 return (rv);
2619 }
2620
2621 static void
2622 mpii_write(struct mpii_softc *sc, bus_size_t r, u_int32_t v)
2623 {
2624 DNPRINTF(MPII_D_RW, "%s: mpii_write %#" PRIx64 " %#x\n", DEVNAME(sc),
2625 (uint64_t)r, v);
2626
2627 bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
2628 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2629 BUS_SPACE_BARRIER_WRITE);
2630 }
2631
2632
2633 static int
2634 mpii_wait_eq(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
2635 u_int32_t target)
2636 {
2637 int i;
2638
2639 DNPRINTF(MPII_D_RW, "%s: mpii_wait_eq %#" PRIx64 " %#x %#x\n",
2640 DEVNAME(sc), (uint64_t)r, mask, target);
2641
2642 for (i = 0; i < 15000; i++) {
2643 if ((mpii_read(sc, r) & mask) == target)
2644 return (0);
2645 delay(1000);
2646 }
2647
2648 return (1);
2649 }
2650
2651 static int
2652 mpii_wait_ne(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
2653 u_int32_t target)
2654 {
2655 int i;
2656
2657 DNPRINTF(MPII_D_RW, "%s: mpii_wait_ne %#" PRIx64 " %#x %#x\n",
2658 DEVNAME(sc), (uint64_t)r, mask, target);
2659
2660 for (i = 0; i < 15000; i++) {
2661 if ((mpii_read(sc, r) & mask) != target)
2662 return (0);
2663 delay(1000);
2664 }
2665
2666 return (1);
2667 }
2668
2669
2670 static int
2671 mpii_init(struct mpii_softc *sc)
2672 {
2673 u_int32_t db;
2674 int i;
2675
2676 /* spin until the ioc leaves the reset state */
2677 if (mpii_wait_ne(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2678 MPII_DOORBELL_STATE_RESET) != 0) {
2679 DNPRINTF(MPII_D_MISC, "%s: mpii_init timeout waiting to leave "
2680 "reset state\n", DEVNAME(sc));
2681 return (1);
2682 }
2683
2684 /* check current ownership */
2685 db = mpii_read_db(sc);
2686 if ((db & MPII_DOORBELL_WHOINIT) == MPII_DOORBELL_WHOINIT_PCIPEER) {
2687 DNPRINTF(MPII_D_MISC, "%s: mpii_init initialised by pci peer\n",
2688 DEVNAME(sc));
2689 return (0);
2690 }
2691
2692 for (i = 0; i < 5; i++) {
2693 switch (db & MPII_DOORBELL_STATE) {
2694 case MPII_DOORBELL_STATE_READY:
2695 DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is ready\n",
2696 DEVNAME(sc));
2697 return (0);
2698
2699 case MPII_DOORBELL_STATE_OPER:
2700 DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is oper\n",
2701 DEVNAME(sc));
2702 if (sc->sc_ioc_event_replay)
2703 mpii_reset_soft(sc);
2704 else
2705 mpii_reset_hard(sc);
2706 break;
2707
2708 case MPII_DOORBELL_STATE_FAULT:
2709 DNPRINTF(MPII_D_MISC, "%s: mpii_init ioc is being "
2710 "reset hard\n" , DEVNAME(sc));
2711 mpii_reset_hard(sc);
2712 break;
2713
2714 case MPII_DOORBELL_STATE_RESET:
2715 DNPRINTF(MPII_D_MISC, "%s: mpii_init waiting to come "
2716 "out of reset\n", DEVNAME(sc));
2717 if (mpii_wait_ne(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2718 MPII_DOORBELL_STATE_RESET) != 0)
2719 return (1);
2720 break;
2721 }
2722 db = mpii_read_db(sc);
2723 }
2724
2725 return (1);
2726 }
2727
2728 static int
2729 mpii_reset_soft(struct mpii_softc *sc)
2730 {
2731 DNPRINTF(MPII_D_MISC, "%s: mpii_reset_soft\n", DEVNAME(sc));
2732
2733 if (mpii_read_db(sc) & MPII_DOORBELL_INUSE) {
2734 return (1);
2735 }
2736
2737 mpii_write_db(sc,
2738 MPII_DOORBELL_FUNCTION(MPII_FUNCTION_IOC_MESSAGE_UNIT_RESET));
2739
2740 /* XXX LSI waits 15 sec */
2741 if (mpii_wait_db_ack(sc) != 0)
2742 return (1);
2743
2744 /* XXX LSI waits 15 sec */
2745 if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_STATE,
2746 MPII_DOORBELL_STATE_READY) != 0)
2747 return (1);
2748
2749 /* XXX wait for Sys2IOCDB bit to clear in HIS?? */
2750
2751 return (0);
2752 }
2753
2754 static int
2755 mpii_reset_hard(struct mpii_softc *sc)
2756 {
2757 u_int16_t i;
2758
2759 DNPRINTF(MPII_D_MISC, "%s: mpii_reset_hard\n", DEVNAME(sc));
2760
2761 mpii_write_intr(sc, 0);
2762
2763 /* enable diagnostic register */
2764 mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_FLUSH);
2765 mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_1);
2766 mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_2);
2767 mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_3);
2768 mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_4);
2769 mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_5);
2770 mpii_write(sc, MPII_WRITESEQ, MPII_WRITESEQ_6);
2771
2772 delay(100);
2773
2774 if ((mpii_read(sc, MPII_HOSTDIAG) & MPII_HOSTDIAG_DWRE) == 0) {
2775 DNPRINTF(MPII_D_MISC, "%s: mpii_reset_hard failure to enable "
2776 "diagnostic read/write\n", DEVNAME(sc));
2777 return(1);
2778 }
2779
2780 /* reset ioc */
2781 mpii_write(sc, MPII_HOSTDIAG, MPII_HOSTDIAG_RESET_ADAPTER);
2782
2783 /* 240 milliseconds */
2784 delay(240000);
2785
2786
2787 /* XXX this whole function should be more robust */
2788
2789 /* XXX read the host diagnostic reg until reset adapter bit clears ? */
2790 for (i = 0; i < 30000; i++) {
2791 if ((mpii_read(sc, MPII_HOSTDIAG) &
2792 MPII_HOSTDIAG_RESET_ADAPTER) == 0)
2793 break;
2794 delay(10000);
2795 }
2796
2797 /* disable diagnostic register */
2798 mpii_write(sc, MPII_WRITESEQ, 0xff);
2799
2800 /* XXX what else? */
2801
2802 DNPRINTF(MPII_D_MISC, "%s: done with mpii_reset_hard\n", DEVNAME(sc));
2803
2804 return(0);
2805 }
2806
2807 static int
2808 mpii_handshake_send(struct mpii_softc *sc, void *buf, size_t dwords)
2809 {
2810 u_int32_t *query = buf;
2811 int i;
2812
2813 /* make sure the doorbell is not in use. */
2814 if (mpii_read_db(sc) & MPII_DOORBELL_INUSE)
2815 return (1);
2816
2817 /* clear pending doorbell interrupts */
2818 if (mpii_read_intr(sc) & MPII_INTR_STATUS_IOC2SYSDB)
2819 mpii_write_intr(sc, 0);
2820
2821 /*
2822 * first write the doorbell with the handshake function and the
2823 * dword count.
2824 */
2825 mpii_write_db(sc, MPII_DOORBELL_FUNCTION(MPII_FUNCTION_HANDSHAKE) |
2826 MPII_DOORBELL_DWORDS(dwords));
2827
2828 /*
2829 * the doorbell used bit will be set because a doorbell function has
2830 * started. wait for the interrupt and then ack it.
2831 */
2832 if (mpii_wait_db_int(sc) != 0)
2833 return (1);
2834 mpii_write_intr(sc, 0);
2835
2836 /* poll for the acknowledgement. */
2837 if (mpii_wait_db_ack(sc) != 0)
2838 return (1);
2839
2840 /* write the query through the doorbell. */
2841 for (i = 0; i < dwords; i++) {
2842 mpii_write_db(sc, htole32(query[i]));
2843 if (mpii_wait_db_ack(sc) != 0)
2844 return (1);
2845 }
2846
2847 return (0);
2848 }
2849
2850 static int
2851 mpii_handshake_recv_dword(struct mpii_softc *sc, u_int32_t *dword)
2852 {
2853 u_int16_t *words = (u_int16_t *)dword;
2854 int i;
2855
2856 for (i = 0; i < 2; i++) {
2857 if (mpii_wait_db_int(sc) != 0)
2858 return (1);
2859 words[i] = le16toh(mpii_read_db(sc) & MPII_DOORBELL_DATA_MASK);
2860 mpii_write_intr(sc, 0);
2861 }
2862
2863 return (0);
2864 }
2865
2866 static int
2867 mpii_handshake_recv(struct mpii_softc *sc, void *buf, size_t dwords)
2868 {
2869 struct mpii_msg_reply *reply = buf;
2870 u_int32_t *dbuf = buf, dummy;
2871 int i;
2872
2873 /* get the first dword so we can read the length out of the header. */
2874 if (mpii_handshake_recv_dword(sc, &dbuf[0]) != 0)
2875 return (1);
2876
2877 DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dwords: %zd reply: %d\n",
2878 DEVNAME(sc), dwords, reply->msg_length);
2879
2880 /*
2881 * the total length, in dwords, is in the message length field of the
2882 * reply header.
2883 */
2884 for (i = 1; i < MIN(dwords, reply->msg_length); i++) {
2885 if (mpii_handshake_recv_dword(sc, &dbuf[i]) != 0)
2886 return (1);
2887 }
2888
2889 /* if there's extra stuff to come off the ioc, discard it */
2890 while (i++ < reply->msg_length) {
2891 if (mpii_handshake_recv_dword(sc, &dummy) != 0)
2892 return (1);
2893 DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dummy read: "
2894 "0x%08x\n", DEVNAME(sc), dummy);
2895 }
2896
2897 /* wait for the doorbell used bit to be reset and clear the intr */
2898 if (mpii_wait_db_int(sc) != 0)
2899 return (1);
2900
2901 if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_INUSE, 0) != 0)
2902 return (1);
2903
2904 mpii_write_intr(sc, 0);
2905
2906 return (0);
2907 }
2908
2909 static void
2910 mpii_empty_done(struct mpii_ccb *ccb)
2911 {
2912 /* nothing to do */
2913 }
2914
2915 static int
2916 mpii_iocfacts(struct mpii_softc *sc)
2917 {
2918 struct mpii_msg_iocfacts_request ifq;
2919 struct mpii_msg_iocfacts_reply ifp;
2920
2921 DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts\n", DEVNAME(sc));
2922
2923 bzero(&ifq, sizeof(ifq));
2924 bzero(&ifp, sizeof(ifp));
2925
2926 ifq.function = MPII_FUNCTION_IOC_FACTS;
2927
2928 if (mpii_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) {
2929 DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts send failed\n",
2930 DEVNAME(sc));
2931 return (1);
2932 }
2933
2934 if (mpii_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) {
2935 DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts recv failed\n",
2936 DEVNAME(sc));
2937 return (1);
2938 }
2939
2940 DNPRINTF(MPII_D_MISC, "%s: func: 0x%02x length: %d msgver: %d.%d\n",
2941 DEVNAME(sc), ifp.function, ifp.msg_length,
2942 ifp.msg_version_maj, ifp.msg_version_min);
2943 DNPRINTF(MPII_D_MISC, "%s: msgflags: 0x%02x iocnumber: 0x%02x "
2944 "headerver: %d.%d\n", DEVNAME(sc), ifp.msg_flags,
2945 ifp.ioc_number, ifp.header_version_unit,
2946 ifp.header_version_dev);
2947 DNPRINTF(MPII_D_MISC, "%s: vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
2948 ifp.vp_id, ifp.vf_id);
2949 DNPRINTF(MPII_D_MISC, "%s: iocstatus: 0x%04x ioexceptions: 0x%04x\n",
2950 DEVNAME(sc), le16toh(ifp.ioc_status),
2951 le16toh(ifp.ioc_exceptions));
2952 DNPRINTF(MPII_D_MISC, "%s: iocloginfo: 0x%08x\n", DEVNAME(sc),
2953 le32toh(ifp.ioc_loginfo));
2954 DNPRINTF(MPII_D_MISC, "%s: numberofports: 0x%02x whoinit: 0x%02x "
2955 "maxchaindepth: %d\n", DEVNAME(sc), ifp.number_of_ports,
2956 ifp.whoinit, ifp.max_chain_depth);
2957 DNPRINTF(MPII_D_MISC, "%s: productid: 0x%04x requestcredit: 0x%04x\n",
2958 DEVNAME(sc), le16toh(ifp.product_id), le16toh(ifp.request_credit));
2959 DNPRINTF(MPII_D_MISC, "%s: ioc_capabilities: 0x%08x\n", DEVNAME(sc),
2960 le32toh(ifp.ioc_capabilities));
2961 DNPRINTF(MPII_D_MISC, "%s: fw_version: %d.%d fw_version_unit: 0x%02x "
2962 "fw_version_dev: 0x%02x\n", DEVNAME(sc),
2963 ifp.fw_version_maj, ifp.fw_version_min,
2964 ifp.fw_version_unit, ifp.fw_version_dev);
2965 DNPRINTF(MPII_D_MISC, "%s: iocrequestframesize: 0x%04x\n",
2966 DEVNAME(sc), le16toh(ifp.ioc_request_frame_size));
2967 DNPRINTF(MPII_D_MISC, "%s: maxtargets: 0x%04x "
2968 "maxinitiators: 0x%04x\n", DEVNAME(sc),
2969 le16toh(ifp.max_targets), le16toh(ifp.max_initiators));
2970 DNPRINTF(MPII_D_MISC, "%s: maxenclosures: 0x%04x "
2971 "maxsasexpanders: 0x%04x\n", DEVNAME(sc),
2972 le16toh(ifp.max_enclosures), le16toh(ifp.max_sas_expanders));
2973 DNPRINTF(MPII_D_MISC, "%s: highprioritycredit: 0x%04x "
2974 "protocolflags: 0x%02x\n", DEVNAME(sc),
2975 le16toh(ifp.high_priority_credit), le16toh(ifp.protocol_flags));
2976 DNPRINTF(MPII_D_MISC, "%s: maxvolumes: 0x%02x replyframesize: 0x%02x "
2977 "mrdpqd: 0x%04x\n", DEVNAME(sc), ifp.max_volumes,
2978 ifp.reply_frame_size,
2979 le16toh(ifp.max_reply_descriptor_post_queue_depth));
2980 DNPRINTF(MPII_D_MISC, "%s: maxpersistententries: 0x%04x "
2981 "maxdevhandle: 0x%02x\n", DEVNAME(sc),
2982 le16toh(ifp.max_persistent_entries), le16toh(ifp.max_dev_handle));
2983
2984 sc->sc_maxchdepth = ifp.max_chain_depth;
2985 sc->sc_ioc_number = ifp.ioc_number;
2986 sc->sc_vf_id = ifp.vf_id;
2987
2988 sc->sc_num_ports = ifp.number_of_ports;
2989 sc->sc_ioc_event_replay = (le32toh(ifp.ioc_capabilities) &
2990 MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY) ? 1 : 0;
2991 sc->sc_max_enclosures = le16toh(ifp.max_enclosures);
2992 sc->sc_max_expanders = le16toh(ifp.max_sas_expanders);
2993 sc->sc_max_volumes = ifp.max_volumes;
2994 sc->sc_max_devices = ifp.max_volumes + le16toh(ifp.max_targets);
2995 sc->sc_num_channels = 1;
2996
2997 if (ISSET(le32toh(ifp.ioc_capabilities),
2998 MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID))
2999 SET(sc->sc_flags, MPII_F_RAID);
3000
3001 sc->sc_request_depth = MIN(le16toh(ifp.request_credit),
3002 MPII_MAX_REQUEST_CREDIT);
3003
3004 /* should not be multiple of 16 */
3005 sc->sc_num_reply_frames = sc->sc_request_depth + 32;
3006 if (!(sc->sc_num_reply_frames % 16))
3007 sc->sc_num_reply_frames--;
3008
3009 /* must be multiple of 16 */
3010 sc->sc_reply_free_qdepth = sc->sc_num_reply_frames +
3011 (16 - (sc->sc_num_reply_frames % 16));
3012 sc->sc_reply_post_qdepth = ((sc->sc_request_depth +
3013 sc->sc_num_reply_frames + 1 + 15) / 16) * 16;
3014
3015 if (sc->sc_reply_post_qdepth >
3016 ifp.max_reply_descriptor_post_queue_depth)
3017 sc->sc_reply_post_qdepth =
3018 ifp.max_reply_descriptor_post_queue_depth;
3019
3020 DNPRINTF(MPII_D_MISC, "%s: sc_request_depth: %d "
3021 "sc_num_reply_frames: %d sc_reply_free_qdepth: %d "
3022 "sc_reply_post_qdepth: %d\n", DEVNAME(sc), sc->sc_request_depth,
3023 sc->sc_num_reply_frames, sc->sc_reply_free_qdepth,
3024 sc->sc_reply_post_qdepth);
3025
3026 /*
3027 * you can fit sg elements on the end of the io cmd if they fit in the
3028 * request frame size.
3029 */
3030
3031 sc->sc_first_sgl_len = ((le16toh(ifp.ioc_request_frame_size) * 4) -
3032 sizeof(struct mpii_msg_scsi_io)) / sizeof(struct mpii_sge);
3033 DNPRINTF(MPII_D_MISC, "%s: first sgl len: %d\n", DEVNAME(sc),
3034 sc->sc_first_sgl_len);
3035
3036 sc->sc_chain_len = (le16toh(ifp.ioc_request_frame_size) * 4) /
3037 sizeof(struct mpii_sge);
3038 DNPRINTF(MPII_D_MISC, "%s: chain len: %d\n", DEVNAME(sc),
3039 sc->sc_chain_len);
3040
3041 /* the sgl tailing the io cmd loses an entry to the chain element. */
3042 sc->sc_max_sgl_len = MPII_MAX_SGL - 1;
3043 /* the sgl chains lose an entry for each chain element */
3044 sc->sc_max_sgl_len -= (MPII_MAX_SGL - sc->sc_first_sgl_len) /
3045 sc->sc_chain_len;
3046 DNPRINTF(MPII_D_MISC, "%s: max sgl len: %d\n", DEVNAME(sc),
3047 sc->sc_max_sgl_len);
3048
3049 /* XXX we're ignoring the max chain depth */
3050
3051 return(0);
3052
3053 }
3054
3055 static int
3056 mpii_iocinit(struct mpii_softc *sc)
3057 {
3058 struct mpii_msg_iocinit_request iiq;
3059 struct mpii_msg_iocinit_reply iip;
3060 u_int32_t hi_addr;
3061
3062 DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit\n", DEVNAME(sc));
3063
3064 bzero(&iiq, sizeof(iiq));
3065 bzero(&iip, sizeof(iip));
3066
3067 iiq.function = MPII_FUNCTION_IOC_INIT;
3068 iiq.whoinit = MPII_WHOINIT_HOST_DRIVER;
3069
3070 /* XXX JPG do something about vf_id */
3071 iiq.vf_id = 0;
3072
3073 iiq.msg_version_maj = 0x02;
3074 iiq.msg_version_min = 0x00;
3075
3076 /* XXX JPG ensure compliance with some level and hard-code? */
3077 iiq.hdr_version_unit = 0x00;
3078 iiq.hdr_version_dev = 0x00;
3079
3080 iiq.system_request_frame_size = htole16(MPII_REQUEST_SIZE / 4);
3081
3082 iiq.reply_descriptor_post_queue_depth =
3083 htole16(sc->sc_reply_post_qdepth);
3084
3085 iiq.reply_free_queue_depth = htole16(sc->sc_reply_free_qdepth);
3086
3087 hi_addr = (u_int32_t)((u_int64_t)MPII_DMA_DVA(sc->sc_requests) >> 32);
3088 iiq.sense_buffer_address_high = htole32(hi_addr);
3089
3090 hi_addr = (u_int32_t)
3091 ((u_int64_t)MPII_DMA_DVA(sc->sc_replies) >> 32);
3092 iiq.system_reply_address_high = htole32(hi_addr);
3093
3094 iiq.system_request_frame_base_address =
3095 (u_int64_t)MPII_DMA_DVA(sc->sc_requests);
3096
3097 iiq.reply_descriptor_post_queue_address =
3098 (u_int64_t)MPII_DMA_DVA(sc->sc_reply_postq);
3099
3100 iiq.reply_free_queue_address =
3101 (u_int64_t)MPII_DMA_DVA(sc->sc_reply_freeq);
3102
3103 if (mpii_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) {
3104 DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit send failed\n",
3105 DEVNAME(sc));
3106 return (1);
3107 }
3108
3109 if (mpii_handshake_recv(sc, &iip, dwordsof(iip)) != 0) {
3110 DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit recv failed\n",
3111 DEVNAME(sc));
3112 return (1);
3113 }
3114
3115 DNPRINTF(MPII_D_MISC, "%s: function: 0x%02x msg_length: %d "
3116 "whoinit: 0x%02x\n", DEVNAME(sc), iip.function,
3117 iip.msg_length, iip.whoinit);
3118 DNPRINTF(MPII_D_MISC, "%s: msg_flags: 0x%02x\n", DEVNAME(sc),
3119 iip.msg_flags);
3120 DNPRINTF(MPII_D_MISC, "%s: vf_id: 0x%02x vp_id: 0x%02x\n", DEVNAME(sc),
3121 iip.vf_id, iip.vp_id);
3122 DNPRINTF(MPII_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc),
3123 le16toh(iip.ioc_status));
3124 DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3125 le32toh(iip.ioc_loginfo));
3126
3127 if ((iip.ioc_status != MPII_IOCSTATUS_SUCCESS) || (iip.ioc_loginfo))
3128 return (1);
3129
3130 return (0);
3131 }
3132
3133 static void
3134 mpii_push_reply(struct mpii_softc *sc, struct mpii_rcb *rcb)
3135 {
3136 u_int32_t *rfp;
3137
3138 if (rcb == NULL)
3139 return;
3140
3141 rfp = MPII_DMA_KVA(sc->sc_reply_freeq);
3142 rfp[sc->sc_reply_free_host_index] = rcb->rcb_reply_dva;
3143
3144 sc->sc_reply_free_host_index = (sc->sc_reply_free_host_index + 1) %
3145 sc->sc_reply_free_qdepth;
3146
3147 mpii_write_reply_free(sc, sc->sc_reply_free_host_index);
3148 }
3149
3150 static int
3151 mpii_portfacts(struct mpii_softc *sc)
3152 {
3153 struct mpii_msg_portfacts_request *pfq;
3154 struct mpii_msg_portfacts_reply *pfp;
3155 struct mpii_ccb *ccb;
3156 int rv = 1;
3157
3158 DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts\n", DEVNAME(sc));
3159
3160 ccb = mpii_get_ccb(sc, 0);
3161 if (ccb == NULL) {
3162 DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts mpii_get_ccb fail\n",
3163 DEVNAME(sc));
3164 return (rv);
3165 }
3166
3167 ccb->ccb_done = mpii_empty_done;
3168 pfq = ccb->ccb_cmd;
3169
3170 bzero(pfq, sizeof(*pfq));
3171
3172 pfq->function = MPII_FUNCTION_PORT_FACTS;
3173 pfq->chain_offset = 0;
3174 pfq->msg_flags = 0;
3175 pfq->port_number = 0;
3176 pfq->vp_id = 0;
3177 pfq->vf_id = 0;
3178
3179 if (mpii_poll(sc, ccb) != 0) {
3180 DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts poll\n",
3181 DEVNAME(sc));
3182 goto err;
3183 }
3184
3185 if (ccb->ccb_rcb == NULL) {
3186 DNPRINTF(MPII_D_MISC, "%s: empty portfacts reply\n",
3187 DEVNAME(sc));
3188 goto err;
3189 }
3190
3191 pfp = ccb->ccb_rcb->rcb_reply;
3192 DNPRINTF(MPII_D_MISC, "%s pfp: %p\n", DEVNAME(sc), pfp);
3193
3194 DNPRINTF(MPII_D_MISC, "%s: function: 0x%02x msg_length: %d\n",
3195 DEVNAME(sc), pfp->function, pfp->msg_length);
3196 DNPRINTF(MPII_D_MISC, "%s: msg_flags: 0x%02x port_number: %d\n",
3197 DEVNAME(sc), pfp->msg_flags, pfp->port_number);
3198 DNPRINTF(MPII_D_MISC, "%s: vf_id: 0x%02x vp_id: 0x%02x\n",
3199 DEVNAME(sc), pfp->vf_id, pfp->vp_id);
3200 DNPRINTF(MPII_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc),
3201 le16toh(pfp->ioc_status));
3202 DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3203 le32toh(pfp->ioc_loginfo));
3204 DNPRINTF(MPII_D_MISC, "%s: port_type: 0x%02x\n", DEVNAME(sc),
3205 pfp->port_type);
3206 DNPRINTF(MPII_D_MISC, "%s: max_posted_cmd_buffers: %d\n", DEVNAME(sc),
3207 le16toh(pfp->max_posted_cmd_buffers));
3208
3209 sc->sc_porttype = pfp->port_type;
3210
3211 mpii_push_reply(sc, ccb->ccb_rcb);
3212 rv = 0;
3213 err:
3214 mpii_put_ccb(sc, ccb);
3215
3216 return (rv);
3217 }
3218
3219 static void
3220 mpii_eventack(struct work *wk, void *cookie)
3221 {
3222 struct mpii_softc *sc = cookie;
3223 struct mpii_ccb *ccb;
3224 struct mpii_rcb *rcb = (void *)wk;
3225 struct mpii_msg_event_reply *enp;
3226 struct mpii_msg_eventack_request *eaq;
3227
3228 ccb = mpii_get_ccb(sc, 0);
3229
3230 enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
3231
3232 ccb->ccb_done = mpii_eventack_done;
3233 eaq = ccb->ccb_cmd;
3234
3235 eaq->function = MPII_FUNCTION_EVENT_ACK;
3236
3237 eaq->event = enp->event;
3238 eaq->event_context = enp->event_context;
3239
3240 mpii_push_reply(sc, rcb);
3241
3242 mpii_start(sc, ccb);
3243
3244 }
3245
3246 static void
3247 mpii_eventack_done(struct mpii_ccb *ccb)
3248 {
3249 struct mpii_softc *sc = ccb->ccb_sc;
3250
3251 DNPRINTF(MPII_D_EVT, "%s: event ack done\n", DEVNAME(sc));
3252
3253 mpii_push_reply(sc, ccb->ccb_rcb);
3254 mpii_put_ccb(sc, ccb);
3255 }
3256
3257 static int
3258 mpii_portenable(struct mpii_softc *sc)
3259 {
3260 struct mpii_msg_portenable_request *peq;
3261 struct mpii_msg_portenable_repy *pep;
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 pep = ccb->ccb_rcb->rcb_reply;
3291
3292 mpii_push_reply(sc, ccb->ccb_rcb);
3293 mpii_put_ccb(sc, ccb);
3294
3295 return (0);
3296 }
3297
3298 static int
3299 mpii_cfg_coalescing(struct mpii_softc *sc)
3300 {
3301 struct mpii_cfg_hdr hdr;
3302 struct mpii_cfg_ioc_pg1 pg;
3303
3304 if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 1, 0,
3305 &hdr) != 0) {
3306 DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1 "
3307 "header\n", DEVNAME(sc));
3308 return (1);
3309 }
3310
3311 if (mpii_cfg_page(sc, 0, &hdr, 1, &pg, sizeof(pg)) != 0) {
3312 DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1\n"
3313 "page 1\n", DEVNAME(sc));
3314 return (1);
3315 }
3316
3317 DNPRINTF(MPII_D_MISC, "%s: IOC page 1\n", DEVNAME(sc));
3318 DNPRINTF(MPII_D_MISC, "%s: flags: 0x08%x\n", DEVNAME(sc),
3319 le32toh(pg.flags));
3320 DNPRINTF(MPII_D_MISC, "%s: coalescing_timeout: %d\n", DEVNAME(sc),
3321 le32toh(pg.coalescing_timeout));
3322 DNPRINTF(MPII_D_MISC, "%s: coalescing_depth: %d pci_slot_num: %d\n",
3323 DEVNAME(sc), pg.coalescing_timeout, pg.pci_slot_num);
3324
3325 if (!ISSET(le32toh(pg.flags), MPII_CFG_IOC_1_REPLY_COALESCING))
3326 return (0);
3327
3328 CLR(pg.flags, htole32(MPII_CFG_IOC_1_REPLY_COALESCING));
3329 if (mpii_cfg_page(sc, 0, &hdr, 0, &pg, sizeof(pg)) != 0) {
3330 DNPRINTF(MPII_D_MISC, "%s: unable to clear coalescing\n",
3331 DEVNAME(sc));
3332 return (1);
3333 }
3334
3335 return (0);
3336 }
3337
3338 #define MPII_EVENT_MASKALL(enq) do { \
3339 enq->event_masks[0] = 0xffffffff; \
3340 enq->event_masks[1] = 0xffffffff; \
3341 enq->event_masks[2] = 0xffffffff; \
3342 enq->event_masks[3] = 0xffffffff; \
3343 } while (0)
3344
3345 #define MPII_EVENT_UNMASK(enq, evt) do { \
3346 enq->event_masks[evt / 32] &= \
3347 htole32(~(1 << (evt % 32))); \
3348 } while (0)
3349
3350 static int
3351 mpii_eventnotify(struct mpii_softc *sc)
3352 {
3353 struct mpii_msg_event_request *enq;
3354 struct mpii_ccb *ccb;
3355
3356 ccb = mpii_get_ccb(sc, 0);
3357 if (ccb == NULL) {
3358 DNPRINTF(MPII_D_MISC, "%s: mpii_eventnotify ccb_get\n",
3359 DEVNAME(sc));
3360 return (1);
3361 }
3362
3363 ccb->ccb_done = mpii_eventnotify_done;
3364 enq = ccb->ccb_cmd;
3365
3366 enq->function = MPII_FUNCTION_EVENT_NOTIFICATION;
3367
3368 /*
3369 * Enable reporting of the following events:
3370 *
3371 * MPII_EVENT_SAS_DISCOVERY
3372 * MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST
3373 * MPII_EVENT_SAS_DEVICE_STATUS_CHANGE
3374 * MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE
3375 * MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST
3376 * MPII_EVENT_IR_VOLUME
3377 * MPII_EVENT_IR_PHYSICAL_DISK
3378 * MPII_EVENT_IR_OPERATION_STATUS
3379 */
3380
3381 MPII_EVENT_MASKALL(enq);
3382 MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_DISCOVERY);
3383 MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
3384 MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_DEVICE_STATUS_CHANGE);
3385 MPII_EVENT_UNMASK(enq, MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE);
3386 MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST);
3387 MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_VOLUME);
3388 MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_PHYSICAL_DISK);
3389 MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_OPERATION_STATUS);
3390
3391 mpii_start(sc, ccb);
3392
3393 return (0);
3394 }
3395
3396 static void
3397 mpii_eventnotify_done(struct mpii_ccb *ccb)
3398 {
3399 struct mpii_softc *sc = ccb->ccb_sc;
3400 struct mpii_rcb *rcb = ccb->ccb_rcb;
3401
3402 DNPRINTF(MPII_D_EVT, "%s: mpii_eventnotify_done\n", DEVNAME(sc));
3403
3404 mpii_put_ccb(sc, ccb);
3405 mpii_event_process(sc, rcb);
3406 }
3407
3408 static void
3409 mpii_event_raid(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
3410 {
3411 struct mpii_evt_ir_cfg_change_list *ccl;
3412 struct mpii_evt_ir_cfg_element *ce;
3413 struct mpii_device *dev;
3414 u_int16_t type;
3415 int i;
3416
3417 ccl = (struct mpii_evt_ir_cfg_change_list *)(enp + 1);
3418
3419 if (ccl->num_elements == 0)
3420 return;
3421 if (ISSET(le32toh(ccl->flags), MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN))
3422 /* bail on foreign configurations */
3423 return;
3424
3425 ce = (struct mpii_evt_ir_cfg_element *)(ccl + 1);
3426
3427 for (i = 0; i < ccl->num_elements; i++, ce++) {
3428 type = (le16toh(ce->element_flags) &
3429 MPII_EVT_IR_CFG_ELEMENT_TYPE_MASK);
3430
3431 switch (type) {
3432 case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME:
3433 switch (ce->reason_code) {
3434 case MPII_EVT_IR_CFG_ELEMENT_RC_ADDED:
3435 case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_CREATED:
3436 if (mpii_find_dev(sc,
3437 le16toh(ce->vol_dev_handle))) {
3438 printf("%s: device %#x is already "
3439 "configured\n", DEVNAME(sc),
3440 le16toh(ce->vol_dev_handle));
3441 break;
3442 }
3443 dev = malloc(sizeof(*dev), M_DEVBUF,
3444 M_NOWAIT | M_ZERO);
3445 if (!dev) {
3446 printf("%s: failed to allocate a "
3447 "device structure\n", DEVNAME(sc));
3448 break;
3449 }
3450 SET(dev->flags, MPII_DF_VOLUME);
3451 dev->slot = sc->sc_vd_id_low;
3452 dev->dev_handle = le16toh(ce->vol_dev_handle);
3453 if (mpii_insert_dev(sc, dev)) {
3454 free(dev, M_DEVBUF);
3455 break;
3456 }
3457 mpii_cache_enable(sc, dev);
3458 sc->sc_vd_count++;
3459 break;
3460 case MPII_EVT_IR_CFG_ELEMENT_RC_REMOVED:
3461 case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_DELETED:
3462 if (!(dev = mpii_find_dev(sc,
3463 le16toh(ce->vol_dev_handle))))
3464 break;
3465 mpii_remove_dev(sc, dev);
3466 sc->sc_vd_count--;
3467 break;
3468 }
3469 break;
3470 case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME_DISK:
3471 if (ce->reason_code ==
3472 MPII_EVT_IR_CFG_ELEMENT_RC_PD_CREATED ||
3473 ce->reason_code ==
3474 MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
3475 /* there should be an underlying sas drive */
3476 if (!(dev = mpii_find_dev(sc,
3477 le16toh(ce->phys_disk_dev_handle))))
3478 break;
3479 /* promoted from a hot spare? */
3480 CLR(dev->flags, MPII_DF_HOT_SPARE);
3481 SET(dev->flags, MPII_DF_VOLUME_DISK |
3482 MPII_DF_HIDDEN);
3483 }
3484 break;
3485 case MPII_EVT_IR_CFG_ELEMENT_TYPE_HOT_SPARE:
3486 if (ce->reason_code ==
3487 MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
3488 /* there should be an underlying sas drive */
3489 if (!(dev = mpii_find_dev(sc,
3490 le16toh(ce->phys_disk_dev_handle))))
3491 break;
3492 SET(dev->flags, MPII_DF_HOT_SPARE |
3493 MPII_DF_HIDDEN);
3494 }
3495 break;
3496 }
3497 }
3498 }
3499
3500 static void
3501 mpii_event_sas(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
3502 {
3503 struct mpii_evt_sas_tcl *tcl;
3504 struct mpii_evt_phy_entry *pe;
3505 struct mpii_device *dev;
3506 int i;
3507
3508 tcl = (struct mpii_evt_sas_tcl *)(enp + 1);
3509
3510 if (tcl->num_entries == 0)
3511 return;
3512
3513 pe = (struct mpii_evt_phy_entry *)(tcl + 1);
3514
3515 for (i = 0; i < tcl->num_entries; i++, pe++) {
3516 switch (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK) {
3517 case MPII_EVENT_SAS_TOPO_PS_RC_ADDED:
3518 if (mpii_find_dev(sc, le16toh(pe->dev_handle))) {
3519 printf("%s: device %#x is already "
3520 "configured\n", DEVNAME(sc),
3521 le16toh(pe->dev_handle));
3522 break;
3523 }
3524 dev = malloc(sizeof(*dev), M_DEVBUF, M_NOWAIT | M_ZERO);
3525 if (!dev) {
3526 printf("%s: failed to allocate a "
3527 "device structure\n", DEVNAME(sc));
3528 break;
3529 }
3530 dev->slot = sc->sc_pd_id_start + tcl->start_phy_num + i;
3531 dev->dev_handle = le16toh(pe->dev_handle);
3532 dev->phy_num = tcl->start_phy_num + i;
3533 if (tcl->enclosure_handle)
3534 dev->physical_port = tcl->physical_port;
3535 dev->enclosure = le16toh(tcl->enclosure_handle);
3536 dev->expander = le16toh(tcl->expander_handle);
3537 if (mpii_insert_dev(sc, dev)) {
3538 free(dev, M_DEVBUF);
3539 break;
3540 }
3541 break;
3542 case MPII_EVENT_SAS_TOPO_PS_RC_MISSING:
3543 if (!(dev = mpii_find_dev(sc,
3544 le16toh(pe->dev_handle))))
3545 break;
3546 mpii_remove_dev(sc, dev);
3547 #if 0
3548 if (sc->sc_scsibus) {
3549 SET(dev->flags, MPII_DF_DETACH);
3550 scsi_activate(sc->sc_scsibus, dev->slot, -1,
3551 DVACT_DEACTIVATE);
3552 if (scsi_task(mpii_event_defer, sc,
3553 dev, 0) != 0)
3554 printf("%s: unable to run device "
3555 "detachment routine\n",
3556 DEVNAME(sc));
3557 }
3558 #else
3559 mpii_event_defer(sc, dev);
3560 #endif /* XXX */
3561 break;
3562 }
3563 }
3564 }
3565
3566 static void
3567 mpii_event_process(struct mpii_softc *sc, struct mpii_rcb *rcb)
3568 {
3569 struct mpii_msg_event_reply *enp;
3570
3571 enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
3572
3573 DNPRINTF(MPII_D_EVT, "%s: mpii_event_process: %#x\n", DEVNAME(sc),
3574 le32toh(enp->event));
3575
3576 switch (le32toh(enp->event)) {
3577 case MPII_EVENT_EVENT_CHANGE:
3578 /* should be properly ignored */
3579 break;
3580 case MPII_EVENT_SAS_DISCOVERY: {
3581 struct mpii_evt_sas_discovery *esd =
3582 (struct mpii_evt_sas_discovery *)(enp + 1);
3583
3584 if (esd->reason_code ==
3585 MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED &&
3586 esd->discovery_status != 0)
3587 printf("%s: sas discovery completed with status %#x\n",
3588 DEVNAME(sc), esd->discovery_status);
3589 }
3590 break;
3591 case MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
3592 mpii_event_sas(sc, enp);
3593 break;
3594 case MPII_EVENT_SAS_DEVICE_STATUS_CHANGE:
3595 break;
3596 case MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
3597 break;
3598 case MPII_EVENT_IR_VOLUME: {
3599 struct mpii_evt_ir_volume *evd =
3600 (struct mpii_evt_ir_volume *)(enp + 1);
3601 struct mpii_device *dev;
3602 #if NBIO > 0
3603 const char *vol_states[] = {
3604 BIOC_SVINVALID_S,
3605 BIOC_SVOFFLINE_S,
3606 BIOC_SVBUILDING_S,
3607 BIOC_SVONLINE_S,
3608 BIOC_SVDEGRADED_S,
3609 BIOC_SVONLINE_S,
3610 };
3611 #endif
3612
3613 if (cold)
3614 break;
3615 if (!(dev = mpii_find_dev(sc, le16toh(evd->vol_dev_handle))))
3616 break;
3617 #if NBIO > 0
3618 if (evd->reason_code == MPII_EVENT_IR_VOL_RC_STATE_CHANGED)
3619 printf("%s: volume %d state changed from %s to %s\n",
3620 DEVNAME(sc), dev->slot - sc->sc_vd_id_low,
3621 vol_states[evd->prev_value],
3622 vol_states[evd->new_value]);
3623 #endif
3624 if (evd->reason_code == MPII_EVENT_IR_VOL_RC_STATUS_CHANGED &&
3625 ISSET(evd->new_value, MPII_CFG_RAID_VOL_0_STATUS_RESYNC) &&
3626 !ISSET(evd->prev_value, MPII_CFG_RAID_VOL_0_STATUS_RESYNC))
3627 printf("%s: started resync on a volume %d\n",
3628 DEVNAME(sc), dev->slot - sc->sc_vd_id_low);
3629 }
3630 break;
3631 case MPII_EVENT_IR_PHYSICAL_DISK:
3632 break;
3633 case MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST:
3634 mpii_event_raid(sc, enp);
3635 break;
3636 case MPII_EVENT_IR_OPERATION_STATUS: {
3637 struct mpii_evt_ir_status *evs =
3638 (struct mpii_evt_ir_status *)(enp + 1);
3639 struct mpii_device *dev;
3640
3641 if (!(dev = mpii_find_dev(sc, le16toh(evs->vol_dev_handle))))
3642 break;
3643 if (evs->operation == MPII_EVENT_IR_RAIDOP_RESYNC)
3644 dev->percent = evs->percent;
3645 break;
3646 }
3647 default:
3648 DNPRINTF(MPII_D_EVT, "%s: unhandled event 0x%02x\n",
3649 DEVNAME(sc), le32toh(enp->event));
3650 }
3651
3652 if (enp->ack_required)
3653 workqueue_enqueue(sc->sc_ssb_evt_ackwk, &rcb->u.rcb_wk, NULL);
3654 else
3655 mpii_push_reply(sc, rcb);
3656 }
3657
3658 static void
3659 mpii_event_defer(void *xsc, void *arg)
3660 {
3661 struct mpii_softc *sc = xsc;
3662 struct mpii_device *dev = arg;
3663
3664 if (ISSET(dev->flags, MPII_DF_DETACH)) {
3665 mpii_sas_remove_device(sc, dev->dev_handle);
3666 #if 0
3667 if (!ISSET(dev->flags, MPII_DF_HIDDEN)) {
3668 scsi_detach_target(sc->sc_scsibus, dev->slot,
3669 DETACH_FORCE);
3670 }
3671 #endif /* XXX */
3672 free(dev, M_DEVBUF);
3673
3674 } else if (ISSET(dev->flags, MPII_DF_ATTACH)) {
3675 CLR(dev->flags, MPII_DF_ATTACH);
3676 #if 0
3677 if (!ISSET(dev->flags, MPII_DF_HIDDEN))
3678 scsi_probe_target(sc->sc_scsibus, dev->slot);
3679 #endif /* XXX */
3680 }
3681 }
3682
3683 static void
3684 mpii_sas_remove_device(struct mpii_softc *sc, u_int16_t handle)
3685 {
3686 struct mpii_msg_scsi_task_request *stq;
3687 struct mpii_msg_sas_oper_request *soq;
3688 struct mpii_ccb *ccb;
3689
3690 ccb = mpii_get_ccb(sc, 0);
3691 if (ccb == NULL)
3692 return;
3693
3694 stq = ccb->ccb_cmd;
3695 stq->function = MPII_FUNCTION_SCSI_TASK_MGMT;
3696 stq->task_type = MPII_SCSI_TASK_TARGET_RESET;
3697 stq->dev_handle = htole16(handle);
3698
3699 ccb->ccb_done = mpii_empty_done;
3700 mpii_wait(sc, ccb);
3701
3702 if (ccb->ccb_rcb != NULL)
3703 mpii_push_reply(sc, ccb->ccb_rcb);
3704
3705 /* reuse a ccb */
3706 ccb->ccb_state = MPII_CCB_READY;
3707 ccb->ccb_rcb = NULL;
3708
3709 soq = ccb->ccb_cmd;
3710 bzero(soq, sizeof(*soq));
3711 soq->function = MPII_FUNCTION_SAS_IO_UNIT_CONTROL;
3712 soq->operation = MPII_SAS_OP_REMOVE_DEVICE;
3713 soq->dev_handle = htole16(handle);
3714
3715 ccb->ccb_done = mpii_empty_done;
3716 mpii_wait(sc, ccb);
3717 if (ccb->ccb_rcb != NULL)
3718 mpii_push_reply(sc, ccb->ccb_rcb);
3719 }
3720
3721 static int
3722 mpii_get_ioc_pg8(struct mpii_softc *sc)
3723 {
3724 struct mpii_cfg_hdr hdr;
3725 struct mpii_cfg_ioc_pg8 *page;
3726 size_t pagelen;
3727 u_int16_t flags;
3728 int pad = 0, rv = 0;
3729
3730 DNPRINTF(MPII_D_RAID, "%s: mpii_get_ioc_pg8\n", DEVNAME(sc));
3731
3732 if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 8, 0,
3733 &hdr) != 0) {
3734 DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to fetch "
3735 "header for IOC page 8\n", DEVNAME(sc));
3736 return (1);
3737 }
3738
3739 pagelen = hdr.page_length * 4; /* dwords to bytes */
3740
3741 page = malloc(pagelen, M_TEMP, M_NOWAIT);
3742 if (page == NULL) {
3743 DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to allocate "
3744 "space for ioc config page 8\n", DEVNAME(sc));
3745 return (1);
3746 }
3747
3748 if (mpii_cfg_page(sc, 0, &hdr, 1, page, pagelen) != 0) {
3749 DNPRINTF(MPII_D_CFG, "%s: mpii_get_raid unable to fetch IOC "
3750 "page 8\n", DEVNAME(sc));
3751 rv = 1;
3752 goto out;
3753 }
3754
3755 DNPRINTF(MPII_D_CFG, "%s: numdevsperenclosure: 0x%02x\n", DEVNAME(sc),
3756 page->num_devs_per_enclosure);
3757 DNPRINTF(MPII_D_CFG, "%s: maxpersistententries: 0x%04x "
3758 "maxnumphysicalmappedids: 0x%04x\n", DEVNAME(sc),
3759 le16toh(page->max_persistent_entries),
3760 le16toh(page->max_num_physical_mapped_ids));
3761 DNPRINTF(MPII_D_CFG, "%s: flags: 0x%04x\n", DEVNAME(sc),
3762 le16toh(page->flags));
3763 DNPRINTF(MPII_D_CFG, "%s: irvolumemappingflags: 0x%04x\n",
3764 DEVNAME(sc), le16toh(page->ir_volume_mapping_flags));
3765
3766 if (page->flags & MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0)
3767 pad = 1;
3768
3769 flags = page->ir_volume_mapping_flags &
3770 MPII_IOC_PG8_IRFLAGS_VOLUME_MAPPING_MODE_MASK;
3771 if (ISSET(sc->sc_flags, MPII_F_RAID)) {
3772 if (flags == MPII_IOC_PG8_IRFLAGS_LOW_VOLUME_MAPPING) {
3773 sc->sc_vd_id_low += pad;
3774 pad = sc->sc_max_volumes; /* for sc_pd_id_start */
3775 } else
3776 sc->sc_vd_id_low = sc->sc_max_devices -
3777 sc->sc_max_volumes;
3778 }
3779
3780 sc->sc_pd_id_start += pad;
3781
3782 DNPRINTF(MPII_D_MAP, "%s: mpii_get_ioc_pg8 mapping: sc_pd_id_start: %d "
3783 "sc_vd_id_low: %d sc_max_volumes: %d\n", DEVNAME(sc),
3784 sc->sc_pd_id_start, sc->sc_vd_id_low, sc->sc_max_volumes);
3785
3786 out:
3787 free(page, M_TEMP);
3788
3789 return(rv);
3790 }
3791
3792 static int
3793 mpii_req_cfg_header(struct mpii_softc *sc, u_int8_t type, u_int8_t number,
3794 u_int32_t address, int flags, void *p)
3795 {
3796 struct mpii_msg_config_request *cq;
3797 struct mpii_msg_config_reply *cp;
3798 struct mpii_cfg_hdr *hdr = p;
3799 struct mpii_ccb *ccb;
3800 struct mpii_ecfg_hdr *ehdr = p;
3801 int etype = 0;
3802 int rv = 0;
3803
3804 DNPRINTF(MPII_D_MISC, "%s: mpii_req_cfg_header type: %#x number: %x "
3805 "address: 0x%08x flags: 0x%x\n", DEVNAME(sc), type, number,
3806 address, flags);
3807
3808 ccb = mpii_get_ccb(sc, ISSET(flags, MPII_PG_POLL) ? MPII_NOSLEEP : 0);
3809 if (ccb == NULL) {
3810 DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header ccb_get\n",
3811 DEVNAME(sc));
3812 return (1);
3813 }
3814
3815 if (ISSET(flags, MPII_PG_EXTENDED)) {
3816 etype = type;
3817 type = MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED;
3818 }
3819
3820 cq = ccb->ccb_cmd;
3821
3822 cq->function = MPII_FUNCTION_CONFIG;
3823
3824 cq->action = MPII_CONFIG_REQ_ACTION_PAGE_HEADER;
3825
3826 cq->config_header.page_number = number;
3827 cq->config_header.page_type = type;
3828 cq->ext_page_type = etype;
3829 cq->page_address = htole32(address);
3830 cq->page_buffer.sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
3831 MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
3832
3833 ccb->ccb_done = mpii_empty_done;
3834 if (ISSET(flags, MPII_PG_POLL)) {
3835 if (mpii_poll(sc, ccb) != 0) {
3836 DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header poll\n",
3837 DEVNAME(sc));
3838 return (1);
3839 }
3840 } else
3841 mpii_wait(sc, ccb);
3842
3843 if (ccb->ccb_rcb == NULL) {
3844 mpii_put_ccb(sc, ccb);
3845 return (1);
3846 }
3847 cp = ccb->ccb_rcb->rcb_reply;
3848
3849 DNPRINTF(MPII_D_MISC, "%s: action: 0x%02x sgl_flags: 0x%02x "
3850 "msg_length: %d function: 0x%02x\n", DEVNAME(sc), cp->action,
3851 cp->sgl_flags, cp->msg_length, cp->function);
3852 DNPRINTF(MPII_D_MISC, "%s: ext_page_length: %d ext_page_type: 0x%02x "
3853 "msg_flags: 0x%02x\n", DEVNAME(sc),
3854 le16toh(cp->ext_page_length), cp->ext_page_type,
3855 cp->msg_flags);
3856 DNPRINTF(MPII_D_MISC, "%s: vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
3857 cp->vp_id, cp->vf_id);
3858 DNPRINTF(MPII_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc),
3859 le16toh(cp->ioc_status));
3860 DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3861 le32toh(cp->ioc_loginfo));
3862 DNPRINTF(MPII_D_MISC, "%s: page_version: 0x%02x page_length: %d "
3863 "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
3864 cp->config_header.page_version,
3865 cp->config_header.page_length,
3866 cp->config_header.page_number,
3867 cp->config_header.page_type);
3868
3869 if (le16toh(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
3870 rv = 1;
3871 else if (ISSET(flags, MPII_PG_EXTENDED)) {
3872 bzero(ehdr, sizeof(*ehdr));
3873 ehdr->page_version = cp->config_header.page_version;
3874 ehdr->page_number = cp->config_header.page_number;
3875 ehdr->page_type = cp->config_header.page_type;
3876 ehdr->ext_page_length = cp->ext_page_length;
3877 ehdr->ext_page_type = cp->ext_page_type;
3878 } else
3879 *hdr = cp->config_header;
3880
3881 mpii_push_reply(sc, ccb->ccb_rcb);
3882 mpii_put_ccb(sc, ccb);
3883
3884 return (rv);
3885 }
3886
3887 static int
3888 mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int flags,
3889 void *p, int read, void *page, size_t len)
3890 {
3891 struct mpii_msg_config_request *cq;
3892 struct mpii_msg_config_reply *cp;
3893 struct mpii_cfg_hdr *hdr = p;
3894 struct mpii_ccb *ccb;
3895 struct mpii_ecfg_hdr *ehdr = p;
3896 u_int64_t dva;
3897 char *kva;
3898 int page_length;
3899 int rv = 0;
3900
3901 DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page address: %d read: %d "
3902 "type: %x\n", DEVNAME(sc), address, read, hdr->page_type);
3903
3904 page_length = ISSET(flags, MPII_PG_EXTENDED) ?
3905 le16toh(ehdr->ext_page_length) : hdr->page_length;
3906
3907 if (len > MPII_REQUEST_SIZE - sizeof(struct mpii_msg_config_request) ||
3908 len < page_length * 4)
3909 return (1);
3910
3911 ccb = mpii_get_ccb(sc,
3912 ISSET(flags, MPII_PG_POLL) ? MPII_NOSLEEP : 0);
3913 if (ccb == NULL) {
3914 DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page ccb_get\n",
3915 DEVNAME(sc));
3916 return (1);
3917 }
3918
3919 cq = ccb->ccb_cmd;
3920
3921 cq->function = MPII_FUNCTION_CONFIG;
3922
3923 cq->action = (read ? MPII_CONFIG_REQ_ACTION_PAGE_READ_CURRENT :
3924 MPII_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT);
3925
3926 if (ISSET(flags, MPII_PG_EXTENDED)) {
3927 cq->config_header.page_version = ehdr->page_version;
3928 cq->config_header.page_number = ehdr->page_number;
3929 cq->config_header.page_type = ehdr->page_type;
3930 cq->ext_page_len = ehdr->ext_page_length;
3931 cq->ext_page_type = ehdr->ext_page_type;
3932 } else
3933 cq->config_header = *hdr;
3934 cq->config_header.page_type &= MPII_CONFIG_REQ_PAGE_TYPE_MASK;
3935 cq->page_address = htole32(address);
3936 cq->page_buffer.sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
3937 MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL |
3938 MPII_SGE_FL_SIZE_64 | (page_length * 4) |
3939 (read ? MPII_SGE_FL_DIR_IN : MPII_SGE_FL_DIR_OUT));
3940
3941 /* bounce the page via the request space to avoid more bus_dma games */
3942 dva = ccb->ccb_cmd_dva + sizeof(struct mpii_msg_config_request);
3943
3944 cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32));
3945 cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva);
3946
3947 kva = ccb->ccb_cmd;
3948 kva += sizeof(struct mpii_msg_config_request);
3949
3950 if (!read)
3951 bcopy(page, kva, len);
3952
3953 ccb->ccb_done = mpii_empty_done;
3954 if (ISSET(flags, MPII_PG_POLL)) {
3955 if (mpii_poll(sc, ccb) != 0) {
3956 DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header poll\n",
3957 DEVNAME(sc));
3958 return (1);
3959 }
3960 } else
3961 mpii_wait(sc, ccb);
3962
3963 if (ccb->ccb_rcb == NULL) {
3964 mpii_put_ccb(sc, ccb);
3965 return (1);
3966 }
3967 cp = ccb->ccb_rcb->rcb_reply;
3968
3969 DNPRINTF(MPII_D_MISC, "%s: action: 0x%02x "
3970 "msg_length: %d function: 0x%02x\n", DEVNAME(sc), cp->action,
3971 cp->msg_length, cp->function);
3972 DNPRINTF(MPII_D_MISC, "%s: ext_page_length: %d ext_page_type: 0x%02x "
3973 "msg_flags: 0x%02x\n", DEVNAME(sc),
3974 le16toh(cp->ext_page_length), cp->ext_page_type,
3975 cp->msg_flags);
3976 DNPRINTF(MPII_D_MISC, "%s: vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
3977 cp->vp_id, cp->vf_id);
3978 DNPRINTF(MPII_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc),
3979 le16toh(cp->ioc_status));
3980 DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
3981 le32toh(cp->ioc_loginfo));
3982 DNPRINTF(MPII_D_MISC, "%s: page_version: 0x%02x page_length: %d "
3983 "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
3984 cp->config_header.page_version,
3985 cp->config_header.page_length,
3986 cp->config_header.page_number,
3987 cp->config_header.page_type);
3988
3989 if (le16toh(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
3990 rv = 1;
3991 else if (read)
3992 bcopy(kva, page, len);
3993
3994 mpii_push_reply(sc, ccb->ccb_rcb);
3995 mpii_put_ccb(sc, ccb);
3996
3997 return (rv);
3998 }
3999
4000 static struct mpii_rcb *
4001 mpii_reply(struct mpii_softc *sc, struct mpii_reply_descr *rdp)
4002 {
4003 struct mpii_rcb *rcb = NULL;
4004 u_int32_t rfid;
4005
4006 DNPRINTF(MPII_D_INTR, "%s: mpii_reply\n", DEVNAME(sc));
4007
4008 if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
4009 MPII_REPLY_DESCR_ADDRESS_REPLY) {
4010 rfid = (le32toh(rdp->frame_addr) -
4011 (u_int32_t)MPII_DMA_DVA(sc->sc_replies)) / MPII_REPLY_SIZE;
4012
4013 bus_dmamap_sync(sc->sc_dmat,
4014 MPII_DMA_MAP(sc->sc_replies), MPII_REPLY_SIZE * rfid,
4015 MPII_REPLY_SIZE, BUS_DMASYNC_POSTREAD);
4016
4017 rcb = &sc->sc_rcbs[rfid];
4018 }
4019
4020 memset(rdp, 0xff, sizeof(*rdp));
4021
4022 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
4023 8 * sc->sc_reply_post_host_index, 8,
4024 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
4025
4026 return (rcb);
4027 }
4028
4029 static struct mpii_dmamem *
4030 mpii_dmamem_alloc(struct mpii_softc *sc, size_t size)
4031 {
4032 struct mpii_dmamem *mdm;
4033 int nsegs;
4034
4035 mdm = malloc(sizeof(*mdm), M_DEVBUF, M_NOWAIT | M_ZERO);
4036 if (mdm == NULL)
4037 return (NULL);
4038
4039 mdm->mdm_size = size;
4040
4041 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
4042 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0)
4043 goto mdmfree;
4044
4045 if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mdm->mdm_seg,
4046 1, &nsegs, BUS_DMA_NOWAIT) != 0) goto destroy;
4047
4048 if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size,
4049 &mdm->mdm_kva, BUS_DMA_NOWAIT) != 0)
4050 goto free;
4051
4052 if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size,
4053 NULL, BUS_DMA_NOWAIT) != 0)
4054 goto unmap;
4055
4056 DNPRINTF(MPII_D_MEM,
4057 " kva: %p dva: 0x%" PRIx64 " map: %p size: %" PRId64 "\n",
4058 mdm->mdm_kva, (uint64_t)mdm->mdm_map->dm_segs[0].ds_addr,
4059 mdm->mdm_map, (uint64_t)size);
4060
4061 bzero(mdm->mdm_kva, size);
4062
4063 return (mdm);
4064
4065 unmap:
4066 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size);
4067 free:
4068 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
4069 destroy:
4070 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
4071 mdmfree:
4072 free(mdm, M_DEVBUF);
4073
4074 return (NULL);
4075 }
4076
4077 static void
4078 mpii_dmamem_free(struct mpii_softc *sc, struct mpii_dmamem *mdm)
4079 {
4080 DNPRINTF(MPII_D_MEM, "%s: mpii_dmamem_free %p\n", DEVNAME(sc), mdm);
4081
4082 bus_dmamap_unload(sc->sc_dmat, mdm->mdm_map);
4083 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size);
4084 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
4085 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
4086 free(mdm, M_DEVBUF);
4087 }
4088
4089 static int
4090 mpii_alloc_dev(struct mpii_softc *sc)
4091 {
4092 sc->sc_devs = malloc(sc->sc_max_devices *
4093 sizeof(struct mpii_device *), M_DEVBUF, M_NOWAIT | M_ZERO);
4094 if (sc->sc_devs == NULL)
4095 return (1);
4096 return (0);
4097 }
4098
4099 static int
4100 mpii_insert_dev(struct mpii_softc *sc, struct mpii_device *dev)
4101 {
4102 int slot = dev->slot; /* initial hint */
4103
4104 if (!dev || slot < 0)
4105 return (1);
4106 while (slot < sc->sc_max_devices && sc->sc_devs[slot] != NULL)
4107 slot++;
4108 if (slot >= sc->sc_max_devices)
4109 return (1);
4110 dev->slot = slot;
4111 sc->sc_devs[slot] = dev;
4112 return (0);
4113 }
4114
4115 static int
4116 mpii_remove_dev(struct mpii_softc *sc, struct mpii_device *dev)
4117 {
4118 int i;
4119
4120 if (!dev)
4121 return (1);
4122 for (i = 0; i < sc->sc_max_devices; i++)
4123 if (sc->sc_devs[i] &&
4124 sc->sc_devs[i]->dev_handle == dev->dev_handle) {
4125 sc->sc_devs[i] = NULL;
4126 return (0);
4127 }
4128 return (1);
4129 }
4130
4131 static struct mpii_device *
4132 mpii_find_dev(struct mpii_softc *sc, u_int16_t handle)
4133 {
4134 int i;
4135
4136 for (i = 0; i < sc->sc_max_devices; i++)
4137 if (sc->sc_devs[i] && sc->sc_devs[i]->dev_handle == handle)
4138 return (sc->sc_devs[i]);
4139 return (NULL);
4140 }
4141
4142 static int
4143 mpii_alloc_ccbs(struct mpii_softc *sc)
4144 {
4145 struct mpii_ccb *ccb;
4146 u_int8_t *cmd;
4147 int i;
4148
4149 SIMPLEQ_INIT(&sc->sc_ccb_free);
4150
4151 sc->sc_ccbs = malloc(sizeof(*ccb) * (sc->sc_request_depth-1),
4152 M_DEVBUF, M_NOWAIT | M_ZERO);
4153 if (sc->sc_ccbs == NULL) {
4154 printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
4155 return (1);
4156 }
4157
4158 sc->sc_requests = mpii_dmamem_alloc(sc,
4159 MPII_REQUEST_SIZE * sc->sc_request_depth);
4160 if (sc->sc_requests == NULL) {
4161 printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
4162 goto free_ccbs;
4163 }
4164 cmd = MPII_DMA_KVA(sc->sc_requests);
4165 bzero(cmd, MPII_REQUEST_SIZE * sc->sc_request_depth);
4166
4167 /*
4168 * we have sc->sc_request_depth system request message
4169 * frames, but smid zero cannot be used. so we then
4170 * have (sc->sc_request_depth - 1) number of ccbs
4171 */
4172 for (i = 1; i < sc->sc_request_depth; i++) {
4173 ccb = &sc->sc_ccbs[i - 1];
4174
4175 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
4176 sc->sc_max_sgl_len, MAXPHYS, 0,
4177 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
4178 &ccb->ccb_dmamap) != 0) {
4179 printf("%s: unable to create dma map\n", DEVNAME(sc));
4180 goto free_maps;
4181 }
4182
4183 ccb->ccb_sc = sc;
4184 ccb->ccb_smid = i;
4185 ccb->ccb_offset = MPII_REQUEST_SIZE * i;
4186
4187 ccb->ccb_cmd = &cmd[ccb->ccb_offset];
4188 ccb->ccb_cmd_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_requests) +
4189 ccb->ccb_offset;
4190
4191 DNPRINTF(MPII_D_CCB, "%s: mpii_alloc_ccbs(%d) ccb: %p map: %p "
4192 "sc: %p smid: %#x offs: %#" PRIx64 " cmd: %#" PRIx64 " dva: %#" PRIx64 "\n",
4193 DEVNAME(sc), i, ccb, ccb->ccb_dmamap, ccb->ccb_sc,
4194 ccb->ccb_smid, (uint64_t)ccb->ccb_offset,
4195 (uint64_t)ccb->ccb_cmd, (uint64_t)ccb->ccb_cmd_dva);
4196
4197 mpii_put_ccb(sc, ccb);
4198 }
4199
4200 return (0);
4201
4202 free_maps:
4203 while ((ccb = mpii_get_ccb(sc, MPII_NOSLEEP)) != NULL)
4204 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
4205
4206 mpii_dmamem_free(sc, sc->sc_requests);
4207 free_ccbs:
4208 free(sc->sc_ccbs, M_DEVBUF);
4209
4210 return (1);
4211 }
4212
4213 static void
4214 mpii_put_ccb(struct mpii_softc *sc, struct mpii_ccb *ccb)
4215 {
4216 KASSERT(ccb->ccb_sc == sc);
4217 DNPRINTF(MPII_D_CCB, "%s: mpii_put_ccb %p\n", DEVNAME(sc), ccb);
4218
4219 ccb->ccb_state = MPII_CCB_FREE;
4220 ccb->ccb_cookie = NULL;
4221 ccb->ccb_done = NULL;
4222 ccb->ccb_rcb = NULL;
4223 bzero(ccb->ccb_cmd, MPII_REQUEST_SIZE);
4224
4225 mutex_enter(&sc->sc_ccb_free_mtx);
4226 SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ccb, u.ccb_link);
4227 cv_signal(&sc->sc_ccb_free_cv);
4228 mutex_exit(&sc->sc_ccb_free_mtx);
4229 }
4230
4231 static struct mpii_ccb *
4232 mpii_get_ccb(struct mpii_softc *sc, int flags)
4233 {
4234 struct mpii_ccb *ccb;
4235
4236 mutex_enter(&sc->sc_ccb_free_mtx);
4237 while ((ccb = SIMPLEQ_FIRST(&sc->sc_ccb_free)) == NULL) {
4238 if (flags & MPII_NOSLEEP)
4239 break;
4240 cv_wait(&sc->sc_ccb_free_cv, &sc->sc_ccb_free_mtx);
4241 }
4242
4243 if (ccb != NULL) {
4244 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, u.ccb_link);
4245 ccb->ccb_state = MPII_CCB_READY;
4246 KASSERT(ccb->ccb_sc == sc);
4247 }
4248 mutex_exit(&sc->sc_ccb_free_mtx);
4249
4250 DNPRINTF(MPII_D_CCB, "%s: mpii_get_ccb %p\n", DEVNAME(sc), ccb);
4251
4252 return (ccb);
4253 }
4254
4255 static int
4256 mpii_alloc_replies(struct mpii_softc *sc)
4257 {
4258 DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_replies\n", DEVNAME(sc));
4259
4260 sc->sc_rcbs = malloc(sc->sc_num_reply_frames * sizeof(struct mpii_rcb),
4261 M_DEVBUF, M_NOWAIT);
4262 if (sc->sc_rcbs == NULL)
4263 return (1);
4264
4265 sc->sc_replies = mpii_dmamem_alloc(sc, MPII_REPLY_SIZE *
4266 sc->sc_num_reply_frames);
4267 if (sc->sc_replies == NULL) {
4268 free(sc->sc_rcbs, M_DEVBUF);
4269 return (1);
4270 }
4271
4272 return (0);
4273 }
4274
4275 static void
4276 mpii_push_replies(struct mpii_softc *sc)
4277 {
4278 struct mpii_rcb *rcb;
4279 char *kva = MPII_DMA_KVA(sc->sc_replies);
4280 int i;
4281
4282 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
4283 0, MPII_REPLY_SIZE * sc->sc_num_reply_frames, BUS_DMASYNC_PREREAD);
4284
4285 for (i = 0; i < sc->sc_num_reply_frames; i++) {
4286 rcb = &sc->sc_rcbs[i];
4287
4288 rcb->rcb_reply = kva + MPII_REPLY_SIZE * i;
4289 rcb->rcb_reply_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
4290 MPII_REPLY_SIZE * i;
4291 mpii_push_reply(sc, rcb);
4292 }
4293 }
4294
4295 static void
4296 mpii_start(struct mpii_softc *sc, struct mpii_ccb *ccb)
4297 {
4298 struct mpii_request_header *rhp;
4299 struct mpii_request_descr descr;
4300 u_int32_t *rdp = (u_int32_t *)&descr;
4301
4302 DNPRINTF(MPII_D_RW, "%s: mpii_start %#" PRIx64 "\n", DEVNAME(sc),
4303 (uint64_t)ccb->ccb_cmd_dva);
4304
4305 rhp = ccb->ccb_cmd;
4306
4307 bzero(&descr, sizeof(descr));
4308
4309 switch (rhp->function) {
4310 case MPII_FUNCTION_SCSI_IO_REQUEST:
4311 descr.request_flags = MPII_REQ_DESCR_SCSI_IO;
4312 descr.dev_handle = htole16(ccb->ccb_dev_handle);
4313 break;
4314 case MPII_FUNCTION_SCSI_TASK_MGMT:
4315 descr.request_flags = MPII_REQ_DESCR_HIGH_PRIORITY;
4316 break;
4317 default:
4318 descr.request_flags = MPII_REQ_DESCR_DEFAULT;
4319 }
4320
4321 descr.vf_id = sc->sc_vf_id;
4322 descr.smid = htole16(ccb->ccb_smid);
4323
4324 bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_requests),
4325 ccb->ccb_offset, MPII_REQUEST_SIZE,
4326 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
4327
4328 ccb->ccb_state = MPII_CCB_QUEUED;
4329
4330 DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESCR_POST_LOW (0x%08x) write "
4331 "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_LOW, *rdp);
4332
4333 DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESCR_POST_HIGH (0x%08x) write "
4334 "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_HIGH, *(rdp+1));
4335
4336 mutex_enter(&sc->sc_req_mtx);
4337 mpii_write(sc, MPII_REQ_DESCR_POST_LOW, htole32(*rdp));
4338 mpii_write(sc, MPII_REQ_DESCR_POST_HIGH, htole32(*(rdp+1)));
4339 mutex_exit(&sc->sc_req_mtx);
4340 }
4341
4342 static int
4343 mpii_poll(struct mpii_softc *sc, struct mpii_ccb *ccb)
4344 {
4345 void (*done)(struct mpii_ccb *);
4346 void *cookie;
4347 int rv = 1;
4348
4349 DNPRINTF(MPII_D_INTR, "%s: mpii_complete\n", DEVNAME(sc));
4350
4351 done = ccb->ccb_done;
4352 cookie = ccb->ccb_cookie;
4353
4354 ccb->ccb_done = mpii_poll_done;
4355 ccb->ccb_cookie = &rv;
4356
4357 mpii_start(sc, ccb);
4358
4359 while (rv == 1) {
4360 /* avoid excessive polling */
4361 if (mpii_reply_waiting(sc))
4362 mpii_intr(sc);
4363 else
4364 delay(10);
4365 }
4366
4367 ccb->ccb_cookie = cookie;
4368 done(ccb);
4369
4370 return (0);
4371 }
4372
4373 static void
4374 mpii_poll_done(struct mpii_ccb *ccb)
4375 {
4376 int *rv = ccb->ccb_cookie;
4377
4378 *rv = 0;
4379 }
4380
4381 static int
4382 mpii_alloc_queues(struct mpii_softc *sc)
4383 {
4384 u_int32_t *kva;
4385 u_int64_t *kva64;
4386 int i;
4387
4388 DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_queues\n", DEVNAME(sc));
4389
4390 sc->sc_reply_freeq = mpii_dmamem_alloc(sc,
4391 sc->sc_reply_free_qdepth * 4);
4392 if (sc->sc_reply_freeq == NULL)
4393 return (1);
4394
4395 kva = MPII_DMA_KVA(sc->sc_reply_freeq);
4396 for (i = 0; i < sc->sc_num_reply_frames; i++) {
4397 kva[i] = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
4398 MPII_REPLY_SIZE * i;
4399
4400 DNPRINTF(MPII_D_MISC, "%s: %d: %p = 0x%08x\n",
4401 DEVNAME(sc), i,
4402 &kva[i], (u_int)MPII_DMA_DVA(sc->sc_replies) +
4403 MPII_REPLY_SIZE * i);
4404 }
4405
4406 sc->sc_reply_postq =
4407 mpii_dmamem_alloc(sc, sc->sc_reply_post_qdepth * 8);
4408 if (sc->sc_reply_postq == NULL)
4409 goto free_reply_freeq;
4410 sc->sc_reply_postq_kva = MPII_DMA_KVA(sc->sc_reply_postq);
4411
4412 DNPRINTF(MPII_D_MISC, "%s: populating reply post descriptor queue\n",
4413 DEVNAME(sc));
4414 kva64 = (u_int64_t *)MPII_DMA_KVA(sc->sc_reply_postq);
4415 for (i = 0; i < sc->sc_reply_post_qdepth; i++) {
4416 kva64[i] = 0xffffffffffffffffllu;
4417 DNPRINTF(MPII_D_MISC, "%s: %d: %p = 0x%" PRIx64 "\n",
4418 DEVNAME(sc), i, &kva64[i], kva64[i]);
4419 }
4420
4421 return (0);
4422
4423 free_reply_freeq:
4424
4425 mpii_dmamem_free(sc, sc->sc_reply_freeq);
4426 return (1);
4427 }
4428
4429 static void
4430 mpii_init_queues(struct mpii_softc *sc)
4431 {
4432 DNPRINTF(MPII_D_MISC, "%s: mpii_init_queues\n", DEVNAME(sc));
4433
4434 sc->sc_reply_free_host_index = sc->sc_reply_free_qdepth - 1;
4435 sc->sc_reply_post_host_index = 0;
4436 mpii_write_reply_free(sc, sc->sc_reply_free_host_index);
4437 mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
4438 }
4439
4440 static void
4441 mpii_wait(struct mpii_softc *sc, struct mpii_ccb *ccb)
4442 {
4443 struct mpii_ccb_wait mpii_ccb_wait;
4444 void (*done)(struct mpii_ccb *);
4445 void *cookie;
4446
4447 done = ccb->ccb_done;
4448 cookie = ccb->ccb_cookie;
4449
4450 ccb->ccb_done = mpii_wait_done;
4451 ccb->ccb_cookie = &mpii_ccb_wait;
4452
4453 mutex_init(&mpii_ccb_wait.mpii_ccbw_mtx, MUTEX_DEFAULT, IPL_BIO);
4454 cv_init(&mpii_ccb_wait.mpii_ccbw_cv, "mpii_wait");
4455
4456 /* XXX this will wait forever for the ccb to complete */
4457
4458 mpii_start(sc, ccb);
4459
4460 mutex_enter(&mpii_ccb_wait.mpii_ccbw_mtx);
4461 while (ccb->ccb_cookie != NULL) {
4462 cv_wait(&mpii_ccb_wait.mpii_ccbw_cv,
4463 &mpii_ccb_wait.mpii_ccbw_mtx);
4464 }
4465 mutex_exit(&mpii_ccb_wait.mpii_ccbw_mtx);
4466 mutex_destroy(&mpii_ccb_wait.mpii_ccbw_mtx);
4467 cv_destroy(&mpii_ccb_wait.mpii_ccbw_cv);
4468
4469 ccb->ccb_cookie = cookie;
4470 done(ccb);
4471 }
4472
4473 static void
4474 mpii_wait_done(struct mpii_ccb *ccb)
4475 {
4476 struct mpii_ccb_wait *mpii_ccb_waitp = ccb->ccb_cookie;
4477
4478 mutex_enter(&mpii_ccb_waitp->mpii_ccbw_mtx);
4479 ccb->ccb_cookie = NULL;
4480 cv_signal(&mpii_ccb_waitp->mpii_ccbw_cv);
4481 mutex_exit(&mpii_ccb_waitp->mpii_ccbw_mtx);
4482 }
4483
4484 static void
4485 mpii_minphys(struct buf *bp)
4486 {
4487 DNPRINTF(MPII_D_MISC, "mpii_minphys: %d\n", bp->b_bcount);
4488
4489 /* XXX currently using MPII_MAXFER = MAXPHYS */
4490 if (bp->b_bcount > MPII_MAXFER) {
4491 bp->b_bcount = MPII_MAXFER;
4492 minphys(bp);
4493 }
4494 }
4495
4496 static void
4497 mpii_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
4498 void *arg)
4499 {
4500 struct scsipi_periph *periph;
4501 struct scsipi_xfer *xs;
4502 struct scsipi_adapter *adapt = chan->chan_adapter;
4503 struct mpii_softc *sc = device_private(adapt->adapt_dev);
4504 struct mpii_ccb *ccb;
4505 struct mpii_ccb_bundle *mcb;
4506 struct mpii_msg_scsi_io *io;
4507 struct mpii_device *dev;
4508 int target;
4509 int timeout;
4510
4511 DNPRINTF(MPII_D_CMD, "%s: mpii_scsipi_request\n", DEVNAME(sc));
4512 switch (req) {
4513 case ADAPTER_REQ_GROW_RESOURCES:
4514 /* Not supported. */
4515 return;
4516 case ADAPTER_REQ_SET_XFER_MODE:
4517 {
4518 struct scsipi_xfer_mode *xm = arg;
4519 xm->xm_mode = PERIPH_CAP_TQING;
4520 xm->xm_period = 0;
4521 xm->xm_offset = 0;
4522 scsipi_async_event(&sc->sc_chan, ASYNC_EVENT_XFER_MODE, xm);
4523 return;
4524 }
4525 case ADAPTER_REQ_RUN_XFER:
4526 break;
4527 }
4528
4529 xs = arg;
4530 periph = xs->xs_periph;
4531 target = periph->periph_target;
4532
4533 if (xs->cmdlen > MPII_CDB_LEN) {
4534 DNPRINTF(MPII_D_CMD, "%s: CBD too big %d\n",
4535 DEVNAME(sc), xs->cmdlen);
4536 bzero(&xs->sense, sizeof(xs->sense));
4537 xs->sense.scsi_sense.response_code =
4538 SSD_RCODE_VALID | SSD_RCODE_CURRENT;
4539 xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
4540 xs->sense.scsi_sense.asc = 0x20;
4541 xs->error = XS_SENSE;
4542 scsipi_done(xs);
4543 return;
4544 }
4545
4546 if ((dev = sc->sc_devs[target]) == NULL) {
4547 /* device no longer exists */
4548 xs->error = XS_SELTIMEOUT;
4549 scsipi_done(xs);
4550 return;
4551 }
4552
4553 ccb = mpii_get_ccb(sc, MPII_NOSLEEP);
4554 if (ccb == NULL) {
4555 xs->error = XS_RESOURCE_SHORTAGE;
4556 scsipi_done(xs);
4557 return;
4558 }
4559
4560 DNPRINTF(MPII_D_CMD, "%s: ccb_smid: %d xs->xs_control: 0x%x\n",
4561 DEVNAME(sc), ccb->ccb_smid, xs->xs_control);
4562
4563 ccb->ccb_cookie = xs;
4564 ccb->ccb_done = mpii_scsi_cmd_done;
4565 ccb->ccb_dev_handle = dev->dev_handle;
4566
4567 mcb = ccb->ccb_cmd;
4568 io = &mcb->mcb_io;
4569
4570 io->function = MPII_FUNCTION_SCSI_IO_REQUEST;
4571 io->sense_buffer_length = sizeof(xs->sense);
4572 io->sgl_offset0 = 24; /* XXX fix this */
4573 io->io_flags = htole16(xs->cmdlen);
4574 io->dev_handle = htole16(ccb->ccb_dev_handle);
4575 io->lun[0] = htobe16(periph->periph_lun);
4576
4577 switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
4578 case XS_CTL_DATA_IN:
4579 io->direction = MPII_SCSIIO_DIR_READ;
4580 break;
4581 case XS_CTL_DATA_OUT:
4582 io->direction = MPII_SCSIIO_DIR_WRITE;
4583 break;
4584 default:
4585 io->direction = MPII_SCSIIO_DIR_NONE;
4586 }
4587
4588 io->tagging = MPII_SCSIIO_ATTR_SIMPLE_Q;
4589
4590 memcpy(io->cdb, xs->cmd, xs->cmdlen);
4591
4592 io->data_length = htole32(xs->datalen);
4593
4594 io->sense_buffer_low_address = htole32(ccb->ccb_cmd_dva +
4595 ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb));
4596
4597 if (mpii_load_xs(ccb) != 0) {
4598 xs->error = XS_DRIVER_STUFFUP;
4599 mpii_put_ccb(sc, ccb);
4600 scsipi_done(xs);
4601 return;
4602 }
4603
4604 DNPRINTF(MPII_D_CMD, "%s: sizeof(mpii_msg_scsi_io): %ld "
4605 "sizeof(mpii_ccb_bundle): %ld sge offset: 0x%02lx\n",
4606 DEVNAME(sc), sizeof(struct mpii_msg_scsi_io),
4607 sizeof(struct mpii_ccb_bundle),
4608 (u_int8_t *)&mcb->mcb_sgl[0] - (u_int8_t *)mcb);
4609
4610 DNPRINTF(MPII_D_CMD, "%s sgl[0]: 0x%04x 0%04x 0x%04x\n",
4611 DEVNAME(sc), mcb->mcb_sgl[0].sg_hdr, mcb->mcb_sgl[0].sg_lo_addr,
4612 mcb->mcb_sgl[0].sg_hi_addr);
4613
4614 DNPRINTF(MPII_D_CMD, "%s: Offset0: 0x%02x\n", DEVNAME(sc),
4615 io->sgl_offset0);
4616
4617 if (xs->xs_control & XS_CTL_POLL) {
4618 if (mpii_poll(sc, ccb) != 0) {
4619 xs->error = XS_DRIVER_STUFFUP;
4620 mpii_put_ccb(sc, ccb);
4621 scsipi_done(xs);
4622 }
4623 return;
4624 }
4625 timeout = mstohz(xs->timeout);
4626 if (timeout == 0)
4627 timeout = 1;
4628 callout_reset(&xs->xs_callout, timeout, mpii_scsi_cmd_tmo, ccb);
4629
4630 DNPRINTF(MPII_D_CMD, "%s: mpii_scsipi_request(): opcode: %02x "
4631 "datalen: %d\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen);
4632
4633 mpii_start(sc, ccb);
4634 }
4635
4636 static void
4637 mpii_scsi_cmd_tmo(void *xccb)
4638 {
4639 struct mpii_ccb *ccb = xccb;
4640 struct mpii_softc *sc = ccb->ccb_sc;
4641
4642 printf("%s: mpii_scsi_cmd_tmo\n", DEVNAME(sc));
4643
4644 mutex_enter(&sc->sc_ccb_mtx);
4645 if (ccb->ccb_state == MPII_CCB_QUEUED) {
4646 ccb->ccb_state = MPII_CCB_TIMEOUT;
4647 workqueue_enqueue(sc->sc_ssb_tmowk, &ccb->u.ccb_wk, NULL);
4648 }
4649 mutex_exit(&sc->sc_ccb_mtx);
4650 }
4651
4652 static void
4653 mpii_scsi_cmd_tmo_handler(struct work *wk, void *cookie)
4654 {
4655 struct mpii_softc *sc = cookie;
4656 struct mpii_ccb *tccb;
4657 struct mpii_ccb *ccb;
4658 struct mpii_msg_scsi_task_request *stq;
4659
4660 ccb = (void *)wk;
4661 tccb = mpii_get_ccb(sc, 0);
4662
4663 mutex_enter(&sc->sc_ccb_mtx);
4664 if (ccb->ccb_state != MPII_CCB_TIMEOUT) {
4665 mpii_put_ccb(sc, tccb);
4666 }
4667 /* should remove any other ccbs for the same dev handle */
4668 mutex_exit(&sc->sc_ccb_mtx);
4669
4670 stq = tccb->ccb_cmd;
4671 stq->function = MPII_FUNCTION_SCSI_TASK_MGMT;
4672 stq->task_type = MPII_SCSI_TASK_TARGET_RESET;
4673 stq->dev_handle = htole16(ccb->ccb_dev_handle);
4674
4675 tccb->ccb_done = mpii_scsi_cmd_tmo_done;
4676 mpii_start(sc, tccb);
4677 }
4678
4679 static void
4680 mpii_scsi_cmd_tmo_done(struct mpii_ccb *tccb)
4681 {
4682 mpii_put_ccb(tccb->ccb_sc, tccb);
4683 }
4684
4685
4686 static void
4687 mpii_scsi_cmd_done(struct mpii_ccb *ccb)
4688 {
4689 struct mpii_msg_scsi_io_error *sie;
4690 struct mpii_softc *sc = ccb->ccb_sc;
4691 struct scsipi_xfer *xs = ccb->ccb_cookie;
4692 struct mpii_ccb_bundle *mcb = ccb->ccb_cmd;
4693 bus_dmamap_t dmap = ccb->ccb_dmamap;
4694 bool timeout = 0;
4695
4696 callout_stop(&xs->xs_callout);
4697 mutex_enter(&sc->sc_ccb_mtx);
4698 if (ccb->ccb_state == MPII_CCB_TIMEOUT)
4699 timeout = 1;
4700 ccb->ccb_state = MPII_CCB_READY;
4701 mutex_exit(&sc->sc_ccb_mtx);
4702
4703 if (xs->datalen != 0) {
4704 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
4705 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD :
4706 BUS_DMASYNC_POSTWRITE);
4707
4708 bus_dmamap_unload(sc->sc_dmat, dmap);
4709 }
4710
4711 xs->error = XS_NOERROR;
4712 xs->resid = 0;
4713
4714 if (ccb->ccb_rcb == NULL) {
4715 /* no scsi error, we're ok so drop out early */
4716 xs->status = SCSI_OK;
4717 mpii_put_ccb(sc, ccb);
4718 scsipi_done(xs);
4719 return;
4720 }
4721
4722 sie = ccb->ccb_rcb->rcb_reply;
4723
4724 DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd_done xs cmd: 0x%02x len: %d "
4725 "xs_control 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
4726 xs->xs_control);
4727 DNPRINTF(MPII_D_CMD, "%s: dev_handle: %d msg_length: %d "
4728 "function: 0x%02x\n", DEVNAME(sc), le16toh(sie->dev_handle),
4729 sie->msg_length, sie->function);
4730 DNPRINTF(MPII_D_CMD, "%s: vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
4731 sie->vp_id, sie->vf_id);
4732 DNPRINTF(MPII_D_CMD, "%s: scsi_status: 0x%02x scsi_state: 0x%02x "
4733 "ioc_status: 0x%04x\n", DEVNAME(sc), sie->scsi_status,
4734 sie->scsi_state, le16toh(sie->ioc_status));
4735 DNPRINTF(MPII_D_CMD, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
4736 le32toh(sie->ioc_loginfo));
4737 DNPRINTF(MPII_D_CMD, "%s: transfer_count: %d\n", DEVNAME(sc),
4738 le32toh(sie->transfer_count));
4739 DNPRINTF(MPII_D_CMD, "%s: sense_count: %d\n", DEVNAME(sc),
4740 le32toh(sie->sense_count));
4741 DNPRINTF(MPII_D_CMD, "%s: response_info: 0x%08x\n", DEVNAME(sc),
4742 le32toh(sie->response_info));
4743 DNPRINTF(MPII_D_CMD, "%s: task_tag: 0x%04x\n", DEVNAME(sc),
4744 le16toh(sie->task_tag));
4745 DNPRINTF(MPII_D_CMD, "%s: bidirectional_transfer_count: 0x%08x\n",
4746 DEVNAME(sc), le32toh(sie->bidirectional_transfer_count));
4747
4748 xs->status = sie->scsi_status;
4749 switch (le16toh(sie->ioc_status) & MPII_IOCSTATUS_MASK) {
4750 case MPII_IOCSTATUS_SCSI_DATA_UNDERRUN:
4751 switch (xs->status) {
4752 case SCSI_OK:
4753 xs->resid = xs->datalen - le32toh(sie->transfer_count);
4754 break;
4755 default:
4756 xs->error = XS_DRIVER_STUFFUP;
4757 break;
4758 }
4759 break;
4760 case MPII_IOCSTATUS_SUCCESS:
4761 case MPII_IOCSTATUS_SCSI_RECOVERED_ERROR:
4762 switch (xs->status) {
4763 case SCSI_OK:
4764 xs->resid = 0;
4765 break;
4766
4767 case SCSI_CHECK:
4768 xs->error = XS_SENSE;
4769 break;
4770
4771 case SCSI_BUSY:
4772 case SCSI_QUEUE_FULL:
4773 xs->error = XS_BUSY;
4774 break;
4775
4776 default:
4777 xs->error = XS_DRIVER_STUFFUP;
4778 }
4779 break;
4780
4781 case MPII_IOCSTATUS_BUSY:
4782 case MPII_IOCSTATUS_INSUFFICIENT_RESOURCES:
4783 xs->error = XS_BUSY;
4784 break;
4785
4786 case MPII_IOCSTATUS_SCSI_IOC_TERMINATED:
4787 case MPII_IOCSTATUS_SCSI_TASK_TERMINATED:
4788 xs->error = timeout ? XS_TIMEOUT : XS_RESET;
4789 break;
4790
4791 case MPII_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
4792 case MPII_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
4793 xs->error = XS_SELTIMEOUT;
4794 break;
4795
4796 default:
4797 xs->error = XS_DRIVER_STUFFUP;
4798 break;
4799 }
4800
4801 if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID)
4802 memcpy(&xs->sense, &mcb->mcb_sense, sizeof(xs->sense));
4803
4804 DNPRINTF(MPII_D_CMD, "%s: xs err: %d status: %#x\n", DEVNAME(sc),
4805 xs->error, xs->status);
4806
4807 mpii_push_reply(sc, ccb->ccb_rcb);
4808 mpii_put_ccb(sc, ccb);
4809 scsipi_done(xs);
4810 }
4811
4812 #if 0
4813 static int
4814 mpii_ioctl_cache(struct scsi_link *link, u_long cmd, struct dk_cache *dc)
4815 {
4816 struct mpii_softc *sc = (struct mpii_softc *)link->adapter_softc;
4817 struct mpii_device *dev = sc->sc_devs[link->target];
4818 struct mpii_cfg_raid_vol_pg0 *vpg;
4819 struct mpii_msg_raid_action_request *req;
4820 struct mpii_msg_raid_action_reply *rep;
4821 struct mpii_cfg_hdr hdr;
4822 struct mpii_ccb *ccb;
4823 u_int32_t addr = MPII_CFG_RAID_VOL_ADDR_HANDLE | dev->dev_handle;
4824 size_t pagelen;
4825 int rv = 0;
4826 int enabled;
4827
4828 if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
4829 addr, MPII_PG_POLL, &hdr) != 0)
4830 return (EINVAL);
4831
4832 pagelen = hdr.page_length * 4;
4833 vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
4834 if (vpg == NULL)
4835 return (ENOMEM);
4836
4837 if (mpii_req_cfg_page(sc, addr, MPII_PG_POLL, &hdr, 1,
4838 vpg, pagelen) != 0) {
4839 rv = EINVAL;
4840 goto done;
4841 free(vpg, M_TEMP);
4842 return (EINVAL);
4843 }
4844
4845 enabled = ((le16toh(vpg->volume_settings) &
4846 MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_MASK) ==
4847 MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_ENABLED) ? 1 : 0;
4848
4849 if (cmd == DIOCGCACHE) {
4850 dc->wrcache = enabled;
4851 dc->rdcache = 0;
4852 goto done;
4853 } /* else DIOCSCACHE */
4854
4855 if (dc->rdcache) {
4856 rv = EOPNOTSUPP;
4857 goto done;
4858 }
4859
4860 if (((dc->wrcache) ? 1 : 0) == enabled)
4861 goto done;
4862
4863 ccb = mpii_get_ccb(sc, MPII_NOSLEEP);
4864 if (ccb == NULL) {
4865 rv = ENOMEM;
4866 goto done;
4867 }
4868
4869 ccb->ccb_done = mpii_empty_done;
4870
4871 req = ccb->ccb_cmd;
4872 bzero(req, sizeof(*req));
4873 req->function = MPII_FUNCTION_RAID_ACTION;
4874 req->action = MPII_RAID_ACTION_CHANGE_VOL_WRITE_CACHE;
4875 req->vol_dev_handle = htole16(dev->dev_handle);
4876 req->action_data = htole32(dc->wrcache ?
4877 MPII_RAID_VOL_WRITE_CACHE_ENABLE :
4878 MPII_RAID_VOL_WRITE_CACHE_DISABLE);
4879
4880 if (mpii_poll(sc, ccb) != 0) {
4881 rv = EIO;
4882 goto done;
4883 }
4884
4885 if (ccb->ccb_rcb != NULL) {
4886 rep = ccb->ccb_rcb->rcb_reply;
4887 if ((rep->ioc_status != MPII_IOCSTATUS_SUCCESS) ||
4888 ((rep->action_data[0] &
4889 MPII_RAID_VOL_WRITE_CACHE_MASK) !=
4890 (dc->wrcache ? MPII_RAID_VOL_WRITE_CACHE_ENABLE :
4891 MPII_RAID_VOL_WRITE_CACHE_DISABLE)))
4892 rv = EINVAL;
4893 mpii_push_reply(sc, ccb->ccb_rcb);
4894 }
4895
4896 mpii_put_ccb(sc, ccb);
4897
4898 done:
4899 free(vpg, M_TEMP);
4900 return (rv);
4901 }
4902 #endif
4903 static int
4904 mpii_cache_enable(struct mpii_softc *sc, struct mpii_device *dev)
4905 {
4906 struct mpii_cfg_raid_vol_pg0 *vpg;
4907 struct mpii_msg_raid_action_request *req;
4908 struct mpii_msg_raid_action_reply *rep;
4909 struct mpii_cfg_hdr hdr;
4910 struct mpii_ccb *ccb;
4911 u_int32_t addr = MPII_CFG_RAID_VOL_ADDR_HANDLE | dev->dev_handle;
4912 size_t pagelen;
4913 int rv = 0;
4914 int enabled;
4915
4916 if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
4917 addr, MPII_PG_POLL, &hdr) != 0)
4918 return (EINVAL);
4919
4920 pagelen = hdr.page_length * 4;
4921 vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
4922 if (vpg == NULL)
4923 return (ENOMEM);
4924
4925 if (mpii_req_cfg_page(sc, addr, MPII_PG_POLL, &hdr, 1,
4926 vpg, pagelen) != 0) {
4927 rv = EINVAL;
4928 goto done;
4929 free(vpg, M_TEMP);
4930 return (EINVAL);
4931 }
4932
4933 enabled = ((le16toh(vpg->volume_settings) &
4934 MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_MASK) ==
4935 MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_ENABLED) ? 1 : 0;
4936 aprint_normal_dev(sc->sc_dev, "target %d cache %s", dev->slot,
4937 enabled ? "enabled" : "disabled, enabling");
4938 aprint_normal("\n");
4939
4940 if (enabled == 0)
4941 goto done;
4942
4943 ccb = mpii_get_ccb(sc, MPII_NOSLEEP);
4944 if (ccb == NULL) {
4945 rv = ENOMEM;
4946 goto done;
4947 }
4948
4949 ccb->ccb_done = mpii_empty_done;
4950
4951 req = ccb->ccb_cmd;
4952 bzero(req, sizeof(*req));
4953 req->function = MPII_FUNCTION_RAID_ACTION;
4954 req->action = MPII_RAID_ACTION_CHANGE_VOL_WRITE_CACHE;
4955 req->vol_dev_handle = htole16(dev->dev_handle);
4956 req->action_data = htole32(
4957 MPII_RAID_VOL_WRITE_CACHE_ENABLE);
4958
4959 if (mpii_poll(sc, ccb) != 0) {
4960 rv = EIO;
4961 goto done;
4962 }
4963
4964 if (ccb->ccb_rcb != NULL) {
4965 rep = ccb->ccb_rcb->rcb_reply;
4966 if ((rep->ioc_status != MPII_IOCSTATUS_SUCCESS) ||
4967 ((rep->action_data[0] &
4968 MPII_RAID_VOL_WRITE_CACHE_MASK) !=
4969 MPII_RAID_VOL_WRITE_CACHE_ENABLE))
4970 rv = EINVAL;
4971 mpii_push_reply(sc, ccb->ccb_rcb);
4972 }
4973
4974 mpii_put_ccb(sc, ccb);
4975
4976 done:
4977 free(vpg, M_TEMP);
4978 if (rv) {
4979 aprint_error_dev(sc->sc_dev,
4980 "enabling cache on target %d failed (%d)\n",
4981 dev->slot, rv);
4982 }
4983 return (rv);
4984 }
4985
4986 #if NBIO > 0
4987 static int
4988 mpii_ioctl(device_t dev, u_long cmd, void *addr)
4989 {
4990 struct mpii_softc *sc = device_private(dev);
4991 int s, error = 0;
4992
4993 DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl ", DEVNAME(sc));
4994 KERNEL_LOCK(1, curlwp);
4995 s = splbio();
4996
4997 switch (cmd) {
4998 case BIOCINQ:
4999 DNPRINTF(MPII_D_IOCTL, "inq\n");
5000 error = mpii_ioctl_inq(sc, (struct bioc_inq *)addr);
5001 break;
5002 case BIOCVOL:
5003 DNPRINTF(MPII_D_IOCTL, "vol\n");
5004 error = mpii_ioctl_vol(sc, (struct bioc_vol *)addr);
5005 break;
5006 case BIOCDISK:
5007 DNPRINTF(MPII_D_IOCTL, "disk\n");
5008 error = mpii_ioctl_disk(sc, (struct bioc_disk *)addr);
5009 break;
5010 default:
5011 DNPRINTF(MPII_D_IOCTL, " invalid ioctl\n");
5012 error = EINVAL;
5013 }
5014
5015 splx(s);
5016 KERNEL_UNLOCK_ONE(curlwp);
5017 return (error);
5018 }
5019
5020 static int
5021 mpii_ioctl_inq(struct mpii_softc *sc, struct bioc_inq *bi)
5022 {
5023 int i;
5024
5025 DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_inq\n", DEVNAME(sc));
5026
5027 strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
5028 for (i = 0; i < sc->sc_max_devices; i++)
5029 if (sc->sc_devs[i] &&
5030 ISSET(sc->sc_devs[i]->flags, MPII_DF_VOLUME))
5031 bi->bi_novol++;
5032 return (0);
5033 }
5034
5035 static int
5036 mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
5037 {
5038 struct mpii_cfg_raid_vol_pg0 *vpg;
5039 struct mpii_cfg_hdr hdr;
5040 struct mpii_device *dev;
5041 struct scsipi_periph *periph;
5042 size_t pagelen;
5043 u_int16_t volh;
5044 int rv, hcnt = 0;
5045
5046 DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_vol %d\n",
5047 DEVNAME(sc), bv->bv_volid);
5048
5049 if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
5050 return (ENODEV);
5051 volh = dev->dev_handle;
5052
5053 if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
5054 MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
5055 printf("%s: unable to fetch header for raid volume page 0\n",
5056 DEVNAME(sc));
5057 return (EINVAL);
5058 }
5059
5060 pagelen = hdr.page_length * 4;
5061 vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
5062 if (vpg == NULL) {
5063 printf("%s: unable to allocate space for raid "
5064 "volume page 0\n", DEVNAME(sc));
5065 return (ENOMEM);
5066 }
5067
5068 if (mpii_req_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0,
5069 &hdr, 1, vpg, pagelen) != 0) {
5070 printf("%s: unable to fetch raid volume page 0\n",
5071 DEVNAME(sc));
5072 free(vpg, M_TEMP);
5073 return (EINVAL);
5074 }
5075
5076 switch (vpg->volume_state) {
5077 case MPII_CFG_RAID_VOL_0_STATE_ONLINE:
5078 case MPII_CFG_RAID_VOL_0_STATE_OPTIMAL:
5079 bv->bv_status = BIOC_SVONLINE;
5080 break;
5081 case MPII_CFG_RAID_VOL_0_STATE_DEGRADED:
5082 if (ISSET(le32toh(vpg->volume_status),
5083 MPII_CFG_RAID_VOL_0_STATUS_RESYNC)) {
5084 bv->bv_status = BIOC_SVREBUILD;
5085 bv->bv_percent = dev->percent;
5086 } else
5087 bv->bv_status = BIOC_SVDEGRADED;
5088 break;
5089 case MPII_CFG_RAID_VOL_0_STATE_FAILED:
5090 bv->bv_status = BIOC_SVOFFLINE;
5091 break;
5092 case MPII_CFG_RAID_VOL_0_STATE_INITIALIZING:
5093 bv->bv_status = BIOC_SVBUILDING;
5094 break;
5095 case MPII_CFG_RAID_VOL_0_STATE_MISSING:
5096 default:
5097 bv->bv_status = BIOC_SVINVALID;
5098 break;
5099 }
5100
5101 switch (vpg->volume_type) {
5102 case MPII_CFG_RAID_VOL_0_TYPE_RAID0:
5103 bv->bv_level = 0;
5104 break;
5105 case MPII_CFG_RAID_VOL_0_TYPE_RAID1:
5106 bv->bv_level = 1;
5107 break;
5108 case MPII_CFG_RAID_VOL_0_TYPE_RAID1E:
5109 case MPII_CFG_RAID_VOL_0_TYPE_RAID10:
5110 bv->bv_level = 10;
5111 break;
5112 default:
5113 bv->bv_level = -1;
5114 }
5115
5116 if ((rv = mpii_bio_hs(sc, NULL, 0, vpg->hot_spare_pool, &hcnt)) != 0) {
5117 free(vpg, M_TEMP);
5118 return (rv);
5119 }
5120
5121 bv->bv_nodisk = vpg->num_phys_disks + hcnt;
5122
5123 bv->bv_size = le64toh(vpg->max_lba) * le16toh(vpg->block_size);
5124
5125 periph = scsipi_lookup_periph(&sc->sc_chan, dev->slot, 0);
5126 if (periph != NULL) {
5127 if (periph->periph_dev == NULL) {
5128 snprintf(bv->bv_dev, sizeof(bv->bv_dev), "%s:%d",
5129 DEVNAME(sc), dev->slot);
5130 } else {
5131 strlcpy(bv->bv_dev, device_xname(periph->periph_dev),
5132 sizeof(bv->bv_dev));
5133 }
5134 }
5135
5136 free(vpg, M_TEMP);
5137 return (0);
5138 }
5139
5140 static int
5141 mpii_ioctl_disk(struct mpii_softc *sc, struct bioc_disk *bd)
5142 {
5143 struct mpii_cfg_raid_vol_pg0 *vpg;
5144 struct mpii_cfg_raid_vol_pg0_physdisk *pd;
5145 struct mpii_cfg_hdr hdr;
5146 struct mpii_device *dev;
5147 size_t pagelen;
5148 u_int16_t volh;
5149 u_int8_t dn;
5150
5151 DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_disk %d/%d\n",
5152 DEVNAME(sc), bd->bd_volid, bd->bd_diskid);
5153
5154 if ((dev = mpii_find_vol(sc, bd->bd_volid)) == NULL)
5155 return (ENODEV);
5156 volh = dev->dev_handle;
5157
5158 if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
5159 MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
5160 printf("%s: unable to fetch header for raid volume page 0\n",
5161 DEVNAME(sc));
5162 return (EINVAL);
5163 }
5164
5165 pagelen = hdr.page_length * 4;
5166 vpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
5167 if (vpg == NULL) {
5168 printf("%s: unable to allocate space for raid "
5169 "volume page 0\n", DEVNAME(sc));
5170 return (ENOMEM);
5171 }
5172
5173 if (mpii_req_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0,
5174 &hdr, 1, vpg, pagelen) != 0) {
5175 printf("%s: unable to fetch raid volume page 0\n",
5176 DEVNAME(sc));
5177 free(vpg, M_TEMP);
5178 return (EINVAL);
5179 }
5180
5181 if (bd->bd_diskid >= vpg->num_phys_disks) {
5182 int nvdsk = vpg->num_phys_disks;
5183 int hsmap = vpg->hot_spare_pool;
5184
5185 free(vpg, M_TEMP);
5186 return (mpii_bio_hs(sc, bd, nvdsk, hsmap, NULL));
5187 }
5188
5189 pd = (struct mpii_cfg_raid_vol_pg0_physdisk *)(vpg + 1) +
5190 bd->bd_diskid;
5191 dn = pd->phys_disk_num;
5192
5193 free(vpg, M_TEMP);
5194 return (mpii_bio_disk(sc, bd, dn));
5195 }
5196
5197 static int
5198 mpii_bio_hs(struct mpii_softc *sc, struct bioc_disk *bd, int nvdsk,
5199 int hsmap, int *hscnt)
5200 {
5201 struct mpii_cfg_raid_config_pg0 *cpg;
5202 struct mpii_raid_config_element *el;
5203 struct mpii_ecfg_hdr ehdr;
5204 size_t pagelen;
5205 int i, nhs = 0;
5206
5207 if (bd) {
5208 DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_hs %d\n", DEVNAME(sc),
5209 bd->bd_diskid - nvdsk);
5210 } else {
5211 DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_hs\n", DEVNAME(sc));
5212 }
5213
5214 if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_CONFIG,
5215 0, MPII_CFG_RAID_CONFIG_ACTIVE_CONFIG, MPII_PG_EXTENDED,
5216 &ehdr) != 0) {
5217 printf("%s: unable to fetch header for raid config page 0\n",
5218 DEVNAME(sc));
5219 return (EINVAL);
5220 }
5221
5222 pagelen = le16toh(ehdr.ext_page_length) * 4;
5223 cpg = malloc(pagelen, M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
5224 if (cpg == NULL) {
5225 printf("%s: unable to allocate space for raid config page 0\n",
5226 DEVNAME(sc));
5227 return (ENOMEM);
5228 }
5229
5230 if (mpii_req_cfg_page(sc, MPII_CFG_RAID_CONFIG_ACTIVE_CONFIG,
5231 MPII_PG_EXTENDED, &ehdr, 1, cpg, pagelen) != 0) {
5232 printf("%s: unable to fetch raid config page 0\n",
5233 DEVNAME(sc));
5234 free(cpg, M_TEMP);
5235 return (EINVAL);
5236 }
5237
5238 el = (struct mpii_raid_config_element *)(cpg + 1);
5239 for (i = 0; i < cpg->num_elements; i++, el++) {
5240 if (ISSET(le16toh(el->element_flags),
5241 MPII_RAID_CONFIG_ELEMENT_FLAG_HSP_PHYS_DISK) &&
5242 el->hot_spare_pool == hsmap) {
5243 /*
5244 * diskid comparison is based on the idea that all
5245 * disks are counted by the bio(4) in sequence, thus
5246 * substracting the number of disks in the volume
5247 * from the diskid yields us a "relative" hotspare
5248 * number, which is good enough for us.
5249 */
5250 if (bd != NULL && bd->bd_diskid == nhs + nvdsk) {
5251 u_int8_t dn = el->phys_disk_num;
5252
5253 free(cpg, M_TEMP);
5254 return (mpii_bio_disk(sc, bd, dn));
5255 }
5256 nhs++;
5257 }
5258 }
5259
5260 if (hscnt)
5261 *hscnt = nhs;
5262
5263 free(cpg, M_TEMP);
5264 return (0);
5265 }
5266
5267 static int
5268 mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk *bd, u_int8_t dn)
5269 {
5270 struct mpii_cfg_raid_physdisk_pg0 *ppg;
5271 struct mpii_cfg_hdr hdr;
5272 struct mpii_device *dev;
5273 int len;
5274
5275 DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_disk %d\n", DEVNAME(sc),
5276 bd->bd_diskid);
5277
5278 ppg = malloc(sizeof(*ppg), M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
5279 if (ppg == NULL) {
5280 printf("%s: unable to allocate space for raid physical disk "
5281 "page 0\n", DEVNAME(sc));
5282 return (ENOMEM);
5283 }
5284
5285 hdr.page_version = 0;
5286 hdr.page_length = sizeof(*ppg) / 4;
5287 hdr.page_number = 0;
5288 hdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_RAID_PD;
5289
5290 if (mpii_req_cfg_page(sc, MPII_CFG_RAID_PHYS_DISK_ADDR_NUMBER | dn, 0,
5291 &hdr, 1, ppg, sizeof(*ppg)) != 0) {
5292 printf("%s: unable to fetch raid drive page 0\n",
5293 DEVNAME(sc));
5294 free(ppg, M_TEMP);
5295 return (EINVAL);
5296 }
5297
5298 bd->bd_target = ppg->phys_disk_num;
5299
5300 if ((dev = mpii_find_dev(sc, le16toh(ppg->dev_handle))) == NULL) {
5301 bd->bd_status = BIOC_SDINVALID;
5302 free(ppg, M_TEMP);
5303 return (0);
5304 }
5305
5306 switch (ppg->phys_disk_state) {
5307 case MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE:
5308 case MPII_CFG_RAID_PHYDISK_0_STATE_OPTIMAL:
5309 bd->bd_status = BIOC_SDONLINE;
5310 break;
5311 case MPII_CFG_RAID_PHYDISK_0_STATE_OFFLINE:
5312 if (ppg->offline_reason ==
5313 MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILED ||
5314 ppg->offline_reason ==
5315 MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILEDREQ)
5316 bd->bd_status = BIOC_SDFAILED;
5317 else
5318 bd->bd_status = BIOC_SDOFFLINE;
5319 break;
5320 case MPII_CFG_RAID_PHYDISK_0_STATE_DEGRADED:
5321 bd->bd_status = BIOC_SDFAILED;
5322 break;
5323 case MPII_CFG_RAID_PHYDISK_0_STATE_REBUILDING:
5324 bd->bd_status = BIOC_SDREBUILD;
5325 break;
5326 case MPII_CFG_RAID_PHYDISK_0_STATE_HOTSPARE:
5327 bd->bd_status = BIOC_SDHOTSPARE;
5328 break;
5329 case MPII_CFG_RAID_PHYDISK_0_STATE_NOTCONFIGURED:
5330 bd->bd_status = BIOC_SDUNUSED;
5331 break;
5332 case MPII_CFG_RAID_PHYDISK_0_STATE_NOTCOMPATIBLE:
5333 default:
5334 bd->bd_status = BIOC_SDINVALID;
5335 break;
5336 }
5337
5338 bd->bd_size = le64toh(ppg->dev_max_lba) * le16toh(ppg->block_size);
5339
5340 scsipi_strvis(bd->bd_vendor, sizeof(bd->bd_vendor),
5341 ppg->vendor_id, sizeof(ppg->vendor_id));
5342 len = strlen(bd->bd_vendor);
5343 bd->bd_vendor[len] = ' ';
5344 scsipi_strvis(&bd->bd_vendor[len + 1], sizeof(ppg->vendor_id) - len - 1,
5345 ppg->product_id, sizeof(ppg->product_id));
5346 scsipi_strvis(bd->bd_serial, sizeof(bd->bd_serial),
5347 ppg->serial, sizeof(ppg->serial));
5348
5349 free(ppg, M_TEMP);
5350 return (0);
5351 }
5352
5353 static struct mpii_device *
5354 mpii_find_vol(struct mpii_softc *sc, int volid)
5355 {
5356 struct mpii_device *dev = NULL;
5357
5358 if (sc->sc_vd_id_low + volid >= sc->sc_max_devices)
5359 return (NULL);
5360 dev = sc->sc_devs[sc->sc_vd_id_low + volid];
5361 if (dev && ISSET(dev->flags, MPII_DF_VOLUME))
5362 return (dev);
5363 return (NULL);
5364 }
5365
5366 /*
5367 * Non-sleeping lightweight version of the mpii_ioctl_vol
5368 */
5369 static int
5370 mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
5371 {
5372 struct mpii_cfg_raid_vol_pg0 *vpg;
5373 struct mpii_cfg_hdr hdr;
5374 struct mpii_device *dev = NULL;
5375 size_t pagelen;
5376 u_int16_t volh;
5377
5378 if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
5379 return (ENODEV);
5380 volh = dev->dev_handle;
5381
5382 if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
5383 MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, &hdr) != 0) {
5384 DNPRINTF(MPII_D_MISC, "%s: unable to fetch header for raid "
5385 "volume page 0\n", DEVNAME(sc));
5386 return (EINVAL);
5387 }
5388
5389 pagelen = hdr.page_length * 4;
5390 vpg = malloc(pagelen, M_TEMP, M_NOWAIT | M_ZERO);
5391 if (vpg == NULL) {
5392 DNPRINTF(MPII_D_MISC, "%s: unable to allocate space for raid "
5393 "volume page 0\n", DEVNAME(sc));
5394 return (ENOMEM);
5395 }
5396
5397 if (mpii_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh,
5398 &hdr, 1, vpg, pagelen) != 0) {
5399 DNPRINTF(MPII_D_MISC, "%s: unable to fetch raid volume "
5400 "page 0\n", DEVNAME(sc));
5401 free(vpg, M_TEMP);
5402 return (EINVAL);
5403 }
5404
5405 switch (vpg->volume_state) {
5406 case MPII_CFG_RAID_VOL_0_STATE_ONLINE:
5407 case MPII_CFG_RAID_VOL_0_STATE_OPTIMAL:
5408 bv->bv_status = BIOC_SVONLINE;
5409 break;
5410 case MPII_CFG_RAID_VOL_0_STATE_DEGRADED:
5411 if (ISSET(le32toh(vpg->volume_status),
5412 MPII_CFG_RAID_VOL_0_STATUS_RESYNC))
5413 bv->bv_status = BIOC_SVREBUILD;
5414 else
5415 bv->bv_status = BIOC_SVDEGRADED;
5416 break;
5417 case MPII_CFG_RAID_VOL_0_STATE_FAILED:
5418 bv->bv_status = BIOC_SVOFFLINE;
5419 break;
5420 case MPII_CFG_RAID_VOL_0_STATE_INITIALIZING:
5421 bv->bv_status = BIOC_SVBUILDING;
5422 break;
5423 case MPII_CFG_RAID_VOL_0_STATE_MISSING:
5424 default:
5425 bv->bv_status = BIOC_SVINVALID;
5426 break;
5427 }
5428
5429 free(vpg, M_TEMP);
5430 return (0);
5431 }
5432
5433 static int
5434 mpii_create_sensors(struct mpii_softc *sc)
5435 {
5436 int i, rv;
5437
5438 sc->sc_sme = sysmon_envsys_create();
5439 sc->sc_sensors = malloc(sizeof(envsys_data_t) * sc->sc_vd_count,
5440 M_DEVBUF, M_NOWAIT | M_ZERO);
5441 if (sc->sc_sensors == NULL) {
5442 aprint_error_dev(sc->sc_dev,
5443 "can't allocate envsys_data_t\n");
5444 return (1);
5445 }
5446
5447 for (i = 0; i < sc->sc_vd_count; i++) {
5448 sc->sc_sensors[i].units = ENVSYS_DRIVE;
5449 sc->sc_sensors[i].state = ENVSYS_SINVALID;
5450 sc->sc_sensors[i].value_cur = ENVSYS_DRIVE_EMPTY;
5451 /* Enable monitoring for drive state changes */
5452 sc->sc_sensors[i].flags |= ENVSYS_FMONSTCHANGED;
5453
5454 /* logical drives */
5455 snprintf(sc->sc_sensors[i].desc,
5456 sizeof(sc->sc_sensors[i].desc), "%s:%d",
5457 DEVNAME(sc), i);
5458 if ((rv = sysmon_envsys_sensor_attach(sc->sc_sme,
5459 &sc->sc_sensors[i])) != 0) {
5460 aprint_error_dev(sc->sc_dev,
5461 "unable to attach sensor (rv = %d)\n", rv);
5462 goto out;
5463 }
5464 }
5465 sc->sc_sme->sme_name = DEVNAME(sc);
5466 sc->sc_sme->sme_cookie = sc;
5467 sc->sc_sme->sme_refresh = mpii_refresh_sensors;
5468
5469 rv = sysmon_envsys_register(sc->sc_sme);
5470
5471 if (rv != 0) {
5472 aprint_error_dev(sc->sc_dev,
5473 "unable to register with sysmon (rv = %d)\n", rv);
5474 goto out;
5475 }
5476 return 0;
5477
5478 out:
5479 free(sc->sc_sensors, M_DEVBUF);
5480 sysmon_envsys_destroy(sc->sc_sme);
5481 sc->sc_sme = NULL;
5482 return EINVAL;
5483 }
5484
5485 static int
5486 mpii_destroy_sensors(struct mpii_softc *sc)
5487 {
5488 if (sc->sc_sme == NULL)
5489 return 0;
5490 sysmon_envsys_unregister(sc->sc_sme);
5491 sc->sc_sme = NULL;
5492 free(sc->sc_sensors, M_DEVBUF);
5493 return 0;
5494 }
5495
5496 static void
5497 mpii_refresh_sensors(struct sysmon_envsys *sme, envsys_data_t *edata)
5498 {
5499 struct mpii_softc *sc = sc = sme->sme_cookie;
5500 struct bioc_vol bv;
5501 int s, error;
5502
5503 bzero(&bv, sizeof(bv));
5504 bv.bv_volid = edata->sensor;
5505 KERNEL_LOCK(1, curlwp);
5506 s = splbio();
5507 error = mpii_bio_volstate(sc, &bv);
5508 splx(s);
5509 KERNEL_UNLOCK_ONE(curlwp);
5510 if (error)
5511 return;
5512 switch(bv.bv_status) {
5513 case BIOC_SVOFFLINE:
5514 edata->value_cur = ENVSYS_DRIVE_FAIL;
5515 edata->state = ENVSYS_SCRITICAL;
5516 break;
5517 case BIOC_SVDEGRADED:
5518 edata->value_cur = ENVSYS_DRIVE_PFAIL;
5519 edata->state = ENVSYS_SCRITICAL;
5520 break;
5521 case BIOC_SVREBUILD:
5522 edata->value_cur = ENVSYS_DRIVE_REBUILD;
5523 edata->state = ENVSYS_SVALID;
5524 break;
5525 case BIOC_SVONLINE:
5526 edata->value_cur = ENVSYS_DRIVE_ONLINE;
5527 edata->state = ENVSYS_SVALID;
5528 break;
5529 case BIOC_SVINVALID:
5530 /* FALLTHROUGH */
5531 default:
5532 edata->value_cur = 0; /* unknown */
5533 edata->state = ENVSYS_SINVALID;
5534 }
5535 }
5536 #endif /* NBIO > 0 */
5537