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