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