diff options
Diffstat (limited to '')
-rw-r--r-- | src/VBox/Devices/Storage/DevLsiLogicSCSI.h | 3648 |
1 files changed, 3648 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..2d4d7b25 --- /dev/null +++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.h @@ -0,0 +1,3648 @@ +/* $Id: DevLsiLogicSCSI.h $ */ +/** @file + * VBox storage devices: LsiLogic LSI53c1030 SCSI controller - Defines and structures. + */ + +/* + * Copyright (C) 2006-2019 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +#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_DEFAULT 256 +#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. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptSGEntrySimple64, 12); + +/** + * A simple SG element for a 32bit address. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptSGEntrySimple32, 8); + +/** + * A chain SG element. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ + #pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptDefaultReplyMessage, 20); + +/** + * IO controller init request. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptIOCInitRequest, 24); + +/** + * IO controller init reply. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptIOCInitReply, 20); + +/** + * IO controller facts request. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptIOCFactsRequest, 12); + +/** + * IO controller facts reply. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptIOCFactsReply, 60); + +/** + * Port facts request + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptPortFactsRequest, 12); + +/** + * Port facts reply. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptPortFactsReply, 40); + +/** + * Port Enable request. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptPortEnableRequest, 12); + +/** + * Port enable reply. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptPortEnableReply, 20); + +/** + * Event notification request. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptEventNotificationRequest, 12); + +/** + * Event notification reply. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptEventNotificationReply, 32); + +#define MPT_EVENT_EVENT_CHANGE (0x0000000a) + +/** + * FW download request. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptFWDownloadReply, 20); + +/** + * FW upload request. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptFWUploadRequest, 12); + +/** + * FW upload reply. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptFWUploadReply, 24); + +/** + * SCSI IO Request + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptSCSITaskManagementRequest, 52); + +/** + * SCSI task management reply. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptSCSITaskManagementReply, 24); + +/** + * Page address for SAS expander page types. + */ +#pragma pack(1) +typedef union MptConfigurationPageAddressSASExpander +{ + struct + { + uint16_t u16Handle; + uint16_t u16Reserved; + } Form0And2; + struct + { + uint16_t u16Handle; + uint8_t u8PhyNum; + uint8_t u8Reserved; + } Form1; +} MptConfigurationPageAddressSASExpander, *PMptConfigurationPageAddressSASExpander; +#pragma pack() + +/** + * Page address for SAS device page types. + */ +#pragma pack(1) +typedef union MptConfigurationPageAddressSASDevice +{ + struct + { + uint16_t u16Handle; + uint16_t u16Reserved; + } Form0And2; + struct + { + uint8_t u8TargetID; + uint8_t u8Bus; + uint8_t u8Reserved; + } Form1; +} MptConfigurationPageAddressSASDevice, *PMptConfigurationPageAddressSASDevice; +#pragma pack() + +/** + * Page address for SAS PHY page types. + */ +#pragma pack(1) +typedef union MptConfigurationPageAddressSASPHY +{ + struct + { + uint8_t u8PhyNumber; + uint8_t u8Reserved[3]; + } Form0; + struct + { + uint16_t u16Index; + uint16_t u16Reserved; + } Form1; +} MptConfigurationPageAddressSASPHY, *PMptConfigurationPageAddressSASPHY; +#pragma pack() + +/** + * Page address for SAS Enclosure page types. + */ +#pragma pack(1) +typedef struct MptConfigurationPageAddressSASEnclosure +{ + uint16_t u16Handle; + uint16_t u16Reserved; +} MptConfigurationPageAddressSASEnclosure, *PMptConfigurationPageAddressSASEnclosure; +#pragma pack() + +/** + * Union of all possible address types. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageAddress, 4); + +#define MPT_CONFIGURATION_PAGE_ADDRESS_GET_SAS_FORM(x) (((x).u32PageAddress >> 28) & 0x0f) + +/** + * Configuration request + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageHeader, 4); + +/** + * Extended configuration page header - Common to all extended pages. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptExtendedConfigurationPageHeader, 8); + +/** + * Manufacturing page 0. - Readonly. + */ +#pragma pack(1) +typedef struct MptConfigurationPageManufacturing0 +{ + /** 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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing0, 76); + +/** + * Manufacturing page 1. - Readonly Persistent. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing1, 260); + +/** + * Manufacturing page 2. - Readonly. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing2, 8); + +/** + * Manufacturing page 3. - Readonly. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing3, 8); + +/** + * Manufacturing page 4. - Readonly. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing4, 84); + +/** + * Manufacturing page 5 - Readonly. + */ +#pragma pack(1) +typedef struct MptConfigurationPageManufacturing5 +{ + /** Union. */ + union + { + /** Byte view. */ + uint8_t abPageData[88]; + /** Field view. */ + struct + { + /** The omnipresent header. */ + MptConfigurationPageHeader Header; + /** Base WWID. */ + 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. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing6, 4); + +/** + * Manufacutring page 7 - PHY element. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing7PHY, 24); + +/** + * Manufacturing page 7 - Readonly. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing8, 4); + +/** + * Manufacturing page 9 - Readonly. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing9, 4); + +/** + * Manufacturing page 10 - Readonly. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageManufacturing10, 4); + +/** + * IO Unit page 0. - Readonly. + */ +#pragma pack(1) +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. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOUnit1, 8); + +/** + * Adapter Ordering. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOUnit2AdapterOrdering, 4); + +/** + * IO Unit page 2. - Read/Write. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOUnit2, 28); + +/* + * IO Unit page 3. - Read/Write. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOUnit3, 8); + +/* + * IO Unit page 4. - Readonly for everyone except the BIOS. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOUnit4, 20); + +/** + * IOC page 0. - Readonly + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOC0, 28); + +/** + * IOC page 1. - Read/Write + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOC1, 16); + +/** + * IOC page 2. - Readonly + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOC2, 12); + +/** + * IOC page 3. - Readonly + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOC3, 8); + +/** + * IOC page 4. - Read/Write + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOC4, 8); + +/** + * IOC page 6. - Read/Write + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageIOC6, 60); + +/** + * BIOS page 1 - Read/write. + */ +#pragma pack(1) +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; +#pragma pack() +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. + */ +#pragma pack(1) +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; + /** 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; + /** 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; +#pragma pack() +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) +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 + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSCSISPIPort0, 12); + +/** + * SCSI-SPI port page 1. - Read/Write + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSCSISPIPort1, 12); + +/** + * Device settings for one device. + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptDeviceSettings, 4); + +/** + * SCSI-SPI port page 2. - Read/Write for the BIOS + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSCSISPIPort2, 76); + +/** + * SCSI-SPI device page 0. - Readonly + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSCSISPIDevice0, 12); + +/** + * SCSI-SPI device page 1. - Read/Write + */ +#pragma pack(1) +typedef struct MptConfigurationPageSCSISPIDevice1 +{ + /** Union. */ + union + { + /** Byte view. */ + uint8_t abPageData[16]; + /** Field view. */ + struct + { + /** The omnipresent header. */ + MptConfigurationPageHeader Header; + /** Requested Parameters. */ + /** Information Units enable. */ + bool fInformationUnitsEnable: 1; + /** Dual Transfers Enable. */ + bool fDTEnable: 1; + /** QAS enable. */ + bool 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. */ + bool fWide: 1; + /** Reserved. */ + bool fReserved1: 1; + /** AIP enable. */ + bool fAIPEnable: 1; + /** Reserved. */ + bool fReserved2: 1; + /** WDTR disallowed. */ + bool fWDTRDisallowed: 1; + /** SDTR disallowed. */ + bool fSDTRDisallowed: 1; + /** Reserved. */ + unsigned u29Reserved: 29; + } fields; + } u; +} MptConfigurationPageSCSISPIDevice1, *PMptConfigurationPageSCSISPIDevice1; +#pragma pack() +AssertCompileSize(MptConfigurationPageSCSISPIDevice1, 16); + +/** + * SCSI-SPI device page 2. - Read/Write + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSCSISPIDevice2, 16); + +/** + * SCSI-SPI device page 3 (Revision G). - Readonly + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSCSISPIDevice3, 12); + +/** + * PHY entry for the SAS I/O unit page 0 + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSASIOUnit0PHY, 16); + +/** + * SAS I/O Unit page 0 - Readonly + */ +#pragma pack(1) +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; +#pragma pack() +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 + */ +#pragma pack(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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSASIOUnit1PHY, 12); + +/** + * SAS I/O Unit page 1 - Read/Write + */ +#pragma pack(1) +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; +#pragma pack() +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 + */ +#pragma pack(1) +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; +#pragma pack() +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 + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSASIOUnit3, 44); + +/** + * SAS PHY page 0 - Readonly + */ +#pragma pack(1) +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 + */ +#pragma pack(1) +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; +#pragma pack() +AssertCompileSize(MptConfigurationPageSASPHY1, 28); + +/** + * SAS Device page 0 - Readonly + */ +#pragma pack(1) +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) +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) +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) +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 + */ +#pragma pack(1) +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; +#pragma pack() +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; + +#pragma pack(1) +typedef struct MptConfigurationPagesSas +{ + /** Size of the manufacturing page 7 */ + uint32_t cbManufacturingPage7; + /** Pointer to the manufacturing page 7 */ + PMptConfigurationPageManufacturing7 pManufacturingPage7; + /** Size of the I/O unit page 0 */ + uint32_t cbSASIOUnitPage0; + /** Pointer to the I/O unit page 0 */ + PMptConfigurationPageSASIOUnit0 pSASIOUnitPage0; + /** Size of the I/O unit page 1 */ + uint32_t cbSASIOUnitPage1; + /** Pointer to the I/O unit page 1 */ + PMptConfigurationPageSASIOUnit1 pSASIOUnitPage1; + /** 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; + /** Pointer to the first SAS device. */ + R3PTRTYPE(PMptSASDevice) pSASDeviceHead; + /** Pointer to the last SAS device. */ + R3PTRTYPE(PMptSASDevice) pSASDeviceTail; +} MptConfigurationPagesSas, *PMptConfigurationPagesSas; +#pragma pack() + +/** + * 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) \ + 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) \ + 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) \ + 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) \ + 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) \ + (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 */ |