VirtualBox

Changeset 25509 in vbox


Ignore:
Timestamp:
Dec 18, 2009 11:03:25 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56182
Message:

LsiLogic: Start for the SAS controller. Define neccessary pages and separate the spi from the sas pages. Move the structs in a separate header file to make the source file smaller

Location:
trunk/src/VBox/Devices/Storage
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r25488 r25509  
    3535#endif
    3636
     37#include "DevLsiLogicSCSI.h"
    3738#include "VBoxSCSI.h"
    3839
    3940#include "../Builtins.h"
    40 
    41 /* I/O port registered in the ISA compatible range to let the BIOS access
    42  * the controller.
    43  */
    44 #define LSILOGIC_ISA_IO_PORT 0x340
    45 
    46 #define LSILOGIC_PORTS_MAX 1
    47 #define LSILOGIC_BUSES_MAX 1
    48 #define LSILOGIC_DEVICES_PER_BUS_MAX 16
    49 
    50 #define LSILOGIC_DEVICES_MAX (LSILOGIC_BUSES_MAX*LSILOGIC_DEVICES_PER_BUS_MAX)
    51 
    52 #define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT 1024
    53 #define LSILOGICSCSI_REPLY_QUEUE_DEPTH_DEFAULT   128
    54 
    55 #define LSILOGICSCSI_MAXIMUM_CHAIN_DEPTH 3
    56 
    57 #define LSILOGIC_NR_OF_ALLOWED_BIGGER_LISTS 100
    58 
    59 #define LSILOGICSCSI_PCI_VENDOR_ID            (0x1000)
    60 #define LSILOGICSCSI_PCI_DEVICE_ID            (0x0030)
    61 #define LSILOGICSCSI_PCI_REVISION_ID          (0x00)
    62 #define LSILOGICSCSI_PCI_CLASS_CODE           (0x01)
    63 #define LSILOGICSCSI_PCI_SUBSYSTEM_VENDOR_ID  (0x1000)
    64 #define LSILOGICSCSI_PCI_SUBSYSTEM_ID         (0x8000)
    65 
    66 /** The current saved state version. */
    67 #define LSILOGIC_SAVED_STATE_VERSION          2
    68 /** The saved state version used by VirtualBox 3.0 and earlier.  It does not
    69  * include the device config part. */
    70 #define LSILOGIC_SAVED_STATE_VERSION_VBOX_30  1
    71 
    72 /**
    73  * A simple SG element for a 64bit adress.
    74  */
    75 #pragma pack(1)
    76 typedef struct MptSGEntrySimple64
    77 {
    78     /** Length of the buffer this entry describes. */
    79     unsigned u24Length:          24;
    80     /** Flag whether this element is the end of the list. */
    81     unsigned fEndOfList:          1;
    82     /** Flag whether the address is 32bit or 64bits wide. */
    83     unsigned f64BitAddress:       1;
    84     /** Flag whether this buffer contains data to be transfered or is the destination. */
    85     unsigned fBufferContainsData: 1;
    86     /** Flag whether this is a local address or a system address. */
    87     unsigned fLocalAddress:       1;
    88     /** Element type. */
    89     unsigned u2ElementType:       2;
    90     /** Flag whether this is the last element of the buffer. */
    91     unsigned fEndOfBuffer:        1;
    92     /** Flag whether this is the last element of the current segment. */
    93     unsigned fLastElement:        1;
    94     /** Lower 32bits of the address of the data buffer. */
    95     unsigned u32DataBufferAddressLow: 32;
    96     /** Upper 32bits of the address of the data buffer. */
    97     unsigned u32DataBufferAddressHigh: 32;
    98 } MptSGEntrySimple64, *PMptSGEntrySimple64;
    99 #pragma pack()
    100 AssertCompileSize(MptSGEntrySimple64, 12);
    101 
    102 /**
    103  * A simple SG element for a 32bit adress.
    104  */
    105 #pragma pack(1)
    106 typedef struct MptSGEntrySimple32
    107 {
    108     /** Length of the buffer this entry describes. */
    109     unsigned u24Length:          24;
    110     /** Flag whether this element is the end of the list. */
    111     unsigned fEndOfList:          1;
    112     /** Flag whether the address is 32bit or 64bits wide. */
    113     unsigned f64BitAddress:       1;
    114     /** Flag whether this buffer contains data to be transfered or is the destination. */
    115     unsigned fBufferContainsData: 1;
    116     /** Flag whether this is a local address or a system address. */
    117     unsigned fLocalAddress:       1;
    118     /** Element type. */
    119     unsigned u2ElementType:       2;
    120     /** Flag whether this is the last element of the buffer. */
    121     unsigned fEndOfBuffer:        1;
    122     /** Flag whether this is the last element of the current segment. */
    123     unsigned fLastElement:        1;
    124     /** Lower 32bits of the address of the data buffer. */
    125     unsigned u32DataBufferAddressLow: 32;
    126 } MptSGEntrySimple32, *PMptSGEntrySimple32;
    127 #pragma pack()
    128 AssertCompileSize(MptSGEntrySimple32, 8);
    129 
    130 /**
    131  * A chain SG element.
    132  */
    133 #pragma pack(1)
    134 typedef struct MptSGEntryChain
    135 {
    136     /** Size of the segment. */
    137     unsigned u16Length: 16;
    138     /** Offset in 32bit words of the next chain element in the segment
    139      *  identified by this element. */
    140     unsigned u8NextChainOffset: 8;
    141     /** Reserved. */
    142     unsigned fReserved0:    1;
    143     /** Flag whether the address is 32bit or 64bits wide. */
    144     unsigned f64BitAddress: 1;
    145     /** Reserved. */
    146     unsigned fReserved1:    1;
    147     /** Flag whether this is a local address or a system address. */
    148     unsigned fLocalAddress: 1;
    149     /** Element type. */
    150     unsigned u2ElementType: 2;
    151     /** Flag whether this is the last element of the buffer. */
    152     unsigned u2Reserved2:   2;
    153     /** Lower 32bits of the address of the data buffer. */
    154     unsigned u32SegmentAddressLow: 32;
    155     /** Upper 32bits of the address of the data buffer. */
    156     unsigned u32SegmentAddressHigh: 32;
    157 } MptSGEntryChain, *PMptSGEntryChain;
    158 #pragma pack()
    159 AssertCompileSize(MptSGEntryChain, 12);
    160 
    161 typedef union MptSGEntryUnion
    162 {
    163     MptSGEntrySimple64 Simple64;
    164     MptSGEntrySimple32 Simple32;
    165     MptSGEntryChain    Chain;
    166 } MptSGEntryUnion, *PMptSGEntryUnion;
    167 
    168 /**
    169  * MPT Fusion message header - Common for all message frames.
    170  * This is filled in by the guest.
    171  */
    172 #pragma pack(1)
    173 typedef struct MptMessageHdr
    174 {
    175     /** Function dependent data. */
    176     uint16_t    u16FunctionDependent;
    177     /** Chain offset. */
    178     uint8_t     u8ChainOffset;
    179     /** The function code. */
    180     uint8_t     u8Function;
    181     /** Function dependent data. */
    182     uint8_t     au8FunctionDependent[3];
    183     /** Message flags. */
    184     uint8_t     u8MessageFlags;
    185     /** Message context - Unique ID from the guest unmodified by the device. */
    186     uint32_t    u32MessageContext;
    187 } MptMessageHdr, *PMptMessageHdr;
    188 #pragma pack()
    189 AssertCompileSize(MptMessageHdr, 12);
    190 
    191 /** Defined function codes found in the message header. */
    192 #define MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST        (0x00)
    193 #define MPT_MESSAGE_HDR_FUNCTION_SCSI_TASK_MGMT         (0x01)
    194 #define MPT_MESSAGE_HDR_FUNCTION_IOC_INIT               (0x02)
    195 #define MPT_MESSAGE_HDR_FUNCTION_IOC_FACTS              (0x03)
    196 #define MPT_MESSAGE_HDR_FUNCTION_CONFIG                 (0x04)
    197 #define MPT_MESSAGE_HDR_FUNCTION_PORT_FACTS             (0x05)
    198 #define MPT_MESSAGE_HDR_FUNCTION_PORT_ENABLE            (0x06)
    199 #define MPT_MESSAGE_HDR_FUNCTION_EVENT_NOTIFICATION     (0x07)
    200 #define MPT_MESSAGE_HDR_FUNCTION_EVENT_ACK              (0x08)
    201 #define MPT_MESSAGE_HDR_FUNCTION_FW_DOWNLOAD            (0x09)
    202 #define MPT_MESSAGE_HDR_FUNCTION_TARGET_CMD_BUFFER_POST (0x0A)
    203 #define MPT_MESSAGE_HDR_FUNCTION_TARGET_ASSIST          (0x0B)
    204 #define MPT_MESSAGE_HDR_FUNCTION_TARGET_STATUS_SEND     (0x0C)
    205 #define MPT_MESSAGE_HDR_FUNCTION_TARGET_MODE_ABORT      (0x0D)
    206 
    207 #ifdef DEBUG
    208 /**
    209  * Function names
    210  */
    211 static const char * const g_apszMPTFunctionNames[] =
    212 {
    213     "SCSI I/O Request",
    214     "SCSI Task Management",
    215     "IOC Init",
    216     "IOC Facts",
    217     "Config",
    218     "Port Facts",
    219     "Port Enable",
    220     "Event Notification",
    221     "Event Ack",
    222     "Firmware Download"
    223 };
    224 #endif
    225 
    226 /**
    227  * Default reply message.
    228  * Send from the device to the guest upon completion of a request.
    229  */
    230  #pragma pack(1)
    231 typedef struct MptDefaultReplyMessage
    232 {
    233     /** Function dependent data. */
    234     uint16_t    u16FunctionDependent;
    235     /** Length of the message in 32bit DWords. */
    236     uint8_t     u8MessageLength;
    237     /** Function which completed. */
    238     uint8_t     u8Function;
    239     /** Function dependent. */
    240     uint8_t     au8FunctionDependent[3];
    241     /** Message flags. */
    242     uint8_t     u8MessageFlags;
    243     /** Message context given in the request. */
    244     uint32_t    u32MessageContext;
    245     /** Function dependent status code. */
    246     uint16_t    u16FunctionDependentStatus;
    247     /** Status of the IOC. */
    248     uint16_t    u16IOCStatus;
    249     /** Additional log info. */
    250     uint32_t    u32IOCLogInfo;
    251 } MptDefaultReplyMessage, *PMptDefaultReplyMessage;
    252 #pragma pack()
    253 AssertCompileSize(MptDefaultReplyMessage, 20);
    254 
    255 /**
    256  * IO controller init request.
    257  */
    258 #pragma pack(1)
    259 typedef struct MptIOCInitRequest
    260 {
    261     /** Which system send this init request. */
    262     uint8_t     u8WhoInit;
    263     /** Reserved */
    264     uint8_t     u8Reserved;
    265     /** Chain offset in the SG list. */
    266     uint8_t     u8ChainOffset;
    267     /** Function to execute. */
    268     uint8_t     u8Function;
    269     /** Flags */
    270     uint8_t     u8Flags;
    271     /** Maximum number of devices the driver can handle. */
    272     uint8_t     u8MaxDevices;
    273     /** Maximum number of buses the driver can handle. */
    274     uint8_t     u8MaxBuses;
    275     /** Message flags. */
    276     uint8_t     u8MessageFlags;
    277     /** Message context ID. */
    278     uint32_t    u32MessageContext;
    279     /** Reply frame size. */
    280     uint16_t    u16ReplyFrameSize;
    281     /** Reserved */
    282     uint16_t    u16Reserved;
    283     /** Upper 32bit part of the 64bit address the message frames are in.
    284      *  That means all frames must be in the same 4GB segment. */
    285     uint32_t    u32HostMfaHighAddr;
    286     /** Upper 32bit of the sense buffer. */
    287     uint32_t    u32SenseBufferHighAddr;
    288 } MptIOCInitRequest, *PMptIOCInitRequest;
    289 #pragma pack()
    290 AssertCompileSize(MptIOCInitRequest, 24);
    291 
    292 /**
    293  * IO controller init reply.
    294  */
    295 #pragma pack(1)
    296 typedef struct MptIOCInitReply
    297 {
    298     /** Which subsystem send this init request. */
    299     uint8_t     u8WhoInit;
    300     /** Reserved */
    301     uint8_t     u8Reserved;
    302     /** Message length */
    303     uint8_t     u8MessageLength;
    304     /** Function. */
    305     uint8_t     u8Function;
    306     /** Flags */
    307     uint8_t     u8Flags;
    308     /** Maximum number of devices the driver can handle. */
    309     uint8_t     u8MaxDevices;
    310     /** Maximum number of busses the driver can handle. */
    311     uint8_t     u8MaxBuses;
    312     /** Message flags. */
    313     uint8_t     u8MessageFlags;
    314     /** Message context ID */
    315     uint32_t    u32MessageContext;
    316     /** Reserved */
    317     uint16_t    u16Reserved;
    318     /** IO controller status. */
    319     uint16_t    u16IOCStatus;
    320     /** IO controller log information. */
    321     uint32_t    u32IOCLogInfo;
    322 } MptIOCInitReply, *PMptIOCInitReply;
    323 #pragma pack()
    324 AssertCompileSize(MptIOCInitReply, 20);
    325 
    326 /**
    327  * IO controller facts request.
    328  */
    329 #pragma pack(1)
    330 typedef struct MptIOCFactsRequest
    331 {
    332     /** Reserved. */
    333     uint16_t    u16Reserved;
    334     /** Chain offset in SG list. */
    335     uint8_t     u8ChainOffset;
    336     /** Function number. */
    337     uint8_t     u8Function;
    338     /** Reserved */
    339     uint8_t     u8Reserved[3];
    340     /** Message flags. */
    341     uint8_t     u8MessageFlags;
    342     /** Message context ID. */
    343     uint32_t    u32MessageContext;
    344 } MptIOCFactsRequest, *PMptIOCFactsRequest;
    345 #pragma pack()
    346 AssertCompileSize(MptIOCFactsRequest, 12);
    347 
    348 /**
    349  * IO controller facts reply.
    350  */
    351 #pragma pack(1)
    352 typedef struct MptIOCFactsReply
    353 {
    354     /** Message version. */
    355     uint16_t    u16MessageVersion;
    356     /** Message length. */
    357     uint8_t     u8MessageLength;
    358     /** Function number. */
    359     uint8_t     u8Function;
    360     /** Reserved */
    361     uint16_t    u16Reserved1;
    362     /** IO controller number */
    363     uint8_t     u8IOCNumber;
    364     /** Message flags. */
    365     uint8_t     u8MessageFlags;
    366     /** Message context ID. */
    367     uint32_t    u32MessageContext;
    368     /** IO controller exceptions */
    369     uint16_t    u16IOCExceptions;
    370     /** IO controller status. */
    371     uint16_t    u16IOCStatus;
    372     /** IO controller log information. */
    373     uint32_t    u32IOCLogInfo;
    374     /** Maximum chain depth. */
    375     uint8_t     u8MaxChainDepth;
    376     /** The current value of the WhoInit field. */
    377     uint8_t     u8WhoInit;
    378     /** Block size. */
    379     uint8_t     u8BlockSize;
    380     /** Flags. */
    381     uint8_t     u8Flags;
    382     /** Depth of the reply queue. */
    383     uint16_t    u16ReplyQueueDepth;
    384     /** Size of a request frame. */
    385     uint16_t    u16RequestFrameSize;
    386     /** Reserved */
    387     uint16_t    u16Reserved2;
    388     /** Product ID. */
    389     uint16_t    u16ProductID;
    390     /** Current value of the high 32bit MFA address. */
    391     uint32_t    u32CurrentHostMFAHighAddr;
    392     /** Global credits - Number of entries allocated to queues */
    393     uint16_t    u16GlobalCredits;
    394     /** Number of ports on the IO controller */
    395     uint8_t     u8NumberOfPorts;
    396     /** Event state. */
    397     uint8_t     u8EventState;
    398     /** Current value of the high 32bit sense buffer address. */
    399     uint32_t    u32CurrentSenseBufferHighAddr;
    400     /** Current reply frame size. */
    401     uint16_t    u16CurReplyFrameSize;
    402     /** Maximum number of devices. */
    403     uint8_t     u8MaxDevices;
    404     /** Maximum number of buses. */
    405     uint8_t     u8MaxBuses;
    406     /** Size of the firmware image. */
    407     uint32_t    u32FwImageSize;
    408     /** Reserved. */
    409     uint32_t    u32Reserved;
    410     /** Firmware version */
    411     uint32_t    u32FWVersion;
    412 } MptIOCFactsReply, *PMptIOCFactsReply;
    413 #pragma pack()
    414 AssertCompileSize(MptIOCFactsReply, 60);
    415 
    416 /**
    417  * Port facts request
    418  */
    419 #pragma pack(1)
    420 typedef struct MptPortFactsRequest
    421 {
    422     /** Reserved */
    423     uint16_t    u16Reserved1;
    424     /** Message length. */
    425     uint8_t     u8MessageLength;
    426     /** Function number. */
    427     uint8_t     u8Function;
    428     /** Reserved */
    429     uint16_t    u16Reserved2;
    430     /** Port number to get facts for. */
    431     uint8_t     u8PortNumber;
    432     /** Message flags. */
    433     uint8_t     u8MessageFlags;
    434     /** Message context ID. */
    435     uint32_t    u32MessageContext;
    436 } MptPortFactsRequest, *PMptPortFactsRequest;
    437 #pragma pack()
    438 AssertCompileSize(MptPortFactsRequest, 12);
    439 
    440 /**
    441  * Port facts reply.
    442  */
    443 #pragma pack(1)
    444 typedef struct MptPortFactsReply
    445 {
    446     /** Reserved. */
    447     uint16_t    u16Reserved1;
    448     /** Message length. */
    449     uint8_t     u8MessageLength;
    450     /** Function number. */
    451     uint8_t     u8Function;
    452     /** Reserved */
    453     uint16_t    u16Reserved2;
    454     /** Port number the facts are for. */
    455     uint8_t     u8PortNumber;
    456     /** Message flags. */
    457     uint8_t     u8MessageFlags;
    458     /** Message context ID. */
    459     uint32_t    u32MessageContext;
    460     /** Reserved. */
    461     uint16_t    u16Reserved3;
    462     /** IO controller status. */
    463     uint16_t    u16IOCStatus;
    464     /** IO controller log information. */
    465     uint32_t    u32IOCLogInfo;
    466     /** Reserved */
    467     uint8_t     u8Reserved;
    468     /** Port type */
    469     uint8_t     u8PortType;
    470     /** Maximum number of devices on this port. */
    471     uint16_t    u16MaxDevices;
    472     /** SCSI ID of this port on the attached bus. */
    473     uint16_t    u16PortSCSIID;
    474     /** Protocol flags. */
    475     uint16_t    u16ProtocolFlags;
    476     /** Maxmimum number of target command buffers which can be posted to this port at a time. */
    477     uint16_t    u16MaxPostedCmdBuffers;
    478     /** Maximum number of target IDs that remain persistent between power/reset cycles. */
    479     uint16_t    u16MaxPersistentIDs;
    480     /** Maximum number of LAN buckets. */
    481     uint16_t    u16MaxLANBuckets;
    482     /** Reserved. */
    483     uint16_t    u16Reserved4;
    484     /** Reserved. */
    485     uint32_t    u32Reserved;
    486 } MptPortFactsReply, *PMptPortFactsReply;
    487 #pragma pack()
    488 AssertCompileSize(MptPortFactsReply, 40);
    489 
    490 /**
    491  * Port Enable request.
    492  */
    493 #pragma pack(1)
    494 typedef struct MptPortEnableRequest
    495 {
    496     /** Reserved. */
    497     uint16_t    u16Reserved1;
    498     /** Message length. */
    499     uint8_t     u8MessageLength;
    500     /** Function number. */
    501     uint8_t     u8Function;
    502     /** Reserved. */
    503     uint16_t    u16Reserved2;
    504     /** Port number to enable. */
    505     uint8_t     u8PortNumber;
    506     /** Message flags. */
    507     uint8_t     u8MessageFlags;
    508     /** Message context ID. */
    509     uint32_t    u32MessageContext;
    510 } MptPortEnableRequest, *PMptPortEnableRequest;
    511 #pragma pack()
    512 AssertCompileSize(MptPortEnableRequest, 12);
    513 
    514 /**
    515  * Port enable reply.
    516  */
    517 #pragma pack(1)
    518 typedef struct MptPortEnableReply
    519 {
    520     /** Reserved. */
    521     uint16_t    u16Reserved1;
    522     /** Message length. */
    523     uint8_t     u8MessageLength;
    524     /** Function number. */
    525     uint8_t     u8Function;
    526     /** Reserved */
    527     uint16_t    u16Reserved2;
    528     /** Port number which was enabled. */
    529     uint8_t     u8PortNumber;
    530     /** Message flags. */
    531     uint8_t     u8MessageFlags;
    532     /** Message context ID. */
    533     uint32_t    u32MessageContext;
    534     /** Reserved. */
    535     uint16_t    u16Reserved3;
    536     /** IO controller status */
    537     uint16_t    u16IOCStatus;
    538     /** IO controller log information. */
    539     uint32_t    u32IOCLogInfo;
    540 } MptPortEnableReply, *PMptPortEnableReply;
    541 #pragma pack()
    542 AssertCompileSize(MptPortEnableReply, 20);
    543 
    544 /**
    545  * Event notification request.
    546  */
    547 #pragma pack(1)
    548 typedef struct MptEventNotificationRequest
    549 {
    550     /** Switch - Turns event notification on and off. */
    551     uint8_t     u8Switch;
    552     /** Reserved. */
    553     uint8_t     u8Reserved1;
    554     /** Chain offset. */
    555     uint8_t     u8ChainOffset;
    556     /** Function number. */
    557     uint8_t     u8Function;
    558     /** Reserved. */
    559     uint8_t     u8reserved2[3];
    560     /** Message flags. */
    561     uint8_t     u8MessageFlags;
    562     /** Message context ID. */
    563     uint32_t    u32MessageContext;
    564 } MptEventNotificationRequest, *PMptEventNotificationRequest;
    565 #pragma pack()
    566 AssertCompileSize(MptEventNotificationRequest, 12);
    567 
    568 /**
    569  * Event notification reply.
    570  */
    571 #pragma pack(1)
    572 typedef struct MptEventNotificationReply
    573 {
    574     /** Event data length. */
    575     uint16_t    u16EventDataLength;
    576     /** Message length. */
    577     uint8_t     u8MessageLength;
    578     /** Function number. */
    579     uint8_t     u8Function;
    580     /** Reserved. */
    581     uint16_t    u16Reserved1;
    582     /** Ack required. */
    583     uint8_t     u8AckRequired;
    584     /** Message flags. */
    585     uint8_t     u8MessageFlags;
    586     /** Message context ID. */
    587     uint32_t    u32MessageContext;
    588     /** Reserved. */
    589     uint16_t    u16Reserved2;
    590     /** IO controller status. */
    591     uint16_t    u16IOCStatus;
    592     /** IO controller log information. */
    593     uint32_t    u32IOCLogInfo;
    594     /** Notification event. */
    595     uint32_t    u32Event;
    596     /** Event context. */
    597     uint32_t    u32EventContext;
    598     /** Event data. */
    599     uint32_t    u32EventData;
    600 } MptEventNotificationReply, *PMptEventNotificationReply;
    601 #pragma pack()
    602 AssertCompileSize(MptEventNotificationReply, 32);
    603 
    604 #define MPT_EVENT_EVENT_CHANGE (0x0000000a)
    605 
    606 /**
    607  * SCSI IO Request
    608  */
    609 #pragma pack(1)
    610 typedef struct MptSCSIIORequest
    611 {
    612     /** Target ID */
    613     uint8_t     u8TargetID;
    614     /** Bus number */
    615     uint8_t     u8Bus;
    616     /** Chain offset */
    617     uint8_t     u8ChainOffset;
    618     /** Function number. */
    619     uint8_t     u8Function;
    620     /** CDB length. */
    621     uint8_t     u8CDBLength;
    622     /** Sense buffer length. */
    623     uint8_t     u8SenseBufferLength;
    624     /** Rserved */
    625     uint8_t     u8Reserved;
    626     /** Message flags. */
    627     uint8_t     u8MessageFlags;
    628     /** Message context ID. */
    629     uint32_t    u32MessageContext;
    630     /** LUN */
    631     uint8_t     au8LUN[8];
    632     /** Control values. */
    633     uint32_t    u32Control;
    634     /** The CDB. */
    635     uint8_t     au8CDB[16];
    636     /** Data length. */
    637     uint32_t    u32DataLength;
    638     /** Sense buffer low 32bit address. */
    639     uint32_t    u32SenseBufferLowAddress;
    640 } MptSCSIIORequest, *PMptSCSIIORequest;
    641 #pragma pack()
    642 AssertCompileSize(MptSCSIIORequest, 48);
    643 
    644 #define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_GET(x) (((x) & 0x3000000) >> 24)
    645 #define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE  (0x0)
    646 #define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE (0x1)
    647 #define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ  (0x2)
    648 
    649 /**
    650  * SCSI IO error reply.
    651  */
    652 #pragma pack(1)
    653 typedef struct MptSCSIIOErrorReply
    654 {
    655     /** Target ID */
    656     uint8_t     u8TargetID;
    657     /** Bus number */
    658     uint8_t     u8Bus;
    659     /** Message length. */
    660     uint8_t     u8MessageLength;
    661     /** Function number. */
    662     uint8_t     u8Function;
    663     /** CDB length */
    664     uint8_t     u8CDBLength;
    665     /** Sense buffer length */
    666     uint8_t     u8SenseBufferLength;
    667     /** Reserved */
    668     uint8_t     u8Reserved;
    669     /** Message flags */
    670     uint8_t     u8MessageFlags;
    671     /** Message context ID */
    672     uint32_t    u32MessageContext;
    673     /** SCSI status. */
    674     uint8_t     u8SCSIStatus;
    675     /** SCSI state */
    676     uint8_t     u8SCSIState;
    677     /** IO controller status */
    678     uint16_t    u16IOCStatus;
    679     /** IO controller log information */
    680     uint32_t    u32IOCLogInfo;
    681     /** Transfer count */
    682     uint32_t    u32TransferCount;
    683     /** Sense count */
    684     uint32_t    u32SenseCount;
    685     /** Response information */
    686     uint32_t    u32ResponseInfo;
    687 } MptSCSIIOErrorReply, *PMptSCSIIOErrorReply;
    688 #pragma pack()
    689 AssertCompileSize(MptSCSIIOErrorReply, 32);
    690 
    691 #define MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID (0x01)
    692 #define MPT_SCSI_IO_ERROR_SCSI_STATE_TERMINATED      (0x08)
    693 
    694 /**
    695  * IOC status codes sepcific to the SCSI I/O error reply.
    696  */
    697 #define MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_BUS      (0x0041)
    698 #define MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_TARGETID (0x0042)
    699 #define MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE (0x0043)
    700 
    701 /**
    702  * SCSI task management request.
    703  */
    704 #pragma pack(1)
    705 typedef struct MptSCSITaskManagementRequest
    706 {
    707     /** Target ID */
    708     uint8_t     u8TargetID;
    709     /** Bus number */
    710     uint8_t     u8Bus;
    711     /** Chain offset */
    712     uint8_t     u8ChainOffset;
    713     /** Function number */
    714     uint8_t     u8Function;
    715     /** Reserved */
    716     uint8_t     u8Reserved1;
    717     /** Task type */
    718     uint8_t     u8TaskType;
    719     /** Reserved */
    720     uint8_t     u8Reserved2;
    721     /** Message flags */
    722     uint8_t     u8MessageFlags;
    723     /** Message context ID */
    724     uint32_t    u32MessageContext;
    725     /** LUN */
    726     uint8_t     au8LUN[8];
    727     /** Reserved */
    728     uint8_t     auReserved[28];
    729     /** Task message context ID. */
    730     uint32_t    u32TaskMessageContext;
    731 } MptSCSITaskManagementRequest, *PMptSCSITaskManagementRequest;
    732 #pragma pack()
    733 AssertCompileSize(MptSCSITaskManagementRequest, 52);
    734 
    735 /**
    736  * SCSI task management reply.
    737  */
    738 #pragma pack(1)
    739 typedef struct MptSCSITaskManagementReply
    740 {
    741     /** Target ID */
    742     uint8_t     u8TargetID;
    743     /** Bus number */
    744     uint8_t     u8Bus;
    745     /** Message length */
    746     uint8_t     u8MessageLength;
    747     /** Function number */
    748     uint8_t     u8Function;
    749     /** Reserved */
    750     uint8_t     u8Reserved1;
    751     /** Task type */
    752     uint8_t     u8TaskType;
    753     /** Reserved */
    754     uint8_t     u8Reserved2;
    755     /** Message flags */
    756     uint8_t     u8MessageFlags;
    757     /** Message context ID */
    758     uint32_t    u32MessageContext;
    759     /** Reserved */
    760     uint16_t    u16Reserved;
    761     /** IO controller status */
    762     uint16_t    u16IOCStatus;
    763     /** IO controller log information */
    764     uint32_t    u32IOCLogInfo;
    765     /** Termination count */
    766     uint32_t    u32TerminationCount;
    767 } MptSCSITaskManagementReply, *PMptSCSITaskManagementReply;
    768 #pragma pack()
    769 AssertCompileSize(MptSCSITaskManagementReply, 24);
    770 
    771 /**
    772  * Configuration request
    773  */
    774 #pragma pack(1)
    775 typedef struct MptConfigurationRequest
    776 {
    777     /** Action code. */
    778     uint8_t    u8Action;
    779     /** Reserved. */
    780     uint8_t    u8Reserved1;
    781     /** Chain offset. */
    782     uint8_t    u8ChainOffset;
    783     /** Function number. */
    784     uint8_t    u8Function;
    785     /** Reserved. */
    786     uint8_t    u8Reserved2[3];
    787     /** Message flags. */
    788     uint8_t    u8MessageFlags;
    789     /** Message context ID. */
    790     uint32_t   u32MessageContext;
    791     /** Reserved. */
    792     uint8_t    u8Reserved3[8];
    793     /** Version number of the page. */
    794     uint8_t    u8PageVersion;
    795     /** Length of the page in 32bit Dwords. */
    796     uint8_t    u8PageLength;
    797     /** Page number to access. */
    798     uint8_t    u8PageNumber;
    799     /** Type of the page beeing accessed. */
    800     uint8_t    u8PageType;
    801     /** Page type dependent address. */
    802     union
    803     {
    804         /** 32bit view. */
    805         uint32_t u32PageAddress;
    806         struct
    807         {
    808             /** Port number to get the configuration page for. */
    809             uint8_t u8PortNumber;
    810             /** Reserved. */
    811             uint8_t u8Reserved[3];
    812         } MPIPortNumber;
    813         struct
    814         {
    815             /** Target ID to get the configuration page for. */
    816             uint8_t u8TargetID;
    817             /** Bus number to get the configuration page for. */
    818             uint8_t u8Bus;
    819             /** Reserved. */
    820             uint8_t u8Reserved[2];
    821         } BusAndTargetId;
    822     } u;
    823     MptSGEntrySimple64 SimpleSGElement;
    824 } MptConfigurationRequest, *PMptConfigurationRequest;
    825 #pragma pack()
    826 AssertCompileSize(MptConfigurationRequest, 40);
    827 
    828 /** Possible action codes. */
    829 #define MPT_CONFIGURATION_REQUEST_ACTION_HEADER        (0x00)
    830 #define MPT_CONFIGURATION_REQUEST_ACTION_READ_CURRENT  (0x01)
    831 #define MPT_CONFIGURATION_REQUEST_ACTION_WRITE_CURRENT (0x02)
    832 #define MPT_CONFIGURATION_REQUEST_ACTION_READ_DEFAULT  (0x03)
    833 #define MPT_CONFIGURATION_REQUEST_ACTION_DEFAULT       (0x04)
    834 #define MPT_CONFIGURATION_REQUEST_ACTION_READ_NVRAM    (0x05)
    835 #define MPT_CONFIGURATION_REQUEST_ACTION_WRITE_NVRAM   (0x06)
    836 
    837 /** Page type codes. */
    838 #define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_IO_UNIT    (0x00)
    839 #define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_IOC        (0x01)
    840 #define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_BIOS       (0x02)
    841 #define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_SCSI_PORT  (0x03)
    842 
    843 /**
    844  * Configuration reply.
    845  */
    846 #pragma pack(1)
    847 typedef struct MptConfigurationReply
    848 {
    849     /** Action code. */
    850     uint8_t    u8Action;
    851     /** Reserved. */
    852     uint8_t    u8Reserved;
    853     /** Message length. */
    854     uint8_t    u8MessageLength;
    855     /** Function number. */
    856     uint8_t    u8Function;
    857     /** Reserved. */
    858     uint8_t    u8Reserved2[3];
    859     /** Message flags. */
    860     uint8_t    u8MessageFlags;
    861     /** Message context ID. */
    862     uint32_t   u32MessageContext;
    863     /** Reserved. */
    864     uint16_t   u16Reserved;
    865     /** I/O controller status. */
    866     uint16_t   u16IOCStatus;
    867     /** I/O controller log information. */
    868     uint32_t   u32IOCLogInfo;
    869     /** Version number of the page. */
    870     uint8_t    u8PageVersion;
    871     /** Length of the page in 32bit Dwords. */
    872     uint8_t    u8PageLength;
    873     /** Page number to access. */
    874     uint8_t    u8PageNumber;
    875     /** Type of the page beeing accessed. */
    876     uint8_t    u8PageType;
    877 } MptConfigurationReply, *PMptConfigurationReply;
    878 #pragma pack()
    879 AssertCompileSize(MptConfigurationReply, 24);
    880 
    881 /** Additional I/O controller status codes for the configuration reply. */
    882 #define MPT_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020)
    883 #define MPT_IOCSTATUS_CONFIG_INVALID_TYPE   (0x0021)
    884 #define MPT_IOCSTATUS_CONFIG_INVALID_PAGE   (0x0022)
    885 #define MPT_IOCSTATUS_CONFIG_INVALID_DATA   (0x0023)
    886 #define MPT_IOCSTATUS_CONFIG_NO_DEFAULTS    (0x0024)
    887 #define MPT_IOCSTATUS_CONFIG_CANT_COMMIT    (0x0025)
    888 
    889 /**
    890  * Union of all possible request messages.
    891  */
    892 typedef union MptRequestUnion
    893 {
    894     MptMessageHdr                Header;
    895     MptIOCInitRequest            IOCInit;
    896     MptIOCFactsRequest           IOCFacts;
    897     MptPortFactsRequest          PortFacts;
    898     MptPortEnableRequest         PortEnable;
    899     MptEventNotificationRequest  EventNotification;
    900     MptSCSIIORequest             SCSIIO;
    901     MptSCSITaskManagementRequest SCSITaskManagement;
    902     MptConfigurationRequest      Configuration;
    903 } MptRequestUnion, *PMptRequestUnion;
    904 
    905 /**
    906  * Union of all possible reply messages.
    907  */
    908 typedef union MptReplyUnion
    909 {
    910     /** 16bit view. */
    911     uint16_t                   au16Reply[30];
    912     MptDefaultReplyMessage     Header;
    913     MptIOCInitReply            IOCInit;
    914     MptIOCFactsReply           IOCFacts;
    915     MptPortFactsReply          PortFacts;
    916     MptPortEnableReply         PortEnable;
    917     MptEventNotificationReply  EventNotification;
    918     MptSCSIIOErrorReply        SCSIIOError;
    919     MptSCSITaskManagementReply SCSITaskManagement;
    920     MptConfigurationReply      Configuration;
    921 } MptReplyUnion, *PMptReplyUnion;
    922 
    923 
    924 /**
    925  * Configuration Page attributes.
    926  */
    927 #define MPT_CONFIGURATION_PAGE_ATTRIBUTE_READONLY            (0x00)
    928 #define MPT_CONFIGURATION_PAGE_ATTRIBUTE_CHANGEABLE          (0x10)
    929 #define MPT_CONFIGURATION_PAGE_ATTRIBUTE_PERSISTENT          (0x20)
    930 #define MPT_CONFIGURATION_PAGE_ATTRIBUTE_PERSISTENT_READONLY (0x30)
    931 
    932 #define MPT_CONFIGURATION_PAGE_ATTRIBUTE_GET(u8PageType) ((u8PageType) & 0xf0)
    933 
    934 /**
    935  * Configuration Page types.
    936  */
    937 #define MPT_CONFIGURATION_PAGE_TYPE_IO_UNIT                  (0x00)
    938 #define MPT_CONFIGURATION_PAGE_TYPE_IOC                      (0x01)
    939 #define MPT_CONFIGURATION_PAGE_TYPE_BIOS                     (0x02)
    940 #define MPT_CONFIGURATION_PAGE_TYPE_SCSI_SPI_PORT            (0x03)
    941 #define MPT_CONFIGURATION_PAGE_TYPE_SCSI_SPI_DEVICE          (0x04)
    942 #define MPT_CONFIGURATION_PAGE_TYPE_MANUFACTURING            (0x09)
    943 
    944 #define MPT_CONFIGURATION_PAGE_TYPE_GET(u8PageType) ((u8PageType) & 0x0f)
    945 
    946 /**
    947  * Configuration Page header - Common to all pages.
    948  */
    949 #pragma pack(1)
    950 typedef struct MptConfigurationPageHeader
    951 {
    952     /** Version of the page. */
    953     uint8_t     u8PageVersion;
    954     /** The length of the page in 32bit D-Words. */
    955     uint8_t     u8PageLength;
    956     /** Number of the page. */
    957     uint8_t     u8PageNumber;
    958     /** Type of the page. */
    959     uint8_t     u8PageType;
    960 } MptConfigurationPageHeader, *PMptConfigurationPageHeader;
    961 #pragma pack()
    962 AssertCompileSize(MptConfigurationPageHeader, 4);
    963 
    964 /**
    965  * Manufacturing page 0. - Readonly.
    966  */
    967 #pragma pack(1)
    968 typedef struct MptConfigurationPageManufacturing0
    969 {
    970     /** Union. */
    971     union
    972     {
    973         /** Byte view. */
    974         uint8_t                   abPageData[76];
    975         /** Field view. */
    976         struct
    977         {
    978             /** The omnipresent header. */
    979             MptConfigurationPageHeader    Header;
    980             /** Name of the chip. */
    981             uint8_t               abChipName[16];
    982             /** Chip revision. */
    983             uint8_t               abChipRevision[8];
    984             /** Board name. */
    985             uint8_t               abBoardName[16];
    986             /** Board assembly. */
    987             uint8_t               abBoardAssembly[16];
    988             /** Board tracer number. */
    989             uint8_t               abBoardTracerNumber[16];
    990         } fields;
    991     } u;
    992 } MptConfigurationPageManufacturing0, *PMptConfigurationPageManufacturing0;
    993 #pragma pack()
    994 AssertCompileSize(MptConfigurationPageManufacturing0, 76);
    995 
    996 /**
    997  * Manufacturing page 1. - Readonly Persistent.
    998  */
    999 #pragma pack(1)
    1000 typedef struct MptConfigurationPageManufacturing1
    1001 {
    1002     /** The omnipresent header. */
    1003     MptConfigurationPageHeader    Header;
    1004     /** VPD info - don't know what belongs here so all zero. */
    1005     uint8_t                       abVPDInfo[256];
    1006 } MptConfigurationPageManufacturing1, *PMptConfigurationPageManufacturing1;
    1007 #pragma pack()
    1008 AssertCompileSize(MptConfigurationPageManufacturing1, 260);
    1009 
    1010 /**
    1011  * Manufacturing page 2. - Readonly.
    1012  */
    1013 #pragma pack(1)
    1014 typedef struct MptConfigurationPageManufacturing2
    1015 {
    1016     /** Union. */
    1017     union
    1018     {
    1019         /** Byte view. */
    1020         uint8_t                        abPageData[8];
    1021         /** Field view. */
    1022         struct
    1023         {
    1024             /** The omnipresent header. */
    1025             MptConfigurationPageHeader Header;
    1026             /** PCI Device ID. */
    1027             uint16_t                   u16PCIDeviceID;
    1028             /** PCI Revision ID. */
    1029             uint8_t                    u8PCIRevisionID;
    1030             /** Reserved. */
    1031             uint8_t                    u8Reserved;
    1032             /** Hardware specific settings... */
    1033         } fields;
    1034     } u;
    1035 } MptConfigurationPageManufacturing2, *PMptConfigurationPageManufacturing2;
    1036 #pragma pack()
    1037 AssertCompileSize(MptConfigurationPageManufacturing2, 8);
    1038 
    1039 /**
    1040  * Manufacturing page 3. - Readonly.
    1041  */
    1042 #pragma pack(1)
    1043 typedef struct MptConfigurationPageManufacturing3
    1044 {
    1045     /** Union. */
    1046     union
    1047     {
    1048         /** Byte view. */
    1049         uint8_t                   abPageData[8];
    1050         /** Field view. */
    1051         struct
    1052         {
    1053             /** The omnipresent header. */
    1054             MptConfigurationPageHeader    Header;
    1055             /** PCI Device ID. */
    1056             uint16_t              u16PCIDeviceID;
    1057             /** PCI Revision ID. */
    1058             uint8_t               u8PCIRevisionID;
    1059             /** Reserved. */
    1060             uint8_t               u8Reserved;
    1061             /** Chip specific settings... */
    1062         } fields;
    1063     } u;
    1064 } MptConfigurationPageManufacturing3, *PMptConfigurationPageManufacturing3;
    1065 #pragma pack()
    1066 AssertCompileSize(MptConfigurationPageManufacturing3, 8);
    1067 
    1068 /**
    1069  * Manufacturing page 4. - Readonly.
    1070  */
    1071 #pragma pack(1)
    1072 typedef struct MptConfigurationPageManufacturing4
    1073 {
    1074     /** Union. */
    1075     union
    1076     {
    1077         /** Byte view. */
    1078         uint8_t                   abPageData[84];
    1079         /** Field view. */
    1080         struct
    1081         {
    1082             /** The omnipresent header. */
    1083             MptConfigurationPageHeader    Header;
    1084             /** Reserved. */
    1085             uint32_t              u32Reserved;
    1086             /** InfoOffset0. */
    1087             uint8_t               u8InfoOffset0;
    1088             /** Info size. */
    1089             uint8_t               u8InfoSize0;
    1090             /** InfoOffset1. */
    1091             uint8_t               u8InfoOffset1;
    1092             /** Info size. */
    1093             uint8_t               u8InfoSize1;
    1094             /** Size of the inquiry data. */
    1095             uint8_t               u8InquirySize;
    1096             /** Reserved. */
    1097             uint8_t               abReserved[3];
    1098             /** Inquiry data. */
    1099             uint8_t               abInquiryData[56];
    1100             /** IS volume settings. */
    1101             uint32_t              u32ISVolumeSettings;
    1102             /** IME volume settings. */
    1103             uint32_t              u32IMEVolumeSettings;
    1104             /** IM volume settings. */
    1105             uint32_t              u32IMVolumeSettings;
    1106         } fields;
    1107     } u;
    1108 } MptConfigurationPageManufacturing4, *PMptConfigurationPageManufacturing4;
    1109 #pragma pack()
    1110 AssertCompileSize(MptConfigurationPageManufacturing4, 84);
    1111 
    1112 /**
    1113  * IO Unit page 0. - Readonly.
    1114  */
    1115 #pragma pack(1)
    1116 typedef struct MptConfigurationPageIOUnit0
    1117 {
    1118     /** Union. */
    1119     union
    1120     {
    1121         /** Byte view. */
    1122         uint8_t                   abPageData[12];
    1123         /** Field view. */
    1124         struct
    1125         {
    1126             /** The omnipresent header. */
    1127             MptConfigurationPageHeader    Header;
    1128             /** A unique identifier. */
    1129             uint64_t              u64UniqueIdentifier;
    1130         } fields;
    1131     } u;
    1132 } MptConfigurationPageIOUnit0, *PMptConfigurationPageIOUnit0;
    1133 #pragma pack()
    1134 AssertCompileSize(MptConfigurationPageIOUnit0, 12);
    1135 
    1136 /**
    1137  * IO Unit page 1. - Read/Write.
    1138  */
    1139 #pragma pack(1)
    1140 typedef struct MptConfigurationPageIOUnit1
    1141 {
    1142     /** Union. */
    1143     union
    1144     {
    1145         /** Byte view. */
    1146         uint8_t                   abPageData[8];
    1147         /** Field view. */
    1148         struct
    1149         {
    1150             /** The omnipresent header. */
    1151             MptConfigurationPageHeader    Header;
    1152             /** Flag whether this is a single function PCI device. */
    1153             unsigned              fSingleFunction:         1;
    1154             /** Flag whether all possible paths to a device are mapped. */
    1155             unsigned              fAllPathsMapped:         1;
    1156             /** Reserved. */
    1157             unsigned              u4Reserved:              4;
    1158             /** Flag whether all RAID functionality is disabled. */
    1159             unsigned              fIntegratedRAIDDisabled: 1;
    1160             /** Flag whether 32bit PCI accesses are forced. */
    1161             unsigned              f32BitAccessForced:      1;
    1162             /** Reserved. */
    1163             unsigned              abReserved:             24;
    1164         } fields;
    1165     } u;
    1166 } MptConfigurationPageIOUnit1, *PMptConfigurationPageIOUnit1;
    1167 #pragma pack()
    1168 AssertCompileSize(MptConfigurationPageIOUnit1, 8);
    1169 
    1170 /**
    1171  * Adapter Ordering.
    1172  */
    1173 #pragma pack(1)
    1174 typedef struct MptConfigurationPageIOUnit2AdapterOrdering
    1175 {
    1176     /** PCI bus number. */
    1177     unsigned    u8PCIBusNumber:   8;
    1178     /** PCI device and function number. */
    1179     unsigned    u8PCIDevFn:       8;
    1180     /** Flag whether the adapter is embedded. */
    1181     unsigned    fAdapterEmbedded: 1;
    1182     /** Flag whether the adapter is enabled. */
    1183     unsigned    fAdapterEnabled:  1;
    1184     /** Reserved. */
    1185     unsigned    u6Reserved:       6;
    1186     /** Reserved. */
    1187     unsigned    u8Reserved:       8;
    1188 } MptConfigurationPageIOUnit2AdapterOrdering, *PMptConfigurationPageIOUnit2AdapterOrdering;
    1189 #pragma pack()
    1190 AssertCompileSize(MptConfigurationPageIOUnit2AdapterOrdering, 4);
    1191 
    1192 /**
    1193  * IO Unit page 2. - Read/Write.
    1194  */
    1195 #pragma pack(1)
    1196 typedef struct MptConfigurationPageIOUnit2
    1197 {
    1198     /** Union. */
    1199     union
    1200     {
    1201         /** Byte view. */
    1202         uint8_t                   abPageData[28];
    1203         /** Field view. */
    1204         struct
    1205         {
    1206             /** The omnipresent header. */
    1207             MptConfigurationPageHeader    Header;
    1208             /** Reserved. */
    1209             unsigned              fReserved:           1;
    1210             /** Flag whether Pause on error is enabled. */
    1211             unsigned              fPauseOnError:       1;
    1212             /** Flag whether verbose mode is enabled. */
    1213             unsigned              fVerboseModeEnabled: 1;
    1214             /** Set to disable color video. */
    1215             unsigned              fDisableColorVideo:  1;
    1216             /** Flag whether int 40h is hooked. */
    1217             unsigned              fNotHookInt40h:      1;
    1218             /** Reserved. */
    1219             unsigned              u3Reserved:          3;
    1220             /** Reserved. */
    1221             unsigned              abReserved:         24;
    1222             /** BIOS version. */
    1223             uint32_t              u32BIOSVersion;
    1224             /** Adapter ordering. */
    1225             MptConfigurationPageIOUnit2AdapterOrdering aAdapterOrder[4];
    1226         } fields;
    1227     } u;
    1228 } MptConfigurationPageIOUnit2, *PMptConfigurationPageIOUnit2;
    1229 #pragma pack()
    1230 AssertCompileSize(MptConfigurationPageIOUnit2, 28);
    1231 
    1232 /*
    1233  * IO Unit page 3. - Read/Write.
    1234  */
    1235 #pragma pack(1)
    1236 typedef struct MptConfigurationPageIOUnit3
    1237 {
    1238     /** Union. */
    1239     union
    1240     {
    1241         /** Byte view. */
    1242         uint8_t                   abPageData[8];
    1243         /** Field view. */
    1244         struct
    1245         {
    1246             /** The omnipresent header. */
    1247             MptConfigurationPageHeader    Header;
    1248             /** Number of GPIO values. */
    1249             uint8_t               u8GPIOCount;
    1250             /** Reserved. */
    1251             uint8_t               abReserved[3];
    1252         } fields;
    1253     } u;
    1254 } MptConfigurationPageIOUnit3, *PMptConfigurationPageIOUnit3;
    1255 #pragma pack()
    1256 AssertCompileSize(MptConfigurationPageIOUnit3, 8);
    1257 
    1258 /**
    1259  * IOC page 0. - Readonly
    1260  */
    1261 #pragma pack(1)
    1262 typedef struct MptConfigurationPageIOC0
    1263 {
    1264     /** Union. */
    1265     union
    1266     {
    1267         /** Byte view. */
    1268         uint8_t                   abPageData[28];
    1269         /** Field view. */
    1270         struct
    1271         {
    1272             /** The omnipresent header. */
    1273             MptConfigurationPageHeader    Header;
    1274             /** Total ammount of NV memory in bytes. */
    1275             uint32_t              u32TotalNVStore;
    1276             /** Number of free bytes in the NV store. */
    1277             uint32_t              u32FreeNVStore;
    1278             /** PCI vendor ID. */
    1279             uint16_t              u16VendorId;
    1280             /** PCI device ID. */
    1281             uint16_t              u16DeviceId;
    1282             /** PCI revision ID. */
    1283             uint8_t               u8RevisionId;
    1284             /** Reserved. */
    1285             uint8_t               abReserved[3];
    1286             /** PCI class code. */
    1287             uint32_t              u32ClassCode;
    1288             /** Subsystem vendor Id. */
    1289             uint16_t              u16SubsystemVendorId;
    1290             /** Subsystem Id. */
    1291             uint16_t              u16SubsystemId;
    1292         } fields;
    1293     } u;
    1294 } MptConfigurationPageIOC0, *PMptConfigurationPageIOC0;
    1295 #pragma pack()
    1296 AssertCompileSize(MptConfigurationPageIOC0, 28);
    1297 
    1298 /**
    1299  * IOC page 1. - Read/Write
    1300  */
    1301 #pragma pack(1)
    1302 typedef struct MptConfigurationPageIOC1
    1303 {
    1304     /** Union. */
    1305     union
    1306     {
    1307         /** Byte view. */
    1308         uint8_t                   abPageData[16];
    1309         /** Field view. */
    1310         struct
    1311         {
    1312             /** The omnipresent header. */
    1313             MptConfigurationPageHeader    Header;
    1314             /** Flag whether reply coalescing is enabled. */
    1315             unsigned              fReplyCoalescingEnabled: 1;
    1316             /** Reserved. */
    1317             unsigned              u31Reserved:            31;
    1318             /** Coalescing Timeout in microseconds. */
    1319             unsigned              u32CoalescingTimeout:   32;
    1320             /** Coalescing depth. */
    1321             unsigned              u8CoalescingDepth:       8;
    1322             /** Reserved. */
    1323             unsigned              u8Reserved0:             8;
    1324             unsigned              u8Reserved1:             8;
    1325             unsigned              u8Reserved2:             8;
    1326         } fields;
    1327     } u;
    1328 } MptConfigurationPageIOC1, *PMptConfigurationPageIOC1;
    1329 #pragma pack()
    1330 AssertCompileSize(MptConfigurationPageIOC1, 16);
    1331 
    1332 /**
    1333  * IOC page 2. - Readonly
    1334  */
    1335 #pragma pack(1)
    1336 typedef struct MptConfigurationPageIOC2
    1337 {
    1338     /** Union. */
    1339     union
    1340     {
    1341         /** Byte view. */
    1342         uint8_t                   abPageData[12];
    1343         /** Field view. */
    1344         struct
    1345         {
    1346             /** The omnipresent header. */
    1347             MptConfigurationPageHeader    Header;
    1348             /** Flag whether striping is supported. */
    1349             unsigned              fStripingSupported:            1;
    1350             /** Flag whether enhanced mirroring is supported. */
    1351             unsigned              fEnhancedMirroringSupported:   1;
    1352             /** Flag whether mirroring is supported. */
    1353             unsigned              fMirroringSupported:           1;
    1354             /** Reserved. */
    1355             unsigned              u26Reserved:                  26;
    1356             /** Flag whether SES is supported. */
    1357             unsigned              fSESSupported:                 1;
    1358             /** Flag whether SAF-TE is supported. */
    1359             unsigned              fSAFTESupported:               1;
    1360             /** Flag whether cross channel volumes are supported. */
    1361             unsigned              fCrossChannelVolumesSupported: 1;
    1362             /** Number of active integrated RAID volumes. */
    1363             unsigned              u8NumActiveVolumes:            8;
    1364             /** Maximum number of integrated RAID volumes supported. */
    1365             unsigned              u8MaxVolumes:                  8;
    1366             /** Number of active integrated RAID physical disks. */
    1367             unsigned              u8NumActivePhysDisks:          8;
    1368             /** Maximum number of integrated RAID physical disks supported. */
    1369             unsigned              u8MaxPhysDisks:                8;
    1370             /** RAID volumes... - not supported. */
    1371         } fields;
    1372     } u;
    1373 } MptConfigurationPageIOC2, *PMptConfigurationPageIOC2;
    1374 #pragma pack()
    1375 AssertCompileSize(MptConfigurationPageIOC2, 12);
    1376 
    1377 /**
    1378  * IOC page 3. - Readonly
    1379  */
    1380 #pragma pack(1)
    1381 typedef struct MptConfigurationPageIOC3
    1382 {
    1383     /** Union. */
    1384     union
    1385     {
    1386         /** Byte view. */
    1387         uint8_t                   abPageData[8];
    1388         /** Field view. */
    1389         struct
    1390         {
    1391             /** The omnipresent header. */
    1392             MptConfigurationPageHeader    Header;
    1393             /** Number of active integrated RAID physical disks. */
    1394             uint8_t               u8NumPhysDisks;
    1395             /** Reserved. */
    1396             uint8_t               abReserved[3];
    1397         } fields;
    1398     } u;
    1399 } MptConfigurationPageIOC3, *PMptConfigurationPageIOC3;
    1400 #pragma pack()
    1401 AssertCompileSize(MptConfigurationPageIOC3, 8);
    1402 
    1403 /**
    1404  * IOC page 4. - Read/Write
    1405  */
    1406 #pragma pack(1)
    1407 typedef struct MptConfigurationPageIOC4
    1408 {
    1409     /** Union. */
    1410     union
    1411     {
    1412         /** Byte view. */
    1413         uint8_t                   abPageData[8];
    1414         /** Field view. */
    1415         struct
    1416         {
    1417             /** The omnipresent header. */
    1418             MptConfigurationPageHeader    Header;
    1419             /** Number of SEP entries in this page. */
    1420             uint8_t               u8ActiveSEP;
    1421             /** Maximum number of SEp entries supported. */
    1422             uint8_t               u8MaxSEP;
    1423             /** Reserved. */
    1424             uint16_t              u16Reserved;
    1425             /** SEP entries... - not supported. */
    1426         } fields;
    1427     } u;
    1428 } MptConfigurationPageIOC4, *PMptConfigurationPageIOC4;
    1429 #pragma pack()
    1430 AssertCompileSize(MptConfigurationPageIOC4, 8);
    1431 
    1432 /**
    1433  * IOC page 6. - Read/Write
    1434  */
    1435 #pragma pack(1)
    1436 typedef struct MptConfigurationPageIOC6
    1437 {
    1438     /** Union. */
    1439     union
    1440     {
    1441         /** Byte view. */
    1442         uint8_t                   abPageData[60];
    1443         /** Field view. */
    1444         struct
    1445         {
    1446             /** The omnipresent header. */
    1447             MptConfigurationPageHeader    Header;
    1448             uint32_t                      u32CapabilitiesFlags;
    1449             uint8_t                       u8MaxDrivesIS;
    1450             uint8_t                       u8MaxDrivesIM;
    1451             uint8_t                       u8MaxDrivesIME;
    1452             uint8_t                       u8Reserved1;
    1453             uint8_t                       u8MinDrivesIS;
    1454             uint8_t                       u8MinDrivesIM;
    1455             uint8_t                       u8MinDrivesIME;
    1456             uint8_t                       u8Reserved2;
    1457             uint8_t                       u8MaxGlobalHotSpares;
    1458             uint8_t                       u8Reserved3;
    1459             uint16_t                      u16Reserved4;
    1460             uint32_t                      u32Reserved5;
    1461             uint32_t                      u32SupportedStripeSizeMapIS;
    1462             uint32_t                      u32SupportedStripeSizeMapIME;
    1463             uint32_t                      u32Reserved6;
    1464             uint8_t                       u8MetadataSize;
    1465             uint8_t                       u8Reserved7;
    1466             uint16_t                      u16Reserved8;
    1467             uint16_t                      u16MaxBadBlockTableEntries;
    1468             uint16_t                      u16Reserved9;
    1469             uint16_t                      u16IRNvsramUsage;
    1470             uint16_t                      u16Reserved10;
    1471             uint32_t                      u32IRNvsramVersion;
    1472             uint32_t                      u32Reserved11;
    1473         } fields;
    1474     } u;
    1475 } MptConfigurationPageIOC6, *PMptConfigurationPageIOC6;
    1476 #pragma pack()
    1477 AssertCompileSize(MptConfigurationPageIOC6, 60);
    1478 
    1479 /**
    1480  * SCSI-SPI port page 0. - Readonly
    1481  */
    1482 #pragma pack(1)
    1483 typedef struct MptConfigurationPageSCSISPIPort0
    1484 {
    1485     /** Union. */
    1486     union
    1487     {
    1488         /** Byte view. */
    1489         uint8_t                   abPageData[12];
    1490         /** Field view. */
    1491         struct
    1492         {
    1493             /** The omnipresent header. */
    1494             MptConfigurationPageHeader    Header;
    1495             /** Flag whether this port is information unit trnafsers capable. */
    1496             unsigned              fInformationUnitTransfersCapable: 1;
    1497             /** Flag whether the port is DT (Dual Transfer) capable. */
    1498             unsigned              fDTCapable:                       1;
    1499             /** Flag whether the port is QAS (Quick Arbitrate and Select) capable. */
    1500             unsigned              fQASCapable:                      1;
    1501             /** Reserved. */
    1502             unsigned              u5Reserved1:                      5;
    1503             /** Minimum Synchronous transfer period. */
    1504             unsigned              u8MinimumSynchronousTransferPeriod: 8;
    1505             /** Maximum synchronous offset. */
    1506             unsigned              u8MaximumSynchronousOffset:         8;
    1507             /** Reserved. */
    1508             unsigned              u5Reserved2:                      5;
    1509             /** Flag whether indicating the width of the bus - 0 narrow and 1 for wide. */
    1510             unsigned              fWide:                            1;
    1511             /** Reserved */
    1512             unsigned              fReserved:                        1;
    1513             /** Flag whether the port is AIP (Asynchronous Information Protection) capable. */
    1514             unsigned              fAIPCapable:                      1;
    1515             /** Signaling Type. */
    1516             unsigned              u2SignalingType:                  2;
    1517             /** Reserved. */
    1518             unsigned              u30Reserved:                     30;
    1519         } fields;
    1520     } u;
    1521 } MptConfigurationPageSCSISPIPort0, *PMptConfigurationPageSCSISPIPort0;
    1522 #pragma pack()
    1523 AssertCompileSize(MptConfigurationPageSCSISPIPort0, 12);
    1524 
    1525 /**
    1526  * SCSI-SPI port page 1. - Read/Write
    1527  */
    1528 #pragma pack(1)
    1529 typedef struct MptConfigurationPageSCSISPIPort1
    1530 {
    1531     /** Union. */
    1532     union
    1533     {
    1534         /** Byte view. */
    1535         uint8_t                   abPageData[12];
    1536         /** Field view. */
    1537         struct
    1538         {
    1539             /** The omnipresent header. */
    1540             MptConfigurationPageHeader    Header;
    1541             /** The SCSI ID of the port. */
    1542             uint8_t               u8SCSIID;
    1543             /** Reserved. */
    1544             uint8_t               u8Reserved;
    1545             /** Port response IDs Bit mask field. */
    1546             uint16_t              u16PortResponseIDsBitmask;
    1547             /** Value for the on BUS timer. */
    1548             uint32_t              u32OnBusTimerValue;
    1549         } fields;
    1550     } u;
    1551 } MptConfigurationPageSCSISPIPort1, *PMptConfigurationPageSCSISPIPort1;
    1552 #pragma pack()
    1553 AssertCompileSize(MptConfigurationPageSCSISPIPort1, 12);
    1554 
    1555 /**
    1556  * Device settings for one device.
    1557  */
    1558 #pragma pack(1)
    1559 typedef struct MptDeviceSettings
    1560 {
    1561     /** Timeout for I/O in seconds. */
    1562     unsigned    u8Timeout:             8;
    1563     /** Minimum synchronous factor. */
    1564     unsigned    u8SyncFactor:          8;
    1565     /** Flag whether disconnect is enabled. */
    1566     unsigned    fDisconnectEnable:     1;
    1567     /** Flag whether Scan ID is enabled. */
    1568     unsigned    fScanIDEnable:         1;
    1569     /** Flag whether Scan LUNs is enabled. */
    1570     unsigned    fScanLUNEnable:        1;
    1571     /** Flag whether tagged queuing is enabled. */
    1572     unsigned    fTaggedQueuingEnabled: 1;
    1573     /** Flag whether wide is enabled. */
    1574     unsigned    fWideDisable:          1;
    1575     /** Flag whether this device is bootable. */
    1576     unsigned    fBootChoice:           1;
    1577     /** Reserved. */
    1578     unsigned    u10Reserved:          10;
    1579 } MptDeviceSettings, *PMptDeviceSettings;
    1580 #pragma pack()
    1581 AssertCompileSize(MptDeviceSettings, 4);
    1582 
    1583 /**
    1584  * SCSI-SPI port page 2. - Read/Write for the BIOS
    1585  */
    1586 #pragma pack(1)
    1587 typedef struct MptConfigurationPageSCSISPIPort2
    1588 {
    1589     /** Union. */
    1590     union
    1591     {
    1592         /** Byte view. */
    1593         uint8_t                   abPageData[76];
    1594         /** Field view. */
    1595         struct
    1596         {
    1597             /** The omnipresent header. */
    1598             MptConfigurationPageHeader    Header;
    1599             /** Flag indicating the bus scan order. */
    1600             unsigned              fBusScanOrderHighToLow:  1;
    1601             /** Reserved. */
    1602             unsigned              fReserved:               1;
    1603             /** Flag whether SCSI Bus resets are avoided. */
    1604             unsigned              fAvoidSCSIBusResets:     1;
    1605             /** Flag whether alternate CHS is used. */
    1606             unsigned              fAlternateCHS:           1;
    1607             /** Flag whether termination is disabled. */
    1608             unsigned              fTerminationDisabled:    1;
    1609             /** Reserved. */
    1610             unsigned              u27Reserved:            27;
    1611             /** Host SCSI ID. */
    1612             unsigned              u4HostSCSIID:            4;
    1613             /** Initialize HBA. */
    1614             unsigned              u2InitializeHBA:         2;
    1615             /** Removeable media setting. */
    1616             unsigned              u2RemovableMediaSetting: 2;
    1617             /** Spinup delay. */
    1618             unsigned              u4SpinupDelay:           4;
    1619             /** Negotiating settings. */
    1620             unsigned              u2NegotitatingSettings:  2;
    1621             /** Reserved. */
    1622             unsigned              u18Reserved:            18;
    1623             /** Device Settings. */
    1624             MptDeviceSettings     aDeviceSettings[16];
    1625         } fields;
    1626     } u;
    1627 } MptConfigurationPageSCSISPIPort2, *PMptConfigurationPageSCSISPIPort2;
    1628 #pragma pack()
    1629 AssertCompileSize(MptConfigurationPageSCSISPIPort2, 76);
    1630 
    1631 /**
    1632  * SCSI-SPI device page 0. - Readonly
    1633  */
    1634 #pragma pack(1)
    1635 typedef struct MptConfigurationPageSCSISPIDevice0
    1636 {
    1637     /** Union. */
    1638     union
    1639     {
    1640         /** Byte view. */
    1641         uint8_t                   abPageData[12];
    1642         /** Field view. */
    1643         struct
    1644         {
    1645             /** The omnipresent header. */
    1646             MptConfigurationPageHeader    Header;
    1647             /** Negotiated Parameters. */
    1648             /** Information Units enabled. */
    1649             unsigned              fInformationUnitsEnabled: 1;
    1650             /** Dual Transfers Enabled. */
    1651             unsigned              fDTEnabled:               1;
    1652             /** QAS enabled. */
    1653             unsigned              fQASEnabled:              1;
    1654             /** Reserved. */
    1655             unsigned              u5Reserved1:              5;
    1656             /** Synchronous Transfer period. */
    1657             unsigned              u8NegotiatedSynchronousTransferPeriod: 8;
    1658             /** Synchronous offset. */
    1659             unsigned              u8NegotiatedSynchronousOffset: 8;
    1660             /** Reserved. */
    1661             unsigned              u5Reserved2:              5;
    1662             /** Width - 0 for narrow and 1 for wide. */
    1663             unsigned              fWide:                    1;
    1664             /** Reserved. */
    1665             unsigned              fReserved:                1;
    1666             /** AIP enabled. */
    1667             unsigned              fAIPEnabled:              1;
    1668             /** Flag whether negotiation occurred. */
    1669             unsigned              fNegotationOccured:       1;
    1670             /** Flag whether a SDTR message was rejected. */
    1671             unsigned              fSDTRRejected:            1;
    1672             /** Flag whether a WDTR message was rejected. */
    1673             unsigned              fWDTRRejected:            1;
    1674             /** Flag whether a PPR message was rejected. */
    1675             unsigned              fPPRRejected:             1;
    1676             /** Reserved. */
    1677             unsigned              u28Reserved:             28;
    1678         } fields;
    1679     } u;
    1680 } MptConfigurationPageSCSISPIDevice0, *PMptConfigurationPageSCSISPIDevice0;
    1681 #pragma pack()
    1682 AssertCompileSize(MptConfigurationPageSCSISPIDevice0, 12);
    1683 
    1684 /**
    1685  * SCSI-SPI device page 1. - Read/Write
    1686  */
    1687 #pragma pack(1)
    1688 typedef struct MptConfigurationPageSCSISPIDevice1
    1689 {
    1690     /** Union. */
    1691     union
    1692     {
    1693         /** Byte view. */
    1694         uint8_t                   abPageData[16];
    1695         /** Field view. */
    1696         struct
    1697         {
    1698             /** The omnipresent header. */
    1699             MptConfigurationPageHeader    Header;
    1700             /** Requested Parameters. */
    1701             /** Information Units enable. */
    1702             bool                  fInformationUnitsEnable: 1;
    1703             /** Dual Transfers Enable. */
    1704             bool                  fDTEnable:               1;
    1705             /** QAS enable. */
    1706             bool                  fQASEnable:              1;
    1707             /** Reserved. */
    1708             unsigned              u5Reserved1:              5;
    1709             /** Synchronous Transfer period. */
    1710             unsigned              u8NegotiatedSynchronousTransferPeriod: 8;
    1711             /** Synchronous offset. */
    1712             unsigned              u8NegotiatedSynchronousOffset: 8;
    1713             /** Reserved. */
    1714             unsigned              u5Reserved2:              5;
    1715             /** Width - 0 for narrow and 1 for wide. */
    1716             bool                  fWide:                   1;
    1717             /** Reserved. */
    1718             bool                  fReserved1:              1;
    1719             /** AIP enable. */
    1720             bool                  fAIPEnable:              1;
    1721             /** Reserved. */
    1722             bool                  fReserved2:              1;
    1723             /** WDTR disallowed. */
    1724             bool                  fWDTRDisallowed:         1;
    1725             /** SDTR disallowed. */
    1726             bool                  fSDTRDisallowed:         1;
    1727             /** Reserved. */
    1728             unsigned              u29Reserved:            29;
    1729         } fields;
    1730     } u;
    1731 } MptConfigurationPageSCSISPIDevice1, *PMptConfigurationPageSCSISPIDevice1;
    1732 #pragma pack()
    1733 AssertCompileSize(MptConfigurationPageSCSISPIDevice1, 16);
    1734 
    1735 /**
    1736  * SCSI-SPI device page 2. - Read/Write
    1737  */
    1738 #pragma pack(1)
    1739 typedef struct MptConfigurationPageSCSISPIDevice2
    1740 {
    1741     /** Union. */
    1742     union
    1743     {
    1744         /** Byte view. */
    1745         uint8_t                   abPageData[16];
    1746         /** Field view. */
    1747         struct
    1748         {
    1749             /** The omnipresent header. */
    1750             MptConfigurationPageHeader    Header;
    1751             /** Reserved. */
    1752             unsigned              u4Reserved: 4;
    1753             /** ISI enable. */
    1754             unsigned              fISIEnable: 1;
    1755             /** Secondary driver enable. */
    1756             unsigned              fSecondaryDriverEnable:          1;
    1757             /** Reserved. */
    1758             unsigned              fReserved:                       1;
    1759             /** Slew reate controler. */
    1760             unsigned              u3SlewRateControler:             3;
    1761             /** Primary drive strength controler. */
    1762             unsigned              u3PrimaryDriveStrengthControl:   3;
    1763             /** Secondary drive strength controler. */
    1764             unsigned              u3SecondaryDriveStrengthControl: 3;
    1765             /** Reserved. */
    1766             unsigned              u12Reserved:                    12;
    1767             /** XCLKH_ST. */
    1768             unsigned              fXCLKH_ST:                       1;
    1769             /** XCLKS_ST. */
    1770             unsigned              fXCLKS_ST:                       1;
    1771             /** XCLKH_DT. */
    1772             unsigned              fXCLKH_DT:                       1;
    1773             /** XCLKS_DT. */
    1774             unsigned              fXCLKS_DT:                       1;
    1775             /** Parity pipe select. */
    1776             unsigned              u2ParityPipeSelect:              2;
    1777             /** Reserved. */
    1778             unsigned              u30Reserved:                    30;
    1779             /** Data bit pipeline select. */
    1780             unsigned              u32DataPipelineSelect:          32;
    1781         } fields;
    1782     } u;
    1783 } MptConfigurationPageSCSISPIDevice2, *PMptConfigurationPageSCSISPIDevice2;
    1784 #pragma pack()
    1785 AssertCompileSize(MptConfigurationPageSCSISPIDevice2, 16);
    1786 
    1787 /**
    1788  * SCSI-SPI device page 3 (Revision G). - Readonly
    1789  */
    1790 #pragma pack(1)
    1791 typedef struct MptConfigurationPageSCSISPIDevice3
    1792 {
    1793     /** Union. */
    1794     union
    1795     {
    1796         /** Byte view. */
    1797         uint8_t                   abPageData[12];
    1798         /** Field view. */
    1799         struct
    1800         {
    1801             /** The omnipresent header. */
    1802             MptConfigurationPageHeader    Header;
    1803             /** Number of times the IOC rejected a message because it doesn't support the operation. */
    1804             uint16_t                      u16MsgRejectCount;
    1805             /** Number of times the SCSI bus entered an invalid operation state. */
    1806             uint16_t                      u16PhaseErrorCount;
    1807             /** Number of parity errors. */
    1808             uint16_t                      u16ParityCount;
    1809             /** Reserved. */
    1810             uint16_t                      u16Reserved;
    1811         } fields;
    1812     } u;
    1813 } MptConfigurationPageSCSISPIDevice3, *PMptConfigurationPageSCSISPIDevice3;
    1814 #pragma pack()
    1815 AssertCompileSize(MptConfigurationPageSCSISPIDevice3, 12);
    1816 
    1817 /**
    1818  * Structure of all supported pages.
    1819  */
    1820 typedef struct MptConfigurationPagesSupported
    1821 {
    1822     MptConfigurationPageManufacturing0 ManufacturingPage0;
    1823     MptConfigurationPageManufacturing1 ManufacturingPage1;
    1824     MptConfigurationPageManufacturing2 ManufacturingPage2;
    1825     MptConfigurationPageManufacturing3 ManufacturingPage3;
    1826     MptConfigurationPageManufacturing4 ManufacturingPage4;
    1827     MptConfigurationPageIOUnit0        IOUnitPage0;
    1828     MptConfigurationPageIOUnit1        IOUnitPage1;
    1829     MptConfigurationPageIOUnit2        IOUnitPage2;
    1830     MptConfigurationPageIOUnit3        IOUnitPage3;
    1831     MptConfigurationPageIOC0           IOCPage0;
    1832     MptConfigurationPageIOC1           IOCPage1;
    1833     MptConfigurationPageIOC2           IOCPage2;
    1834     MptConfigurationPageIOC3           IOCPage3;
    1835     MptConfigurationPageIOC4           IOCPage4;
    1836     MptConfigurationPageIOC6           IOCPage6;
    1837     struct
    1838     {
    1839         MptConfigurationPageSCSISPIPort0   SCSISPIPortPage0;
    1840         MptConfigurationPageSCSISPIPort1   SCSISPIPortPage1;
    1841         MptConfigurationPageSCSISPIPort2   SCSISPIPortPage2;
    1842     } aPortPages[1]; /* Currently only one port supported. */
    1843     struct
    1844     {
    1845         struct
    1846         {
    1847             MptConfigurationPageSCSISPIDevice0 SCSISPIDevicePage0;
    1848             MptConfigurationPageSCSISPIDevice1 SCSISPIDevicePage1;
    1849             MptConfigurationPageSCSISPIDevice2 SCSISPIDevicePage2;
    1850             MptConfigurationPageSCSISPIDevice3 SCSISPIDevicePage3;
    1851         } aDevicePages[LSILOGIC_DEVICES_MAX];
    1852     } aBuses[1]; /* Only one bus at the moment. */
    1853 } MptConfigurationPagesSupported, *PMptConfigurationPagesSupported;
    1854 
    1855 /**
    1856  * Possible SG element types.
    1857  */
    1858 enum MPTSGENTRYTYPE
    1859 {
    1860     MPTSGENTRYTYPE_TRANSACTION_CONTEXT = 0x00,
    1861     MPTSGENTRYTYPE_SIMPLE              = 0x01,
    1862     MPTSGENTRYTYPE_CHAIN               = 0x03
    1863 };
    186441
    186542/**
     
    2113290    volatile uint32_t     uRequestQueueNextAddressRead;
    2114291
     292    /* Emulated controller type */
     293    LSILOGICCTRLTYPE      enmCtrlType;
     294
    2115295    /** Configuration pages. */
    2116     MptConfigurationPagesSupported ConfigurationPages;
     296    union
     297    {
     298        /** Pages for the SPI controller. */
     299        MptConfigurationPagesSupportedSpi SpiPages;
     300        /** Pages for the SAS controller. */
     301        MptConfigurationPagesSupportedSas SasPages;
     302    } ConfigurationPages;
     303
     304    uint32_t                       u32Alignment2;
    2117305
    2118306    /** BIOS emulation. */
     
    38612049    {
    38622050        case 0:
    3863             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOUnitPage0.u.fields.Header;
    3864             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOUnitPage0.u.abPageData;
    3865             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOUnitPage0);
     2051            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage0.u.fields.Header;
     2052            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage0.u.abPageData;
     2053            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage0);
    38662054            break;
    38672055        case 1:
    3868             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOUnitPage1.u.fields.Header;
    3869             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOUnitPage1.u.abPageData;
    3870             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOUnitPage1);
     2056            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage1.u.fields.Header;
     2057            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage1.u.abPageData;
     2058            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage1);
    38712059            break;
    38722060        case 2:
    3873             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOUnitPage2.u.fields.Header;
    3874             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOUnitPage2.u.abPageData;
    3875             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOUnitPage2);
     2061            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage2.u.fields.Header;
     2062            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage2.u.abPageData;
     2063            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage2);
    38762064            break;
    38772065        case 3:
    3878             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOUnitPage3.u.fields.Header;
    3879             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOUnitPage3.u.abPageData;
    3880             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOUnitPage3);
     2066            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage3.u.fields.Header;
     2067            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage3.u.abPageData;
     2068            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOUnitPage3);
    38812069            break;
    38822070        default:
     
    39082096    {
    39092097        case 0:
    3910             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOCPage0.u.fields.Header;
    3911             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOCPage0.u.abPageData;
    3912             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOCPage0);
     2098            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOCPage0.u.fields.Header;
     2099            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOCPage0.u.abPageData;
     2100            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOCPage0);
    39132101            break;
    39142102        case 1:
    3915             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOCPage1.u.fields.Header;
    3916             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOCPage1.u.abPageData;
    3917             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOCPage1);
     2103            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOCPage1.u.fields.Header;
     2104            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOCPage1.u.abPageData;
     2105            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOCPage1);
    39182106            break;
    39192107        case 2:
    3920             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOCPage2.u.fields.Header;
    3921             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOCPage2.u.abPageData;
    3922             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOCPage2);
     2108            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOCPage2.u.fields.Header;
     2109            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOCPage2.u.abPageData;
     2110            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOCPage2);
    39232111            break;
    39242112        case 3:
    3925             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOCPage3.u.fields.Header;
    3926             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOCPage3.u.abPageData;
    3927             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOCPage3);
     2113            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOCPage3.u.fields.Header;
     2114            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOCPage3.u.abPageData;
     2115            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOCPage3);
    39282116            break;
    39292117        case 4:
    3930             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOCPage4.u.fields.Header;
    3931             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOCPage4.u.abPageData;
    3932             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOCPage4);
     2118            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOCPage4.u.fields.Header;
     2119            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOCPage4.u.abPageData;
     2120            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOCPage4);
    39332121            break;
    39342122        case 6:
    3935             *ppPageHeader = &pLsiLogic->ConfigurationPages.IOCPage6.u.fields.Header;
    3936             *ppbPageData  =  pLsiLogic->ConfigurationPages.IOCPage6.u.abPageData;
    3937             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.IOCPage6);
     2123            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.IOCPage6.u.fields.Header;
     2124            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.IOCPage6.u.abPageData;
     2125            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.IOCPage6);
    39382126            break;
    39392127        default:
     
    39652153    {
    39662154        case 0:
    3967             *ppPageHeader = &pLsiLogic->ConfigurationPages.ManufacturingPage0.u.fields.Header;
    3968             *ppbPageData  =  pLsiLogic->ConfigurationPages.ManufacturingPage0.u.abPageData;
    3969             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.ManufacturingPage0);
     2155            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage0.u.fields.Header;
     2156            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage0.u.abPageData;
     2157            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage0);
    39702158            break;
    39712159        case 1:
    3972             *ppPageHeader = &pLsiLogic->ConfigurationPages.ManufacturingPage1.Header;
    3973             *ppbPageData  =  pLsiLogic->ConfigurationPages.ManufacturingPage1.abVPDInfo;
    3974             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.ManufacturingPage1);
     2160            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage1.Header;
     2161            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage1.abVPDInfo;
     2162            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage1);
    39752163            break;
    39762164        case 2:
    3977             *ppPageHeader = &pLsiLogic->ConfigurationPages.ManufacturingPage2.u.fields.Header;
    3978             *ppbPageData  =  pLsiLogic->ConfigurationPages.ManufacturingPage2.u.abPageData;
    3979             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.ManufacturingPage2);
     2165            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage2.u.fields.Header;
     2166            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage2.u.abPageData;
     2167            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage2);
    39802168            break;
    39812169        case 3:
    3982             *ppPageHeader = &pLsiLogic->ConfigurationPages.ManufacturingPage3.u.fields.Header;
    3983             *ppbPageData  =  pLsiLogic->ConfigurationPages.ManufacturingPage3.u.abPageData;
    3984             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.ManufacturingPage3);
     2170            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage3.u.fields.Header;
     2171            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage3.u.abPageData;
     2172            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage3);
    39852173            break;
    39862174        case 4:
    3987             *ppPageHeader = &pLsiLogic->ConfigurationPages.ManufacturingPage4.u.fields.Header;
    3988             *ppbPageData  =  pLsiLogic->ConfigurationPages.ManufacturingPage4.u.abPageData;
    3989             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.ManufacturingPage4);
     2175            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage4.u.fields.Header;
     2176            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage4.u.abPageData;
     2177            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.ManufacturingPage4);
    39902178            break;
    39912179        default:
     
    40152203    AssertMsg(VALID_PTR(ppPageHeader) && VALID_PTR(ppbPageData), ("Invalid parameters\n"));
    40162204
    4017     if (u8Port >= RT_ELEMENTS(pLsiLogic->ConfigurationPages.aPortPages))
     2205    if (u8Port >= RT_ELEMENTS(pLsiLogic->ConfigurationPages.SpiPages.aPortPages))
    40182206        return VERR_NOT_FOUND;
    40192207
     
    40212209    {
    40222210        case 0:
    4023             *ppPageHeader = &pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage0.u.fields.Header;
    4024             *ppbPageData  =  pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage0.u.abPageData;
    4025             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage0);
     2211            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage0.u.fields.Header;
     2212            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage0.u.abPageData;
     2213            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage0);
    40262214            break;
    40272215        case 1:
    4028             *ppPageHeader = &pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage1.u.fields.Header;
    4029             *ppbPageData  =  pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage1.u.abPageData;
    4030             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage1);
     2216            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage1.u.fields.Header;
     2217            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage1.u.abPageData;
     2218            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage1);
    40312219            break;
    40322220        case 2:
    4033             *ppPageHeader = &pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage2.u.fields.Header;
    4034             *ppbPageData  =  pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage2.u.abPageData;
    4035             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.aPortPages[u8Port].SCSISPIPortPage2);
     2221            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage2.u.fields.Header;
     2222            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage2.u.abPageData;
     2223            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.aPortPages[u8Port].SCSISPIPortPage2);
    40362224            break;
    40372225        default:
     
    40612249    AssertMsg(VALID_PTR(ppPageHeader) && VALID_PTR(ppbPageData), ("Invalid parameters\n"));
    40622250
    4063     if (u8Bus >= RT_ELEMENTS(pLsiLogic->ConfigurationPages.aBuses))
     2251    if (u8Bus >= RT_ELEMENTS(pLsiLogic->ConfigurationPages.SpiPages.aBuses))
    40642252        return VERR_NOT_FOUND;
    40652253
    4066     if (u8TargetID >= RT_ELEMENTS(pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages))
     2254    if (u8TargetID >= RT_ELEMENTS(pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages))
    40672255        return VERR_NOT_FOUND;
    40682256
     
    40702258    {
    40712259        case 0:
    4072             *ppPageHeader = &pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage0.u.fields.Header;
    4073             *ppbPageData  =  pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage0.u.abPageData;
    4074             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage0);
     2260            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage0.u.fields.Header;
     2261            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage0.u.abPageData;
     2262            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage0);
    40752263            break;
    40762264        case 1:
    4077             *ppPageHeader = &pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage1.u.fields.Header;
    4078             *ppbPageData  =  pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage1.u.abPageData;
    4079             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage1);
     2265            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage1.u.fields.Header;
     2266            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage1.u.abPageData;
     2267            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage1);
    40802268            break;
    40812269        case 2:
    4082             *ppPageHeader = &pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage2.u.fields.Header;
    4083             *ppbPageData  =  pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage2.u.abPageData;
    4084             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage2);
     2270            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage2.u.fields.Header;
     2271            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage2.u.abPageData;
     2272            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage2);
    40852273            break;
    40862274        case 3:
    4087             *ppPageHeader = &pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage3.u.fields.Header;
    4088             *ppbPageData  =  pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage3.u.abPageData;
    4089             *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage3);
     2275            *ppPageHeader = &pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage3.u.fields.Header;
     2276            *ppbPageData  =  pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage3.u.abPageData;
     2277            *pcbPage      = sizeof(pLsiLogic->ConfigurationPages.SpiPages.aBuses[u8Bus].aDevicePages[u8TargetID].SCSISPIDevicePage3);
    40902278            break;
    40912279        default:
     
    42552443static void lsilogicInitializeConfigurationPages(PLSILOGICSCSI pLsiLogic)
    42562444{
    4257     PMptConfigurationPagesSupported pPages = &pLsiLogic->ConfigurationPages;
     2445    PMptConfigurationPagesSupportedSpi pPages = &pLsiLogic->ConfigurationPages.SpiPages;
    42582446
    42592447    LogFlowFunc(("pLsiLogic=%#p\n", pLsiLogic));
    42602448
    42612449    /* Clear everything first. */
    4262     memset(pPages, 0, sizeof(MptConfigurationPagesSupported));
     2450    memset(pPages, 0, sizeof(MptConfigurationPagesSupportedSpi));
    42632451
    42642452    /* Manufacturing Page 0. */
     
    42842472    pPages->ManufacturingPage2.u.fields.Header.u8PageNumber = 2;
    42852473    pPages->ManufacturingPage2.u.fields.Header.u8PageLength = sizeof(MptConfigurationPageManufacturing2) / 4;
    4286     pPages->ManufacturingPage2.u.fields.u16PCIDeviceID = LSILOGICSCSI_PCI_DEVICE_ID;
    4287     pPages->ManufacturingPage2.u.fields.u8PCIRevisionID = LSILOGICSCSI_PCI_REVISION_ID;
     2474    pPages->ManufacturingPage2.u.fields.u16PCIDeviceID = LSILOGICSCSI_PCI_SPI_DEVICE_ID;
     2475    pPages->ManufacturingPage2.u.fields.u8PCIRevisionID = LSILOGICSCSI_PCI_SPI_REVISION_ID;
    42882476    /* Hardware specific settings - everything 0 for now. */
    42892477
     
    42932481    pPages->ManufacturingPage3.u.fields.Header.u8PageNumber = 3;
    42942482    pPages->ManufacturingPage3.u.fields.Header.u8PageLength = sizeof(MptConfigurationPageManufacturing3) / 4;
    4295     pPages->ManufacturingPage3.u.fields.u16PCIDeviceID = LSILOGICSCSI_PCI_DEVICE_ID;
    4296     pPages->ManufacturingPage3.u.fields.u8PCIRevisionID = LSILOGICSCSI_PCI_REVISION_ID;
     2483    pPages->ManufacturingPage3.u.fields.u16PCIDeviceID = LSILOGICSCSI_PCI_SPI_DEVICE_ID;
     2484    pPages->ManufacturingPage3.u.fields.u8PCIRevisionID = LSILOGICSCSI_PCI_SPI_REVISION_ID;
    42972485    /* Chip specific settings - everything 0 for now. */
    42982486
     
    43512539    pPages->IOCPage0.u.fields.u32FreeNVStore       = 0;
    43522540    pPages->IOCPage0.u.fields.u16VendorId          = LSILOGICSCSI_PCI_VENDOR_ID;
    4353     pPages->IOCPage0.u.fields.u16DeviceId          = LSILOGICSCSI_PCI_DEVICE_ID;
    4354     pPages->IOCPage0.u.fields.u8RevisionId         = LSILOGICSCSI_PCI_REVISION_ID;
    4355     pPages->IOCPage0.u.fields.u32ClassCode         = LSILOGICSCSI_PCI_CLASS_CODE;
    4356     pPages->IOCPage0.u.fields.u16SubsystemVendorId = LSILOGICSCSI_PCI_SUBSYSTEM_VENDOR_ID;
    4357     pPages->IOCPage0.u.fields.u16SubsystemId       = LSILOGICSCSI_PCI_SUBSYSTEM_ID;
     2541    pPages->IOCPage0.u.fields.u16DeviceId          = LSILOGICSCSI_PCI_SPI_DEVICE_ID;
     2542    pPages->IOCPage0.u.fields.u8RevisionId         = LSILOGICSCSI_PCI_SPI_REVISION_ID;
     2543    pPages->IOCPage0.u.fields.u32ClassCode         = LSILOGICSCSI_PCI_SPI_CLASS_CODE;
     2544    pPages->IOCPage0.u.fields.u16SubsystemVendorId = LSILOGICSCSI_PCI_SPI_SUBSYSTEM_VENDOR_ID;
     2545    pPages->IOCPage0.u.fields.u16SubsystemId       = LSILOGICSCSI_PCI_SPI_SUBSYSTEM_ID;
    43582546
    43592547    /* IOC page 1. */
     
    45782766
    45792767/**
     2768 * Sets the emulated controller type from a given string.
     2769 *
     2770 * @returns VBox status code.
     2771 *
     2772 * @param   pThis        The LsiLogic devi state.
     2773 * @param   pcszCtrlType The string to use.
     2774 */
     2775static int lsilogicGetCtrlTypeFromString(PLSILOGICSCSI pThis, const char *pcszCtrlType)
     2776{
     2777    int rc = VERR_INVALID_PARAMETER;
     2778
     2779    if (!RTStrCmp(pcszCtrlType, LSILOGICSCSI_PCI_SPI_CTRLNAME))
     2780    {
     2781        pThis->enmCtrlType = LSILOGICCTRLTYPE_SCSI_SPI;
     2782        rc = VINF_SUCCESS;
     2783    }
     2784    else if (!RTStrCmp(pcszCtrlType, LSILOGICSCSI_PCI_SAS_CTRLNAME))
     2785    {
     2786        pThis->enmCtrlType = LSILOGICCTRLTYPE_SCSI_SAS;
     2787        rc = VINF_SUCCESS;
     2788    }
     2789
     2790    return rc;
     2791}
     2792
     2793/**
    45802794 * Port I/O Handler for IN operations - legacy port.
    45812795 *
     
    48853099    SSMR3PutU32   (pSSM, pLsiLogic->uRequestQueueNextEntryFreeWrite);
    48863100    SSMR3PutU32   (pSSM, pLsiLogic->uRequestQueueNextAddressRead);
    4887     SSMR3PutMem   (pSSM, &pLsiLogic->ConfigurationPages, sizeof(pLsiLogic->ConfigurationPages));
     3101    SSMR3PutMem   (pSSM, &pLsiLogic->ConfigurationPages.SpiPages,
     3102                   sizeof(pLsiLogic->ConfigurationPages.SpiPages));
    48883103    /* Now the data for the BIOS interface. */
    48893104    SSMR3PutU8    (pSSM, pLsiLogic->VBoxSCSI.regIdentify);
     
    49683183    SSMR3GetU32   (pSSM, (uint32_t *)&pLsiLogic->uRequestQueueNextEntryFreeWrite);
    49693184    SSMR3GetU32   (pSSM, (uint32_t *)&pLsiLogic->uRequestQueueNextAddressRead);
    4970     SSMR3GetMem   (pSSM, &pLsiLogic->ConfigurationPages, sizeof(pLsiLogic->ConfigurationPages));
     3185    SSMR3GetMem   (pSSM, &pLsiLogic->ConfigurationPages.SpiPages,
     3186                   sizeof(pLsiLogic->ConfigurationPages.SpiPages));
    49713187    /* Now the data for the BIOS interface. */
    49723188    SSMR3GetU8  (pSSM, &pLsiLogic->VBoxSCSI.regIdentify);
     
    52163432    PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    52173433    int rc = VINF_SUCCESS;
     3434    char *pszCtrlType = NULL;
    52183435    PVM pVM = PDMDevHlpGetVM(pDevIns);
    52193436
     
    52243441                                          "R0Enabled\0"
    52253442                                          "ReplyQueueDepth\0"
    5226                                           "RequestQueueDepth\0");
     3443                                          "RequestQueueDepth\0"
     3444                                          "ControllerType\0");
    52273445    if (RT_FAILURE(rc))
    52283446        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
     
    52563474    Log(("%s: RequestQueueDepth=%u\n", __FUNCTION__, pThis->cRequestQueueEntries));
    52573475
     3476    rc = CFGMR3QueryStringAllocDef(pCfgHandle, "ControllerType",
     3477                                   &pszCtrlType, LSILOGICSCSI_PCI_SPI_CTRLNAME);
     3478    if (RT_FAILURE(rc))
     3479        return PDMDEV_SET_ERROR(pDevIns, rc,
     3480                                N_("LsiLogic configuration error: failed to read ControllerType as string"));
     3481    Log(("%s: ControllerType=%s\n", __FUNCTION__, pszCtrlType));
     3482
     3483    rc = lsilogicGetCtrlTypeFromString(pThis, pszCtrlType);
     3484    MMR3HeapFree(pszCtrlType);
     3485
     3486    if (RT_FAILURE(rc))
     3487        return PDMDEV_SET_ERROR(pDevIns, rc,
     3488                                N_("LsiLogic configuration error: failed to determine controller type from string"));
    52583489
    52593490    /* Init static parts. */
    5260     PCIDevSetVendorId         (&pThis->PciDev, LSILOGICSCSI_PCI_VENDOR_ID); /* LsiLogic */
    5261     PCIDevSetDeviceId         (&pThis->PciDev, LSILOGICSCSI_PCI_DEVICE_ID); /* LSI53C1030 */
    5262     PCIDevSetClassProg        (&pThis->PciDev,   0x00); /* SCSI */
    5263     PCIDevSetClassSub         (&pThis->PciDev,   0x00); /* SCSI */
    5264     PCIDevSetClassBase        (&pThis->PciDev,   0x01); /* Mass storage */
    5265     PCIDevSetSubSystemVendorId(&pThis->PciDev, LSILOGICSCSI_PCI_SUBSYSTEM_VENDOR_ID);
    5266     PCIDevSetSubSystemId      (&pThis->PciDev, LSILOGICSCSI_PCI_SUBSYSTEM_ID);
    5267     PCIDevSetInterruptPin     (&pThis->PciDev,   0x01); /* Interrupt pin A */
     3491    PCIDevSetVendorId(&pThis->PciDev, LSILOGICSCSI_PCI_VENDOR_ID); /* LsiLogic */
     3492
     3493    if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI)
     3494    {
     3495        PCIDevSetDeviceId         (&pThis->PciDev, LSILOGICSCSI_PCI_SPI_DEVICE_ID); /* LSI53C1030 */
     3496        PCIDevSetSubSystemVendorId(&pThis->PciDev, LSILOGICSCSI_PCI_SPI_SUBSYSTEM_VENDOR_ID);
     3497        PCIDevSetSubSystemId      (&pThis->PciDev, LSILOGICSCSI_PCI_SPI_SUBSYSTEM_ID);
     3498    }
     3499    else if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SAS)
     3500    {
     3501        PCIDevSetDeviceId         (&pThis->PciDev, LSILOGICSCSI_PCI_SAS_DEVICE_ID); /* SAS1068 */
     3502        PCIDevSetSubSystemVendorId(&pThis->PciDev, LSILOGICSCSI_PCI_SAS_SUBSYSTEM_VENDOR_ID);
     3503        PCIDevSetSubSystemId      (&pThis->PciDev, LSILOGICSCSI_PCI_SAS_SUBSYSTEM_ID);
     3504    }
     3505    else
     3506        AssertMsgFailed(("Invalid controller type: %d\n", pThis->enmCtrlType));
     3507
     3508    PCIDevSetClassProg   (&pThis->PciDev,   0x00); /* SCSI */
     3509    PCIDevSetClassSub    (&pThis->PciDev,   0x00); /* SCSI */
     3510    PCIDevSetClassBase   (&pThis->PciDev,   0x01); /* Mass storage */
     3511    PCIDevSetInterruptPin(&pThis->PciDev,   0x01); /* Interrupt pin A */
    52683512
    52693513    pThis->pDevInsR3 = pDevIns;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette