summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/Storage/DevLsiLogicSCSI.h
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/Storage/DevLsiLogicSCSI.h')
-rw-r--r--src/VBox/Devices/Storage/DevLsiLogicSCSI.h3531
1 files changed, 3531 insertions, 0 deletions
diff --git a/src/VBox/Devices/Storage/DevLsiLogicSCSI.h b/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
new file mode 100644
index 00000000..9af14623
--- /dev/null
+++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
@@ -0,0 +1,3531 @@
+/* $Id: DevLsiLogicSCSI.h $ */
+/** @file
+ * VBox storage devices: LsiLogic LSI53c1030 SCSI controller - Defines and structures.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef VBOX_INCLUDED_SRC_Storage_DevLsiLogicSCSI_h
+#define VBOX_INCLUDED_SRC_Storage_DevLsiLogicSCSI_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/stdint.h>
+
+/*
+ * Custom fixed I/O ports for BIOS controller access. Note that these should
+ * not be in the ISA range (below 400h) to avoid conflicts with ISA device
+ * probing. Addresses in the 300h-340h range should be especially avoided.
+ */
+#define LSILOGIC_BIOS_IO_PORT 0x434
+#define LSILOGIC_SAS_BIOS_IO_PORT 0x438
+
+#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN 8 /**< (bird just picked this out thin air) */
+#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX 1024 /**< (bird just picked this out thin air) */
+#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT 256
+
+#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN 8 /**< (bird just picked this out thin air) */
+#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX 1024 /**< (bird just picked this out thin air) */
+#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_DEFAULT 256
+
+#define LSILOGICSCSI_MAXIMUM_CHAIN_DEPTH 3
+
+#define LSILOGIC_NR_OF_ALLOWED_BIGGER_LISTS 100
+
+/** Equal for all devices */
+#define LSILOGICSCSI_PCI_VENDOR_ID (0x1000)
+
+/** SPI SCSI controller (LSI53C1030) */
+#define LSILOGICSCSI_PCI_SPI_CTRLNAME "LSI53C1030"
+#define LSILOGICSCSI_PCI_SPI_DEVICE_ID (0x0030)
+#define LSILOGICSCSI_PCI_SPI_REVISION_ID (0x00)
+#define LSILOGICSCSI_PCI_SPI_CLASS_CODE (0x01)
+#define LSILOGICSCSI_PCI_SPI_SUBSYSTEM_VENDOR_ID (0x1000)
+#define LSILOGICSCSI_PCI_SPI_SUBSYSTEM_ID (0x8000)
+#define LSILOGICSCSI_PCI_SPI_PORTS_MAX 1
+#define LSILOGICSCSI_PCI_SPI_BUSES_MAX 1
+#define LSILOGICSCSI_PCI_SPI_DEVICES_PER_BUS_MAX 16
+#define LSILOGICSCSI_PCI_SPI_DEVICES_MAX (LSILOGICSCSI_PCI_SPI_BUSES_MAX*LSILOGICSCSI_PCI_SPI_DEVICES_PER_BUS_MAX)
+
+/** SAS SCSI controller (SAS1068 PCI-X Fusion-MPT SAS) */
+#define LSILOGICSCSI_PCI_SAS_CTRLNAME "SAS1068"
+#define LSILOGICSCSI_PCI_SAS_DEVICE_ID (0x0054)
+#define LSILOGICSCSI_PCI_SAS_REVISION_ID (0x00)
+#define LSILOGICSCSI_PCI_SAS_CLASS_CODE (0x00)
+#define LSILOGICSCSI_PCI_SAS_SUBSYSTEM_VENDOR_ID (0x1000)
+#define LSILOGICSCSI_PCI_SAS_SUBSYSTEM_ID (0x8000)
+#define LSILOGICSCSI_PCI_SAS_PORTS_MAX 256
+#define LSILOGICSCSI_PCI_SAS_PORTS_DEFAULT 8
+#define LSILOGICSCSI_PCI_SAS_DEVICES_PER_PORT_MAX 1
+#define LSILOGICSCSI_PCI_SAS_DEVICES_MAX (LSILOGICSCSI_PCI_SAS_PORTS_MAX * LSILOGICSCSI_PCI_SAS_DEVICES_PER_PORT_MAX)
+
+/**
+ * A SAS address.
+ */
+typedef union SASADDRESS
+{
+ /** 64bit view. */
+ uint64_t u64Address;
+ /** 32bit view. */
+ uint32_t u32Address[2];
+ /** 16bit view. */
+ uint16_t u16Address[4];
+ /** Byte view. */
+ uint8_t u8Address[8];
+} SASADDRESS, *PSASADDRESS;
+AssertCompileSize(SASADDRESS, 8);
+
+/**
+ * Possible device types we support.
+ */
+typedef enum LSILOGICCTRLTYPE
+{
+ /** SPI SCSI controller (PCI dev id 0x0030) */
+ LSILOGICCTRLTYPE_SCSI_SPI = 0,
+ /** SAS SCSI controller (PCI dev id 0x0054) */
+ LSILOGICCTRLTYPE_SCSI_SAS = 1,
+ /** 32bit hack */
+ LSILOGICCTRLTYPE_32BIT_HACK = 0x7fffffff
+} LSILOGICCTRLTYPE, *PLSILOGICCTRLTYPE;
+
+/**
+ * A simple SG element for a 64bit address.
+ */
+typedef struct MptSGEntrySimple64
+{
+ /** Length of the buffer this entry describes. */
+ unsigned u24Length: 24;
+ /** Flag whether this element is the end of the list. */
+ unsigned fEndOfList: 1;
+ /** Flag whether the address is 32bit or 64bits wide. */
+ unsigned f64BitAddress: 1;
+ /** Flag whether this buffer contains data to be transferred or is the destination. */
+ unsigned fBufferContainsData: 1;
+ /** Flag whether this is a local address or a system address. */
+ unsigned fLocalAddress: 1;
+ /** Element type. */
+ unsigned u2ElementType: 2;
+ /** Flag whether this is the last element of the buffer. */
+ unsigned fEndOfBuffer: 1;
+ /** Flag whether this is the last element of the current segment. */
+ unsigned fLastElement: 1;
+ /** Lower 32bits of the address of the data buffer. */
+ unsigned u32DataBufferAddressLow: 32;
+ /** Upper 32bits of the address of the data buffer. */
+ unsigned u32DataBufferAddressHigh: 32;
+} MptSGEntrySimple64, *PMptSGEntrySimple64;
+AssertCompileSize(MptSGEntrySimple64, 12);
+
+/**
+ * A simple SG element for a 32bit address.
+ */
+typedef struct MptSGEntrySimple32
+{
+ /** Length of the buffer this entry describes. */
+ unsigned u24Length: 24;
+ /** Flag whether this element is the end of the list. */
+ unsigned fEndOfList: 1;
+ /** Flag whether the address is 32bit or 64bits wide. */
+ unsigned f64BitAddress: 1;
+ /** Flag whether this buffer contains data to be transferred or is the destination. */
+ unsigned fBufferContainsData: 1;
+ /** Flag whether this is a local address or a system address. */
+ unsigned fLocalAddress: 1;
+ /** Element type. */
+ unsigned u2ElementType: 2;
+ /** Flag whether this is the last element of the buffer. */
+ unsigned fEndOfBuffer: 1;
+ /** Flag whether this is the last element of the current segment. */
+ unsigned fLastElement: 1;
+ /** Lower 32bits of the address of the data buffer. */
+ unsigned u32DataBufferAddressLow: 32;
+} MptSGEntrySimple32, *PMptSGEntrySimple32;
+AssertCompileSize(MptSGEntrySimple32, 8);
+
+/**
+ * A chain SG element.
+ */
+typedef struct MptSGEntryChain
+{
+ /** Size of the segment. */
+ unsigned u16Length: 16;
+ /** Offset in 32bit words of the next chain element in the segment
+ * identified by this element. */
+ unsigned u8NextChainOffset: 8;
+ /** Reserved. */
+ unsigned fReserved0: 1;
+ /** Flag whether the address is 32bit or 64bits wide. */
+ unsigned f64BitAddress: 1;
+ /** Reserved. */
+ unsigned fReserved1: 1;
+ /** Flag whether this is a local address or a system address. */
+ unsigned fLocalAddress: 1;
+ /** Element type. */
+ unsigned u2ElementType: 2;
+ /** Flag whether this is the last element of the buffer. */
+ unsigned u2Reserved2: 2;
+ /** Lower 32bits of the address of the data buffer. */
+ unsigned u32SegmentAddressLow: 32;
+ /** Upper 32bits of the address of the data buffer. */
+ unsigned u32SegmentAddressHigh: 32;
+} MptSGEntryChain, *PMptSGEntryChain;
+AssertCompileSize(MptSGEntryChain, 12);
+
+typedef union MptSGEntryUnion
+{
+ MptSGEntrySimple64 Simple64;
+ MptSGEntrySimple32 Simple32;
+ MptSGEntryChain Chain;
+} MptSGEntryUnion, *PMptSGEntryUnion;
+
+/**
+ * MPT Fusion message header - Common for all message frames.
+ * This is filled in by the guest.
+ */
+typedef struct MptMessageHdr
+{
+ /** Function dependent data. */
+ uint16_t u16FunctionDependent;
+ /** Chain offset. */
+ uint8_t u8ChainOffset;
+ /** The function code. */
+ uint8_t u8Function;
+ /** Function dependent data. */
+ uint8_t au8FunctionDependent[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context - Unique ID from the guest unmodified by the device. */
+ uint32_t u32MessageContext;
+} MptMessageHdr, *PMptMessageHdr;
+AssertCompileSize(MptMessageHdr, 12);
+
+/** Defined function codes found in the message header. */
+#define MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST (0x00)
+#define MPT_MESSAGE_HDR_FUNCTION_SCSI_TASK_MGMT (0x01)
+#define MPT_MESSAGE_HDR_FUNCTION_IOC_INIT (0x02)
+#define MPT_MESSAGE_HDR_FUNCTION_IOC_FACTS (0x03)
+#define MPT_MESSAGE_HDR_FUNCTION_CONFIG (0x04)
+#define MPT_MESSAGE_HDR_FUNCTION_PORT_FACTS (0x05)
+#define MPT_MESSAGE_HDR_FUNCTION_PORT_ENABLE (0x06)
+#define MPT_MESSAGE_HDR_FUNCTION_EVENT_NOTIFICATION (0x07)
+#define MPT_MESSAGE_HDR_FUNCTION_EVENT_ACK (0x08)
+#define MPT_MESSAGE_HDR_FUNCTION_FW_DOWNLOAD (0x09)
+#define MPT_MESSAGE_HDR_FUNCTION_TARGET_CMD_BUFFER_POST (0x0A)
+#define MPT_MESSAGE_HDR_FUNCTION_TARGET_ASSIST (0x0B)
+#define MPT_MESSAGE_HDR_FUNCTION_TARGET_STATUS_SEND (0x0C)
+#define MPT_MESSAGE_HDR_FUNCTION_TARGET_MODE_ABORT (0x0D)
+#define MPT_MESSAGE_HDR_FUNCTION_FW_UPLOAD (0x12)
+
+#ifdef DEBUG
+/**
+ * Function names
+ */
+static const char * const g_apszMPTFunctionNames[] =
+{
+ "SCSI I/O Request",
+ "SCSI Task Management",
+ "IOC Init",
+ "IOC Facts",
+ "Config",
+ "Port Facts",
+ "Port Enable",
+ "Event Notification",
+ "Event Ack",
+ "Firmware Download"
+};
+#endif
+
+/**
+ * Default reply message.
+ * Send from the device to the guest upon completion of a request.
+ */
+typedef struct MptDefaultReplyMessage
+{
+ /** Function dependent data. */
+ uint16_t u16FunctionDependent;
+ /** Length of the message in 32bit DWords. */
+ uint8_t u8MessageLength;
+ /** Function which completed. */
+ uint8_t u8Function;
+ /** Function dependent. */
+ uint8_t au8FunctionDependent[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context given in the request. */
+ uint32_t u32MessageContext;
+ /** Function dependent status code. */
+ uint16_t u16FunctionDependentStatus;
+ /** Status of the IOC. */
+ uint16_t u16IOCStatus;
+ /** Additional log info. */
+ uint32_t u32IOCLogInfo;
+} MptDefaultReplyMessage, *PMptDefaultReplyMessage;
+AssertCompileSize(MptDefaultReplyMessage, 20);
+
+/**
+ * IO controller init request.
+ */
+typedef struct MptIOCInitRequest
+{
+ /** Which system send this init request. */
+ uint8_t u8WhoInit;
+ /** Reserved */
+ uint8_t u8Reserved;
+ /** Chain offset in the SG list. */
+ uint8_t u8ChainOffset;
+ /** Function to execute. */
+ uint8_t u8Function;
+ /** Flags */
+ uint8_t u8Flags;
+ /** Maximum number of devices the driver can handle. */
+ uint8_t u8MaxDevices;
+ /** Maximum number of buses the driver can handle. */
+ uint8_t u8MaxBuses;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reply frame size. */
+ uint16_t u16ReplyFrameSize;
+ /** Reserved */
+ uint16_t u16Reserved;
+ /** Upper 32bit part of the 64bit address the message frames are in.
+ * That means all frames must be in the same 4GB segment. */
+ uint32_t u32HostMfaHighAddr;
+ /** Upper 32bit of the sense buffer. */
+ uint32_t u32SenseBufferHighAddr;
+} MptIOCInitRequest, *PMptIOCInitRequest;
+AssertCompileSize(MptIOCInitRequest, 24);
+
+/**
+ * IO controller init reply.
+ */
+typedef struct MptIOCInitReply
+{
+ /** Which subsystem send this init request. */
+ uint8_t u8WhoInit;
+ /** Reserved */
+ uint8_t u8Reserved;
+ /** Message length */
+ uint8_t u8MessageLength;
+ /** Function. */
+ uint8_t u8Function;
+ /** Flags */
+ uint8_t u8Flags;
+ /** Maximum number of devices the driver can handle. */
+ uint8_t u8MaxDevices;
+ /** Maximum number of busses the driver can handle. */
+ uint8_t u8MaxBuses;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID */
+ uint32_t u32MessageContext;
+ /** Reserved */
+ uint16_t u16Reserved;
+ /** IO controller status. */
+ uint16_t u16IOCStatus;
+ /** IO controller log information. */
+ uint32_t u32IOCLogInfo;
+} MptIOCInitReply, *PMptIOCInitReply;
+AssertCompileSize(MptIOCInitReply, 20);
+
+/**
+ * IO controller facts request.
+ */
+typedef struct MptIOCFactsRequest
+{
+ /** Reserved. */
+ uint16_t u16Reserved;
+ /** Chain offset in SG list. */
+ uint8_t u8ChainOffset;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved */
+ uint8_t u8Reserved[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+} MptIOCFactsRequest, *PMptIOCFactsRequest;
+AssertCompileSize(MptIOCFactsRequest, 12);
+
+/**
+ * IO controller facts reply.
+ */
+typedef struct MptIOCFactsReply
+{
+ /** Message version. */
+ uint16_t u16MessageVersion;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved */
+ uint16_t u16Reserved1;
+ /** IO controller number */
+ uint8_t u8IOCNumber;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** IO controller exceptions */
+ uint16_t u16IOCExceptions;
+ /** IO controller status. */
+ uint16_t u16IOCStatus;
+ /** IO controller log information. */
+ uint32_t u32IOCLogInfo;
+ /** Maximum chain depth. */
+ uint8_t u8MaxChainDepth;
+ /** The current value of the WhoInit field. */
+ uint8_t u8WhoInit;
+ /** Block size. */
+ uint8_t u8BlockSize;
+ /** Flags. */
+ uint8_t u8Flags;
+ /** Depth of the reply queue. */
+ uint16_t u16ReplyQueueDepth;
+ /** Size of a request frame. */
+ uint16_t u16RequestFrameSize;
+ /** Reserved */
+ uint16_t u16Reserved2;
+ /** Product ID. */
+ uint16_t u16ProductID;
+ /** Current value of the high 32bit MFA address. */
+ uint32_t u32CurrentHostMFAHighAddr;
+ /** Global credits - Number of entries allocated to queues */
+ uint16_t u16GlobalCredits;
+ /** Number of ports on the IO controller */
+ uint8_t u8NumberOfPorts;
+ /** Event state. */
+ uint8_t u8EventState;
+ /** Current value of the high 32bit sense buffer address. */
+ uint32_t u32CurrentSenseBufferHighAddr;
+ /** Current reply frame size. */
+ uint16_t u16CurReplyFrameSize;
+ /** Maximum number of devices. */
+ uint8_t u8MaxDevices;
+ /** Maximum number of buses. */
+ uint8_t u8MaxBuses;
+ /** Size of the firmware image. */
+ uint32_t u32FwImageSize;
+ /** Reserved. */
+ uint32_t u32Reserved;
+ /** Firmware version */
+ uint32_t u32FWVersion;
+} MptIOCFactsReply, *PMptIOCFactsReply;
+AssertCompileSize(MptIOCFactsReply, 60);
+
+/**
+ * Port facts request
+ */
+typedef struct MptPortFactsRequest
+{
+ /** Reserved */
+ uint16_t u16Reserved1;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved */
+ uint16_t u16Reserved2;
+ /** Port number to get facts for. */
+ uint8_t u8PortNumber;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+} MptPortFactsRequest, *PMptPortFactsRequest;
+AssertCompileSize(MptPortFactsRequest, 12);
+
+/**
+ * Port facts reply.
+ */
+typedef struct MptPortFactsReply
+{
+ /** Reserved. */
+ uint16_t u16Reserved1;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved */
+ uint16_t u16Reserved2;
+ /** Port number the facts are for. */
+ uint8_t u8PortNumber;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reserved. */
+ uint16_t u16Reserved3;
+ /** IO controller status. */
+ uint16_t u16IOCStatus;
+ /** IO controller log information. */
+ uint32_t u32IOCLogInfo;
+ /** Reserved */
+ uint8_t u8Reserved;
+ /** Port type */
+ uint8_t u8PortType;
+ /** Maximum number of devices on this port. */
+ uint16_t u16MaxDevices;
+ /** SCSI ID of this port on the attached bus. */
+ uint16_t u16PortSCSIID;
+ /** Protocol flags. */
+ uint16_t u16ProtocolFlags;
+ /** Maximum number of target command buffers which can be posted to this port at a time. */
+ uint16_t u16MaxPostedCmdBuffers;
+ /** Maximum number of target IDs that remain persistent between power/reset cycles. */
+ uint16_t u16MaxPersistentIDs;
+ /** Maximum number of LAN buckets. */
+ uint16_t u16MaxLANBuckets;
+ /** Reserved. */
+ uint16_t u16Reserved4;
+ /** Reserved. */
+ uint32_t u32Reserved;
+} MptPortFactsReply, *PMptPortFactsReply;
+AssertCompileSize(MptPortFactsReply, 40);
+
+/**
+ * Port Enable request.
+ */
+typedef struct MptPortEnableRequest
+{
+ /** Reserved. */
+ uint16_t u16Reserved1;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved. */
+ uint16_t u16Reserved2;
+ /** Port number to enable. */
+ uint8_t u8PortNumber;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+} MptPortEnableRequest, *PMptPortEnableRequest;
+AssertCompileSize(MptPortEnableRequest, 12);
+
+/**
+ * Port enable reply.
+ */
+typedef struct MptPortEnableReply
+{
+ /** Reserved. */
+ uint16_t u16Reserved1;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved */
+ uint16_t u16Reserved2;
+ /** Port number which was enabled. */
+ uint8_t u8PortNumber;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reserved. */
+ uint16_t u16Reserved3;
+ /** IO controller status */
+ uint16_t u16IOCStatus;
+ /** IO controller log information. */
+ uint32_t u32IOCLogInfo;
+} MptPortEnableReply, *PMptPortEnableReply;
+AssertCompileSize(MptPortEnableReply, 20);
+
+/**
+ * Event notification request.
+ */
+typedef struct MptEventNotificationRequest
+{
+ /** Switch - Turns event notification on and off. */
+ uint8_t u8Switch;
+ /** Reserved. */
+ uint8_t u8Reserved1;
+ /** Chain offset. */
+ uint8_t u8ChainOffset;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved. */
+ uint8_t u8reserved2[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+} MptEventNotificationRequest, *PMptEventNotificationRequest;
+AssertCompileSize(MptEventNotificationRequest, 12);
+
+/**
+ * Event notification reply.
+ */
+typedef struct MptEventNotificationReply
+{
+ /** Event data length. */
+ uint16_t u16EventDataLength;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved. */
+ uint16_t u16Reserved1;
+ /** Ack required. */
+ uint8_t u8AckRequired;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reserved. */
+ uint16_t u16Reserved2;
+ /** IO controller status. */
+ uint16_t u16IOCStatus;
+ /** IO controller log information. */
+ uint32_t u32IOCLogInfo;
+ /** Notification event. */
+ uint32_t u32Event;
+ /** Event context. */
+ uint32_t u32EventContext;
+ /** Event data. */
+ uint32_t u32EventData;
+} MptEventNotificationReply, *PMptEventNotificationReply;
+AssertCompileSize(MptEventNotificationReply, 32);
+
+#define MPT_EVENT_EVENT_CHANGE (0x0000000a)
+
+/**
+ * FW download request.
+ */
+typedef struct MptFWDownloadRequest
+{
+ /** Switch - Turns event notification on and off. */
+ uint8_t u8ImageType;
+ /** Reserved. */
+ uint8_t u8Reserved1;
+ /** Chain offset. */
+ uint8_t u8ChainOffset;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved. */
+ uint8_t u8Reserved2[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+} MptFWDownloadRequest, *PMptFWDownloadRequest;
+AssertCompileSize(MptFWDownloadRequest, 12);
+
+#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_RESERVED 0
+#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_FIRMWARE 1
+#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_MPI_BIOS 2
+#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_NVDATA 3
+
+/**
+ * FW download reply.
+ */
+typedef struct MptFWDownloadReply
+{
+ /** Reserved. */
+ uint16_t u16Reserved1;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved. */
+ uint8_t u8Reserved2[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reserved. */
+ uint16_t u16Reserved2;
+ /** IO controller status. */
+ uint16_t u16IOCStatus;
+ /** IO controller log information. */
+ uint32_t u32IOCLogInfo;
+} MptFWDownloadReply, *PMptFWDownloadReply;
+AssertCompileSize(MptFWDownloadReply, 20);
+
+/**
+ * FW upload request.
+ */
+typedef struct MptFWUploadRequest
+{
+ /** Requested image type. */
+ uint8_t u8ImageType;
+ /** Reserved. */
+ uint8_t u8Reserved1;
+ /** Chain offset. */
+ uint8_t u8ChainOffset;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved. */
+ uint8_t u8Reserved2[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+} MptFWUploadRequest, *PMptFWUploadRequest;
+AssertCompileSize(MptFWUploadRequest, 12);
+
+/**
+ * FW upload reply.
+ */
+typedef struct MptFWUploadReply
+{
+ /** Image type. */
+ uint8_t u8ImageType;
+ /** Reserved. */
+ uint8_t u8Reserved1;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Reserved. */
+ uint8_t u8Reserved2[3];
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reserved. */
+ uint16_t u16Reserved2;
+ /** IO controller status. */
+ uint16_t u16IOCStatus;
+ /** IO controller log information. */
+ uint32_t u32IOCLogInfo;
+ /** Uploaded image size. */
+ uint32_t u32ActualImageSize;
+} MptFWUploadReply, *PMptFWUploadReply;
+AssertCompileSize(MptFWUploadReply, 24);
+
+/**
+ * SCSI IO Request
+ */
+typedef struct MptSCSIIORequest
+{
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus number */
+ uint8_t u8Bus;
+ /** Chain offset */
+ uint8_t u8ChainOffset;
+ /** Function number. */
+ uint8_t u8Function;
+ /** CDB length. */
+ uint8_t u8CDBLength;
+ /** Sense buffer length. */
+ uint8_t u8SenseBufferLength;
+ /** Reserved */
+ uint8_t u8Reserved;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** LUN */
+ uint8_t au8LUN[8];
+ /** Control values. */
+ uint32_t u32Control;
+ /** The CDB. */
+ uint8_t au8CDB[16];
+ /** Data length. */
+ uint32_t u32DataLength;
+ /** Sense buffer low 32bit address. */
+ uint32_t u32SenseBufferLowAddress;
+} MptSCSIIORequest, *PMptSCSIIORequest;
+AssertCompileSize(MptSCSIIORequest, 48);
+
+#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_GET(x) (((x) & 0x3000000) >> 24)
+#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE (0x0)
+#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE (0x1)
+#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ (0x2)
+
+/**
+ * SCSI IO error reply.
+ */
+typedef struct MptSCSIIOErrorReply
+{
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus number */
+ uint8_t u8Bus;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** CDB length */
+ uint8_t u8CDBLength;
+ /** Sense buffer length */
+ uint8_t u8SenseBufferLength;
+ /** Reserved */
+ uint8_t u8Reserved;
+ /** Message flags */
+ uint8_t u8MessageFlags;
+ /** Message context ID */
+ uint32_t u32MessageContext;
+ /** SCSI status. */
+ uint8_t u8SCSIStatus;
+ /** SCSI state */
+ uint8_t u8SCSIState;
+ /** IO controller status */
+ uint16_t u16IOCStatus;
+ /** IO controller log information */
+ uint32_t u32IOCLogInfo;
+ /** Transfer count */
+ uint32_t u32TransferCount;
+ /** Sense count */
+ uint32_t u32SenseCount;
+ /** Response information */
+ uint32_t u32ResponseInfo;
+} MptSCSIIOErrorReply, *PMptSCSIIOErrorReply;
+AssertCompileSize(MptSCSIIOErrorReply, 32);
+
+#define MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID (0x01)
+#define MPT_SCSI_IO_ERROR_SCSI_STATE_TERMINATED (0x08)
+
+/**
+ * IOC status codes specific to the SCSI I/O error reply.
+ */
+#define MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_BUS (0x0041)
+#define MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_TARGETID (0x0042)
+#define MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE (0x0043)
+
+/**
+ * SCSI task management request.
+ */
+typedef struct MptSCSITaskManagementRequest
+{
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus number */
+ uint8_t u8Bus;
+ /** Chain offset */
+ uint8_t u8ChainOffset;
+ /** Function number */
+ uint8_t u8Function;
+ /** Reserved */
+ uint8_t u8Reserved1;
+ /** Task type */
+ uint8_t u8TaskType;
+ /** Reserved */
+ uint8_t u8Reserved2;
+ /** Message flags */
+ uint8_t u8MessageFlags;
+ /** Message context ID */
+ uint32_t u32MessageContext;
+ /** LUN */
+ uint8_t au8LUN[8];
+ /** Reserved */
+ uint8_t auReserved[28];
+ /** Task message context ID. */
+ uint32_t u32TaskMessageContext;
+} MptSCSITaskManagementRequest, *PMptSCSITaskManagementRequest;
+AssertCompileSize(MptSCSITaskManagementRequest, 52);
+
+/**
+ * SCSI task management reply.
+ */
+typedef struct MptSCSITaskManagementReply
+{
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus number */
+ uint8_t u8Bus;
+ /** Message length */
+ uint8_t u8MessageLength;
+ /** Function number */
+ uint8_t u8Function;
+ /** Reserved */
+ uint8_t u8Reserved1;
+ /** Task type */
+ uint8_t u8TaskType;
+ /** Reserved */
+ uint8_t u8Reserved2;
+ /** Message flags */
+ uint8_t u8MessageFlags;
+ /** Message context ID */
+ uint32_t u32MessageContext;
+ /** Reserved */
+ uint16_t u16Reserved;
+ /** IO controller status */
+ uint16_t u16IOCStatus;
+ /** IO controller log information */
+ uint32_t u32IOCLogInfo;
+ /** Termination count */
+ uint32_t u32TerminationCount;
+} MptSCSITaskManagementReply, *PMptSCSITaskManagementReply;
+AssertCompileSize(MptSCSITaskManagementReply, 24);
+
+/**
+ * Page address for SAS expander page types.
+ */
+typedef union MptConfigurationPageAddressSASExpander
+{
+ struct
+ {
+ uint16_t u16Handle;
+ uint16_t u16Reserved;
+ } Form0And2;
+ struct
+ {
+ uint16_t u16Handle;
+ uint8_t u8PhyNum;
+ uint8_t u8Reserved;
+ } Form1;
+} MptConfigurationPageAddressSASExpander, *PMptConfigurationPageAddressSASExpander;
+AssertCompileSize(MptConfigurationPageAddressSASExpander, 4);
+
+/**
+ * Page address for SAS device page types.
+ */
+typedef union MptConfigurationPageAddressSASDevice
+{
+ struct
+ {
+ uint16_t u16Handle;
+ uint16_t u16Reserved;
+ } Form0And2;
+ struct
+ {
+ uint8_t u8TargetID;
+ uint8_t u8Bus;
+ uint8_t u8Reserved;
+ } Form1; /**< r=bird: only three bytes? */
+} MptConfigurationPageAddressSASDevice, *PMptConfigurationPageAddressSASDevice;
+AssertCompileSize(MptConfigurationPageAddressSASDevice, 4);
+
+/**
+ * Page address for SAS PHY page types.
+ */
+typedef union MptConfigurationPageAddressSASPHY
+{
+ struct
+ {
+ uint8_t u8PhyNumber;
+ uint8_t u8Reserved[3];
+ } Form0;
+ struct
+ {
+ uint16_t u16Index;
+ uint16_t u16Reserved;
+ } Form1;
+} MptConfigurationPageAddressSASPHY, *PMptConfigurationPageAddressSASPHY;
+AssertCompileSize(MptConfigurationPageAddressSASPHY, 4);
+
+/**
+ * Page address for SAS Enclosure page types.
+ */
+typedef struct MptConfigurationPageAddressSASEnclosure
+{
+ uint16_t u16Handle;
+ uint16_t u16Reserved;
+} MptConfigurationPageAddressSASEnclosure, *PMptConfigurationPageAddressSASEnclosure;
+AssertCompileSize(MptConfigurationPageAddressSASEnclosure, 4);
+
+/**
+ * Union of all possible address types.
+ */
+typedef union MptConfigurationPageAddress
+{
+ /** 32bit view. */
+ uint32_t u32PageAddress;
+ struct
+ {
+ /** Port number to get the configuration page for. */
+ uint8_t u8PortNumber;
+ /** Reserved. */
+ uint8_t u8Reserved[3];
+ } MPIPortNumber;
+ struct
+ {
+ /** Target ID to get the configuration page for. */
+ uint8_t u8TargetID;
+ /** Bus number to get the configuration page for. */
+ uint8_t u8Bus;
+ /** Reserved. */
+ uint8_t u8Reserved[2];
+ } BusAndTargetId;
+ MptConfigurationPageAddressSASExpander SASExpander;
+ MptConfigurationPageAddressSASDevice SASDevice;
+ MptConfigurationPageAddressSASPHY SASPHY;
+ MptConfigurationPageAddressSASEnclosure SASEnclosure;
+} MptConfigurationPageAddress, *PMptConfigurationPageAddress;
+AssertCompileSize(MptConfigurationPageAddress, 4);
+
+#define MPT_CONFIGURATION_PAGE_ADDRESS_GET_SAS_FORM(x) (((x).u32PageAddress >> 28) & 0x0f)
+
+/**
+ * Configuration request
+ */
+typedef struct MptConfigurationRequest
+{
+ /** Action code. */
+ uint8_t u8Action;
+ /** Reserved. */
+ uint8_t u8Reserved1;
+ /** Chain offset. */
+ uint8_t u8ChainOffset;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Extended page length. */
+ uint16_t u16ExtPageLength;
+ /** Extended page type */
+ uint8_t u8ExtPageType;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reserved. */
+ uint8_t u8Reserved2[8];
+ /** Version number of the page. */
+ uint8_t u8PageVersion;
+ /** Length of the page in 32bit Dwords. */
+ uint8_t u8PageLength;
+ /** Page number to access. */
+ uint8_t u8PageNumber;
+ /** Type of the page being accessed. */
+ uint8_t u8PageType;
+ /** Page type dependent address. */
+ MptConfigurationPageAddress PageAddress;
+ /** Simple SG element describing the buffer. */
+ MptSGEntrySimple64 SimpleSGElement;
+} MptConfigurationRequest, *PMptConfigurationRequest;
+AssertCompileSize(MptConfigurationRequest, 40);
+
+/** Possible action codes. */
+#define MPT_CONFIGURATION_REQUEST_ACTION_HEADER (0x00)
+#define MPT_CONFIGURATION_REQUEST_ACTION_READ_CURRENT (0x01)
+#define MPT_CONFIGURATION_REQUEST_ACTION_WRITE_CURRENT (0x02)
+#define MPT_CONFIGURATION_REQUEST_ACTION_DEFAULT (0x03)
+#define MPT_CONFIGURATION_REQUEST_ACTION_WRITE_NVRAM (0x04)
+#define MPT_CONFIGURATION_REQUEST_ACTION_READ_DEFAULT (0x05)
+#define MPT_CONFIGURATION_REQUEST_ACTION_READ_NVRAM (0x06)
+
+/** Page type codes. */
+#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_IO_UNIT (0x00)
+#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_IOC (0x01)
+#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_BIOS (0x02)
+#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_SCSI_PORT (0x03)
+#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_EXTENDED (0x0F)
+
+/**
+ * Configuration reply.
+ */
+typedef struct MptConfigurationReply
+{
+ /** Action code. */
+ uint8_t u8Action;
+ /** Reserved. */
+ uint8_t u8Reserved;
+ /** Message length. */
+ uint8_t u8MessageLength;
+ /** Function number. */
+ uint8_t u8Function;
+ /** Extended page length. */
+ uint16_t u16ExtPageLength;
+ /** Extended page type */
+ uint8_t u8ExtPageType;
+ /** Message flags. */
+ uint8_t u8MessageFlags;
+ /** Message context ID. */
+ uint32_t u32MessageContext;
+ /** Reserved. */
+ uint16_t u16Reserved;
+ /** I/O controller status. */
+ uint16_t u16IOCStatus;
+ /** I/O controller log information. */
+ uint32_t u32IOCLogInfo;
+ /** Version number of the page. */
+ uint8_t u8PageVersion;
+ /** Length of the page in 32bit Dwords. */
+ uint8_t u8PageLength;
+ /** Page number to access. */
+ uint8_t u8PageNumber;
+ /** Type of the page being accessed. */
+ uint8_t u8PageType;
+} MptConfigurationReply, *PMptConfigurationReply;
+AssertCompileSize(MptConfigurationReply, 24);
+
+/** Additional I/O controller status codes for the configuration reply. */
+#define MPT_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020)
+#define MPT_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021)
+#define MPT_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022)
+#define MPT_IOCSTATUS_CONFIG_INVALID_DATA (0x0023)
+#define MPT_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024)
+#define MPT_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025)
+
+/**
+ * Union of all possible request messages.
+ */
+typedef union MptRequestUnion
+{
+ MptMessageHdr Header;
+ MptIOCInitRequest IOCInit;
+ MptIOCFactsRequest IOCFacts;
+ MptPortFactsRequest PortFacts;
+ MptPortEnableRequest PortEnable;
+ MptEventNotificationRequest EventNotification;
+ MptSCSIIORequest SCSIIO;
+ MptSCSITaskManagementRequest SCSITaskManagement;
+ MptConfigurationRequest Configuration;
+ MptFWDownloadRequest FWDownload;
+ MptFWUploadRequest FWUpload;
+} MptRequestUnion, *PMptRequestUnion;
+
+/**
+ * Union of all possible reply messages.
+ */
+typedef union MptReplyUnion
+{
+ /** 16bit view. */
+ uint16_t au16Reply[30];
+ MptDefaultReplyMessage Header;
+ MptIOCInitReply IOCInit;
+ MptIOCFactsReply IOCFacts;
+ MptPortFactsReply PortFacts;
+ MptPortEnableReply PortEnable;
+ MptEventNotificationReply EventNotification;
+ MptSCSIIOErrorReply SCSIIOError;
+ MptSCSITaskManagementReply SCSITaskManagement;
+ MptConfigurationReply Configuration;
+ MptFWDownloadReply FWDownload;
+ MptFWUploadReply FWUpload;
+} MptReplyUnion, *PMptReplyUnion;
+AssertCompileSize(MptReplyUnion, 60);
+
+/**
+ * Firmware image header.
+ */
+typedef struct FwImageHdr
+{
+ /** ARM branch instruction. */
+ uint32_t u32ArmBrInsn;
+ /** Signature part 1. */
+ uint32_t u32Signature1;
+ /** Signature part 2. */
+ uint32_t u32Signature2;
+ /** Signature part 3. */
+ uint32_t u32Signature3;
+ /** Another ARM branch instruction. */
+ uint32_t u32ArmBrInsn2;
+ /** Yet another ARM branch instruction. */
+ uint32_t u32ArmBrInsn3;
+ /** Reserved. */
+ uint32_t u32Reserved;
+ /** Checksum of the image. */
+ uint32_t u32Checksum;
+ /** Vendor ID. */
+ uint16_t u16VendorId;
+ /** Product ID. */
+ uint16_t u16ProductId;
+ /** Firmware version. */
+ uint32_t u32FwVersion;
+ /** Firmware sequencer Code version. */
+ uint32_t u32SeqCodeVersion;
+ /** Image size in bytes including the header. */
+ uint32_t u32ImageSize;
+ /** Offset of the first extended image header. */
+ uint32_t u32NextImageHeaderOffset;
+ /** Start address of the image in IOC memory. */
+ uint32_t u32LoadStartAddress;
+ /** Absolute start address of the Iop ARM. */
+ uint32_t u32IopResetVectorValue;
+ /** Address of the IopResetVector register. */
+ uint32_t u32IopResetVectorRegAddr;
+ /** Marker value for what utility. */
+ uint32_t u32VersionNameWhat;
+ /** ASCII string of version. */
+ uint8_t aszVersionName[256];
+ /** Marker value for what utility. */
+ uint32_t u32VendorNameWhat;
+ /** ASCII string of vendor name. */
+ uint8_t aszVendorName[256];
+} FwImageHdr, *PFwImageHdr;
+AssertCompileSize(FwImageHdr, 584);
+
+/** First part of the signature. */
+#define LSILOGIC_FWIMGHDR_SIGNATURE1 UINT32_C(0x5aeaa55a)
+/** Second part of the signature. */
+#define LSILOGIC_FWIMGHDR_SIGNATURE2 UINT32_C(0xa55aeaa5)
+/** Third part of the signature. */
+#define LSILOGIC_FWIMGHDR_SIGNATURE3 UINT32_C(0x5aa55aea)
+/** Load address of the firmware image to watch for,
+ * seen used by Solaris 9. When this value is written to the
+ * diagnostic address register we know a firmware image is downloaded.
+ */
+#define LSILOGIC_FWIMGHDR_LOAD_ADDRESS UINT32_C(0x21ff5e00)
+
+/**
+ * Configuration Page attributes.
+ */
+#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_READONLY (0x00)
+#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_CHANGEABLE (0x10)
+#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_PERSISTENT (0x20)
+#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_PERSISTENT_READONLY (0x30)
+
+#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_GET(u8PageType) ((u8PageType) & 0xf0)
+
+/**
+ * Configuration Page types.
+ */
+#define MPT_CONFIGURATION_PAGE_TYPE_IO_UNIT (0x00)
+#define MPT_CONFIGURATION_PAGE_TYPE_IOC (0x01)
+#define MPT_CONFIGURATION_PAGE_TYPE_BIOS (0x02)
+#define MPT_CONFIGURATION_PAGE_TYPE_SCSI_SPI_PORT (0x03)
+#define MPT_CONFIGURATION_PAGE_TYPE_SCSI_SPI_DEVICE (0x04)
+#define MPT_CONFIGURATION_PAGE_TYPE_MANUFACTURING (0x09)
+#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED (0x0F)
+
+#define MPT_CONFIGURATION_PAGE_TYPE_GET(u8PageType) ((u8PageType) & 0x0f)
+
+/**
+ * Extented page types.
+ */
+#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASIOUNIT (0x10)
+#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASEXPANDER (0x11)
+#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASDEVICE (0x12)
+#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASPHYS (0x13)
+#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_LOG (0x14)
+#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_ENCLOSURE (0x15)
+
+/**
+ * Configuration Page header - Common to all pages.
+ */
+typedef struct MptConfigurationPageHeader
+{
+ /** Version of the page. */
+ uint8_t u8PageVersion;
+ /** The length of the page in 32bit D-Words. */
+ uint8_t u8PageLength;
+ /** Number of the page. */
+ uint8_t u8PageNumber;
+ /** Type of the page. */
+ uint8_t u8PageType;
+} MptConfigurationPageHeader, *PMptConfigurationPageHeader;
+AssertCompileSize(MptConfigurationPageHeader, 4);
+
+/**
+ * Extended configuration page header - Common to all extended pages.
+ */
+typedef struct MptExtendedConfigurationPageHeader
+{
+ /** Version of the page. */
+ uint8_t u8PageVersion;
+ /** Reserved. */
+ uint8_t u8Reserved1;
+ /** Number of the page. */
+ uint8_t u8PageNumber;
+ /** Type of the page. */
+ uint8_t u8PageType;
+ /** Extended page length. */
+ uint16_t u16ExtPageLength;
+ /** Extended page type. */
+ uint8_t u8ExtPageType;
+ /** Reserved */
+ uint8_t u8Reserved2;
+} MptExtendedConfigurationPageHeader, *PMptExtendedConfigurationPageHeader;
+AssertCompileSize(MptExtendedConfigurationPageHeader, 8);
+
+/**
+ * Manufacturing page 0. - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing0 /**< @todo r=bird: This and a series of other structs could save a lot of 'u.' typing by promoting the inner 'u' union... */
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[76];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Name of the chip. */
+ uint8_t abChipName[16];
+ /** Chip revision. */
+ uint8_t abChipRevision[8];
+ /** Board name. */
+ uint8_t abBoardName[16];
+ /** Board assembly. */
+ uint8_t abBoardAssembly[16];
+ /** Board tracer number. */
+ uint8_t abBoardTracerNumber[16];
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing0, *PMptConfigurationPageManufacturing0;
+AssertCompileSize(MptConfigurationPageManufacturing0, 76);
+
+/**
+ * Manufacturing page 1. - Readonly Persistent.
+ */
+typedef struct MptConfigurationPageManufacturing1
+{
+ /** Union */
+ union
+ {
+ /** Byte view */
+ uint8_t abPageData[260];
+ /** Field view */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** VPD info - don't know what belongs here so all zero. */
+ uint8_t abVPDInfo[256];
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing1, *PMptConfigurationPageManufacturing1;
+AssertCompileSize(MptConfigurationPageManufacturing1, 260);
+
+/**
+ * Manufacturing page 2. - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[8];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** PCI Device ID. */
+ uint16_t u16PCIDeviceID;
+ /** PCI Revision ID. */
+ uint8_t u8PCIRevisionID;
+ /** Reserved. */
+ uint8_t u8Reserved;
+ /** Hardware specific settings... */
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing2, *PMptConfigurationPageManufacturing2;
+AssertCompileSize(MptConfigurationPageManufacturing2, 8);
+
+/**
+ * Manufacturing page 3. - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing3
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[8];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** PCI Device ID. */
+ uint16_t u16PCIDeviceID;
+ /** PCI Revision ID. */
+ uint8_t u8PCIRevisionID;
+ /** Reserved. */
+ uint8_t u8Reserved;
+ /** Chip specific settings... */
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing3, *PMptConfigurationPageManufacturing3;
+AssertCompileSize(MptConfigurationPageManufacturing3, 8);
+
+/**
+ * Manufacturing page 4. - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing4
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[84];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Reserved. */
+ uint32_t u32Reserved;
+ /** InfoOffset0. */
+ uint8_t u8InfoOffset0;
+ /** Info size. */
+ uint8_t u8InfoSize0;
+ /** InfoOffset1. */
+ uint8_t u8InfoOffset1;
+ /** Info size. */
+ uint8_t u8InfoSize1;
+ /** Size of the inquiry data. */
+ uint8_t u8InquirySize;
+ /** Reserved. */
+ uint8_t abReserved[3];
+ /** Inquiry data. */
+ uint8_t abInquiryData[56];
+ /** IS volume settings. */
+ uint32_t u32ISVolumeSettings;
+ /** IME volume settings. */
+ uint32_t u32IMEVolumeSettings;
+ /** IM volume settings. */
+ uint32_t u32IMVolumeSettings;
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing4, *PMptConfigurationPageManufacturing4;
+AssertCompileSize(MptConfigurationPageManufacturing4, 84);
+
+/**
+ * Manufacturing page 5 - Readonly.
+ */
+#pragma pack(1) /* u64BaseWWID is at offset 4, which isn't natural for uint64_t. */
+typedef struct MptConfigurationPageManufacturing5
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[88];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Base WWID.
+ * @note Not aligned on 8-byte boundrary */
+ uint64_t u64BaseWWID;
+ /** Flags */
+ uint8_t u8Flags;
+ /** Number of ForceWWID fields in this page. */
+ uint8_t u8NumForceWWID;
+ /** Reserved */
+ uint16_t u16Reserved;
+ /** Reserved */
+ uint32_t au32Reserved[2];
+ /** ForceWWID entries Maximum of 8 because the SAS controller doesn't has more */
+ uint64_t au64ForceWWID[8];
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing5, *PMptConfigurationPageManufacturing5;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageManufacturing5, 24+64);
+
+/**
+ * Manufacturing page 6 - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing6
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[4];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Product specific data - 0 for now */
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing6, *PMptConfigurationPageManufacturing6;
+AssertCompileSize(MptConfigurationPageManufacturing6, 4);
+
+/**
+ * Manufacutring page 7 - PHY element.
+ */
+typedef struct MptConfigurationPageManufacturing7PHY
+{
+ /** Pinout */
+ uint32_t u32Pinout;
+ /** Connector name */
+ uint8_t szConnector[16];
+ /** Location */
+ uint8_t u8Location;
+ /** reserved */
+ uint8_t u8Reserved;
+ /** Slot */
+ uint16_t u16Slot;
+} MptConfigurationPageManufacturing7PHY, *PMptConfigurationPageManufacturing7PHY;
+AssertCompileSize(MptConfigurationPageManufacturing7PHY, 24);
+
+/**
+ * Manufacturing page 7 - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing7
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Reserved */
+ uint32_t au32Reserved[2];
+ /** Flags */
+ uint32_t u32Flags;
+ /** Enclosure name */
+ uint8_t szEnclosureName[16];
+ /** Number of PHYs */
+ uint8_t u8NumPhys;
+ /** Reserved */
+ uint8_t au8Reserved[3];
+ /** PHY list for the SAS controller - variable depending on the number of ports */
+ MptConfigurationPageManufacturing7PHY aPHY[1];
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing7, *PMptConfigurationPageManufacturing7;
+AssertCompileSize(MptConfigurationPageManufacturing7, 36+sizeof(MptConfigurationPageManufacturing7PHY));
+
+#define LSILOGICSCSI_MANUFACTURING7_GET_SIZE(ports) (sizeof(MptConfigurationPageManufacturing7) + ((ports) - 1) * sizeof(MptConfigurationPageManufacturing7PHY))
+
+/** Flags for the flags field */
+#define LSILOGICSCSI_MANUFACTURING7_FLAGS_USE_PROVIDED_INFORMATION RT_BIT(0)
+
+/** Flags for the pinout field */
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_UNKNOWN RT_BIT(0)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8482 RT_BIT(1)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE1 RT_BIT(8)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE2 RT_BIT(9)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE3 RT_BIT(10)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE4 RT_BIT(11)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE1 RT_BIT(16)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE2 RT_BIT(17)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE3 RT_BIT(18)
+#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE4 RT_BIT(19)
+
+/** Flags for the location field */
+#define LSILOGICSCSI_MANUFACTURING7_LOCATION_UNKNOWN 0x01
+#define LSILOGICSCSI_MANUFACTURING7_LOCATION_INTERNAL 0x02
+#define LSILOGICSCSI_MANUFACTURING7_LOCATION_EXTERNAL 0x04
+#define LSILOGICSCSI_MANUFACTURING7_LOCATION_SWITCHABLE 0x08
+#define LSILOGICSCSI_MANUFACTURING7_LOCATION_AUTO 0x10
+#define LSILOGICSCSI_MANUFACTURING7_LOCATION_NOT_PRESENT 0x20
+#define LSILOGICSCSI_MANUFACTURING7_LOCATION_NOT_CONNECTED 0x80
+
+/**
+ * Manufacturing page 8 - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing8
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[4];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Product specific information */
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing8, *PMptConfigurationPageManufacturing8;
+AssertCompileSize(MptConfigurationPageManufacturing8, 4);
+
+/**
+ * Manufacturing page 9 - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing9
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[4];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Product specific information */
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing9, *PMptConfigurationPageManufacturing9;
+AssertCompileSize(MptConfigurationPageManufacturing9, 4);
+
+/**
+ * Manufacturing page 10 - Readonly.
+ */
+typedef struct MptConfigurationPageManufacturing10
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[4];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Product specific information */
+ } fields;
+ } u;
+} MptConfigurationPageManufacturing10, *PMptConfigurationPageManufacturing10;
+AssertCompileSize(MptConfigurationPageManufacturing10, 4);
+
+/**
+ * IO Unit page 0. - Readonly.
+ */
+#pragma pack(1) /* u64UniqueIdentifier is at offset 4, which isn't natural for uint64_t. */
+typedef struct MptConfigurationPageIOUnit0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[12];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** A unique identifier. */
+ uint64_t u64UniqueIdentifier;
+ } fields;
+ } u;
+} MptConfigurationPageIOUnit0, *PMptConfigurationPageIOUnit0;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageIOUnit0, 12);
+
+/**
+ * IO Unit page 1. - Read/Write.
+ */
+typedef struct MptConfigurationPageIOUnit1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[8];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Flag whether this is a single function PCI device. */
+ unsigned fSingleFunction: 1;
+ /** Flag whether all possible paths to a device are mapped. */
+ unsigned fAllPathsMapped: 1;
+ /** Reserved. */
+ unsigned u4Reserved: 4;
+ /** Flag whether all RAID functionality is disabled. */
+ unsigned fIntegratedRAIDDisabled: 1;
+ /** Flag whether 32bit PCI accesses are forced. */
+ unsigned f32BitAccessForced: 1;
+ /** Reserved. */
+ unsigned abReserved: 24;
+ } fields;
+ } u;
+} MptConfigurationPageIOUnit1, *PMptConfigurationPageIOUnit1;
+AssertCompileSize(MptConfigurationPageIOUnit1, 8);
+
+/**
+ * Adapter Ordering.
+ */
+typedef struct MptConfigurationPageIOUnit2AdapterOrdering
+{
+ /** PCI bus number. */
+ unsigned u8PCIBusNumber: 8;
+ /** PCI device and function number. */
+ unsigned u8PCIDevFn: 8;
+ /** Flag whether the adapter is embedded. */
+ unsigned fAdapterEmbedded: 1;
+ /** Flag whether the adapter is enabled. */
+ unsigned fAdapterEnabled: 1;
+ /** Reserved. */
+ unsigned u6Reserved: 6;
+ /** Reserved. */
+ unsigned u8Reserved: 8;
+} MptConfigurationPageIOUnit2AdapterOrdering, *PMptConfigurationPageIOUnit2AdapterOrdering;
+AssertCompileSize(MptConfigurationPageIOUnit2AdapterOrdering, 4);
+
+/**
+ * IO Unit page 2. - Read/Write.
+ */
+typedef struct MptConfigurationPageIOUnit2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[28];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Reserved. */
+ unsigned fReserved: 1;
+ /** Flag whether Pause on error is enabled. */
+ unsigned fPauseOnError: 1;
+ /** Flag whether verbose mode is enabled. */
+ unsigned fVerboseModeEnabled: 1;
+ /** Set to disable color video. */
+ unsigned fDisableColorVideo: 1;
+ /** Flag whether int 40h is hooked. */
+ unsigned fNotHookInt40h: 1;
+ /** Reserved. */
+ unsigned u3Reserved: 3;
+ /** Reserved. */
+ unsigned abReserved: 24;
+ /** BIOS version. */
+ uint32_t u32BIOSVersion;
+ /** Adapter ordering. */
+ MptConfigurationPageIOUnit2AdapterOrdering aAdapterOrder[4];
+ } fields;
+ } u;
+} MptConfigurationPageIOUnit2, *PMptConfigurationPageIOUnit2;
+AssertCompileSize(MptConfigurationPageIOUnit2, 28);
+
+/*
+ * IO Unit page 3. - Read/Write.
+ */
+typedef struct MptConfigurationPageIOUnit3
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[8];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Number of GPIO values. */
+ uint8_t u8GPIOCount;
+ /** Reserved. */
+ uint8_t abReserved[3];
+ } fields;
+ } u;
+} MptConfigurationPageIOUnit3, *PMptConfigurationPageIOUnit3;
+AssertCompileSize(MptConfigurationPageIOUnit3, 8);
+
+/*
+ * IO Unit page 4. - Readonly for everyone except the BIOS.
+ */
+typedef struct MptConfigurationPageIOUnit4
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[20];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Reserved */
+ uint32_t u32Reserved;
+ /** SG entry describing the Firmware location. */
+ MptSGEntrySimple64 FWImageSGE;
+ } fields;
+ } u;
+} MptConfigurationPageIOUnit4, *PMptConfigurationPageIOUnit4;
+AssertCompileSize(MptConfigurationPageIOUnit4, 20);
+
+/**
+ * IOC page 0. - Readonly
+ */
+typedef struct MptConfigurationPageIOC0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[28];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Total amount of NV memory in bytes. */
+ uint32_t u32TotalNVStore;
+ /** Number of free bytes in the NV store. */
+ uint32_t u32FreeNVStore;
+ /** PCI vendor ID. */
+ uint16_t u16VendorId;
+ /** PCI device ID. */
+ uint16_t u16DeviceId;
+ /** PCI revision ID. */
+ uint8_t u8RevisionId;
+ /** Reserved. */
+ uint8_t abReserved[3];
+ /** PCI class code. */
+ uint32_t u32ClassCode;
+ /** Subsystem vendor Id. */
+ uint16_t u16SubsystemVendorId;
+ /** Subsystem Id. */
+ uint16_t u16SubsystemId;
+ } fields;
+ } u;
+} MptConfigurationPageIOC0, *PMptConfigurationPageIOC0;
+AssertCompileSize(MptConfigurationPageIOC0, 28);
+
+/**
+ * IOC page 1. - Read/Write
+ */
+typedef struct MptConfigurationPageIOC1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[16];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Flag whether reply coalescing is enabled. */
+ unsigned fReplyCoalescingEnabled: 1;
+ /** Reserved. */
+ unsigned u31Reserved: 31;
+ /** Coalescing Timeout in microseconds. */
+ unsigned u32CoalescingTimeout: 32;
+ /** Coalescing depth. */
+ unsigned u8CoalescingDepth: 8;
+ /** Reserved. */
+ unsigned u8Reserved0: 8;
+ unsigned u8Reserved1: 8;
+ unsigned u8Reserved2: 8;
+ } fields;
+ } u;
+} MptConfigurationPageIOC1, *PMptConfigurationPageIOC1;
+AssertCompileSize(MptConfigurationPageIOC1, 16);
+
+/**
+ * IOC page 2. - Readonly
+ */
+typedef struct MptConfigurationPageIOC2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[12];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Flag whether striping is supported. */
+ unsigned fStripingSupported: 1;
+ /** Flag whether enhanced mirroring is supported. */
+ unsigned fEnhancedMirroringSupported: 1;
+ /** Flag whether mirroring is supported. */
+ unsigned fMirroringSupported: 1;
+ /** Reserved. */
+ unsigned u26Reserved: 26;
+ /** Flag whether SES is supported. */
+ unsigned fSESSupported: 1;
+ /** Flag whether SAF-TE is supported. */
+ unsigned fSAFTESupported: 1;
+ /** Flag whether cross channel volumes are supported. */
+ unsigned fCrossChannelVolumesSupported: 1;
+ /** Number of active integrated RAID volumes. */
+ unsigned u8NumActiveVolumes: 8;
+ /** Maximum number of integrated RAID volumes supported. */
+ unsigned u8MaxVolumes: 8;
+ /** Number of active integrated RAID physical disks. */
+ unsigned u8NumActivePhysDisks: 8;
+ /** Maximum number of integrated RAID physical disks supported. */
+ unsigned u8MaxPhysDisks: 8;
+ /** RAID volumes... - not supported. */
+ } fields;
+ } u;
+} MptConfigurationPageIOC2, *PMptConfigurationPageIOC2;
+AssertCompileSize(MptConfigurationPageIOC2, 12);
+
+/**
+ * IOC page 3. - Readonly
+ */
+typedef struct MptConfigurationPageIOC3
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[8];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Number of active integrated RAID physical disks. */
+ uint8_t u8NumPhysDisks;
+ /** Reserved. */
+ uint8_t abReserved[3];
+ } fields;
+ } u;
+} MptConfigurationPageIOC3, *PMptConfigurationPageIOC3;
+AssertCompileSize(MptConfigurationPageIOC3, 8);
+
+/**
+ * IOC page 4. - Read/Write
+ */
+typedef struct MptConfigurationPageIOC4
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[8];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Number of SEP entries in this page. */
+ uint8_t u8ActiveSEP;
+ /** Maximum number of SEp entries supported. */
+ uint8_t u8MaxSEP;
+ /** Reserved. */
+ uint16_t u16Reserved;
+ /** SEP entries... - not supported. */
+ } fields;
+ } u;
+} MptConfigurationPageIOC4, *PMptConfigurationPageIOC4;
+AssertCompileSize(MptConfigurationPageIOC4, 8);
+
+/**
+ * IOC page 6. - Read/Write
+ */
+typedef struct MptConfigurationPageIOC6
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[60];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ uint32_t u32CapabilitiesFlags;
+ uint8_t u8MaxDrivesIS;
+ uint8_t u8MaxDrivesIM;
+ uint8_t u8MaxDrivesIME;
+ uint8_t u8Reserved1;
+ uint8_t u8MinDrivesIS;
+ uint8_t u8MinDrivesIM;
+ uint8_t u8MinDrivesIME;
+ uint8_t u8Reserved2;
+ uint8_t u8MaxGlobalHotSpares;
+ uint8_t u8Reserved3;
+ uint16_t u16Reserved4;
+ uint32_t u32Reserved5;
+ uint32_t u32SupportedStripeSizeMapIS;
+ uint32_t u32SupportedStripeSizeMapIME;
+ uint32_t u32Reserved6;
+ uint8_t u8MetadataSize;
+ uint8_t u8Reserved7;
+ uint16_t u16Reserved8;
+ uint16_t u16MaxBadBlockTableEntries;
+ uint16_t u16Reserved9;
+ uint16_t u16IRNvsramUsage;
+ uint16_t u16Reserved10;
+ uint32_t u32IRNvsramVersion;
+ uint32_t u32Reserved11;
+ } fields;
+ } u;
+} MptConfigurationPageIOC6, *PMptConfigurationPageIOC6;
+AssertCompileSize(MptConfigurationPageIOC6, 60);
+
+/**
+ * BIOS page 1 - Read/write.
+ */
+typedef struct MptConfigurationPageBIOS1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[48];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** BIOS options */
+ uint32_t u32BiosOptions;
+ /** IOC settings */
+ uint32_t u32IOCSettings;
+ /** Reserved */
+ uint32_t u32Reserved;
+ /** Device settings */
+ uint32_t u32DeviceSettings;
+ /** Number of devices */
+ uint16_t u16NumberOfDevices;
+ /** Expander spinup */
+ uint8_t u8ExpanderSpinup;
+ /** Reserved */
+ uint8_t u8Reserved;
+ /** I/O timeout of block devices without removable media */
+ uint16_t u16IOTimeoutBlockDevicesNonRM;
+ /** I/O timeout sequential */
+ uint16_t u16IOTimeoutSequential;
+ /** I/O timeout other */
+ uint16_t u16IOTimeoutOther;
+ /** I/O timeout of block devices with removable media */
+ uint16_t u16IOTimeoutBlockDevicesRM;
+ } fields;
+ } u;
+} MptConfigurationPageBIOS1, *PMptConfigurationPageBIOS1;
+AssertCompileSize(MptConfigurationPageBIOS1, 48);
+
+#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_DISABLE RT_BIT(0)
+#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_SCAN_FROM_HIGH_TO_LOW RT_BIT(1)
+#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_EXTENDED_SAS_SUPPORT RT_BIT(8)
+#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_EXTENDED_FC_SUPPORT RT_BIT(9)
+#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_EXTENDED_SPI_SUPPORT RT_BIT(10)
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ALTERNATE_CHS RT_BIT(3)
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_SET(x) ((x) << 4)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_DISABLED 0x00
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_BIOS_ONLY 0x01
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_OS_ONLY 0x02
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_BOT 0x03
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_MEDIA_SET(x) ((x) << 6)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_MEDIA_NO_INT13H 0x00
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_BOOT_MEDIA_INT13H 0x01
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_MEDIA_INT13H 0x02
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_SPINUP_DELAY_SET(x) ((x & 0xF) << 8)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_SPINUP_DELAY_GET(x) ((x >> 8) & 0x0F)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_MAX_TARGET_SPINUP_SET(x) ((x & 0xF) << 12)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_MAX_TARGET_SPINUP_GET(x) ((x >> 12) & 0x0F)
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_BOOT_PREFERENCE_SET(x) (((x) & 0x3) << 16)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_BOOT_PREFERENCE_ENCLOSURE 0x0
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_BOOT_PREFERENCE_SAS_ADDRESS 0x1
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_DIRECT_ATTACH_SPINUP_MODE_ALL RT_BIT(18)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_AUTO_PORT_ENABLE RT_BIT(19)
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_REPLY_DELAY_SET(x) (((x) & 0xF) << 20)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_REPLY_DELAY_GET(x) ((x >> 20) & 0x0F)
+
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_SPINUP_DELAY_SET(x) (((x) & 0xF) << 24)
+#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_SPINUP_DELAY_GET(x) ((x >> 24) & 0x0F)
+
+#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS RT_BIT(0)
+#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS_FOR_NON_REMOVABLE_DEVICES RT_BIT(1)
+#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS_FOR_REMOVABLE_DEVICES RT_BIT(2)
+#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS2 RT_BIT(3)
+#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_SMART_POLLING RT_BIT(4)
+
+#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_SPINUP_DELAY_SET(x) ((x) & 0x0F)
+#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_SPINUP_DELAY_GET(x) ((x) & 0x0F)
+#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_MAX_SPINUP_DELAY_SET(x) (((x) & 0x0F) << 4)
+#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_MAX_SPINUP_DELAY_GET(x) ((x >> 4) & 0x0F)
+
+/**
+ * BIOS page 2 - Read/write.
+ */
+typedef struct MptConfigurationPageBIOS2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[384];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Reserved */
+ uint32_t au32Reserved[6];
+ /** Format of the boot device field. */
+ uint8_t u8BootDeviceForm;
+ /** Previous format of the boot device field. */
+ uint8_t u8PrevBootDeviceForm;
+ /** Reserved */
+ uint16_t u16Reserved;
+ /** Boot device fields - dependent on the format */
+ union
+ {
+ /** Device for AdapterNumber:Bus:Target:LUN */
+ struct
+ {
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus */
+ uint8_t u8Bus;
+ /** Adapter Number */
+ uint8_t u8AdapterNumber;
+ /** Reserved */
+ uint8_t u8Reserved;
+ /** Reserved */
+ uint32_t au32Reserved[3];
+ /** LUN */
+ uint32_t aLUN[5];
+ /** Reserved */
+ uint32_t au32Reserved2[56];
+ } AdapterNumberBusTargetLUN;
+ /** Device for PCIAddress:Bus:Target:LUN */
+ struct
+ {
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus */
+ uint8_t u8Bus;
+ /** Adapter Number */
+ uint16_t u16PCIAddress;
+ /** Reserved */
+ uint32_t au32Reserved[3];
+ /** LUN */
+ uint32_t aLUN[5];
+ /** Reserved */
+ uint32_t au32Reserved2[56];
+ } PCIAddressBusTargetLUN;
+#if 0 /** @todo r=bird: The u16PCISlotNo member looks like it has the wrong type, but I cannot immediately locate specs and check. */
+ /** Device for PCISlotNo:Bus:Target:LUN */
+ struct
+ {
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus */
+ uint8_t u8Bus;
+ /** PCI Slot Number */
+ uint8_t u16PCISlotNo;
+ /** Reserved */
+ uint32_t au32Reserved[3];
+ /** LUN */
+ uint32_t aLUN[5];
+ /** Reserved */
+ uint32_t au32Reserved2[56];
+ } PCIAddressBusSlotLUN;
+#endif
+ /** Device for FC channel world wide name */
+ struct
+ {
+ /** World wide port name low */
+ uint32_t u32WorldWidePortNameLow;
+ /** World wide port name high */
+ uint32_t u32WorldWidePortNameHigh;
+ /** Reserved */
+ uint32_t au32Reserved[3];
+ /** LUN */
+ uint32_t aLUN[5];
+ /** Reserved */
+ uint32_t au32Reserved2[56];
+ } FCWorldWideName;
+ /** Device for FC channel world wide name */
+ struct
+ {
+ /** SAS address */
+ SASADDRESS SASAddress;
+ /** Reserved */
+ uint32_t au32Reserved[3];
+ /** LUN */
+ uint32_t aLUN[5];
+ /** Reserved */
+ uint32_t au32Reserved2[56];
+ } SASWorldWideName;
+ /** Device for Enclosure/Slot */
+ struct
+ {
+ /** Enclosure logical ID */
+ uint64_t u64EnclosureLogicalID;
+ /** Reserved */
+ uint32_t au32Reserved[3];
+ /** LUN */
+ uint32_t aLUN[5];
+ /** Reserved */
+ uint32_t au32Reserved2[56];
+ } EnclosureSlot;
+ } BootDevice;
+ } fields;
+ } u;
+} MptConfigurationPageBIOS2, *PMptConfigurationPageBIOS2;
+AssertCompileMemberAlignment(MptConfigurationPageBIOS2, u.fields, 8);
+AssertCompileSize(MptConfigurationPageBIOS2, 384);
+
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_SET(x) ((x) & 0x0F)
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_FIRST 0x0
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_ADAPTER_BUS_TARGET_LUN 0x1
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_PCIADDR_BUS_TARGET_LUN 0x2
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_PCISLOT_BUS_TARGET_LUN 0x3
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_FC_WWN 0x4
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_SAS_WWN 0x5
+#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_ENCLOSURE_SLOT 0x6
+
+/**
+ * BIOS page 4 - Read/Write (Where is 3? - not defined in the spec)
+ */
+#pragma pack(1) /* u64ReassignmentBaseWWID starts at offset 4, which isn't normally natural for uint64_t. */
+typedef struct MptConfigurationPageBIOS4
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[12];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Reassignment Base WWID */
+ uint64_t u64ReassignmentBaseWWID;
+ } fields;
+ } u;
+} MptConfigurationPageBIOS4, *PMptConfigurationPageBIOS4;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageBIOS4, 12);
+
+/**
+ * SCSI-SPI port page 0. - Readonly
+ */
+typedef struct MptConfigurationPageSCSISPIPort0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[12];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Flag whether this port is information unit transfers capable. */
+ unsigned fInformationUnitTransfersCapable: 1;
+ /** Flag whether the port is DT (Dual Transfer) capable. */
+ unsigned fDTCapable: 1;
+ /** Flag whether the port is QAS (Quick Arbitrate and Select) capable. */
+ unsigned fQASCapable: 1;
+ /** Reserved. */
+ unsigned u5Reserved1: 5;
+ /** Minimum Synchronous transfer period. */
+ unsigned u8MinimumSynchronousTransferPeriod: 8;
+ /** Maximum synchronous offset. */
+ unsigned u8MaximumSynchronousOffset: 8;
+ /** Reserved. */
+ unsigned u5Reserved2: 5;
+ /** Flag whether indicating the width of the bus - 0 narrow and 1 for wide. */
+ unsigned fWide: 1;
+ /** Reserved */
+ unsigned fReserved: 1;
+ /** Flag whether the port is AIP (Asynchronous Information Protection) capable. */
+ unsigned fAIPCapable: 1;
+ /** Signaling Type. */
+ unsigned u2SignalingType: 2;
+ /** Reserved. */
+ unsigned u30Reserved: 30;
+ } fields;
+ } u;
+} MptConfigurationPageSCSISPIPort0, *PMptConfigurationPageSCSISPIPort0;
+AssertCompileSize(MptConfigurationPageSCSISPIPort0, 12);
+
+/**
+ * SCSI-SPI port page 1. - Read/Write
+ */
+typedef struct MptConfigurationPageSCSISPIPort1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[12];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** The SCSI ID of the port. */
+ uint8_t u8SCSIID;
+ /** Reserved. */
+ uint8_t u8Reserved;
+ /** Port response IDs Bit mask field. */
+ uint16_t u16PortResponseIDsBitmask;
+ /** Value for the on BUS timer. */
+ uint32_t u32OnBusTimerValue;
+ } fields;
+ } u;
+} MptConfigurationPageSCSISPIPort1, *PMptConfigurationPageSCSISPIPort1;
+AssertCompileSize(MptConfigurationPageSCSISPIPort1, 12);
+
+/**
+ * Device settings for one device.
+ */
+typedef struct MptDeviceSettings
+{
+ /** Timeout for I/O in seconds. */
+ unsigned u8Timeout: 8;
+ /** Minimum synchronous factor. */
+ unsigned u8SyncFactor: 8;
+ /** Flag whether disconnect is enabled. */
+ unsigned fDisconnectEnable: 1;
+ /** Flag whether Scan ID is enabled. */
+ unsigned fScanIDEnable: 1;
+ /** Flag whether Scan LUNs is enabled. */
+ unsigned fScanLUNEnable: 1;
+ /** Flag whether tagged queuing is enabled. */
+ unsigned fTaggedQueuingEnabled: 1;
+ /** Flag whether wide is enabled. */
+ unsigned fWideDisable: 1;
+ /** Flag whether this device is bootable. */
+ unsigned fBootChoice: 1;
+ /** Reserved. */
+ unsigned u10Reserved: 10;
+} MptDeviceSettings, *PMptDeviceSettings;
+AssertCompileSize(MptDeviceSettings, 4);
+
+/**
+ * SCSI-SPI port page 2. - Read/Write for the BIOS
+ */
+typedef struct MptConfigurationPageSCSISPIPort2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[76];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Flag indicating the bus scan order. */
+ unsigned fBusScanOrderHighToLow: 1;
+ /** Reserved. */
+ unsigned fReserved: 1;
+ /** Flag whether SCSI Bus resets are avoided. */
+ unsigned fAvoidSCSIBusResets: 1;
+ /** Flag whether alternate CHS is used. */
+ unsigned fAlternateCHS: 1;
+ /** Flag whether termination is disabled. */
+ unsigned fTerminationDisabled: 1;
+ /** Reserved. */
+ unsigned u27Reserved: 27;
+ /** Host SCSI ID. */
+ unsigned u4HostSCSIID: 4;
+ /** Initialize HBA. */
+ unsigned u2InitializeHBA: 2;
+ /** Removeable media setting. */
+ unsigned u2RemovableMediaSetting: 2;
+ /** Spinup delay. */
+ unsigned u4SpinupDelay: 4;
+ /** Negotiating settings. */
+ unsigned u2NegotitatingSettings: 2;
+ /** Reserved. */
+ unsigned u18Reserved: 18;
+ /** Device Settings. */
+ MptDeviceSettings aDeviceSettings[16];
+ } fields;
+ } u;
+} MptConfigurationPageSCSISPIPort2, *PMptConfigurationPageSCSISPIPort2;
+AssertCompileSize(MptConfigurationPageSCSISPIPort2, 76);
+
+/**
+ * SCSI-SPI device page 0. - Readonly
+ */
+typedef struct MptConfigurationPageSCSISPIDevice0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[12];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Negotiated Parameters. */
+ /** Information Units enabled. */
+ unsigned fInformationUnitsEnabled: 1;
+ /** Dual Transfers Enabled. */
+ unsigned fDTEnabled: 1;
+ /** QAS enabled. */
+ unsigned fQASEnabled: 1;
+ /** Reserved. */
+ unsigned u5Reserved1: 5;
+ /** Synchronous Transfer period. */
+ unsigned u8NegotiatedSynchronousTransferPeriod: 8;
+ /** Synchronous offset. */
+ unsigned u8NegotiatedSynchronousOffset: 8;
+ /** Reserved. */
+ unsigned u5Reserved2: 5;
+ /** Width - 0 for narrow and 1 for wide. */
+ unsigned fWide: 1;
+ /** Reserved. */
+ unsigned fReserved: 1;
+ /** AIP enabled. */
+ unsigned fAIPEnabled: 1;
+ /** Flag whether negotiation occurred. */
+ unsigned fNegotationOccured: 1;
+ /** Flag whether a SDTR message was rejected. */
+ unsigned fSDTRRejected: 1;
+ /** Flag whether a WDTR message was rejected. */
+ unsigned fWDTRRejected: 1;
+ /** Flag whether a PPR message was rejected. */
+ unsigned fPPRRejected: 1;
+ /** Reserved. */
+ unsigned u28Reserved: 28;
+ } fields;
+ } u;
+} MptConfigurationPageSCSISPIDevice0, *PMptConfigurationPageSCSISPIDevice0;
+AssertCompileSize(MptConfigurationPageSCSISPIDevice0, 12);
+
+/**
+ * SCSI-SPI device page 1. - Read/Write
+ */
+typedef struct MptConfigurationPageSCSISPIDevice1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[16];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Requested Parameters. */
+ /** Information Units enable. */
+ unsigned fInformationUnitsEnable: 1;
+ /** Dual Transfers Enable. */
+ unsigned fDTEnable: 1;
+ /** QAS enable. */
+ unsigned fQASEnable: 1;
+ /** Reserved. */
+ unsigned u5Reserved1: 5;
+ /** Synchronous Transfer period. */
+ unsigned u8NegotiatedSynchronousTransferPeriod: 8;
+ /** Synchronous offset. */
+ unsigned u8NegotiatedSynchronousOffset: 8;
+ /** Reserved. */
+ unsigned u5Reserved2: 5;
+ /** Width - 0 for narrow and 1 for wide. */
+ unsigned fWide: 1;
+ /** Reserved. */
+ unsigned fReserved1: 1;
+ /** AIP enable. */
+ unsigned fAIPEnable: 1;
+ /** Reserved. */
+ unsigned fReserved2: 1;
+ /** WDTR disallowed. */
+ unsigned fWDTRDisallowed: 1;
+ /** SDTR disallowed. */
+ unsigned fSDTRDisallowed: 1;
+ /** Reserved. */
+ unsigned u29Reserved: 29;
+ } fields;
+ } u;
+} MptConfigurationPageSCSISPIDevice1, *PMptConfigurationPageSCSISPIDevice1;
+AssertCompileSize(MptConfigurationPageSCSISPIDevice1, 16);
+
+/**
+ * SCSI-SPI device page 2. - Read/Write
+ */
+typedef struct MptConfigurationPageSCSISPIDevice2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[16];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Reserved. */
+ unsigned u4Reserved: 4;
+ /** ISI enable. */
+ unsigned fISIEnable: 1;
+ /** Secondary driver enable. */
+ unsigned fSecondaryDriverEnable: 1;
+ /** Reserved. */
+ unsigned fReserved: 1;
+ /** Slew create controller. */
+ unsigned u3SlewRateControler: 3;
+ /** Primary drive strength controller. */
+ unsigned u3PrimaryDriveStrengthControl: 3;
+ /** Secondary drive strength controller. */
+ unsigned u3SecondaryDriveStrengthControl: 3;
+ /** Reserved. */
+ unsigned u12Reserved: 12;
+ /** XCLKH_ST. */
+ unsigned fXCLKH_ST: 1;
+ /** XCLKS_ST. */
+ unsigned fXCLKS_ST: 1;
+ /** XCLKH_DT. */
+ unsigned fXCLKH_DT: 1;
+ /** XCLKS_DT. */
+ unsigned fXCLKS_DT: 1;
+ /** Parity pipe select. */
+ unsigned u2ParityPipeSelect: 2;
+ /** Reserved. */
+ unsigned u30Reserved: 30;
+ /** Data bit pipeline select. */
+ unsigned u32DataPipelineSelect: 32;
+ } fields;
+ } u;
+} MptConfigurationPageSCSISPIDevice2, *PMptConfigurationPageSCSISPIDevice2;
+AssertCompileSize(MptConfigurationPageSCSISPIDevice2, 16);
+
+/**
+ * SCSI-SPI device page 3 (Revision G). - Readonly
+ */
+typedef struct MptConfigurationPageSCSISPIDevice3
+{
+ /** Union. */
+ union
+ {
+ /** Byte view. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptConfigurationPageHeader Header;
+ /** Number of times the IOC rejected a message because it doesn't support the operation. */
+ uint16_t u16MsgRejectCount;
+ /** Number of times the SCSI bus entered an invalid operation state. */
+ uint16_t u16PhaseErrorCount;
+ /** Number of parity errors. */
+ uint16_t u16ParityCount;
+ /** Reserved. */
+ uint16_t u16Reserved;
+ } fields;
+ } u;
+} MptConfigurationPageSCSISPIDevice3, *PMptConfigurationPageSCSISPIDevice3;
+AssertCompileSize(MptConfigurationPageSCSISPIDevice3, 12);
+
+/**
+ * PHY entry for the SAS I/O unit page 0
+ */
+typedef struct MptConfigurationPageSASIOUnit0PHY
+{
+ /** Port number */
+ uint8_t u8Port;
+ /** Port flags */
+ uint8_t u8PortFlags;
+ /** Phy flags */
+ uint8_t u8PhyFlags;
+ /** negotiated link rate */
+ uint8_t u8NegotiatedLinkRate;
+ /** Controller phy device info */
+ uint32_t u32ControllerPhyDeviceInfo;
+ /** Attached device handle */
+ uint16_t u16AttachedDevHandle;
+ /** Controller device handle */
+ uint16_t u16ControllerDevHandle;
+ /** Discovery status */
+ uint32_t u32DiscoveryStatus;
+} MptConfigurationPageSASIOUnit0PHY, *PMptConfigurationPageSASIOUnit0PHY;
+AssertCompileSize(MptConfigurationPageSASIOUnit0PHY, 16);
+
+/**
+ * SAS I/O Unit page 0 - Readonly
+ */
+typedef struct MptConfigurationPageSASIOUnit0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Nvdata version default */
+ uint16_t u16NvdataVersionDefault;
+ /** Nvdata version persistent */
+ uint16_t u16NvdataVersionPersistent;
+ /** Number of physical ports */
+ uint8_t u8NumPhys;
+ /** Reserved */
+ uint8_t au8Reserved[3];
+ /** Content for each physical port - variable depending on the amount of ports. */
+ MptConfigurationPageSASIOUnit0PHY aPHY[1];
+ } fields;
+ } u;
+} MptConfigurationPageSASIOUnit0, *PMptConfigurationPageSASIOUnit0;
+AssertCompileSize(MptConfigurationPageSASIOUnit0, 8+2+2+1+3+sizeof(MptConfigurationPageSASIOUnit0PHY));
+
+#define LSILOGICSCSI_SASIOUNIT0_GET_SIZE(ports) (sizeof(MptConfigurationPageSASIOUnit0) + ((ports) - 1) * sizeof(MptConfigurationPageSASIOUnit0PHY))
+
+#define LSILOGICSCSI_SASIOUNIT0_PORT_CONFIGURATION_AUTO RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT0_PORT_TARGET_IOC RT_BIT(2)
+#define LSILOGICSCSI_SASIOUNIT0_PORT_DISCOVERY_IN_STATUS RT_BIT(3)
+
+#define LSILOGICSCSI_SASIOUNIT0_PHY_RX_INVERTED RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT0_PHY_TX_INVERTED RT_BIT(1)
+#define LSILOGICSCSI_SASIOUNIT0_PHY_DISABLED RT_BIT(2)
+
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_SET(x) ((x) & 0x0F)
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_GET(x) ((x) & 0x0F)
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_UNKNOWN 0x00
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_DISABLED 0x01
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_FAILED 0x02
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_SATA_OOB 0x03
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_15GB 0x08
+#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_30GB 0x09
+
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_SET(x) ((x) & 0x3)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_NO 0x0
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_END 0x1
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_EDGE_EXPANDER 0x2
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_FANOUT_EXPANDER 0x3
+
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SATA_HOST RT_BIT(3)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SMP_INITIATOR RT_BIT(4)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_STP_INITIATOR RT_BIT(5)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SSP_INITIATOR RT_BIT(6)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SATA RT_BIT(7)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SMP_TARGET RT_BIT(8)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_STP_TARGET RT_BIT(9)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SSP_TARGET RT_BIT(10)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_DIRECT_ATTACHED RT_BIT(11)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_LSI RT_BIT(12)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_ATAPI_DEVICE RT_BIT(13)
+#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SEP_DEVICE RT_BIT(14)
+
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_LOOP RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_UNADDRESSABLE RT_BIT(1)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SAME_SAS_ADDR RT_BIT(2)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_EXPANDER_ERROR RT_BIT(3)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SMP_TIMEOUT RT_BIT(4)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_EXP_ROUTE_OOE RT_BIT(5)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_EXP_ROUTE_IDX RT_BIT(6)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SMP_FUNC_FAILED RT_BIT(7)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SMP_CRC_ERROR RT_BIT(8)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SUBTRSCTIVE_LNK RT_BIT(9)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_TBL_LNK RT_BIT(10)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_UNSUPPORTED_DEV RT_BIT(11)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_MAX_SATA_TGTS RT_BIT(12)
+#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_MULT_CTRLS RT_BIT(13)
+
+/**
+ * PHY entry for the SAS I/O unit page 1
+ */
+typedef struct MptConfigurationPageSASIOUnit1PHY
+{
+ /** Port number */
+ uint8_t u8Port;
+ /** Port flags */
+ uint8_t u8PortFlags;
+ /** Phy flags */
+ uint8_t u8PhyFlags;
+ /** Max link rate */
+ uint8_t u8MaxMinLinkRate;
+ /** Controller phy device info */
+ uint32_t u32ControllerPhyDeviceInfo;
+ /** Maximum target port connect time */
+ uint16_t u16MaxTargetPortConnectTime;
+ /** Reserved */
+ uint16_t u16Reserved;
+} MptConfigurationPageSASIOUnit1PHY, *PMptConfigurationPageSASIOUnit1PHY;
+AssertCompileSize(MptConfigurationPageSASIOUnit1PHY, 12);
+
+/**
+ * SAS I/O Unit page 1 - Read/Write
+ */
+typedef struct MptConfigurationPageSASIOUnit1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Control flags */
+ uint16_t u16ControlFlags;
+ /** maximum number of SATA targets */
+ uint16_t u16MaxNumSATATargets;
+ /** additional control flags */
+ uint16_t u16AdditionalControlFlags;
+ /** Reserved */
+ uint16_t u16Reserved;
+ /** Number of PHYs */
+ uint8_t u8NumPhys;
+ /** maximum SATA queue depth */
+ uint8_t u8SATAMaxQDepth;
+ /** Delay for reporting missing devices. */
+ uint8_t u8ReportDeviceMissingDelay;
+ /** I/O device missing delay */
+ uint8_t u8IODeviceMissingDelay;
+ /** Content for each physical port - variable depending on the number of ports */
+ MptConfigurationPageSASIOUnit1PHY aPHY[1];
+ } fields;
+ } u;
+} MptConfigurationPageSASIOUnit1, *PMptConfigurationPageSASIOUnit1;
+AssertCompileSize(MptConfigurationPageSASIOUnit1, 8+12+sizeof(MptConfigurationPageSASIOUnit1PHY));
+
+#define LSILOGICSCSI_SASIOUNIT1_GET_SIZE(ports) (sizeof(MptConfigurationPageSASIOUnit1) + ((ports) - 1) * sizeof(MptConfigurationPageSASIOUnit1PHY))
+
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_CLEAR_SATA_AFFILIATION RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_FIRST_LEVEL_DISCOVERY_ONLY RT_BIT(1)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SUBTRACTIVE_LNK_ILLEGAL RT_BIT(2)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_IOC_ENABLE_HIGH_PHY RT_BIT(3)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_FUA_REQUIRED RT_BIT(4)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_NCQ_REQUIRED RT_BIT(5)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_SMART_REQUIRED RT_BIT(6)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_LBA48_REQUIRED RT_BIT(7)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_INIT_POSTPONED RT_BIT(8)
+
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SET(x) (((x) & 0x3) << 9)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_GET(x) (((x) >> 9) & 0x3)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SAS_AND_SATA 0x00
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SAS 0x01
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SATA 0x02
+
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_EXP_ADDR RT_BIT(11)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_SETTINGS_PRESERV_REQUIRED RT_BIT(12)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_LIMIT_RATE_15GB RT_BIT(13)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_LIMIT_RATE_30GB RT_BIT(14)
+#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SAS_SELF_TEST_ENABLED RT_BIT(15)
+
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_TBL_LNKS_ALLOW RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_NO_AFFIL RT_BIT(1)
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_SELF_AFFIL RT_BIT(2)
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_OTHER_AFFIL RT_BIT(3)
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_PORT_EN_ONLY RT_BIT(4)
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_HIDE_NON_ZERO_PHYS RT_BIT(5)
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_ASYNC_NOTIF RT_BIT(6)
+#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_MULT_PORTS_ILL_SAME_DOMAIN RT_BIT(7)
+
+#define LSILOGICSCSI_SASIOUNIT1_MISSING_DEVICE_DELAY_UNITS_16_SEC RT_BIT(7)
+#define LSILOGICSCSI_SASIOUNIT1_MISSING_DEVICE_DELAY_SET(x) ((x) & 0x7F)
+#define LSILOGICSCSI_SASIOUNIT1_MISSING_DEVICE_DELAY_GET(x) ((x) & 0x7F)
+
+#define LSILOGICSCSI_SASIOUNIT1_PORT_CONFIGURATION_AUTO RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT1_PORT_CONFIGURATION_IOC1 RT_BIT(2)
+
+#define LSILOGICSCSI_SASIOUNIT1_PHY_RX_INVERT RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT1_PHY_TX_INVERT RT_BIT(1)
+#define LSILOGICSCSI_SASIOUNIT1_PHY_DISABLE RT_BIT(2)
+
+#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MIN_SET(x) ((x) & 0x0F)
+#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MIN_GET(x) ((x) & 0x0F)
+#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MAX_SET(x) (((x) & 0x0F) << 4)
+#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MAX_GET(x) ((x >> 4) & 0x0F)
+#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_15GB 0x8
+#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_30GB 0x9
+
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_SET(x) ((x) & 0x3)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_GET(x) ((x) & 0x3)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_NO 0x0
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_END 0x1
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_EDGE_EXPANDER 0x2
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_FANOUT_EXPANDER 0x3
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SMP_INITIATOR RT_BIT(4)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_STP_INITIATOR RT_BIT(5)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SSP_INITIATOR RT_BIT(6)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SMP_TARGET RT_BIT(8)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_STP_TARGET RT_BIT(9)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SSP_TARGET RT_BIT(10)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_DIRECT_ATTACHED RT_BIT(11)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_LSI RT_BIT(12)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_ATAPI RT_BIT(13)
+#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SEP RT_BIT(14)
+
+/**
+ * SAS I/O unit page 2 - Read/Write
+ */
+typedef struct MptConfigurationPageSASIOUnit2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Device numbers per enclosure */
+ uint8_t u8NumDevsPerEnclosure;
+ /** Boot device wait time */
+ uint8_t u8BootDeviceWaitTime;
+ /** Reserved */
+ uint16_t u16Reserved;
+ /** Maximum number of persistent Bus and target ID mappings */
+ uint16_t u16MaxPersistentIDs;
+ /** Number of persistent IDs used */
+ uint16_t u16NumPersistentIDsUsed;
+ /** Status */
+ uint8_t u8Status;
+ /** Flags */
+ uint8_t u8Flags;
+ /** Maximum number of physical mapped IDs */
+ uint16_t u16MaxNumPhysicalMappedIDs;
+ } fields;
+ } u;
+} MptConfigurationPageSASIOUnit2, *PMptConfigurationPageSASIOUnit2;
+AssertCompileSize(MptConfigurationPageSASIOUnit2, 20);
+
+#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_MAP_TBL_FULL RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_MAP_DISABLED RT_BIT(1)
+#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_ENC_DEV_UNMAPPED RT_BIT(2)
+#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_DEV_LIMIT_EXCEEDED RT_BIT(3)
+
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_MAP_DISABLE RT_BIT(0)
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_SET(x) ((x & 0x7) << 1)
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_GET(x) ((x >> 1) & 0x7)
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_NO 0x0
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_DIRECT_ATTACHED 0x1
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_ENC 0x2
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_HOST 0x7
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_RESERVE_TARGET_ID_ZERO RT_BIT(4)
+#define LSILOGICSCSI_SASIOUNIT2_FLAGS_START_SLOT_NUMBER_ONE RT_BIT(5)
+
+/**
+ * SAS I/O unit page 3 - Read/Write
+ */
+typedef struct MptConfigurationPageSASIOUnit3
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Reserved */
+ uint32_t u32Reserved;
+ uint32_t u32MaxInvalidDwordCount;
+ uint32_t u32InvalidDwordCountTime;
+ uint32_t u32MaxRunningDisparityErrorCount;
+ uint32_t u32RunningDisparityErrorTime;
+ uint32_t u32MaxLossDwordSynchCount;
+ uint32_t u32LossDwordSynchCountTime;
+ uint32_t u32MaxPhysResetProblemCount;
+ uint32_t u32PhyResetProblemTime;
+ } fields;
+ } u;
+} MptConfigurationPageSASIOUnit3, *PMptConfigurationPageSASIOUnit3;
+AssertCompileSize(MptConfigurationPageSASIOUnit3, 44);
+
+/**
+ * SAS PHY page 0 - Readonly
+ */
+#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
+typedef struct MptConfigurationPageSASPHY0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Owner dev handle. */
+ uint16_t u16OwnerDevHandle;
+ /** Reserved */
+ uint16_t u16Reserved0;
+ /** SAS address */
+ SASADDRESS SASAddress;
+ /** Attached device handle */
+ uint16_t u16AttachedDevHandle;
+ /** Attached phy identifier */
+ uint8_t u8AttachedPhyIdentifier;
+ /** Reserved */
+ uint8_t u8Reserved1;
+ /** Attached device information */
+ uint32_t u32AttachedDeviceInfo;
+ /** Programmed link rate */
+ uint8_t u8ProgrammedLinkRate;
+ /** Hardware link rate */
+ uint8_t u8HwLinkRate;
+ /** Change count */
+ uint8_t u8ChangeCount;
+ /** Flags */
+ uint8_t u8Flags;
+ /** Phy information */
+ uint32_t u32PhyInfo;
+ } fields;
+ } u;
+} MptConfigurationPageSASPHY0, *PMptConfigurationPageSASPHY0;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageSASPHY0, 36);
+
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_SET(x) ((x) & 0x3)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_GET(x) ((x) & 0x3)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_NO 0x0
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_END 0x1
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_EDGE_EXPANDER 0x2
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_FANOUT_EXPANDER 0x3
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SMP_INITIATOR RT_BIT(4)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_STP_INITIATOR RT_BIT(5)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SSP_INITIATOR RT_BIT(6)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SMP_TARGET RT_BIT(8)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_STP_TARGET RT_BIT(9)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SSP_TARGET RT_BIT(10)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_DIRECT_ATTACHED RT_BIT(11)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_LSI RT_BIT(12)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_ATAPI RT_BIT(13)
+#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SEP RT_BIT(14)
+
+/**
+ * SAS PHY page 1 - Readonly
+ */
+typedef struct MptConfigurationPageSASPHY1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Reserved */
+ uint32_t u32Reserved0;
+ uint32_t u32InvalidDwordCound;
+ uint32_t u32RunningDisparityErrorCount;
+ uint32_t u32LossDwordSynchCount;
+ uint32_t u32PhyResetProblemCount;
+ } fields;
+ } u;
+} MptConfigurationPageSASPHY1, *PMptConfigurationPageSASPHY1;
+AssertCompileSize(MptConfigurationPageSASPHY1, 28);
+
+/**
+ * SAS Device page 0 - Readonly
+ */
+#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
+typedef struct MptConfigurationPageSASDevice0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Slot number */
+ uint16_t u16Slot;
+ /** Enclosure handle. */
+ uint16_t u16EnclosureHandle;
+ /** SAS address */
+ SASADDRESS SASAddress;
+ /** Parent device handle */
+ uint16_t u16ParentDevHandle;
+ /** Phy number */
+ uint8_t u8PhyNum;
+ /** Access status */
+ uint8_t u8AccessStatus;
+ /** Device handle */
+ uint16_t u16DevHandle;
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus */
+ uint8_t u8Bus;
+ /** Device info */
+ uint32_t u32DeviceInfo;
+ /** Flags */
+ uint16_t u16Flags;
+ /** Physical port */
+ uint8_t u8PhysicalPort;
+ /** Reserved */
+ uint8_t u8Reserved0;
+ } fields;
+ } u;
+} MptConfigurationPageSASDevice0, *PMptConfigurationPageSASDevice0;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageSASDevice0, 36);
+
+#define LSILOGICSCSI_SASDEVICE0_STATUS_NO_ERRORS (0x00)
+
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_SET(x) ((x) & 0x3)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_GET(x) ((x) & 0x3)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_NO 0x0
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_END 0x1
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_EDGE_EXPANDER 0x2
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_FANOUT_EXPANDER 0x3
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SMP_INITIATOR RT_BIT(4)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_STP_INITIATOR RT_BIT(5)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SSP_INITIATOR RT_BIT(6)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SMP_TARGET RT_BIT(8)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_STP_TARGET RT_BIT(9)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SSP_TARGET RT_BIT(10)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_DIRECT_ATTACHED RT_BIT(11)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_LSI RT_BIT(12)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_ATAPI RT_BIT(13)
+#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SEP RT_BIT(14)
+
+#define LSILOGICSCSI_SASDEVICE0_FLAGS_DEVICE_PRESENT (RT_BIT(0))
+#define LSILOGICSCSI_SASDEVICE0_FLAGS_DEVICE_MAPPED_TO_BUS_AND_TARGET_ID (RT_BIT(1))
+#define LSILOGICSCSI_SASDEVICE0_FLAGS_DEVICE_MAPPING_PERSISTENT (RT_BIT(2))
+
+/**
+ * SAS Device page 1 - Readonly
+ */
+#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
+typedef struct MptConfigurationPageSASDevice1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Reserved */
+ uint32_t u32Reserved0;
+ /** SAS address */
+ SASADDRESS SASAddress;
+ /** Reserved */
+ uint32_t u32Reserved;
+ /** Device handle */
+ uint16_t u16DevHandle;
+ /** Target ID */
+ uint8_t u8TargetID;
+ /** Bus */
+ uint8_t u8Bus;
+ /** Initial REgister device FIS */
+ uint32_t au32InitialRegDeviceFIS[5];
+ } fields;
+ } u;
+} MptConfigurationPageSASDevice1, *PMptConfigurationPageSASDevice1;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageSASDevice1, 48);
+
+/**
+ * SAS Device page 2 - Read/Write persistent
+ */
+#pragma pack(1) /* Because of a uint64_t inside SASAddress, the struct size would be 24 without packing. */
+typedef struct MptConfigurationPageSASDevice2
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Physical identifier */
+ SASADDRESS SASAddress;
+ /** Enclosure mapping */
+ uint32_t u32EnclosureMapping;
+ } fields;
+ } u;
+} MptConfigurationPageSASDevice2, *PMptConfigurationPageSASDevice2;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageSASDevice2, 20);
+
+/**
+ * A device entitiy containing all pages.
+ */
+typedef struct MptSASDevice
+{
+ /** Pointer to the next device if any. */
+ struct MptSASDevice *pNext;
+ /** Pointer to the previous device if any. */
+ struct MptSASDevice *pPrev;
+
+ MptConfigurationPageSASDevice0 SASDevicePage0;
+ MptConfigurationPageSASDevice1 SASDevicePage1;
+ MptConfigurationPageSASDevice2 SASDevicePage2;
+} MptSASDevice, *PMptSASDevice;
+
+/**
+ * SAS Expander page 0 - Readonly
+ */
+#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
+typedef struct MptConfigurationPageSASExpander0
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Physical port */
+ uint8_t u8PhysicalPort;
+ /** Reserved */
+ uint8_t u8Reserved0;
+ /** Enclosure handle */
+ uint16_t u16EnclosureHandle;
+ /** SAS address */
+ SASADDRESS SASAddress;
+ /** Discovery status */
+ uint32_t u32DiscoveryStatus;
+ /** Device handle. */
+ uint16_t u16DevHandle;
+ /** Parent device handle */
+ uint16_t u16ParentDevHandle;
+ /** Expander change count */
+ uint16_t u16ExpanderChangeCount;
+ /** Expander route indexes */
+ uint16_t u16ExpanderRouteIndexes;
+ /** Number of PHys in this expander */
+ uint8_t u8NumPhys;
+ /** SAS level */
+ uint8_t u8SASLevel;
+ /** Flags */
+ uint8_t u8Flags;
+ /** Reserved */
+ uint8_t u8Reserved1;
+ } fields;
+ } u;
+} MptConfigurationPageSASExpander0, *PMptConfigurationPageSASExpander0;
+#pragma pack()
+AssertCompileSize(MptConfigurationPageSASExpander0, 36);
+
+/**
+ * SAS Expander page 1 - Readonly
+ */
+typedef struct MptConfigurationPageSASExpander1
+{
+ /** Union. */
+ union
+ {
+ /** Byte view - variable. */
+ uint8_t abPageData[1];
+ /** Field view. */
+ struct
+ {
+ /** The omnipresent header. */
+ MptExtendedConfigurationPageHeader ExtHeader;
+ /** Physical port */
+ uint8_t u8PhysicalPort;
+ /** Reserved */
+ uint8_t u8Reserved0[3];
+ /** Number of PHYs */
+ uint8_t u8NumPhys;
+ /** Number of the Phy the information in this page is for. */
+ uint8_t u8Phy;
+ /** Number of routing table entries */
+ uint16_t u16NumTableEntriesProgrammed;
+ /** Programmed link rate */
+ uint8_t u8ProgrammedLinkRate;
+ /** Hardware link rate */
+ uint8_t u8HwLinkRate;
+ /** Attached device handle */
+ uint16_t u16AttachedDevHandle;
+ /** Phy information */
+ uint32_t u32PhyInfo;
+ /** Attached device information */
+ uint32_t u32AttachedDeviceInfo;
+ /** Owner device handle. */
+ uint16_t u16OwnerDevHandle;
+ /** Change count */
+ uint8_t u8ChangeCount;
+ /** Negotiated link rate */
+ uint8_t u8NegotiatedLinkRate;
+ /** Phy identifier */
+ uint8_t u8PhyIdentifier;
+ /** Attached phy identifier */
+ uint8_t u8AttachedPhyIdentifier;
+ /** Reserved */
+ uint8_t u8Reserved1;
+ /** Discovery information */
+ uint8_t u8DiscoveryInfo;
+ /** Reserved */
+ uint32_t u32Reserved;
+ } fields;
+ } u;
+} MptConfigurationPageSASExpander1, *PMptConfigurationPageSASExpander1;
+AssertCompileSize(MptConfigurationPageSASExpander1, 40);
+
+/**
+ * Structure of all supported pages for the SCSI SPI controller.
+ * Used to load the device state from older versions.
+ */
+typedef struct MptConfigurationPagesSupported_SSM_V2
+{
+ MptConfigurationPageManufacturing0 ManufacturingPage0;
+ MptConfigurationPageManufacturing1 ManufacturingPage1;
+ MptConfigurationPageManufacturing2 ManufacturingPage2;
+ MptConfigurationPageManufacturing3 ManufacturingPage3;
+ MptConfigurationPageManufacturing4 ManufacturingPage4;
+ MptConfigurationPageIOUnit0 IOUnitPage0;
+ MptConfigurationPageIOUnit1 IOUnitPage1;
+ MptConfigurationPageIOUnit2 IOUnitPage2;
+ MptConfigurationPageIOUnit3 IOUnitPage3;
+ MptConfigurationPageIOC0 IOCPage0;
+ MptConfigurationPageIOC1 IOCPage1;
+ MptConfigurationPageIOC2 IOCPage2;
+ MptConfigurationPageIOC3 IOCPage3;
+ MptConfigurationPageIOC4 IOCPage4;
+ MptConfigurationPageIOC6 IOCPage6;
+ struct
+ {
+ MptConfigurationPageSCSISPIPort0 SCSISPIPortPage0;
+ MptConfigurationPageSCSISPIPort1 SCSISPIPortPage1;
+ MptConfigurationPageSCSISPIPort2 SCSISPIPortPage2;
+ } aPortPages[1]; /* Currently only one port supported. */
+ struct
+ {
+ struct
+ {
+ MptConfigurationPageSCSISPIDevice0 SCSISPIDevicePage0;
+ MptConfigurationPageSCSISPIDevice1 SCSISPIDevicePage1;
+ MptConfigurationPageSCSISPIDevice2 SCSISPIDevicePage2;
+ MptConfigurationPageSCSISPIDevice3 SCSISPIDevicePage3;
+ } aDevicePages[LSILOGICSCSI_PCI_SPI_DEVICES_MAX];
+ } aBuses[1]; /* Only one bus at the moment. */
+} MptConfigurationPagesSupported_SSM_V2, *PMptConfigurationPagesSupported_SSM_V2;
+
+typedef struct MptConfigurationPagesSpi
+{
+ struct
+ {
+ MptConfigurationPageSCSISPIPort0 SCSISPIPortPage0;
+ MptConfigurationPageSCSISPIPort1 SCSISPIPortPage1;
+ MptConfigurationPageSCSISPIPort2 SCSISPIPortPage2;
+ } aPortPages[1]; /* Currently only one port supported. */
+ struct
+ {
+ struct
+ {
+ MptConfigurationPageSCSISPIDevice0 SCSISPIDevicePage0;
+ MptConfigurationPageSCSISPIDevice1 SCSISPIDevicePage1;
+ MptConfigurationPageSCSISPIDevice2 SCSISPIDevicePage2;
+ MptConfigurationPageSCSISPIDevice3 SCSISPIDevicePage3;
+ } aDevicePages[LSILOGICSCSI_PCI_SPI_DEVICES_MAX];
+ } aBuses[1]; /* Only one bus at the moment. */
+} MptConfigurationPagesSpi, *PMptConfigurationPagesSpi;
+
+typedef struct MptPHY
+{
+ MptConfigurationPageSASPHY0 SASPHYPage0;
+ MptConfigurationPageSASPHY1 SASPHYPage1;
+} MptPHY, *PMptPHY;
+
+typedef struct MptConfigurationPagesSas
+{
+ /** Pointer to the manufacturing page 7 */
+ PMptConfigurationPageManufacturing7 pManufacturingPage7;
+ /** Size of the manufacturing page 7 */
+ uint32_t cbManufacturingPage7;
+ /** Size of the I/O unit page 0 */
+ uint32_t cbSASIOUnitPage0;
+ /** Pointer to the I/O unit page 0 */
+ PMptConfigurationPageSASIOUnit0 pSASIOUnitPage0;
+ /** Pointer to the I/O unit page 1 */
+ PMptConfigurationPageSASIOUnit1 pSASIOUnitPage1;
+ /** Size of the I/O unit page 1 */
+ uint32_t cbSASIOUnitPage1;
+ /** I/O unit page 2 */
+ MptConfigurationPageSASIOUnit2 SASIOUnitPage2;
+ /** I/O unit page 3 */
+ MptConfigurationPageSASIOUnit3 SASIOUnitPage3;
+
+ /** Number of PHYs in the array. */
+ uint32_t cPHYs;
+ /** Pointer to an array of per PHYS pages. */
+ R3PTRTYPE(PMptPHY) paPHYs;
+
+ /** Number of devices detected. */
+ uint32_t cDevices;
+ uint32_t u32Padding;
+ /** Pointer to the first SAS device. */
+ R3PTRTYPE(PMptSASDevice) pSASDeviceHead;
+ /** Pointer to the last SAS device. */
+ R3PTRTYPE(PMptSASDevice) pSASDeviceTail;
+} MptConfigurationPagesSas, *PMptConfigurationPagesSas;
+AssertCompile(RTASSERT_OFFSET_OF(MptConfigurationPagesSas,cbSASIOUnitPage0) + 4 == RTASSERT_OFFSET_OF(MptConfigurationPagesSas, pSASIOUnitPage0));
+AssertCompile(RTASSERT_OFFSET_OF(MptConfigurationPagesSas,cPHYs) + 4 == RTASSERT_OFFSET_OF(MptConfigurationPagesSas, paPHYs));
+AssertCompile(RTASSERT_OFFSET_OF(MptConfigurationPagesSas,cDevices) + 8 == RTASSERT_OFFSET_OF(MptConfigurationPagesSas, pSASDeviceHead));
+
+
+/**
+ * Structure of all supported pages for both controllers.
+ */
+typedef struct MptConfigurationPagesSupported
+{
+ MptConfigurationPageManufacturing0 ManufacturingPage0;
+ MptConfigurationPageManufacturing1 ManufacturingPage1;
+ MptConfigurationPageManufacturing2 ManufacturingPage2;
+ MptConfigurationPageManufacturing3 ManufacturingPage3;
+ MptConfigurationPageManufacturing4 ManufacturingPage4;
+ MptConfigurationPageManufacturing5 ManufacturingPage5;
+ MptConfigurationPageManufacturing6 ManufacturingPage6;
+ MptConfigurationPageManufacturing8 ManufacturingPage8;
+ MptConfigurationPageManufacturing9 ManufacturingPage9;
+ MptConfigurationPageManufacturing10 ManufacturingPage10;
+ MptConfigurationPageIOUnit0 IOUnitPage0;
+ MptConfigurationPageIOUnit1 IOUnitPage1;
+ MptConfigurationPageIOUnit2 IOUnitPage2;
+ MptConfigurationPageIOUnit3 IOUnitPage3;
+ MptConfigurationPageIOUnit4 IOUnitPage4;
+ MptConfigurationPageIOC0 IOCPage0;
+ MptConfigurationPageIOC1 IOCPage1;
+ MptConfigurationPageIOC2 IOCPage2;
+ MptConfigurationPageIOC3 IOCPage3;
+ MptConfigurationPageIOC4 IOCPage4;
+ MptConfigurationPageIOC6 IOCPage6;
+ /* BIOS page 0 is not described */
+ MptConfigurationPageBIOS1 BIOSPage1;
+ MptConfigurationPageBIOS2 BIOSPage2;
+ /* BIOS page 3 is not described */
+ MptConfigurationPageBIOS4 BIOSPage4;
+
+ /** Controller dependent data. */
+ union
+ {
+ MptConfigurationPagesSpi SpiPages;
+ MptConfigurationPagesSas SasPages;
+ } u;
+} MptConfigurationPagesSupported, *PMptConfigurationPagesSupported;
+
+/**
+ * Initializes a page header.
+ */
+#define MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags) \
+ (pg)->u.fields.Header.u8PageType = (flags); \
+ (pg)->u.fields.Header.u8PageNumber = (nr); \
+ (pg)->u.fields.Header.u8PageLength = sizeof(type) / 4
+
+#define MPT_CONFIG_PAGE_HEADER_INIT_MANUFACTURING(pg, type, nr, flags) \
+ RT_ZERO(*pg); \
+ MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_MANUFACTURING)
+
+#define MPT_CONFIG_PAGE_HEADER_INIT_IO_UNIT(pg, type, nr, flags) \
+ RT_ZERO(*pg); \
+ MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_IO_UNIT)
+
+#define MPT_CONFIG_PAGE_HEADER_INIT_IOC(pg, type, nr, flags) \
+ RT_ZERO(*pg); \
+ MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_IOC)
+
+#define MPT_CONFIG_PAGE_HEADER_INIT_BIOS(pg, type, nr, flags) \
+ RT_ZERO(*pg); \
+ MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_BIOS)
+
+/**
+ * Initializes a extended page header.
+ */
+#define MPT_CONFIG_EXTENDED_PAGE_HEADER_INIT(pg, cb, nr, flags, exttype) \
+ RT_BZERO(pg, cb); \
+ (pg)->u.fields.ExtHeader.u8PageType = (flags) | MPT_CONFIGURATION_PAGE_TYPE_EXTENDED; \
+ (pg)->u.fields.ExtHeader.u8PageNumber = (nr); \
+ (pg)->u.fields.ExtHeader.u8ExtPageType = (exttype); \
+ (pg)->u.fields.ExtHeader.u16ExtPageLength = (cb) / 4
+
+/**
+ * Possible SG element types.
+ */
+enum MPTSGENTRYTYPE
+{
+ MPTSGENTRYTYPE_TRANSACTION_CONTEXT = 0x00,
+ MPTSGENTRYTYPE_SIMPLE = 0x01,
+ MPTSGENTRYTYPE_CHAIN = 0x03
+};
+
+/**
+ * Register interface.
+ */
+
+/**
+ * Defined states that the SCSI controller can have.
+ */
+typedef enum LSILOGICSTATE
+{
+ /** Reset state. */
+ LSILOGICSTATE_RESET = 0x00,
+ /** Ready state. */
+ LSILOGICSTATE_READY = 0x01,
+ /** Operational state. */
+ LSILOGICSTATE_OPERATIONAL = 0x02,
+ /** Fault state. */
+ LSILOGICSTATE_FAULT = 0x04,
+ /** 32bit size hack */
+ LSILOGICSTATE_32BIT_HACK = 0x7fffffff
+} LSILOGICSTATE;
+
+/**
+ * Which entity needs to initialize the controller
+ * to get into the operational state.
+ */
+typedef enum LSILOGICWHOINIT
+{
+ /** Not initialized. */
+ LSILOGICWHOINIT_NOT_INITIALIZED = 0x00,
+ /** System BIOS. */
+ LSILOGICWHOINIT_SYSTEM_BIOS = 0x01,
+ /** ROM Bios. */
+ LSILOGICWHOINIT_ROM_BIOS = 0x02,
+ /** PCI Peer. */
+ LSILOGICWHOINIT_PCI_PEER = 0x03,
+ /** Host driver. */
+ LSILOGICWHOINIT_HOST_DRIVER = 0x04,
+ /** Manufacturing. */
+ LSILOGICWHOINIT_MANUFACTURING = 0x05,
+ /** 32bit size hack. */
+ LSILOGICWHOINIT_32BIT_HACK = 0x7fffffff
+} LSILOGICWHOINIT;
+
+
+/**
+ * Doorbell state.
+ */
+typedef enum LSILOGICDOORBELLSTATE
+{
+ /** Invalid value. */
+ LSILOGICDOORBELLSTATE_INVALID = 0,
+ /** Doorbell not in use. */
+ LSILOGICDOORBELLSTATE_NOT_IN_USE,
+ /** Reply frame removal, transfer number of entries, low 16bits. */
+ LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW,
+ /** Reply frame removal, transfer number of entries, high 16bits. */
+ LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH,
+ /** Reply frame removal, remove next free frame, low part. */
+ LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW,
+ /** Reply frame removal, remove next free frame, high part. */
+ LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH,
+ /** Function handshake. */
+ LSILOGICDOORBELLSTATE_FN_HANDSHAKE,
+ /** 32bit hack. */
+ LSILOGICDOORBELLSTATE_32BIT_HACK = 0x7fffffff
+} LSILOGICDOORBELLSTATE;
+/** Pointer to a doorbell state. */
+typedef LSILOGICDOORBELLSTATE *PLSILOGICDOORBELLSTATE;
+
+
+/**
+ * IOC status codes.
+ */
+#define LSILOGIC_IOCSTATUS_SUCCESS 0x0000
+#define LSILOGIC_IOCSTATUS_INVALID_FUNCTION 0x0001
+#define LSILOGIC_IOCSTATUS_BUSY 0x0002
+#define LSILOGIC_IOCSTATUS_INVALID_SGL 0x0003
+#define LSILOGIC_IOCSTATUS_INTERNAL_ERROR 0x0004
+#define LSILOGIC_IOCSTATUS_RESERVED 0x0005
+#define LSILOGIC_IOCSTATUS_INSUFFICIENT_RESOURCES 0x0006
+#define LSILOGIC_IOCSTATUS_INVALID_FIELD 0x0007
+#define LSILOGIC_IOCSTATUS_INVALID_STATE 0x0008
+#define LSILOGIC_IOCSTATUS_OP_STATE_NOT_SUPPOTED 0x0009
+
+/**
+ * Size of the I/O and MMIO space.
+ */
+#define LSILOGIC_PCI_SPACE_IO_SIZE 256
+#define LSILOGIC_PCI_SPACE_MEM_SIZE 128 * _1K
+
+/**
+ * Doorbell register - Used to get the status of the controller and
+ * initialise it.
+ */
+#define LSILOGIC_REG_DOORBELL 0x00
+# define LSILOGIC_REG_DOORBELL_SET_STATE(enmState) (((enmState) & 0x0f) << 28)
+# define LSILOGIC_REG_DOORBELL_SET_USED(enmDoorbell) (((enmDoorbell != LSILOGICDOORBELLSTATE_NOT_IN_USE) ? 1 : 0) << 27)
+# define LSILOGIC_REG_DOORBELL_SET_WHOINIT(enmWhoInit) (((enmWhoInit) & 0x07) << 24)
+# define LSILOGIC_REG_DOORBELL_SET_FAULT_CODE(u16Code) (u16Code)
+# define LSILOGIC_REG_DOORBELL_GET_FUNCTION(x) (((x) & 0xff000000) >> 24)
+# define LSILOGIC_REG_DOORBELL_GET_SIZE(x) (((x) & 0x00ff0000) >> 16)
+
+/**
+ * Functions which can be passed through the system doorbell.
+ */
+#define LSILOGIC_DOORBELL_FUNCTION_IOC_MSG_UNIT_RESET 0x40
+#define LSILOGIC_DOORBELL_FUNCTION_IO_UNIT_RESET 0x41
+#define LSILOGIC_DOORBELL_FUNCTION_HANDSHAKE 0x42
+#define LSILOGIC_DOORBELL_FUNCTION_REPLY_FRAME_REMOVAL 0x43
+
+/**
+ * Write sequence register for the diagnostic register.
+ */
+#define LSILOGIC_REG_WRITE_SEQUENCE 0x04
+
+/**
+ * Diagnostic register - used to reset the controller.
+ */
+#define LSILOGIC_REG_HOST_DIAGNOSTIC 0x08
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_DIAG_MEM_ENABLE (RT_BIT(0))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_DISABLE_ARM (RT_BIT(1))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_RESET_ADAPTER (RT_BIT(2))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_DIAG_RW_ENABLE (RT_BIT(4))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_RESET_HISTORY (RT_BIT(5))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_FLASH_BAD_SIG (RT_BIT(6))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_DRWE (RT_BIT(7))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_PREVENT_IOC_BOOT (RT_BIT(9))
+# define LSILOGIC_REG_HOST_DIAGNOSTIC_CLEAR_FLASH_BAD_SIG (RT_BIT(10))
+
+#define LSILOGIC_REG_TEST_BASE_ADDRESS 0x0c
+#define LSILOGIC_REG_DIAG_RW_DATA 0x10
+#define LSILOGIC_REG_DIAG_RW_ADDRESS 0x14
+
+/**
+ * Interrupt status register.
+ */
+#define LSILOGIC_REG_HOST_INTR_STATUS 0x30
+# define LSILOGIC_REG_HOST_INTR_STATUS_W_MASK (RT_BIT(3))
+# define LSILOGIC_REG_HOST_INTR_STATUS_DOORBELL_STS (RT_BIT(31))
+# define LSILOGIC_REG_HOST_INTR_STATUS_REPLY_INTR (RT_BIT(3))
+# define LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL (RT_BIT(0))
+
+/**
+ * Interrupt mask register.
+ */
+#define LSILOGIC_REG_HOST_INTR_MASK 0x34
+# define LSILOGIC_REG_HOST_INTR_MASK_W_MASK (RT_BIT(0) | RT_BIT(3) | RT_BIT(8) | RT_BIT(9))
+# define LSILOGIC_REG_HOST_INTR_MASK_IRQ_ROUTING (RT_BIT(8) | RT_BIT(9))
+# define LSILOGIC_REG_HOST_INTR_MASK_DOORBELL RT_BIT(0)
+# define LSILOGIC_REG_HOST_INTR_MASK_REPLY RT_BIT(3)
+
+/**
+ * Queue registers.
+ */
+#define LSILOGIC_REG_REQUEST_QUEUE 0x40
+#define LSILOGIC_REG_REPLY_QUEUE 0x44
+
+#endif /* !VBOX_INCLUDED_SRC_Storage_DevLsiLogicSCSI_h */