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