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