VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.h@ 88956

Last change on this file since 88956 was 88643, checked in by vboxsync, 4 years ago

Devices/Storage/DevLsiLogicSCSI: Fix crashing on NULL pointer dereference during device construction when the SAS variant is used (regression from r143802), bugref:9914

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 129.4 KB
Line 
1/* $Id: DevLsiLogicSCSI.h 88643 2021-04-22 07:57:03Z vboxsync $ */
2/** @file
3 * VBox storage devices: LsiLogic LSI53c1030 SCSI controller - Defines and structures.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_INCLUDED_SRC_Storage_DevLsiLogicSCSI_h
19#define VBOX_INCLUDED_SRC_Storage_DevLsiLogicSCSI_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <iprt/stdint.h>
25
26/*
27 * Custom fixed I/O ports for BIOS controller access. Note that these should
28 * not be in the ISA range (below 400h) to avoid conflicts with ISA device
29 * probing. Addresses in the 300h-340h range should be especially avoided.
30 */
31#define LSILOGIC_BIOS_IO_PORT 0x434
32#define LSILOGIC_SAS_BIOS_IO_PORT 0x438
33
34#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN 8 /**< (bird just picked this out thin air) */
35#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX 1024 /**< (bird just picked this out thin air) */
36#define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT 256
37
38#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN 8 /**< (bird just picked this out thin air) */
39#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX 1024 /**< (bird just picked this out thin air) */
40#define LSILOGICSCSI_REPLY_QUEUE_DEPTH_DEFAULT 256
41
42#define LSILOGICSCSI_MAXIMUM_CHAIN_DEPTH 3
43
44#define LSILOGIC_NR_OF_ALLOWED_BIGGER_LISTS 100
45
46/** Equal for all devices */
47#define LSILOGICSCSI_PCI_VENDOR_ID (0x1000)
48
49/** SPI SCSI controller (LSI53C1030) */
50#define LSILOGICSCSI_PCI_SPI_CTRLNAME "LSI53C1030"
51#define LSILOGICSCSI_PCI_SPI_DEVICE_ID (0x0030)
52#define LSILOGICSCSI_PCI_SPI_REVISION_ID (0x00)
53#define LSILOGICSCSI_PCI_SPI_CLASS_CODE (0x01)
54#define LSILOGICSCSI_PCI_SPI_SUBSYSTEM_VENDOR_ID (0x1000)
55#define LSILOGICSCSI_PCI_SPI_SUBSYSTEM_ID (0x8000)
56#define LSILOGICSCSI_PCI_SPI_PORTS_MAX 1
57#define LSILOGICSCSI_PCI_SPI_BUSES_MAX 1
58#define LSILOGICSCSI_PCI_SPI_DEVICES_PER_BUS_MAX 16
59#define LSILOGICSCSI_PCI_SPI_DEVICES_MAX (LSILOGICSCSI_PCI_SPI_BUSES_MAX*LSILOGICSCSI_PCI_SPI_DEVICES_PER_BUS_MAX)
60
61/** SAS SCSI controller (SAS1068 PCI-X Fusion-MPT SAS) */
62#define LSILOGICSCSI_PCI_SAS_CTRLNAME "SAS1068"
63#define LSILOGICSCSI_PCI_SAS_DEVICE_ID (0x0054)
64#define LSILOGICSCSI_PCI_SAS_REVISION_ID (0x00)
65#define LSILOGICSCSI_PCI_SAS_CLASS_CODE (0x00)
66#define LSILOGICSCSI_PCI_SAS_SUBSYSTEM_VENDOR_ID (0x1000)
67#define LSILOGICSCSI_PCI_SAS_SUBSYSTEM_ID (0x8000)
68#define LSILOGICSCSI_PCI_SAS_PORTS_MAX 256
69#define LSILOGICSCSI_PCI_SAS_PORTS_DEFAULT 8
70#define LSILOGICSCSI_PCI_SAS_DEVICES_PER_PORT_MAX 1
71#define LSILOGICSCSI_PCI_SAS_DEVICES_MAX (LSILOGICSCSI_PCI_SAS_PORTS_MAX * LSILOGICSCSI_PCI_SAS_DEVICES_PER_PORT_MAX)
72
73/**
74 * A SAS address.
75 */
76typedef union SASADDRESS
77{
78 /** 64bit view. */
79 uint64_t u64Address;
80 /** 32bit view. */
81 uint32_t u32Address[2];
82 /** 16bit view. */
83 uint16_t u16Address[4];
84 /** Byte view. */
85 uint8_t u8Address[8];
86} SASADDRESS, *PSASADDRESS;
87AssertCompileSize(SASADDRESS, 8);
88
89/**
90 * Possible device types we support.
91 */
92typedef enum LSILOGICCTRLTYPE
93{
94 /** SPI SCSI controller (PCI dev id 0x0030) */
95 LSILOGICCTRLTYPE_SCSI_SPI = 0,
96 /** SAS SCSI controller (PCI dev id 0x0054) */
97 LSILOGICCTRLTYPE_SCSI_SAS = 1,
98 /** 32bit hack */
99 LSILOGICCTRLTYPE_32BIT_HACK = 0x7fffffff
100} LSILOGICCTRLTYPE, *PLSILOGICCTRLTYPE;
101
102/**
103 * A simple SG element for a 64bit address.
104 */
105typedef struct MptSGEntrySimple64
106{
107 /** Length of the buffer this entry describes. */
108 unsigned u24Length: 24;
109 /** Flag whether this element is the end of the list. */
110 unsigned fEndOfList: 1;
111 /** Flag whether the address is 32bit or 64bits wide. */
112 unsigned f64BitAddress: 1;
113 /** Flag whether this buffer contains data to be transferred or is the destination. */
114 unsigned fBufferContainsData: 1;
115 /** Flag whether this is a local address or a system address. */
116 unsigned fLocalAddress: 1;
117 /** Element type. */
118 unsigned u2ElementType: 2;
119 /** Flag whether this is the last element of the buffer. */
120 unsigned fEndOfBuffer: 1;
121 /** Flag whether this is the last element of the current segment. */
122 unsigned fLastElement: 1;
123 /** Lower 32bits of the address of the data buffer. */
124 unsigned u32DataBufferAddressLow: 32;
125 /** Upper 32bits of the address of the data buffer. */
126 unsigned u32DataBufferAddressHigh: 32;
127} MptSGEntrySimple64, *PMptSGEntrySimple64;
128AssertCompileSize(MptSGEntrySimple64, 12);
129
130/**
131 * A simple SG element for a 32bit address.
132 */
133typedef struct MptSGEntrySimple32
134{
135 /** Length of the buffer this entry describes. */
136 unsigned u24Length: 24;
137 /** Flag whether this element is the end of the list. */
138 unsigned fEndOfList: 1;
139 /** Flag whether the address is 32bit or 64bits wide. */
140 unsigned f64BitAddress: 1;
141 /** Flag whether this buffer contains data to be transferred or is the destination. */
142 unsigned fBufferContainsData: 1;
143 /** Flag whether this is a local address or a system address. */
144 unsigned fLocalAddress: 1;
145 /** Element type. */
146 unsigned u2ElementType: 2;
147 /** Flag whether this is the last element of the buffer. */
148 unsigned fEndOfBuffer: 1;
149 /** Flag whether this is the last element of the current segment. */
150 unsigned fLastElement: 1;
151 /** Lower 32bits of the address of the data buffer. */
152 unsigned u32DataBufferAddressLow: 32;
153} MptSGEntrySimple32, *PMptSGEntrySimple32;
154AssertCompileSize(MptSGEntrySimple32, 8);
155
156/**
157 * A chain SG element.
158 */
159typedef struct MptSGEntryChain
160{
161 /** Size of the segment. */
162 unsigned u16Length: 16;
163 /** Offset in 32bit words of the next chain element in the segment
164 * identified by this element. */
165 unsigned u8NextChainOffset: 8;
166 /** Reserved. */
167 unsigned fReserved0: 1;
168 /** Flag whether the address is 32bit or 64bits wide. */
169 unsigned f64BitAddress: 1;
170 /** Reserved. */
171 unsigned fReserved1: 1;
172 /** Flag whether this is a local address or a system address. */
173 unsigned fLocalAddress: 1;
174 /** Element type. */
175 unsigned u2ElementType: 2;
176 /** Flag whether this is the last element of the buffer. */
177 unsigned u2Reserved2: 2;
178 /** Lower 32bits of the address of the data buffer. */
179 unsigned u32SegmentAddressLow: 32;
180 /** Upper 32bits of the address of the data buffer. */
181 unsigned u32SegmentAddressHigh: 32;
182} MptSGEntryChain, *PMptSGEntryChain;
183AssertCompileSize(MptSGEntryChain, 12);
184
185typedef union MptSGEntryUnion
186{
187 MptSGEntrySimple64 Simple64;
188 MptSGEntrySimple32 Simple32;
189 MptSGEntryChain Chain;
190} MptSGEntryUnion, *PMptSGEntryUnion;
191
192/**
193 * MPT Fusion message header - Common for all message frames.
194 * This is filled in by the guest.
195 */
196typedef struct MptMessageHdr
197{
198 /** Function dependent data. */
199 uint16_t u16FunctionDependent;
200 /** Chain offset. */
201 uint8_t u8ChainOffset;
202 /** The function code. */
203 uint8_t u8Function;
204 /** Function dependent data. */
205 uint8_t au8FunctionDependent[3];
206 /** Message flags. */
207 uint8_t u8MessageFlags;
208 /** Message context - Unique ID from the guest unmodified by the device. */
209 uint32_t u32MessageContext;
210} MptMessageHdr, *PMptMessageHdr;
211AssertCompileSize(MptMessageHdr, 12);
212
213/** Defined function codes found in the message header. */
214#define MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST (0x00)
215#define MPT_MESSAGE_HDR_FUNCTION_SCSI_TASK_MGMT (0x01)
216#define MPT_MESSAGE_HDR_FUNCTION_IOC_INIT (0x02)
217#define MPT_MESSAGE_HDR_FUNCTION_IOC_FACTS (0x03)
218#define MPT_MESSAGE_HDR_FUNCTION_CONFIG (0x04)
219#define MPT_MESSAGE_HDR_FUNCTION_PORT_FACTS (0x05)
220#define MPT_MESSAGE_HDR_FUNCTION_PORT_ENABLE (0x06)
221#define MPT_MESSAGE_HDR_FUNCTION_EVENT_NOTIFICATION (0x07)
222#define MPT_MESSAGE_HDR_FUNCTION_EVENT_ACK (0x08)
223#define MPT_MESSAGE_HDR_FUNCTION_FW_DOWNLOAD (0x09)
224#define MPT_MESSAGE_HDR_FUNCTION_TARGET_CMD_BUFFER_POST (0x0A)
225#define MPT_MESSAGE_HDR_FUNCTION_TARGET_ASSIST (0x0B)
226#define MPT_MESSAGE_HDR_FUNCTION_TARGET_STATUS_SEND (0x0C)
227#define MPT_MESSAGE_HDR_FUNCTION_TARGET_MODE_ABORT (0x0D)
228#define MPT_MESSAGE_HDR_FUNCTION_FW_UPLOAD (0x12)
229
230#ifdef DEBUG
231/**
232 * Function names
233 */
234static const char * const g_apszMPTFunctionNames[] =
235{
236 "SCSI I/O Request",
237 "SCSI Task Management",
238 "IOC Init",
239 "IOC Facts",
240 "Config",
241 "Port Facts",
242 "Port Enable",
243 "Event Notification",
244 "Event Ack",
245 "Firmware Download"
246};
247#endif
248
249/**
250 * Default reply message.
251 * Send from the device to the guest upon completion of a request.
252 */
253typedef struct MptDefaultReplyMessage
254{
255 /** Function dependent data. */
256 uint16_t u16FunctionDependent;
257 /** Length of the message in 32bit DWords. */
258 uint8_t u8MessageLength;
259 /** Function which completed. */
260 uint8_t u8Function;
261 /** Function dependent. */
262 uint8_t au8FunctionDependent[3];
263 /** Message flags. */
264 uint8_t u8MessageFlags;
265 /** Message context given in the request. */
266 uint32_t u32MessageContext;
267 /** Function dependent status code. */
268 uint16_t u16FunctionDependentStatus;
269 /** Status of the IOC. */
270 uint16_t u16IOCStatus;
271 /** Additional log info. */
272 uint32_t u32IOCLogInfo;
273} MptDefaultReplyMessage, *PMptDefaultReplyMessage;
274AssertCompileSize(MptDefaultReplyMessage, 20);
275
276/**
277 * IO controller init request.
278 */
279typedef struct MptIOCInitRequest
280{
281 /** Which system send this init request. */
282 uint8_t u8WhoInit;
283 /** Reserved */
284 uint8_t u8Reserved;
285 /** Chain offset in the SG list. */
286 uint8_t u8ChainOffset;
287 /** Function to execute. */
288 uint8_t u8Function;
289 /** Flags */
290 uint8_t u8Flags;
291 /** Maximum number of devices the driver can handle. */
292 uint8_t u8MaxDevices;
293 /** Maximum number of buses the driver can handle. */
294 uint8_t u8MaxBuses;
295 /** Message flags. */
296 uint8_t u8MessageFlags;
297 /** Message context ID. */
298 uint32_t u32MessageContext;
299 /** Reply frame size. */
300 uint16_t u16ReplyFrameSize;
301 /** Reserved */
302 uint16_t u16Reserved;
303 /** Upper 32bit part of the 64bit address the message frames are in.
304 * That means all frames must be in the same 4GB segment. */
305 uint32_t u32HostMfaHighAddr;
306 /** Upper 32bit of the sense buffer. */
307 uint32_t u32SenseBufferHighAddr;
308} MptIOCInitRequest, *PMptIOCInitRequest;
309AssertCompileSize(MptIOCInitRequest, 24);
310
311/**
312 * IO controller init reply.
313 */
314typedef struct MptIOCInitReply
315{
316 /** Which subsystem send this init request. */
317 uint8_t u8WhoInit;
318 /** Reserved */
319 uint8_t u8Reserved;
320 /** Message length */
321 uint8_t u8MessageLength;
322 /** Function. */
323 uint8_t u8Function;
324 /** Flags */
325 uint8_t u8Flags;
326 /** Maximum number of devices the driver can handle. */
327 uint8_t u8MaxDevices;
328 /** Maximum number of busses the driver can handle. */
329 uint8_t u8MaxBuses;
330 /** Message flags. */
331 uint8_t u8MessageFlags;
332 /** Message context ID */
333 uint32_t u32MessageContext;
334 /** Reserved */
335 uint16_t u16Reserved;
336 /** IO controller status. */
337 uint16_t u16IOCStatus;
338 /** IO controller log information. */
339 uint32_t u32IOCLogInfo;
340} MptIOCInitReply, *PMptIOCInitReply;
341AssertCompileSize(MptIOCInitReply, 20);
342
343/**
344 * IO controller facts request.
345 */
346typedef struct MptIOCFactsRequest
347{
348 /** Reserved. */
349 uint16_t u16Reserved;
350 /** Chain offset in SG list. */
351 uint8_t u8ChainOffset;
352 /** Function number. */
353 uint8_t u8Function;
354 /** Reserved */
355 uint8_t u8Reserved[3];
356 /** Message flags. */
357 uint8_t u8MessageFlags;
358 /** Message context ID. */
359 uint32_t u32MessageContext;
360} MptIOCFactsRequest, *PMptIOCFactsRequest;
361AssertCompileSize(MptIOCFactsRequest, 12);
362
363/**
364 * IO controller facts reply.
365 */
366typedef struct MptIOCFactsReply
367{
368 /** Message version. */
369 uint16_t u16MessageVersion;
370 /** Message length. */
371 uint8_t u8MessageLength;
372 /** Function number. */
373 uint8_t u8Function;
374 /** Reserved */
375 uint16_t u16Reserved1;
376 /** IO controller number */
377 uint8_t u8IOCNumber;
378 /** Message flags. */
379 uint8_t u8MessageFlags;
380 /** Message context ID. */
381 uint32_t u32MessageContext;
382 /** IO controller exceptions */
383 uint16_t u16IOCExceptions;
384 /** IO controller status. */
385 uint16_t u16IOCStatus;
386 /** IO controller log information. */
387 uint32_t u32IOCLogInfo;
388 /** Maximum chain depth. */
389 uint8_t u8MaxChainDepth;
390 /** The current value of the WhoInit field. */
391 uint8_t u8WhoInit;
392 /** Block size. */
393 uint8_t u8BlockSize;
394 /** Flags. */
395 uint8_t u8Flags;
396 /** Depth of the reply queue. */
397 uint16_t u16ReplyQueueDepth;
398 /** Size of a request frame. */
399 uint16_t u16RequestFrameSize;
400 /** Reserved */
401 uint16_t u16Reserved2;
402 /** Product ID. */
403 uint16_t u16ProductID;
404 /** Current value of the high 32bit MFA address. */
405 uint32_t u32CurrentHostMFAHighAddr;
406 /** Global credits - Number of entries allocated to queues */
407 uint16_t u16GlobalCredits;
408 /** Number of ports on the IO controller */
409 uint8_t u8NumberOfPorts;
410 /** Event state. */
411 uint8_t u8EventState;
412 /** Current value of the high 32bit sense buffer address. */
413 uint32_t u32CurrentSenseBufferHighAddr;
414 /** Current reply frame size. */
415 uint16_t u16CurReplyFrameSize;
416 /** Maximum number of devices. */
417 uint8_t u8MaxDevices;
418 /** Maximum number of buses. */
419 uint8_t u8MaxBuses;
420 /** Size of the firmware image. */
421 uint32_t u32FwImageSize;
422 /** Reserved. */
423 uint32_t u32Reserved;
424 /** Firmware version */
425 uint32_t u32FWVersion;
426} MptIOCFactsReply, *PMptIOCFactsReply;
427AssertCompileSize(MptIOCFactsReply, 60);
428
429/**
430 * Port facts request
431 */
432typedef struct MptPortFactsRequest
433{
434 /** Reserved */
435 uint16_t u16Reserved1;
436 /** Message length. */
437 uint8_t u8MessageLength;
438 /** Function number. */
439 uint8_t u8Function;
440 /** Reserved */
441 uint16_t u16Reserved2;
442 /** Port number to get facts for. */
443 uint8_t u8PortNumber;
444 /** Message flags. */
445 uint8_t u8MessageFlags;
446 /** Message context ID. */
447 uint32_t u32MessageContext;
448} MptPortFactsRequest, *PMptPortFactsRequest;
449AssertCompileSize(MptPortFactsRequest, 12);
450
451/**
452 * Port facts reply.
453 */
454typedef struct MptPortFactsReply
455{
456 /** Reserved. */
457 uint16_t u16Reserved1;
458 /** Message length. */
459 uint8_t u8MessageLength;
460 /** Function number. */
461 uint8_t u8Function;
462 /** Reserved */
463 uint16_t u16Reserved2;
464 /** Port number the facts are for. */
465 uint8_t u8PortNumber;
466 /** Message flags. */
467 uint8_t u8MessageFlags;
468 /** Message context ID. */
469 uint32_t u32MessageContext;
470 /** Reserved. */
471 uint16_t u16Reserved3;
472 /** IO controller status. */
473 uint16_t u16IOCStatus;
474 /** IO controller log information. */
475 uint32_t u32IOCLogInfo;
476 /** Reserved */
477 uint8_t u8Reserved;
478 /** Port type */
479 uint8_t u8PortType;
480 /** Maximum number of devices on this port. */
481 uint16_t u16MaxDevices;
482 /** SCSI ID of this port on the attached bus. */
483 uint16_t u16PortSCSIID;
484 /** Protocol flags. */
485 uint16_t u16ProtocolFlags;
486 /** Maximum number of target command buffers which can be posted to this port at a time. */
487 uint16_t u16MaxPostedCmdBuffers;
488 /** Maximum number of target IDs that remain persistent between power/reset cycles. */
489 uint16_t u16MaxPersistentIDs;
490 /** Maximum number of LAN buckets. */
491 uint16_t u16MaxLANBuckets;
492 /** Reserved. */
493 uint16_t u16Reserved4;
494 /** Reserved. */
495 uint32_t u32Reserved;
496} MptPortFactsReply, *PMptPortFactsReply;
497AssertCompileSize(MptPortFactsReply, 40);
498
499/**
500 * Port Enable request.
501 */
502typedef struct MptPortEnableRequest
503{
504 /** Reserved. */
505 uint16_t u16Reserved1;
506 /** Message length. */
507 uint8_t u8MessageLength;
508 /** Function number. */
509 uint8_t u8Function;
510 /** Reserved. */
511 uint16_t u16Reserved2;
512 /** Port number to enable. */
513 uint8_t u8PortNumber;
514 /** Message flags. */
515 uint8_t u8MessageFlags;
516 /** Message context ID. */
517 uint32_t u32MessageContext;
518} MptPortEnableRequest, *PMptPortEnableRequest;
519AssertCompileSize(MptPortEnableRequest, 12);
520
521/**
522 * Port enable reply.
523 */
524typedef struct MptPortEnableReply
525{
526 /** Reserved. */
527 uint16_t u16Reserved1;
528 /** Message length. */
529 uint8_t u8MessageLength;
530 /** Function number. */
531 uint8_t u8Function;
532 /** Reserved */
533 uint16_t u16Reserved2;
534 /** Port number which was enabled. */
535 uint8_t u8PortNumber;
536 /** Message flags. */
537 uint8_t u8MessageFlags;
538 /** Message context ID. */
539 uint32_t u32MessageContext;
540 /** Reserved. */
541 uint16_t u16Reserved3;
542 /** IO controller status */
543 uint16_t u16IOCStatus;
544 /** IO controller log information. */
545 uint32_t u32IOCLogInfo;
546} MptPortEnableReply, *PMptPortEnableReply;
547AssertCompileSize(MptPortEnableReply, 20);
548
549/**
550 * Event notification request.
551 */
552typedef struct MptEventNotificationRequest
553{
554 /** Switch - Turns event notification on and off. */
555 uint8_t u8Switch;
556 /** Reserved. */
557 uint8_t u8Reserved1;
558 /** Chain offset. */
559 uint8_t u8ChainOffset;
560 /** Function number. */
561 uint8_t u8Function;
562 /** Reserved. */
563 uint8_t u8reserved2[3];
564 /** Message flags. */
565 uint8_t u8MessageFlags;
566 /** Message context ID. */
567 uint32_t u32MessageContext;
568} MptEventNotificationRequest, *PMptEventNotificationRequest;
569AssertCompileSize(MptEventNotificationRequest, 12);
570
571/**
572 * Event notification reply.
573 */
574typedef struct MptEventNotificationReply
575{
576 /** Event data length. */
577 uint16_t u16EventDataLength;
578 /** Message length. */
579 uint8_t u8MessageLength;
580 /** Function number. */
581 uint8_t u8Function;
582 /** Reserved. */
583 uint16_t u16Reserved1;
584 /** Ack required. */
585 uint8_t u8AckRequired;
586 /** Message flags. */
587 uint8_t u8MessageFlags;
588 /** Message context ID. */
589 uint32_t u32MessageContext;
590 /** Reserved. */
591 uint16_t u16Reserved2;
592 /** IO controller status. */
593 uint16_t u16IOCStatus;
594 /** IO controller log information. */
595 uint32_t u32IOCLogInfo;
596 /** Notification event. */
597 uint32_t u32Event;
598 /** Event context. */
599 uint32_t u32EventContext;
600 /** Event data. */
601 uint32_t u32EventData;
602} MptEventNotificationReply, *PMptEventNotificationReply;
603AssertCompileSize(MptEventNotificationReply, 32);
604
605#define MPT_EVENT_EVENT_CHANGE (0x0000000a)
606
607/**
608 * FW download request.
609 */
610typedef struct MptFWDownloadRequest
611{
612 /** Switch - Turns event notification on and off. */
613 uint8_t u8ImageType;
614 /** Reserved. */
615 uint8_t u8Reserved1;
616 /** Chain offset. */
617 uint8_t u8ChainOffset;
618 /** Function number. */
619 uint8_t u8Function;
620 /** Reserved. */
621 uint8_t u8Reserved2[3];
622 /** Message flags. */
623 uint8_t u8MessageFlags;
624 /** Message context ID. */
625 uint32_t u32MessageContext;
626} MptFWDownloadRequest, *PMptFWDownloadRequest;
627AssertCompileSize(MptFWDownloadRequest, 12);
628
629#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_RESERVED 0
630#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_FIRMWARE 1
631#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_MPI_BIOS 2
632#define MPT_FW_DOWNLOAD_REQUEST_IMAGE_TYPE_NVDATA 3
633
634/**
635 * FW download reply.
636 */
637typedef struct MptFWDownloadReply
638{
639 /** Reserved. */
640 uint16_t u16Reserved1;
641 /** Message length. */
642 uint8_t u8MessageLength;
643 /** Function number. */
644 uint8_t u8Function;
645 /** Reserved. */
646 uint8_t u8Reserved2[3];
647 /** Message flags. */
648 uint8_t u8MessageFlags;
649 /** Message context ID. */
650 uint32_t u32MessageContext;
651 /** Reserved. */
652 uint16_t u16Reserved2;
653 /** IO controller status. */
654 uint16_t u16IOCStatus;
655 /** IO controller log information. */
656 uint32_t u32IOCLogInfo;
657} MptFWDownloadReply, *PMptFWDownloadReply;
658AssertCompileSize(MptFWDownloadReply, 20);
659
660/**
661 * FW upload request.
662 */
663typedef struct MptFWUploadRequest
664{
665 /** Requested image type. */
666 uint8_t u8ImageType;
667 /** Reserved. */
668 uint8_t u8Reserved1;
669 /** Chain offset. */
670 uint8_t u8ChainOffset;
671 /** Function number. */
672 uint8_t u8Function;
673 /** Reserved. */
674 uint8_t u8Reserved2[3];
675 /** Message flags. */
676 uint8_t u8MessageFlags;
677 /** Message context ID. */
678 uint32_t u32MessageContext;
679} MptFWUploadRequest, *PMptFWUploadRequest;
680AssertCompileSize(MptFWUploadRequest, 12);
681
682/**
683 * FW upload reply.
684 */
685typedef struct MptFWUploadReply
686{
687 /** Image type. */
688 uint8_t u8ImageType;
689 /** Reserved. */
690 uint8_t u8Reserved1;
691 /** Message length. */
692 uint8_t u8MessageLength;
693 /** Function number. */
694 uint8_t u8Function;
695 /** Reserved. */
696 uint8_t u8Reserved2[3];
697 /** Message flags. */
698 uint8_t u8MessageFlags;
699 /** Message context ID. */
700 uint32_t u32MessageContext;
701 /** Reserved. */
702 uint16_t u16Reserved2;
703 /** IO controller status. */
704 uint16_t u16IOCStatus;
705 /** IO controller log information. */
706 uint32_t u32IOCLogInfo;
707 /** Uploaded image size. */
708 uint32_t u32ActualImageSize;
709} MptFWUploadReply, *PMptFWUploadReply;
710AssertCompileSize(MptFWUploadReply, 24);
711
712/**
713 * SCSI IO Request
714 */
715typedef struct MptSCSIIORequest
716{
717 /** Target ID */
718 uint8_t u8TargetID;
719 /** Bus number */
720 uint8_t u8Bus;
721 /** Chain offset */
722 uint8_t u8ChainOffset;
723 /** Function number. */
724 uint8_t u8Function;
725 /** CDB length. */
726 uint8_t u8CDBLength;
727 /** Sense buffer length. */
728 uint8_t u8SenseBufferLength;
729 /** Reserved */
730 uint8_t u8Reserved;
731 /** Message flags. */
732 uint8_t u8MessageFlags;
733 /** Message context ID. */
734 uint32_t u32MessageContext;
735 /** LUN */
736 uint8_t au8LUN[8];
737 /** Control values. */
738 uint32_t u32Control;
739 /** The CDB. */
740 uint8_t au8CDB[16];
741 /** Data length. */
742 uint32_t u32DataLength;
743 /** Sense buffer low 32bit address. */
744 uint32_t u32SenseBufferLowAddress;
745} MptSCSIIORequest, *PMptSCSIIORequest;
746AssertCompileSize(MptSCSIIORequest, 48);
747
748#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_GET(x) (((x) & 0x3000000) >> 24)
749#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE (0x0)
750#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE (0x1)
751#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ (0x2)
752
753/**
754 * SCSI IO error reply.
755 */
756typedef struct MptSCSIIOErrorReply
757{
758 /** Target ID */
759 uint8_t u8TargetID;
760 /** Bus number */
761 uint8_t u8Bus;
762 /** Message length. */
763 uint8_t u8MessageLength;
764 /** Function number. */
765 uint8_t u8Function;
766 /** CDB length */
767 uint8_t u8CDBLength;
768 /** Sense buffer length */
769 uint8_t u8SenseBufferLength;
770 /** Reserved */
771 uint8_t u8Reserved;
772 /** Message flags */
773 uint8_t u8MessageFlags;
774 /** Message context ID */
775 uint32_t u32MessageContext;
776 /** SCSI status. */
777 uint8_t u8SCSIStatus;
778 /** SCSI state */
779 uint8_t u8SCSIState;
780 /** IO controller status */
781 uint16_t u16IOCStatus;
782 /** IO controller log information */
783 uint32_t u32IOCLogInfo;
784 /** Transfer count */
785 uint32_t u32TransferCount;
786 /** Sense count */
787 uint32_t u32SenseCount;
788 /** Response information */
789 uint32_t u32ResponseInfo;
790} MptSCSIIOErrorReply, *PMptSCSIIOErrorReply;
791AssertCompileSize(MptSCSIIOErrorReply, 32);
792
793#define MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID (0x01)
794#define MPT_SCSI_IO_ERROR_SCSI_STATE_TERMINATED (0x08)
795
796/**
797 * IOC status codes specific to the SCSI I/O error reply.
798 */
799#define MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_BUS (0x0041)
800#define MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_TARGETID (0x0042)
801#define MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE (0x0043)
802
803/**
804 * SCSI task management request.
805 */
806typedef struct MptSCSITaskManagementRequest
807{
808 /** Target ID */
809 uint8_t u8TargetID;
810 /** Bus number */
811 uint8_t u8Bus;
812 /** Chain offset */
813 uint8_t u8ChainOffset;
814 /** Function number */
815 uint8_t u8Function;
816 /** Reserved */
817 uint8_t u8Reserved1;
818 /** Task type */
819 uint8_t u8TaskType;
820 /** Reserved */
821 uint8_t u8Reserved2;
822 /** Message flags */
823 uint8_t u8MessageFlags;
824 /** Message context ID */
825 uint32_t u32MessageContext;
826 /** LUN */
827 uint8_t au8LUN[8];
828 /** Reserved */
829 uint8_t auReserved[28];
830 /** Task message context ID. */
831 uint32_t u32TaskMessageContext;
832} MptSCSITaskManagementRequest, *PMptSCSITaskManagementRequest;
833AssertCompileSize(MptSCSITaskManagementRequest, 52);
834
835/**
836 * SCSI task management reply.
837 */
838typedef struct MptSCSITaskManagementReply
839{
840 /** Target ID */
841 uint8_t u8TargetID;
842 /** Bus number */
843 uint8_t u8Bus;
844 /** Message length */
845 uint8_t u8MessageLength;
846 /** Function number */
847 uint8_t u8Function;
848 /** Reserved */
849 uint8_t u8Reserved1;
850 /** Task type */
851 uint8_t u8TaskType;
852 /** Reserved */
853 uint8_t u8Reserved2;
854 /** Message flags */
855 uint8_t u8MessageFlags;
856 /** Message context ID */
857 uint32_t u32MessageContext;
858 /** Reserved */
859 uint16_t u16Reserved;
860 /** IO controller status */
861 uint16_t u16IOCStatus;
862 /** IO controller log information */
863 uint32_t u32IOCLogInfo;
864 /** Termination count */
865 uint32_t u32TerminationCount;
866} MptSCSITaskManagementReply, *PMptSCSITaskManagementReply;
867AssertCompileSize(MptSCSITaskManagementReply, 24);
868
869/**
870 * Page address for SAS expander page types.
871 */
872typedef union MptConfigurationPageAddressSASExpander
873{
874 struct
875 {
876 uint16_t u16Handle;
877 uint16_t u16Reserved;
878 } Form0And2;
879 struct
880 {
881 uint16_t u16Handle;
882 uint8_t u8PhyNum;
883 uint8_t u8Reserved;
884 } Form1;
885} MptConfigurationPageAddressSASExpander, *PMptConfigurationPageAddressSASExpander;
886AssertCompileSize(MptConfigurationPageAddressSASExpander, 4);
887
888/**
889 * Page address for SAS device page types.
890 */
891typedef union MptConfigurationPageAddressSASDevice
892{
893 struct
894 {
895 uint16_t u16Handle;
896 uint16_t u16Reserved;
897 } Form0And2;
898 struct
899 {
900 uint8_t u8TargetID;
901 uint8_t u8Bus;
902 uint8_t u8Reserved;
903 } Form1; /**< r=bird: only three bytes? */
904} MptConfigurationPageAddressSASDevice, *PMptConfigurationPageAddressSASDevice;
905AssertCompileSize(MptConfigurationPageAddressSASDevice, 4);
906
907/**
908 * Page address for SAS PHY page types.
909 */
910typedef union MptConfigurationPageAddressSASPHY
911{
912 struct
913 {
914 uint8_t u8PhyNumber;
915 uint8_t u8Reserved[3];
916 } Form0;
917 struct
918 {
919 uint16_t u16Index;
920 uint16_t u16Reserved;
921 } Form1;
922} MptConfigurationPageAddressSASPHY, *PMptConfigurationPageAddressSASPHY;
923AssertCompileSize(MptConfigurationPageAddressSASPHY, 4);
924
925/**
926 * Page address for SAS Enclosure page types.
927 */
928typedef struct MptConfigurationPageAddressSASEnclosure
929{
930 uint16_t u16Handle;
931 uint16_t u16Reserved;
932} MptConfigurationPageAddressSASEnclosure, *PMptConfigurationPageAddressSASEnclosure;
933AssertCompileSize(MptConfigurationPageAddressSASEnclosure, 4);
934
935/**
936 * Union of all possible address types.
937 */
938typedef union MptConfigurationPageAddress
939{
940 /** 32bit view. */
941 uint32_t u32PageAddress;
942 struct
943 {
944 /** Port number to get the configuration page for. */
945 uint8_t u8PortNumber;
946 /** Reserved. */
947 uint8_t u8Reserved[3];
948 } MPIPortNumber;
949 struct
950 {
951 /** Target ID to get the configuration page for. */
952 uint8_t u8TargetID;
953 /** Bus number to get the configuration page for. */
954 uint8_t u8Bus;
955 /** Reserved. */
956 uint8_t u8Reserved[2];
957 } BusAndTargetId;
958 MptConfigurationPageAddressSASExpander SASExpander;
959 MptConfigurationPageAddressSASDevice SASDevice;
960 MptConfigurationPageAddressSASPHY SASPHY;
961 MptConfigurationPageAddressSASEnclosure SASEnclosure;
962} MptConfigurationPageAddress, *PMptConfigurationPageAddress;
963AssertCompileSize(MptConfigurationPageAddress, 4);
964
965#define MPT_CONFIGURATION_PAGE_ADDRESS_GET_SAS_FORM(x) (((x).u32PageAddress >> 28) & 0x0f)
966
967/**
968 * Configuration request
969 */
970typedef struct MptConfigurationRequest
971{
972 /** Action code. */
973 uint8_t u8Action;
974 /** Reserved. */
975 uint8_t u8Reserved1;
976 /** Chain offset. */
977 uint8_t u8ChainOffset;
978 /** Function number. */
979 uint8_t u8Function;
980 /** Extended page length. */
981 uint16_t u16ExtPageLength;
982 /** Extended page type */
983 uint8_t u8ExtPageType;
984 /** Message flags. */
985 uint8_t u8MessageFlags;
986 /** Message context ID. */
987 uint32_t u32MessageContext;
988 /** Reserved. */
989 uint8_t u8Reserved2[8];
990 /** Version number of the page. */
991 uint8_t u8PageVersion;
992 /** Length of the page in 32bit Dwords. */
993 uint8_t u8PageLength;
994 /** Page number to access. */
995 uint8_t u8PageNumber;
996 /** Type of the page being accessed. */
997 uint8_t u8PageType;
998 /** Page type dependent address. */
999 MptConfigurationPageAddress PageAddress;
1000 /** Simple SG element describing the buffer. */
1001 MptSGEntrySimple64 SimpleSGElement;
1002} MptConfigurationRequest, *PMptConfigurationRequest;
1003AssertCompileSize(MptConfigurationRequest, 40);
1004
1005/** Possible action codes. */
1006#define MPT_CONFIGURATION_REQUEST_ACTION_HEADER (0x00)
1007#define MPT_CONFIGURATION_REQUEST_ACTION_READ_CURRENT (0x01)
1008#define MPT_CONFIGURATION_REQUEST_ACTION_WRITE_CURRENT (0x02)
1009#define MPT_CONFIGURATION_REQUEST_ACTION_DEFAULT (0x03)
1010#define MPT_CONFIGURATION_REQUEST_ACTION_WRITE_NVRAM (0x04)
1011#define MPT_CONFIGURATION_REQUEST_ACTION_READ_DEFAULT (0x05)
1012#define MPT_CONFIGURATION_REQUEST_ACTION_READ_NVRAM (0x06)
1013
1014/** Page type codes. */
1015#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_IO_UNIT (0x00)
1016#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_IOC (0x01)
1017#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_BIOS (0x02)
1018#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_SCSI_PORT (0x03)
1019#define MPT_CONFIGURATION_REQUEST_PAGE_TYPE_EXTENDED (0x0F)
1020
1021/**
1022 * Configuration reply.
1023 */
1024typedef struct MptConfigurationReply
1025{
1026 /** Action code. */
1027 uint8_t u8Action;
1028 /** Reserved. */
1029 uint8_t u8Reserved;
1030 /** Message length. */
1031 uint8_t u8MessageLength;
1032 /** Function number. */
1033 uint8_t u8Function;
1034 /** Extended page length. */
1035 uint16_t u16ExtPageLength;
1036 /** Extended page type */
1037 uint8_t u8ExtPageType;
1038 /** Message flags. */
1039 uint8_t u8MessageFlags;
1040 /** Message context ID. */
1041 uint32_t u32MessageContext;
1042 /** Reserved. */
1043 uint16_t u16Reserved;
1044 /** I/O controller status. */
1045 uint16_t u16IOCStatus;
1046 /** I/O controller log information. */
1047 uint32_t u32IOCLogInfo;
1048 /** Version number of the page. */
1049 uint8_t u8PageVersion;
1050 /** Length of the page in 32bit Dwords. */
1051 uint8_t u8PageLength;
1052 /** Page number to access. */
1053 uint8_t u8PageNumber;
1054 /** Type of the page being accessed. */
1055 uint8_t u8PageType;
1056} MptConfigurationReply, *PMptConfigurationReply;
1057AssertCompileSize(MptConfigurationReply, 24);
1058
1059/** Additional I/O controller status codes for the configuration reply. */
1060#define MPT_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020)
1061#define MPT_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021)
1062#define MPT_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022)
1063#define MPT_IOCSTATUS_CONFIG_INVALID_DATA (0x0023)
1064#define MPT_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024)
1065#define MPT_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025)
1066
1067/**
1068 * Union of all possible request messages.
1069 */
1070typedef union MptRequestUnion
1071{
1072 MptMessageHdr Header;
1073 MptIOCInitRequest IOCInit;
1074 MptIOCFactsRequest IOCFacts;
1075 MptPortFactsRequest PortFacts;
1076 MptPortEnableRequest PortEnable;
1077 MptEventNotificationRequest EventNotification;
1078 MptSCSIIORequest SCSIIO;
1079 MptSCSITaskManagementRequest SCSITaskManagement;
1080 MptConfigurationRequest Configuration;
1081 MptFWDownloadRequest FWDownload;
1082 MptFWUploadRequest FWUpload;
1083} MptRequestUnion, *PMptRequestUnion;
1084
1085/**
1086 * Union of all possible reply messages.
1087 */
1088typedef union MptReplyUnion
1089{
1090 /** 16bit view. */
1091 uint16_t au16Reply[30];
1092 MptDefaultReplyMessage Header;
1093 MptIOCInitReply IOCInit;
1094 MptIOCFactsReply IOCFacts;
1095 MptPortFactsReply PortFacts;
1096 MptPortEnableReply PortEnable;
1097 MptEventNotificationReply EventNotification;
1098 MptSCSIIOErrorReply SCSIIOError;
1099 MptSCSITaskManagementReply SCSITaskManagement;
1100 MptConfigurationReply Configuration;
1101 MptFWDownloadReply FWDownload;
1102 MptFWUploadReply FWUpload;
1103} MptReplyUnion, *PMptReplyUnion;
1104AssertCompileSize(MptReplyUnion, 60);
1105
1106/**
1107 * Firmware image header.
1108 */
1109typedef struct FwImageHdr
1110{
1111 /** ARM branch instruction. */
1112 uint32_t u32ArmBrInsn;
1113 /** Signature part 1. */
1114 uint32_t u32Signature1;
1115 /** Signature part 2. */
1116 uint32_t u32Signature2;
1117 /** Signature part 3. */
1118 uint32_t u32Signature3;
1119 /** Another ARM branch instruction. */
1120 uint32_t u32ArmBrInsn2;
1121 /** Yet another ARM branch instruction. */
1122 uint32_t u32ArmBrInsn3;
1123 /** Reserved. */
1124 uint32_t u32Reserved;
1125 /** Checksum of the image. */
1126 uint32_t u32Checksum;
1127 /** Vendor ID. */
1128 uint16_t u16VendorId;
1129 /** Product ID. */
1130 uint16_t u16ProductId;
1131 /** Firmware version. */
1132 uint32_t u32FwVersion;
1133 /** Firmware sequencer Code version. */
1134 uint32_t u32SeqCodeVersion;
1135 /** Image size in bytes including the header. */
1136 uint32_t u32ImageSize;
1137 /** Offset of the first extended image header. */
1138 uint32_t u32NextImageHeaderOffset;
1139 /** Start address of the image in IOC memory. */
1140 uint32_t u32LoadStartAddress;
1141 /** Absolute start address of the Iop ARM. */
1142 uint32_t u32IopResetVectorValue;
1143 /** Address of the IopResetVector register. */
1144 uint32_t u32IopResetVectorRegAddr;
1145 /** Marker value for what utility. */
1146 uint32_t u32VersionNameWhat;
1147 /** ASCII string of version. */
1148 uint8_t aszVersionName[256];
1149 /** Marker value for what utility. */
1150 uint32_t u32VendorNameWhat;
1151 /** ASCII string of vendor name. */
1152 uint8_t aszVendorName[256];
1153} FwImageHdr, *PFwImageHdr;
1154AssertCompileSize(FwImageHdr, 584);
1155
1156/** First part of the signature. */
1157#define LSILOGIC_FWIMGHDR_SIGNATURE1 UINT32_C(0x5aeaa55a)
1158/** Second part of the signature. */
1159#define LSILOGIC_FWIMGHDR_SIGNATURE2 UINT32_C(0xa55aeaa5)
1160/** Third part of the signature. */
1161#define LSILOGIC_FWIMGHDR_SIGNATURE3 UINT32_C(0x5aa55aea)
1162/** Load address of the firmware image to watch for,
1163 * seen used by Solaris 9. When this value is written to the
1164 * diagnostic address register we know a firmware image is downloaded.
1165 */
1166#define LSILOGIC_FWIMGHDR_LOAD_ADDRESS UINT32_C(0x21ff5e00)
1167
1168/**
1169 * Configuration Page attributes.
1170 */
1171#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_READONLY (0x00)
1172#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_CHANGEABLE (0x10)
1173#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_PERSISTENT (0x20)
1174#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_PERSISTENT_READONLY (0x30)
1175
1176#define MPT_CONFIGURATION_PAGE_ATTRIBUTE_GET(u8PageType) ((u8PageType) & 0xf0)
1177
1178/**
1179 * Configuration Page types.
1180 */
1181#define MPT_CONFIGURATION_PAGE_TYPE_IO_UNIT (0x00)
1182#define MPT_CONFIGURATION_PAGE_TYPE_IOC (0x01)
1183#define MPT_CONFIGURATION_PAGE_TYPE_BIOS (0x02)
1184#define MPT_CONFIGURATION_PAGE_TYPE_SCSI_SPI_PORT (0x03)
1185#define MPT_CONFIGURATION_PAGE_TYPE_SCSI_SPI_DEVICE (0x04)
1186#define MPT_CONFIGURATION_PAGE_TYPE_MANUFACTURING (0x09)
1187#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED (0x0F)
1188
1189#define MPT_CONFIGURATION_PAGE_TYPE_GET(u8PageType) ((u8PageType) & 0x0f)
1190
1191/**
1192 * Extented page types.
1193 */
1194#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASIOUNIT (0x10)
1195#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASEXPANDER (0x11)
1196#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASDEVICE (0x12)
1197#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_SASPHYS (0x13)
1198#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_LOG (0x14)
1199#define MPT_CONFIGURATION_PAGE_TYPE_EXTENDED_ENCLOSURE (0x15)
1200
1201/**
1202 * Configuration Page header - Common to all pages.
1203 */
1204typedef struct MptConfigurationPageHeader
1205{
1206 /** Version of the page. */
1207 uint8_t u8PageVersion;
1208 /** The length of the page in 32bit D-Words. */
1209 uint8_t u8PageLength;
1210 /** Number of the page. */
1211 uint8_t u8PageNumber;
1212 /** Type of the page. */
1213 uint8_t u8PageType;
1214} MptConfigurationPageHeader, *PMptConfigurationPageHeader;
1215AssertCompileSize(MptConfigurationPageHeader, 4);
1216
1217/**
1218 * Extended configuration page header - Common to all extended pages.
1219 */
1220typedef struct MptExtendedConfigurationPageHeader
1221{
1222 /** Version of the page. */
1223 uint8_t u8PageVersion;
1224 /** Reserved. */
1225 uint8_t u8Reserved1;
1226 /** Number of the page. */
1227 uint8_t u8PageNumber;
1228 /** Type of the page. */
1229 uint8_t u8PageType;
1230 /** Extended page length. */
1231 uint16_t u16ExtPageLength;
1232 /** Extended page type. */
1233 uint8_t u8ExtPageType;
1234 /** Reserved */
1235 uint8_t u8Reserved2;
1236} MptExtendedConfigurationPageHeader, *PMptExtendedConfigurationPageHeader;
1237AssertCompileSize(MptExtendedConfigurationPageHeader, 8);
1238
1239/**
1240 * Manufacturing page 0. - Readonly.
1241 */
1242typedef struct MptConfigurationPageManufacturing0 /**< @todo r=bird: This and a series of other structs could save a lot of 'u.' typing by promoting the inner 'u' union... */
1243{
1244 /** Union. */
1245 union
1246 {
1247 /** Byte view. */
1248 uint8_t abPageData[76];
1249 /** Field view. */
1250 struct
1251 {
1252 /** The omnipresent header. */
1253 MptConfigurationPageHeader Header;
1254 /** Name of the chip. */
1255 uint8_t abChipName[16];
1256 /** Chip revision. */
1257 uint8_t abChipRevision[8];
1258 /** Board name. */
1259 uint8_t abBoardName[16];
1260 /** Board assembly. */
1261 uint8_t abBoardAssembly[16];
1262 /** Board tracer number. */
1263 uint8_t abBoardTracerNumber[16];
1264 } fields;
1265 } u;
1266} MptConfigurationPageManufacturing0, *PMptConfigurationPageManufacturing0;
1267AssertCompileSize(MptConfigurationPageManufacturing0, 76);
1268
1269/**
1270 * Manufacturing page 1. - Readonly Persistent.
1271 */
1272typedef struct MptConfigurationPageManufacturing1
1273{
1274 /** Union */
1275 union
1276 {
1277 /** Byte view */
1278 uint8_t abPageData[260];
1279 /** Field view */
1280 struct
1281 {
1282 /** The omnipresent header. */
1283 MptConfigurationPageHeader Header;
1284 /** VPD info - don't know what belongs here so all zero. */
1285 uint8_t abVPDInfo[256];
1286 } fields;
1287 } u;
1288} MptConfigurationPageManufacturing1, *PMptConfigurationPageManufacturing1;
1289AssertCompileSize(MptConfigurationPageManufacturing1, 260);
1290
1291/**
1292 * Manufacturing page 2. - Readonly.
1293 */
1294typedef struct MptConfigurationPageManufacturing2
1295{
1296 /** Union. */
1297 union
1298 {
1299 /** Byte view. */
1300 uint8_t abPageData[8];
1301 /** Field view. */
1302 struct
1303 {
1304 /** The omnipresent header. */
1305 MptConfigurationPageHeader Header;
1306 /** PCI Device ID. */
1307 uint16_t u16PCIDeviceID;
1308 /** PCI Revision ID. */
1309 uint8_t u8PCIRevisionID;
1310 /** Reserved. */
1311 uint8_t u8Reserved;
1312 /** Hardware specific settings... */
1313 } fields;
1314 } u;
1315} MptConfigurationPageManufacturing2, *PMptConfigurationPageManufacturing2;
1316AssertCompileSize(MptConfigurationPageManufacturing2, 8);
1317
1318/**
1319 * Manufacturing page 3. - Readonly.
1320 */
1321typedef struct MptConfigurationPageManufacturing3
1322{
1323 /** Union. */
1324 union
1325 {
1326 /** Byte view. */
1327 uint8_t abPageData[8];
1328 /** Field view. */
1329 struct
1330 {
1331 /** The omnipresent header. */
1332 MptConfigurationPageHeader Header;
1333 /** PCI Device ID. */
1334 uint16_t u16PCIDeviceID;
1335 /** PCI Revision ID. */
1336 uint8_t u8PCIRevisionID;
1337 /** Reserved. */
1338 uint8_t u8Reserved;
1339 /** Chip specific settings... */
1340 } fields;
1341 } u;
1342} MptConfigurationPageManufacturing3, *PMptConfigurationPageManufacturing3;
1343AssertCompileSize(MptConfigurationPageManufacturing3, 8);
1344
1345/**
1346 * Manufacturing page 4. - Readonly.
1347 */
1348typedef struct MptConfigurationPageManufacturing4
1349{
1350 /** Union. */
1351 union
1352 {
1353 /** Byte view. */
1354 uint8_t abPageData[84];
1355 /** Field view. */
1356 struct
1357 {
1358 /** The omnipresent header. */
1359 MptConfigurationPageHeader Header;
1360 /** Reserved. */
1361 uint32_t u32Reserved;
1362 /** InfoOffset0. */
1363 uint8_t u8InfoOffset0;
1364 /** Info size. */
1365 uint8_t u8InfoSize0;
1366 /** InfoOffset1. */
1367 uint8_t u8InfoOffset1;
1368 /** Info size. */
1369 uint8_t u8InfoSize1;
1370 /** Size of the inquiry data. */
1371 uint8_t u8InquirySize;
1372 /** Reserved. */
1373 uint8_t abReserved[3];
1374 /** Inquiry data. */
1375 uint8_t abInquiryData[56];
1376 /** IS volume settings. */
1377 uint32_t u32ISVolumeSettings;
1378 /** IME volume settings. */
1379 uint32_t u32IMEVolumeSettings;
1380 /** IM volume settings. */
1381 uint32_t u32IMVolumeSettings;
1382 } fields;
1383 } u;
1384} MptConfigurationPageManufacturing4, *PMptConfigurationPageManufacturing4;
1385AssertCompileSize(MptConfigurationPageManufacturing4, 84);
1386
1387/**
1388 * Manufacturing page 5 - Readonly.
1389 */
1390#pragma pack(1) /* u64BaseWWID is at offset 4, which isn't natural for uint64_t. */
1391typedef struct MptConfigurationPageManufacturing5
1392{
1393 /** Union. */
1394 union
1395 {
1396 /** Byte view. */
1397 uint8_t abPageData[88];
1398 /** Field view. */
1399 struct
1400 {
1401 /** The omnipresent header. */
1402 MptConfigurationPageHeader Header;
1403 /** Base WWID.
1404 * @note Not aligned on 8-byte boundrary */
1405 uint64_t u64BaseWWID;
1406 /** Flags */
1407 uint8_t u8Flags;
1408 /** Number of ForceWWID fields in this page. */
1409 uint8_t u8NumForceWWID;
1410 /** Reserved */
1411 uint16_t u16Reserved;
1412 /** Reserved */
1413 uint32_t au32Reserved[2];
1414 /** ForceWWID entries Maximum of 8 because the SAS controller doesn't has more */
1415 uint64_t au64ForceWWID[8];
1416 } fields;
1417 } u;
1418} MptConfigurationPageManufacturing5, *PMptConfigurationPageManufacturing5;
1419#pragma pack()
1420AssertCompileSize(MptConfigurationPageManufacturing5, 24+64);
1421
1422/**
1423 * Manufacturing page 6 - Readonly.
1424 */
1425typedef struct MptConfigurationPageManufacturing6
1426{
1427 /** Union. */
1428 union
1429 {
1430 /** Byte view. */
1431 uint8_t abPageData[4];
1432 /** Field view. */
1433 struct
1434 {
1435 /** The omnipresent header. */
1436 MptConfigurationPageHeader Header;
1437 /** Product specific data - 0 for now */
1438 } fields;
1439 } u;
1440} MptConfigurationPageManufacturing6, *PMptConfigurationPageManufacturing6;
1441AssertCompileSize(MptConfigurationPageManufacturing6, 4);
1442
1443/**
1444 * Manufacutring page 7 - PHY element.
1445 */
1446typedef struct MptConfigurationPageManufacturing7PHY
1447{
1448 /** Pinout */
1449 uint32_t u32Pinout;
1450 /** Connector name */
1451 uint8_t szConnector[16];
1452 /** Location */
1453 uint8_t u8Location;
1454 /** reserved */
1455 uint8_t u8Reserved;
1456 /** Slot */
1457 uint16_t u16Slot;
1458} MptConfigurationPageManufacturing7PHY, *PMptConfigurationPageManufacturing7PHY;
1459AssertCompileSize(MptConfigurationPageManufacturing7PHY, 24);
1460
1461/**
1462 * Manufacturing page 7 - Readonly.
1463 */
1464typedef struct MptConfigurationPageManufacturing7
1465{
1466 /** Union. */
1467 union
1468 {
1469 /** Byte view. */
1470 uint8_t abPageData[1];
1471 /** Field view. */
1472 struct
1473 {
1474 /** The omnipresent header. */
1475 MptConfigurationPageHeader Header;
1476 /** Reserved */
1477 uint32_t au32Reserved[2];
1478 /** Flags */
1479 uint32_t u32Flags;
1480 /** Enclosure name */
1481 uint8_t szEnclosureName[16];
1482 /** Number of PHYs */
1483 uint8_t u8NumPhys;
1484 /** Reserved */
1485 uint8_t au8Reserved[3];
1486 /** PHY list for the SAS controller - variable depending on the number of ports */
1487 MptConfigurationPageManufacturing7PHY aPHY[1];
1488 } fields;
1489 } u;
1490} MptConfigurationPageManufacturing7, *PMptConfigurationPageManufacturing7;
1491AssertCompileSize(MptConfigurationPageManufacturing7, 36+sizeof(MptConfigurationPageManufacturing7PHY));
1492
1493#define LSILOGICSCSI_MANUFACTURING7_GET_SIZE(ports) (sizeof(MptConfigurationPageManufacturing7) + ((ports) - 1) * sizeof(MptConfigurationPageManufacturing7PHY))
1494
1495/** Flags for the flags field */
1496#define LSILOGICSCSI_MANUFACTURING7_FLAGS_USE_PROVIDED_INFORMATION RT_BIT(0)
1497
1498/** Flags for the pinout field */
1499#define LSILOGICSCSI_MANUFACTURING7_PINOUT_UNKNOWN RT_BIT(0)
1500#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8482 RT_BIT(1)
1501#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE1 RT_BIT(8)
1502#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE2 RT_BIT(9)
1503#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE3 RT_BIT(10)
1504#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8470_LANE4 RT_BIT(11)
1505#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE1 RT_BIT(16)
1506#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE2 RT_BIT(17)
1507#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE3 RT_BIT(18)
1508#define LSILOGICSCSI_MANUFACTURING7_PINOUT_SFF8484_LANE4 RT_BIT(19)
1509
1510/** Flags for the location field */
1511#define LSILOGICSCSI_MANUFACTURING7_LOCATION_UNKNOWN 0x01
1512#define LSILOGICSCSI_MANUFACTURING7_LOCATION_INTERNAL 0x02
1513#define LSILOGICSCSI_MANUFACTURING7_LOCATION_EXTERNAL 0x04
1514#define LSILOGICSCSI_MANUFACTURING7_LOCATION_SWITCHABLE 0x08
1515#define LSILOGICSCSI_MANUFACTURING7_LOCATION_AUTO 0x10
1516#define LSILOGICSCSI_MANUFACTURING7_LOCATION_NOT_PRESENT 0x20
1517#define LSILOGICSCSI_MANUFACTURING7_LOCATION_NOT_CONNECTED 0x80
1518
1519/**
1520 * Manufacturing page 8 - Readonly.
1521 */
1522typedef struct MptConfigurationPageManufacturing8
1523{
1524 /** Union. */
1525 union
1526 {
1527 /** Byte view. */
1528 uint8_t abPageData[4];
1529 /** Field view. */
1530 struct
1531 {
1532 /** The omnipresent header. */
1533 MptConfigurationPageHeader Header;
1534 /** Product specific information */
1535 } fields;
1536 } u;
1537} MptConfigurationPageManufacturing8, *PMptConfigurationPageManufacturing8;
1538AssertCompileSize(MptConfigurationPageManufacturing8, 4);
1539
1540/**
1541 * Manufacturing page 9 - Readonly.
1542 */
1543typedef struct MptConfigurationPageManufacturing9
1544{
1545 /** Union. */
1546 union
1547 {
1548 /** Byte view. */
1549 uint8_t abPageData[4];
1550 /** Field view. */
1551 struct
1552 {
1553 /** The omnipresent header. */
1554 MptConfigurationPageHeader Header;
1555 /** Product specific information */
1556 } fields;
1557 } u;
1558} MptConfigurationPageManufacturing9, *PMptConfigurationPageManufacturing9;
1559AssertCompileSize(MptConfigurationPageManufacturing9, 4);
1560
1561/**
1562 * Manufacturing page 10 - Readonly.
1563 */
1564typedef struct MptConfigurationPageManufacturing10
1565{
1566 /** Union. */
1567 union
1568 {
1569 /** Byte view. */
1570 uint8_t abPageData[4];
1571 /** Field view. */
1572 struct
1573 {
1574 /** The omnipresent header. */
1575 MptConfigurationPageHeader Header;
1576 /** Product specific information */
1577 } fields;
1578 } u;
1579} MptConfigurationPageManufacturing10, *PMptConfigurationPageManufacturing10;
1580AssertCompileSize(MptConfigurationPageManufacturing10, 4);
1581
1582/**
1583 * IO Unit page 0. - Readonly.
1584 */
1585#pragma pack(1) /* u64UniqueIdentifier is at offset 4, which isn't natural for uint64_t. */
1586typedef struct MptConfigurationPageIOUnit0
1587{
1588 /** Union. */
1589 union
1590 {
1591 /** Byte view. */
1592 uint8_t abPageData[12];
1593 /** Field view. */
1594 struct
1595 {
1596 /** The omnipresent header. */
1597 MptConfigurationPageHeader Header;
1598 /** A unique identifier. */
1599 uint64_t u64UniqueIdentifier;
1600 } fields;
1601 } u;
1602} MptConfigurationPageIOUnit0, *PMptConfigurationPageIOUnit0;
1603#pragma pack()
1604AssertCompileSize(MptConfigurationPageIOUnit0, 12);
1605
1606/**
1607 * IO Unit page 1. - Read/Write.
1608 */
1609typedef struct MptConfigurationPageIOUnit1
1610{
1611 /** Union. */
1612 union
1613 {
1614 /** Byte view. */
1615 uint8_t abPageData[8];
1616 /** Field view. */
1617 struct
1618 {
1619 /** The omnipresent header. */
1620 MptConfigurationPageHeader Header;
1621 /** Flag whether this is a single function PCI device. */
1622 unsigned fSingleFunction: 1;
1623 /** Flag whether all possible paths to a device are mapped. */
1624 unsigned fAllPathsMapped: 1;
1625 /** Reserved. */
1626 unsigned u4Reserved: 4;
1627 /** Flag whether all RAID functionality is disabled. */
1628 unsigned fIntegratedRAIDDisabled: 1;
1629 /** Flag whether 32bit PCI accesses are forced. */
1630 unsigned f32BitAccessForced: 1;
1631 /** Reserved. */
1632 unsigned abReserved: 24;
1633 } fields;
1634 } u;
1635} MptConfigurationPageIOUnit1, *PMptConfigurationPageIOUnit1;
1636AssertCompileSize(MptConfigurationPageIOUnit1, 8);
1637
1638/**
1639 * Adapter Ordering.
1640 */
1641typedef struct MptConfigurationPageIOUnit2AdapterOrdering
1642{
1643 /** PCI bus number. */
1644 unsigned u8PCIBusNumber: 8;
1645 /** PCI device and function number. */
1646 unsigned u8PCIDevFn: 8;
1647 /** Flag whether the adapter is embedded. */
1648 unsigned fAdapterEmbedded: 1;
1649 /** Flag whether the adapter is enabled. */
1650 unsigned fAdapterEnabled: 1;
1651 /** Reserved. */
1652 unsigned u6Reserved: 6;
1653 /** Reserved. */
1654 unsigned u8Reserved: 8;
1655} MptConfigurationPageIOUnit2AdapterOrdering, *PMptConfigurationPageIOUnit2AdapterOrdering;
1656AssertCompileSize(MptConfigurationPageIOUnit2AdapterOrdering, 4);
1657
1658/**
1659 * IO Unit page 2. - Read/Write.
1660 */
1661typedef struct MptConfigurationPageIOUnit2
1662{
1663 /** Union. */
1664 union
1665 {
1666 /** Byte view. */
1667 uint8_t abPageData[28];
1668 /** Field view. */
1669 struct
1670 {
1671 /** The omnipresent header. */
1672 MptConfigurationPageHeader Header;
1673 /** Reserved. */
1674 unsigned fReserved: 1;
1675 /** Flag whether Pause on error is enabled. */
1676 unsigned fPauseOnError: 1;
1677 /** Flag whether verbose mode is enabled. */
1678 unsigned fVerboseModeEnabled: 1;
1679 /** Set to disable color video. */
1680 unsigned fDisableColorVideo: 1;
1681 /** Flag whether int 40h is hooked. */
1682 unsigned fNotHookInt40h: 1;
1683 /** Reserved. */
1684 unsigned u3Reserved: 3;
1685 /** Reserved. */
1686 unsigned abReserved: 24;
1687 /** BIOS version. */
1688 uint32_t u32BIOSVersion;
1689 /** Adapter ordering. */
1690 MptConfigurationPageIOUnit2AdapterOrdering aAdapterOrder[4];
1691 } fields;
1692 } u;
1693} MptConfigurationPageIOUnit2, *PMptConfigurationPageIOUnit2;
1694AssertCompileSize(MptConfigurationPageIOUnit2, 28);
1695
1696/*
1697 * IO Unit page 3. - Read/Write.
1698 */
1699typedef struct MptConfigurationPageIOUnit3
1700{
1701 /** Union. */
1702 union
1703 {
1704 /** Byte view. */
1705 uint8_t abPageData[8];
1706 /** Field view. */
1707 struct
1708 {
1709 /** The omnipresent header. */
1710 MptConfigurationPageHeader Header;
1711 /** Number of GPIO values. */
1712 uint8_t u8GPIOCount;
1713 /** Reserved. */
1714 uint8_t abReserved[3];
1715 } fields;
1716 } u;
1717} MptConfigurationPageIOUnit3, *PMptConfigurationPageIOUnit3;
1718AssertCompileSize(MptConfigurationPageIOUnit3, 8);
1719
1720/*
1721 * IO Unit page 4. - Readonly for everyone except the BIOS.
1722 */
1723typedef struct MptConfigurationPageIOUnit4
1724{
1725 /** Union. */
1726 union
1727 {
1728 /** Byte view. */
1729 uint8_t abPageData[20];
1730 /** Field view. */
1731 struct
1732 {
1733 /** The omnipresent header. */
1734 MptConfigurationPageHeader Header;
1735 /** Reserved */
1736 uint32_t u32Reserved;
1737 /** SG entry describing the Firmware location. */
1738 MptSGEntrySimple64 FWImageSGE;
1739 } fields;
1740 } u;
1741} MptConfigurationPageIOUnit4, *PMptConfigurationPageIOUnit4;
1742AssertCompileSize(MptConfigurationPageIOUnit4, 20);
1743
1744/**
1745 * IOC page 0. - Readonly
1746 */
1747typedef struct MptConfigurationPageIOC0
1748{
1749 /** Union. */
1750 union
1751 {
1752 /** Byte view. */
1753 uint8_t abPageData[28];
1754 /** Field view. */
1755 struct
1756 {
1757 /** The omnipresent header. */
1758 MptConfigurationPageHeader Header;
1759 /** Total amount of NV memory in bytes. */
1760 uint32_t u32TotalNVStore;
1761 /** Number of free bytes in the NV store. */
1762 uint32_t u32FreeNVStore;
1763 /** PCI vendor ID. */
1764 uint16_t u16VendorId;
1765 /** PCI device ID. */
1766 uint16_t u16DeviceId;
1767 /** PCI revision ID. */
1768 uint8_t u8RevisionId;
1769 /** Reserved. */
1770 uint8_t abReserved[3];
1771 /** PCI class code. */
1772 uint32_t u32ClassCode;
1773 /** Subsystem vendor Id. */
1774 uint16_t u16SubsystemVendorId;
1775 /** Subsystem Id. */
1776 uint16_t u16SubsystemId;
1777 } fields;
1778 } u;
1779} MptConfigurationPageIOC0, *PMptConfigurationPageIOC0;
1780AssertCompileSize(MptConfigurationPageIOC0, 28);
1781
1782/**
1783 * IOC page 1. - Read/Write
1784 */
1785typedef struct MptConfigurationPageIOC1
1786{
1787 /** Union. */
1788 union
1789 {
1790 /** Byte view. */
1791 uint8_t abPageData[16];
1792 /** Field view. */
1793 struct
1794 {
1795 /** The omnipresent header. */
1796 MptConfigurationPageHeader Header;
1797 /** Flag whether reply coalescing is enabled. */
1798 unsigned fReplyCoalescingEnabled: 1;
1799 /** Reserved. */
1800 unsigned u31Reserved: 31;
1801 /** Coalescing Timeout in microseconds. */
1802 unsigned u32CoalescingTimeout: 32;
1803 /** Coalescing depth. */
1804 unsigned u8CoalescingDepth: 8;
1805 /** Reserved. */
1806 unsigned u8Reserved0: 8;
1807 unsigned u8Reserved1: 8;
1808 unsigned u8Reserved2: 8;
1809 } fields;
1810 } u;
1811} MptConfigurationPageIOC1, *PMptConfigurationPageIOC1;
1812AssertCompileSize(MptConfigurationPageIOC1, 16);
1813
1814/**
1815 * IOC page 2. - Readonly
1816 */
1817typedef struct MptConfigurationPageIOC2
1818{
1819 /** Union. */
1820 union
1821 {
1822 /** Byte view. */
1823 uint8_t abPageData[12];
1824 /** Field view. */
1825 struct
1826 {
1827 /** The omnipresent header. */
1828 MptConfigurationPageHeader Header;
1829 /** Flag whether striping is supported. */
1830 unsigned fStripingSupported: 1;
1831 /** Flag whether enhanced mirroring is supported. */
1832 unsigned fEnhancedMirroringSupported: 1;
1833 /** Flag whether mirroring is supported. */
1834 unsigned fMirroringSupported: 1;
1835 /** Reserved. */
1836 unsigned u26Reserved: 26;
1837 /** Flag whether SES is supported. */
1838 unsigned fSESSupported: 1;
1839 /** Flag whether SAF-TE is supported. */
1840 unsigned fSAFTESupported: 1;
1841 /** Flag whether cross channel volumes are supported. */
1842 unsigned fCrossChannelVolumesSupported: 1;
1843 /** Number of active integrated RAID volumes. */
1844 unsigned u8NumActiveVolumes: 8;
1845 /** Maximum number of integrated RAID volumes supported. */
1846 unsigned u8MaxVolumes: 8;
1847 /** Number of active integrated RAID physical disks. */
1848 unsigned u8NumActivePhysDisks: 8;
1849 /** Maximum number of integrated RAID physical disks supported. */
1850 unsigned u8MaxPhysDisks: 8;
1851 /** RAID volumes... - not supported. */
1852 } fields;
1853 } u;
1854} MptConfigurationPageIOC2, *PMptConfigurationPageIOC2;
1855AssertCompileSize(MptConfigurationPageIOC2, 12);
1856
1857/**
1858 * IOC page 3. - Readonly
1859 */
1860typedef struct MptConfigurationPageIOC3
1861{
1862 /** Union. */
1863 union
1864 {
1865 /** Byte view. */
1866 uint8_t abPageData[8];
1867 /** Field view. */
1868 struct
1869 {
1870 /** The omnipresent header. */
1871 MptConfigurationPageHeader Header;
1872 /** Number of active integrated RAID physical disks. */
1873 uint8_t u8NumPhysDisks;
1874 /** Reserved. */
1875 uint8_t abReserved[3];
1876 } fields;
1877 } u;
1878} MptConfigurationPageIOC3, *PMptConfigurationPageIOC3;
1879AssertCompileSize(MptConfigurationPageIOC3, 8);
1880
1881/**
1882 * IOC page 4. - Read/Write
1883 */
1884typedef struct MptConfigurationPageIOC4
1885{
1886 /** Union. */
1887 union
1888 {
1889 /** Byte view. */
1890 uint8_t abPageData[8];
1891 /** Field view. */
1892 struct
1893 {
1894 /** The omnipresent header. */
1895 MptConfigurationPageHeader Header;
1896 /** Number of SEP entries in this page. */
1897 uint8_t u8ActiveSEP;
1898 /** Maximum number of SEp entries supported. */
1899 uint8_t u8MaxSEP;
1900 /** Reserved. */
1901 uint16_t u16Reserved;
1902 /** SEP entries... - not supported. */
1903 } fields;
1904 } u;
1905} MptConfigurationPageIOC4, *PMptConfigurationPageIOC4;
1906AssertCompileSize(MptConfigurationPageIOC4, 8);
1907
1908/**
1909 * IOC page 6. - Read/Write
1910 */
1911typedef struct MptConfigurationPageIOC6
1912{
1913 /** Union. */
1914 union
1915 {
1916 /** Byte view. */
1917 uint8_t abPageData[60];
1918 /** Field view. */
1919 struct
1920 {
1921 /** The omnipresent header. */
1922 MptConfigurationPageHeader Header;
1923 uint32_t u32CapabilitiesFlags;
1924 uint8_t u8MaxDrivesIS;
1925 uint8_t u8MaxDrivesIM;
1926 uint8_t u8MaxDrivesIME;
1927 uint8_t u8Reserved1;
1928 uint8_t u8MinDrivesIS;
1929 uint8_t u8MinDrivesIM;
1930 uint8_t u8MinDrivesIME;
1931 uint8_t u8Reserved2;
1932 uint8_t u8MaxGlobalHotSpares;
1933 uint8_t u8Reserved3;
1934 uint16_t u16Reserved4;
1935 uint32_t u32Reserved5;
1936 uint32_t u32SupportedStripeSizeMapIS;
1937 uint32_t u32SupportedStripeSizeMapIME;
1938 uint32_t u32Reserved6;
1939 uint8_t u8MetadataSize;
1940 uint8_t u8Reserved7;
1941 uint16_t u16Reserved8;
1942 uint16_t u16MaxBadBlockTableEntries;
1943 uint16_t u16Reserved9;
1944 uint16_t u16IRNvsramUsage;
1945 uint16_t u16Reserved10;
1946 uint32_t u32IRNvsramVersion;
1947 uint32_t u32Reserved11;
1948 } fields;
1949 } u;
1950} MptConfigurationPageIOC6, *PMptConfigurationPageIOC6;
1951AssertCompileSize(MptConfigurationPageIOC6, 60);
1952
1953/**
1954 * BIOS page 1 - Read/write.
1955 */
1956typedef struct MptConfigurationPageBIOS1
1957{
1958 /** Union. */
1959 union
1960 {
1961 /** Byte view. */
1962 uint8_t abPageData[48];
1963 /** Field view. */
1964 struct
1965 {
1966 /** The omnipresent header. */
1967 MptConfigurationPageHeader Header;
1968 /** BIOS options */
1969 uint32_t u32BiosOptions;
1970 /** IOC settings */
1971 uint32_t u32IOCSettings;
1972 /** Reserved */
1973 uint32_t u32Reserved;
1974 /** Device settings */
1975 uint32_t u32DeviceSettings;
1976 /** Number of devices */
1977 uint16_t u16NumberOfDevices;
1978 /** Expander spinup */
1979 uint8_t u8ExpanderSpinup;
1980 /** Reserved */
1981 uint8_t u8Reserved;
1982 /** I/O timeout of block devices without removable media */
1983 uint16_t u16IOTimeoutBlockDevicesNonRM;
1984 /** I/O timeout sequential */
1985 uint16_t u16IOTimeoutSequential;
1986 /** I/O timeout other */
1987 uint16_t u16IOTimeoutOther;
1988 /** I/O timeout of block devices with removable media */
1989 uint16_t u16IOTimeoutBlockDevicesRM;
1990 } fields;
1991 } u;
1992} MptConfigurationPageBIOS1, *PMptConfigurationPageBIOS1;
1993AssertCompileSize(MptConfigurationPageBIOS1, 48);
1994
1995#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_DISABLE RT_BIT(0)
1996#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_SCAN_FROM_HIGH_TO_LOW RT_BIT(1)
1997#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_EXTENDED_SAS_SUPPORT RT_BIT(8)
1998#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_EXTENDED_FC_SUPPORT RT_BIT(9)
1999#define LSILOGICSCSI_BIOS1_BIOSOPTIONS_BIOS_EXTENDED_SPI_SUPPORT RT_BIT(10)
2000
2001#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ALTERNATE_CHS RT_BIT(3)
2002
2003#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_SET(x) ((x) << 4)
2004#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_DISABLED 0x00
2005#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_BIOS_ONLY 0x01
2006#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_OS_ONLY 0x02
2007#define LSILOGICSCSI_BIOS1_IOCSETTINGS_ADAPTER_SUPPORT_BOT 0x03
2008
2009#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_MEDIA_SET(x) ((x) << 6)
2010#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_MEDIA_NO_INT13H 0x00
2011#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_BOOT_MEDIA_INT13H 0x01
2012#define LSILOGICSCSI_BIOS1_IOCSETTINGS_REMOVABLE_MEDIA_INT13H 0x02
2013
2014#define LSILOGICSCSI_BIOS1_IOCSETTINGS_SPINUP_DELAY_SET(x) ((x & 0xF) << 8)
2015#define LSILOGICSCSI_BIOS1_IOCSETTINGS_SPINUP_DELAY_GET(x) ((x >> 8) & 0x0F)
2016#define LSILOGICSCSI_BIOS1_IOCSETTINGS_MAX_TARGET_SPINUP_SET(x) ((x & 0xF) << 12)
2017#define LSILOGICSCSI_BIOS1_IOCSETTINGS_MAX_TARGET_SPINUP_GET(x) ((x >> 12) & 0x0F)
2018
2019#define LSILOGICSCSI_BIOS1_IOCSETTINGS_BOOT_PREFERENCE_SET(x) (((x) & 0x3) << 16)
2020#define LSILOGICSCSI_BIOS1_IOCSETTINGS_BOOT_PREFERENCE_ENCLOSURE 0x0
2021#define LSILOGICSCSI_BIOS1_IOCSETTINGS_BOOT_PREFERENCE_SAS_ADDRESS 0x1
2022
2023#define LSILOGICSCSI_BIOS1_IOCSETTINGS_DIRECT_ATTACH_SPINUP_MODE_ALL RT_BIT(18)
2024#define LSILOGICSCSI_BIOS1_IOCSETTINGS_AUTO_PORT_ENABLE RT_BIT(19)
2025
2026#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_REPLY_DELAY_SET(x) (((x) & 0xF) << 20)
2027#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_REPLY_DELAY_GET(x) ((x >> 20) & 0x0F)
2028
2029#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_SPINUP_DELAY_SET(x) (((x) & 0xF) << 24)
2030#define LSILOGICSCSI_BIOS1_IOCSETTINGS_PORT_ENABLE_SPINUP_DELAY_GET(x) ((x >> 24) & 0x0F)
2031
2032#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS RT_BIT(0)
2033#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS_FOR_NON_REMOVABLE_DEVICES RT_BIT(1)
2034#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS_FOR_REMOVABLE_DEVICES RT_BIT(2)
2035#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_LUN_SCANS2 RT_BIT(3)
2036#define LSILOGICSCSI_BIOS1_DEVICESETTINGS_DISABLE_SMART_POLLING RT_BIT(4)
2037
2038#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_SPINUP_DELAY_SET(x) ((x) & 0x0F)
2039#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_SPINUP_DELAY_GET(x) ((x) & 0x0F)
2040#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_MAX_SPINUP_DELAY_SET(x) (((x) & 0x0F) << 4)
2041#define LSILOGICSCSI_BIOS1_EXPANDERSPINUP_MAX_SPINUP_DELAY_GET(x) ((x >> 4) & 0x0F)
2042
2043/**
2044 * BIOS page 2 - Read/write.
2045 */
2046typedef struct MptConfigurationPageBIOS2
2047{
2048 /** Union. */
2049 union
2050 {
2051 /** Byte view. */
2052 uint8_t abPageData[384];
2053 /** Field view. */
2054 struct
2055 {
2056 /** The omnipresent header. */
2057 MptConfigurationPageHeader Header;
2058 /** Reserved */
2059 uint32_t au32Reserved[6];
2060 /** Format of the boot device field. */
2061 uint8_t u8BootDeviceForm;
2062 /** Previous format of the boot device field. */
2063 uint8_t u8PrevBootDeviceForm;
2064 /** Reserved */
2065 uint16_t u16Reserved;
2066 /** Boot device fields - dependent on the format */
2067 union
2068 {
2069 /** Device for AdapterNumber:Bus:Target:LUN */
2070 struct
2071 {
2072 /** Target ID */
2073 uint8_t u8TargetID;
2074 /** Bus */
2075 uint8_t u8Bus;
2076 /** Adapter Number */
2077 uint8_t u8AdapterNumber;
2078 /** Reserved */
2079 uint8_t u8Reserved;
2080 /** Reserved */
2081 uint32_t au32Reserved[3];
2082 /** LUN */
2083 uint32_t aLUN[5];
2084 /** Reserved */
2085 uint32_t au32Reserved2[56];
2086 } AdapterNumberBusTargetLUN;
2087 /** Device for PCIAddress:Bus:Target:LUN */
2088 struct
2089 {
2090 /** Target ID */
2091 uint8_t u8TargetID;
2092 /** Bus */
2093 uint8_t u8Bus;
2094 /** Adapter Number */
2095 uint16_t u16PCIAddress;
2096 /** Reserved */
2097 uint32_t au32Reserved[3];
2098 /** LUN */
2099 uint32_t aLUN[5];
2100 /** Reserved */
2101 uint32_t au32Reserved2[56];
2102 } PCIAddressBusTargetLUN;
2103#if 0 /** @todo r=bird: The u16PCISlotNo member looks like it has the wrong type, but I cannot immediately locate specs and check. */
2104 /** Device for PCISlotNo:Bus:Target:LUN */
2105 struct
2106 {
2107 /** Target ID */
2108 uint8_t u8TargetID;
2109 /** Bus */
2110 uint8_t u8Bus;
2111 /** PCI Slot Number */
2112 uint8_t u16PCISlotNo;
2113 /** Reserved */
2114 uint32_t au32Reserved[3];
2115 /** LUN */
2116 uint32_t aLUN[5];
2117 /** Reserved */
2118 uint32_t au32Reserved2[56];
2119 } PCIAddressBusSlotLUN;
2120#endif
2121 /** Device for FC channel world wide name */
2122 struct
2123 {
2124 /** World wide port name low */
2125 uint32_t u32WorldWidePortNameLow;
2126 /** World wide port name high */
2127 uint32_t u32WorldWidePortNameHigh;
2128 /** Reserved */
2129 uint32_t au32Reserved[3];
2130 /** LUN */
2131 uint32_t aLUN[5];
2132 /** Reserved */
2133 uint32_t au32Reserved2[56];
2134 } FCWorldWideName;
2135 /** Device for FC channel world wide name */
2136 struct
2137 {
2138 /** SAS address */
2139 SASADDRESS SASAddress;
2140 /** Reserved */
2141 uint32_t au32Reserved[3];
2142 /** LUN */
2143 uint32_t aLUN[5];
2144 /** Reserved */
2145 uint32_t au32Reserved2[56];
2146 } SASWorldWideName;
2147 /** Device for Enclosure/Slot */
2148 struct
2149 {
2150 /** Enclosure logical ID */
2151 uint64_t u64EnclosureLogicalID;
2152 /** Reserved */
2153 uint32_t au32Reserved[3];
2154 /** LUN */
2155 uint32_t aLUN[5];
2156 /** Reserved */
2157 uint32_t au32Reserved2[56];
2158 } EnclosureSlot;
2159 } BootDevice;
2160 } fields;
2161 } u;
2162} MptConfigurationPageBIOS2, *PMptConfigurationPageBIOS2;
2163AssertCompileMemberAlignment(MptConfigurationPageBIOS2, u.fields, 8);
2164AssertCompileSize(MptConfigurationPageBIOS2, 384);
2165
2166#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_SET(x) ((x) & 0x0F)
2167#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_FIRST 0x0
2168#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_ADAPTER_BUS_TARGET_LUN 0x1
2169#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_PCIADDR_BUS_TARGET_LUN 0x2
2170#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_PCISLOT_BUS_TARGET_LUN 0x3
2171#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_FC_WWN 0x4
2172#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_SAS_WWN 0x5
2173#define LSILOGICSCSI_BIOS2_BOOT_DEVICE_FORM_ENCLOSURE_SLOT 0x6
2174
2175/**
2176 * BIOS page 4 - Read/Write (Where is 3? - not defined in the spec)
2177 */
2178#pragma pack(1) /* u64ReassignmentBaseWWID starts at offset 4, which isn't normally natural for uint64_t. */
2179typedef struct MptConfigurationPageBIOS4
2180{
2181 /** Union. */
2182 union
2183 {
2184 /** Byte view. */
2185 uint8_t abPageData[12];
2186 /** Field view. */
2187 struct
2188 {
2189 /** The omnipresent header. */
2190 MptConfigurationPageHeader Header;
2191 /** Reassignment Base WWID */
2192 uint64_t u64ReassignmentBaseWWID;
2193 } fields;
2194 } u;
2195} MptConfigurationPageBIOS4, *PMptConfigurationPageBIOS4;
2196#pragma pack()
2197AssertCompileSize(MptConfigurationPageBIOS4, 12);
2198
2199/**
2200 * SCSI-SPI port page 0. - Readonly
2201 */
2202typedef struct MptConfigurationPageSCSISPIPort0
2203{
2204 /** Union. */
2205 union
2206 {
2207 /** Byte view. */
2208 uint8_t abPageData[12];
2209 /** Field view. */
2210 struct
2211 {
2212 /** The omnipresent header. */
2213 MptConfigurationPageHeader Header;
2214 /** Flag whether this port is information unit transfers capable. */
2215 unsigned fInformationUnitTransfersCapable: 1;
2216 /** Flag whether the port is DT (Dual Transfer) capable. */
2217 unsigned fDTCapable: 1;
2218 /** Flag whether the port is QAS (Quick Arbitrate and Select) capable. */
2219 unsigned fQASCapable: 1;
2220 /** Reserved. */
2221 unsigned u5Reserved1: 5;
2222 /** Minimum Synchronous transfer period. */
2223 unsigned u8MinimumSynchronousTransferPeriod: 8;
2224 /** Maximum synchronous offset. */
2225 unsigned u8MaximumSynchronousOffset: 8;
2226 /** Reserved. */
2227 unsigned u5Reserved2: 5;
2228 /** Flag whether indicating the width of the bus - 0 narrow and 1 for wide. */
2229 unsigned fWide: 1;
2230 /** Reserved */
2231 unsigned fReserved: 1;
2232 /** Flag whether the port is AIP (Asynchronous Information Protection) capable. */
2233 unsigned fAIPCapable: 1;
2234 /** Signaling Type. */
2235 unsigned u2SignalingType: 2;
2236 /** Reserved. */
2237 unsigned u30Reserved: 30;
2238 } fields;
2239 } u;
2240} MptConfigurationPageSCSISPIPort0, *PMptConfigurationPageSCSISPIPort0;
2241AssertCompileSize(MptConfigurationPageSCSISPIPort0, 12);
2242
2243/**
2244 * SCSI-SPI port page 1. - Read/Write
2245 */
2246typedef struct MptConfigurationPageSCSISPIPort1
2247{
2248 /** Union. */
2249 union
2250 {
2251 /** Byte view. */
2252 uint8_t abPageData[12];
2253 /** Field view. */
2254 struct
2255 {
2256 /** The omnipresent header. */
2257 MptConfigurationPageHeader Header;
2258 /** The SCSI ID of the port. */
2259 uint8_t u8SCSIID;
2260 /** Reserved. */
2261 uint8_t u8Reserved;
2262 /** Port response IDs Bit mask field. */
2263 uint16_t u16PortResponseIDsBitmask;
2264 /** Value for the on BUS timer. */
2265 uint32_t u32OnBusTimerValue;
2266 } fields;
2267 } u;
2268} MptConfigurationPageSCSISPIPort1, *PMptConfigurationPageSCSISPIPort1;
2269AssertCompileSize(MptConfigurationPageSCSISPIPort1, 12);
2270
2271/**
2272 * Device settings for one device.
2273 */
2274typedef struct MptDeviceSettings
2275{
2276 /** Timeout for I/O in seconds. */
2277 unsigned u8Timeout: 8;
2278 /** Minimum synchronous factor. */
2279 unsigned u8SyncFactor: 8;
2280 /** Flag whether disconnect is enabled. */
2281 unsigned fDisconnectEnable: 1;
2282 /** Flag whether Scan ID is enabled. */
2283 unsigned fScanIDEnable: 1;
2284 /** Flag whether Scan LUNs is enabled. */
2285 unsigned fScanLUNEnable: 1;
2286 /** Flag whether tagged queuing is enabled. */
2287 unsigned fTaggedQueuingEnabled: 1;
2288 /** Flag whether wide is enabled. */
2289 unsigned fWideDisable: 1;
2290 /** Flag whether this device is bootable. */
2291 unsigned fBootChoice: 1;
2292 /** Reserved. */
2293 unsigned u10Reserved: 10;
2294} MptDeviceSettings, *PMptDeviceSettings;
2295AssertCompileSize(MptDeviceSettings, 4);
2296
2297/**
2298 * SCSI-SPI port page 2. - Read/Write for the BIOS
2299 */
2300typedef struct MptConfigurationPageSCSISPIPort2
2301{
2302 /** Union. */
2303 union
2304 {
2305 /** Byte view. */
2306 uint8_t abPageData[76];
2307 /** Field view. */
2308 struct
2309 {
2310 /** The omnipresent header. */
2311 MptConfigurationPageHeader Header;
2312 /** Flag indicating the bus scan order. */
2313 unsigned fBusScanOrderHighToLow: 1;
2314 /** Reserved. */
2315 unsigned fReserved: 1;
2316 /** Flag whether SCSI Bus resets are avoided. */
2317 unsigned fAvoidSCSIBusResets: 1;
2318 /** Flag whether alternate CHS is used. */
2319 unsigned fAlternateCHS: 1;
2320 /** Flag whether termination is disabled. */
2321 unsigned fTerminationDisabled: 1;
2322 /** Reserved. */
2323 unsigned u27Reserved: 27;
2324 /** Host SCSI ID. */
2325 unsigned u4HostSCSIID: 4;
2326 /** Initialize HBA. */
2327 unsigned u2InitializeHBA: 2;
2328 /** Removeable media setting. */
2329 unsigned u2RemovableMediaSetting: 2;
2330 /** Spinup delay. */
2331 unsigned u4SpinupDelay: 4;
2332 /** Negotiating settings. */
2333 unsigned u2NegotitatingSettings: 2;
2334 /** Reserved. */
2335 unsigned u18Reserved: 18;
2336 /** Device Settings. */
2337 MptDeviceSettings aDeviceSettings[16];
2338 } fields;
2339 } u;
2340} MptConfigurationPageSCSISPIPort2, *PMptConfigurationPageSCSISPIPort2;
2341AssertCompileSize(MptConfigurationPageSCSISPIPort2, 76);
2342
2343/**
2344 * SCSI-SPI device page 0. - Readonly
2345 */
2346typedef struct MptConfigurationPageSCSISPIDevice0
2347{
2348 /** Union. */
2349 union
2350 {
2351 /** Byte view. */
2352 uint8_t abPageData[12];
2353 /** Field view. */
2354 struct
2355 {
2356 /** The omnipresent header. */
2357 MptConfigurationPageHeader Header;
2358 /** Negotiated Parameters. */
2359 /** Information Units enabled. */
2360 unsigned fInformationUnitsEnabled: 1;
2361 /** Dual Transfers Enabled. */
2362 unsigned fDTEnabled: 1;
2363 /** QAS enabled. */
2364 unsigned fQASEnabled: 1;
2365 /** Reserved. */
2366 unsigned u5Reserved1: 5;
2367 /** Synchronous Transfer period. */
2368 unsigned u8NegotiatedSynchronousTransferPeriod: 8;
2369 /** Synchronous offset. */
2370 unsigned u8NegotiatedSynchronousOffset: 8;
2371 /** Reserved. */
2372 unsigned u5Reserved2: 5;
2373 /** Width - 0 for narrow and 1 for wide. */
2374 unsigned fWide: 1;
2375 /** Reserved. */
2376 unsigned fReserved: 1;
2377 /** AIP enabled. */
2378 unsigned fAIPEnabled: 1;
2379 /** Flag whether negotiation occurred. */
2380 unsigned fNegotationOccured: 1;
2381 /** Flag whether a SDTR message was rejected. */
2382 unsigned fSDTRRejected: 1;
2383 /** Flag whether a WDTR message was rejected. */
2384 unsigned fWDTRRejected: 1;
2385 /** Flag whether a PPR message was rejected. */
2386 unsigned fPPRRejected: 1;
2387 /** Reserved. */
2388 unsigned u28Reserved: 28;
2389 } fields;
2390 } u;
2391} MptConfigurationPageSCSISPIDevice0, *PMptConfigurationPageSCSISPIDevice0;
2392AssertCompileSize(MptConfigurationPageSCSISPIDevice0, 12);
2393
2394/**
2395 * SCSI-SPI device page 1. - Read/Write
2396 */
2397typedef struct MptConfigurationPageSCSISPIDevice1
2398{
2399 /** Union. */
2400 union
2401 {
2402 /** Byte view. */
2403 uint8_t abPageData[16];
2404 /** Field view. */
2405 struct
2406 {
2407 /** The omnipresent header. */
2408 MptConfigurationPageHeader Header;
2409 /** Requested Parameters. */
2410 /** Information Units enable. */
2411 unsigned fInformationUnitsEnable: 1;
2412 /** Dual Transfers Enable. */
2413 unsigned fDTEnable: 1;
2414 /** QAS enable. */
2415 unsigned fQASEnable: 1;
2416 /** Reserved. */
2417 unsigned u5Reserved1: 5;
2418 /** Synchronous Transfer period. */
2419 unsigned u8NegotiatedSynchronousTransferPeriod: 8;
2420 /** Synchronous offset. */
2421 unsigned u8NegotiatedSynchronousOffset: 8;
2422 /** Reserved. */
2423 unsigned u5Reserved2: 5;
2424 /** Width - 0 for narrow and 1 for wide. */
2425 unsigned fWide: 1;
2426 /** Reserved. */
2427 unsigned fReserved1: 1;
2428 /** AIP enable. */
2429 unsigned fAIPEnable: 1;
2430 /** Reserved. */
2431 unsigned fReserved2: 1;
2432 /** WDTR disallowed. */
2433 unsigned fWDTRDisallowed: 1;
2434 /** SDTR disallowed. */
2435 unsigned fSDTRDisallowed: 1;
2436 /** Reserved. */
2437 unsigned u29Reserved: 29;
2438 } fields;
2439 } u;
2440} MptConfigurationPageSCSISPIDevice1, *PMptConfigurationPageSCSISPIDevice1;
2441AssertCompileSize(MptConfigurationPageSCSISPIDevice1, 16);
2442
2443/**
2444 * SCSI-SPI device page 2. - Read/Write
2445 */
2446typedef struct MptConfigurationPageSCSISPIDevice2
2447{
2448 /** Union. */
2449 union
2450 {
2451 /** Byte view. */
2452 uint8_t abPageData[16];
2453 /** Field view. */
2454 struct
2455 {
2456 /** The omnipresent header. */
2457 MptConfigurationPageHeader Header;
2458 /** Reserved. */
2459 unsigned u4Reserved: 4;
2460 /** ISI enable. */
2461 unsigned fISIEnable: 1;
2462 /** Secondary driver enable. */
2463 unsigned fSecondaryDriverEnable: 1;
2464 /** Reserved. */
2465 unsigned fReserved: 1;
2466 /** Slew create controller. */
2467 unsigned u3SlewRateControler: 3;
2468 /** Primary drive strength controller. */
2469 unsigned u3PrimaryDriveStrengthControl: 3;
2470 /** Secondary drive strength controller. */
2471 unsigned u3SecondaryDriveStrengthControl: 3;
2472 /** Reserved. */
2473 unsigned u12Reserved: 12;
2474 /** XCLKH_ST. */
2475 unsigned fXCLKH_ST: 1;
2476 /** XCLKS_ST. */
2477 unsigned fXCLKS_ST: 1;
2478 /** XCLKH_DT. */
2479 unsigned fXCLKH_DT: 1;
2480 /** XCLKS_DT. */
2481 unsigned fXCLKS_DT: 1;
2482 /** Parity pipe select. */
2483 unsigned u2ParityPipeSelect: 2;
2484 /** Reserved. */
2485 unsigned u30Reserved: 30;
2486 /** Data bit pipeline select. */
2487 unsigned u32DataPipelineSelect: 32;
2488 } fields;
2489 } u;
2490} MptConfigurationPageSCSISPIDevice2, *PMptConfigurationPageSCSISPIDevice2;
2491AssertCompileSize(MptConfigurationPageSCSISPIDevice2, 16);
2492
2493/**
2494 * SCSI-SPI device page 3 (Revision G). - Readonly
2495 */
2496typedef struct MptConfigurationPageSCSISPIDevice3
2497{
2498 /** Union. */
2499 union
2500 {
2501 /** Byte view. */
2502 uint8_t abPageData[1];
2503 /** Field view. */
2504 struct
2505 {
2506 /** The omnipresent header. */
2507 MptConfigurationPageHeader Header;
2508 /** Number of times the IOC rejected a message because it doesn't support the operation. */
2509 uint16_t u16MsgRejectCount;
2510 /** Number of times the SCSI bus entered an invalid operation state. */
2511 uint16_t u16PhaseErrorCount;
2512 /** Number of parity errors. */
2513 uint16_t u16ParityCount;
2514 /** Reserved. */
2515 uint16_t u16Reserved;
2516 } fields;
2517 } u;
2518} MptConfigurationPageSCSISPIDevice3, *PMptConfigurationPageSCSISPIDevice3;
2519AssertCompileSize(MptConfigurationPageSCSISPIDevice3, 12);
2520
2521/**
2522 * PHY entry for the SAS I/O unit page 0
2523 */
2524typedef struct MptConfigurationPageSASIOUnit0PHY
2525{
2526 /** Port number */
2527 uint8_t u8Port;
2528 /** Port flags */
2529 uint8_t u8PortFlags;
2530 /** Phy flags */
2531 uint8_t u8PhyFlags;
2532 /** negotiated link rate */
2533 uint8_t u8NegotiatedLinkRate;
2534 /** Controller phy device info */
2535 uint32_t u32ControllerPhyDeviceInfo;
2536 /** Attached device handle */
2537 uint16_t u16AttachedDevHandle;
2538 /** Controller device handle */
2539 uint16_t u16ControllerDevHandle;
2540 /** Discovery status */
2541 uint32_t u32DiscoveryStatus;
2542} MptConfigurationPageSASIOUnit0PHY, *PMptConfigurationPageSASIOUnit0PHY;
2543AssertCompileSize(MptConfigurationPageSASIOUnit0PHY, 16);
2544
2545/**
2546 * SAS I/O Unit page 0 - Readonly
2547 */
2548typedef struct MptConfigurationPageSASIOUnit0
2549{
2550 /** Union. */
2551 union
2552 {
2553 /** Byte view - variable. */
2554 uint8_t abPageData[1];
2555 /** Field view. */
2556 struct
2557 {
2558 /** The omnipresent header. */
2559 MptExtendedConfigurationPageHeader ExtHeader;
2560 /** Nvdata version default */
2561 uint16_t u16NvdataVersionDefault;
2562 /** Nvdata version persistent */
2563 uint16_t u16NvdataVersionPersistent;
2564 /** Number of physical ports */
2565 uint8_t u8NumPhys;
2566 /** Reserved */
2567 uint8_t au8Reserved[3];
2568 /** Content for each physical port - variable depending on the amount of ports. */
2569 MptConfigurationPageSASIOUnit0PHY aPHY[1];
2570 } fields;
2571 } u;
2572} MptConfigurationPageSASIOUnit0, *PMptConfigurationPageSASIOUnit0;
2573AssertCompileSize(MptConfigurationPageSASIOUnit0, 8+2+2+1+3+sizeof(MptConfigurationPageSASIOUnit0PHY));
2574
2575#define LSILOGICSCSI_SASIOUNIT0_GET_SIZE(ports) (sizeof(MptConfigurationPageSASIOUnit0) + ((ports) - 1) * sizeof(MptConfigurationPageSASIOUnit0PHY))
2576
2577#define LSILOGICSCSI_SASIOUNIT0_PORT_CONFIGURATION_AUTO RT_BIT(0)
2578#define LSILOGICSCSI_SASIOUNIT0_PORT_TARGET_IOC RT_BIT(2)
2579#define LSILOGICSCSI_SASIOUNIT0_PORT_DISCOVERY_IN_STATUS RT_BIT(3)
2580
2581#define LSILOGICSCSI_SASIOUNIT0_PHY_RX_INVERTED RT_BIT(0)
2582#define LSILOGICSCSI_SASIOUNIT0_PHY_TX_INVERTED RT_BIT(1)
2583#define LSILOGICSCSI_SASIOUNIT0_PHY_DISABLED RT_BIT(2)
2584
2585#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_SET(x) ((x) & 0x0F)
2586#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_GET(x) ((x) & 0x0F)
2587#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_UNKNOWN 0x00
2588#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_DISABLED 0x01
2589#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_FAILED 0x02
2590#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_SATA_OOB 0x03
2591#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_15GB 0x08
2592#define LSILOGICSCSI_SASIOUNIT0_NEGOTIATED_RATE_30GB 0x09
2593
2594#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_SET(x) ((x) & 0x3)
2595#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_NO 0x0
2596#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_END 0x1
2597#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_EDGE_EXPANDER 0x2
2598#define LSILOGICSCSI_SASIOUNIT0_DEVICE_TYPE_FANOUT_EXPANDER 0x3
2599
2600#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SATA_HOST RT_BIT(3)
2601#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SMP_INITIATOR RT_BIT(4)
2602#define LSILOGICSCSI_SASIOUNIT0_DEVICE_STP_INITIATOR RT_BIT(5)
2603#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SSP_INITIATOR RT_BIT(6)
2604#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SATA RT_BIT(7)
2605#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SMP_TARGET RT_BIT(8)
2606#define LSILOGICSCSI_SASIOUNIT0_DEVICE_STP_TARGET RT_BIT(9)
2607#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SSP_TARGET RT_BIT(10)
2608#define LSILOGICSCSI_SASIOUNIT0_DEVICE_DIRECT_ATTACHED RT_BIT(11)
2609#define LSILOGICSCSI_SASIOUNIT0_DEVICE_LSI RT_BIT(12)
2610#define LSILOGICSCSI_SASIOUNIT0_DEVICE_ATAPI_DEVICE RT_BIT(13)
2611#define LSILOGICSCSI_SASIOUNIT0_DEVICE_SEP_DEVICE RT_BIT(14)
2612
2613#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_LOOP RT_BIT(0)
2614#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_UNADDRESSABLE RT_BIT(1)
2615#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SAME_SAS_ADDR RT_BIT(2)
2616#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_EXPANDER_ERROR RT_BIT(3)
2617#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SMP_TIMEOUT RT_BIT(4)
2618#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_EXP_ROUTE_OOE RT_BIT(5)
2619#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_EXP_ROUTE_IDX RT_BIT(6)
2620#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SMP_FUNC_FAILED RT_BIT(7)
2621#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SMP_CRC_ERROR RT_BIT(8)
2622#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_SUBTRSCTIVE_LNK RT_BIT(9)
2623#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_TBL_LNK RT_BIT(10)
2624#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_UNSUPPORTED_DEV RT_BIT(11)
2625#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_MAX_SATA_TGTS RT_BIT(12)
2626#define LSILOGICSCSI_SASIOUNIT0_DISCOVERY_STATUS_MULT_CTRLS RT_BIT(13)
2627
2628/**
2629 * PHY entry for the SAS I/O unit page 1
2630 */
2631typedef struct MptConfigurationPageSASIOUnit1PHY
2632{
2633 /** Port number */
2634 uint8_t u8Port;
2635 /** Port flags */
2636 uint8_t u8PortFlags;
2637 /** Phy flags */
2638 uint8_t u8PhyFlags;
2639 /** Max link rate */
2640 uint8_t u8MaxMinLinkRate;
2641 /** Controller phy device info */
2642 uint32_t u32ControllerPhyDeviceInfo;
2643 /** Maximum target port connect time */
2644 uint16_t u16MaxTargetPortConnectTime;
2645 /** Reserved */
2646 uint16_t u16Reserved;
2647} MptConfigurationPageSASIOUnit1PHY, *PMptConfigurationPageSASIOUnit1PHY;
2648AssertCompileSize(MptConfigurationPageSASIOUnit1PHY, 12);
2649
2650/**
2651 * SAS I/O Unit page 1 - Read/Write
2652 */
2653typedef struct MptConfigurationPageSASIOUnit1
2654{
2655 /** Union. */
2656 union
2657 {
2658 /** Byte view - variable. */
2659 uint8_t abPageData[1];
2660 /** Field view. */
2661 struct
2662 {
2663 /** The omnipresent header. */
2664 MptExtendedConfigurationPageHeader ExtHeader;
2665 /** Control flags */
2666 uint16_t u16ControlFlags;
2667 /** maximum number of SATA targets */
2668 uint16_t u16MaxNumSATATargets;
2669 /** additional control flags */
2670 uint16_t u16AdditionalControlFlags;
2671 /** Reserved */
2672 uint16_t u16Reserved;
2673 /** Number of PHYs */
2674 uint8_t u8NumPhys;
2675 /** maximum SATA queue depth */
2676 uint8_t u8SATAMaxQDepth;
2677 /** Delay for reporting missing devices. */
2678 uint8_t u8ReportDeviceMissingDelay;
2679 /** I/O device missing delay */
2680 uint8_t u8IODeviceMissingDelay;
2681 /** Content for each physical port - variable depending on the number of ports */
2682 MptConfigurationPageSASIOUnit1PHY aPHY[1];
2683 } fields;
2684 } u;
2685} MptConfigurationPageSASIOUnit1, *PMptConfigurationPageSASIOUnit1;
2686AssertCompileSize(MptConfigurationPageSASIOUnit1, 8+12+sizeof(MptConfigurationPageSASIOUnit1PHY));
2687
2688#define LSILOGICSCSI_SASIOUNIT1_GET_SIZE(ports) (sizeof(MptConfigurationPageSASIOUnit1) + ((ports) - 1) * sizeof(MptConfigurationPageSASIOUnit1PHY))
2689
2690#define LSILOGICSCSI_SASIOUNIT1_CONTROL_CLEAR_SATA_AFFILIATION RT_BIT(0)
2691#define LSILOGICSCSI_SASIOUNIT1_CONTROL_FIRST_LEVEL_DISCOVERY_ONLY RT_BIT(1)
2692#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SUBTRACTIVE_LNK_ILLEGAL RT_BIT(2)
2693#define LSILOGICSCSI_SASIOUNIT1_CONTROL_IOC_ENABLE_HIGH_PHY RT_BIT(3)
2694#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_FUA_REQUIRED RT_BIT(4)
2695#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_NCQ_REQUIRED RT_BIT(5)
2696#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_SMART_REQUIRED RT_BIT(6)
2697#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_LBA48_REQUIRED RT_BIT(7)
2698#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_INIT_POSTPONED RT_BIT(8)
2699
2700#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SET(x) (((x) & 0x3) << 9)
2701#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_GET(x) (((x) >> 9) & 0x3)
2702#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SAS_AND_SATA 0x00
2703#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SAS 0x01
2704#define LSILOGICSCSI_SASIOUNIT1_CONTROL_DEVICE_SUPPORT_SATA 0x02
2705
2706#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_EXP_ADDR RT_BIT(11)
2707#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_SETTINGS_PRESERV_REQUIRED RT_BIT(12)
2708#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_LIMIT_RATE_15GB RT_BIT(13)
2709#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SATA_LIMIT_RATE_30GB RT_BIT(14)
2710#define LSILOGICSCSI_SASIOUNIT1_CONTROL_SAS_SELF_TEST_ENABLED RT_BIT(15)
2711
2712#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_TBL_LNKS_ALLOW RT_BIT(0)
2713#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_NO_AFFIL RT_BIT(1)
2714#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_SELF_AFFIL RT_BIT(2)
2715#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_OTHER_AFFIL RT_BIT(3)
2716#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_RST_PORT_EN_ONLY RT_BIT(4)
2717#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_HIDE_NON_ZERO_PHYS RT_BIT(5)
2718#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_SATA_ASYNC_NOTIF RT_BIT(6)
2719#define LSILOGICSCSI_SASIOUNIT1_ADDITIONAL_CONTROL_MULT_PORTS_ILL_SAME_DOMAIN RT_BIT(7)
2720
2721#define LSILOGICSCSI_SASIOUNIT1_MISSING_DEVICE_DELAY_UNITS_16_SEC RT_BIT(7)
2722#define LSILOGICSCSI_SASIOUNIT1_MISSING_DEVICE_DELAY_SET(x) ((x) & 0x7F)
2723#define LSILOGICSCSI_SASIOUNIT1_MISSING_DEVICE_DELAY_GET(x) ((x) & 0x7F)
2724
2725#define LSILOGICSCSI_SASIOUNIT1_PORT_CONFIGURATION_AUTO RT_BIT(0)
2726#define LSILOGICSCSI_SASIOUNIT1_PORT_CONFIGURATION_IOC1 RT_BIT(2)
2727
2728#define LSILOGICSCSI_SASIOUNIT1_PHY_RX_INVERT RT_BIT(0)
2729#define LSILOGICSCSI_SASIOUNIT1_PHY_TX_INVERT RT_BIT(1)
2730#define LSILOGICSCSI_SASIOUNIT1_PHY_DISABLE RT_BIT(2)
2731
2732#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MIN_SET(x) ((x) & 0x0F)
2733#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MIN_GET(x) ((x) & 0x0F)
2734#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MAX_SET(x) (((x) & 0x0F) << 4)
2735#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_MAX_GET(x) ((x >> 4) & 0x0F)
2736#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_15GB 0x8
2737#define LSILOGICSCSI_SASIOUNIT1_LINK_RATE_30GB 0x9
2738
2739#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_SET(x) ((x) & 0x3)
2740#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_GET(x) ((x) & 0x3)
2741#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_NO 0x0
2742#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_END 0x1
2743#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_EDGE_EXPANDER 0x2
2744#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_TYPE_FANOUT_EXPANDER 0x3
2745#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SMP_INITIATOR RT_BIT(4)
2746#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_STP_INITIATOR RT_BIT(5)
2747#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SSP_INITIATOR RT_BIT(6)
2748#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SMP_TARGET RT_BIT(8)
2749#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_STP_TARGET RT_BIT(9)
2750#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SSP_TARGET RT_BIT(10)
2751#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_DIRECT_ATTACHED RT_BIT(11)
2752#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_LSI RT_BIT(12)
2753#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_ATAPI RT_BIT(13)
2754#define LSILOGICSCSI_SASIOUNIT1_CTL_PHY_DEVICE_SEP RT_BIT(14)
2755
2756/**
2757 * SAS I/O unit page 2 - Read/Write
2758 */
2759typedef struct MptConfigurationPageSASIOUnit2
2760{
2761 /** Union. */
2762 union
2763 {
2764 /** Byte view - variable. */
2765 uint8_t abPageData[1];
2766 /** Field view. */
2767 struct
2768 {
2769 /** The omnipresent header. */
2770 MptExtendedConfigurationPageHeader ExtHeader;
2771 /** Device numbers per enclosure */
2772 uint8_t u8NumDevsPerEnclosure;
2773 /** Boot device wait time */
2774 uint8_t u8BootDeviceWaitTime;
2775 /** Reserved */
2776 uint16_t u16Reserved;
2777 /** Maximum number of persistent Bus and target ID mappings */
2778 uint16_t u16MaxPersistentIDs;
2779 /** Number of persistent IDs used */
2780 uint16_t u16NumPersistentIDsUsed;
2781 /** Status */
2782 uint8_t u8Status;
2783 /** Flags */
2784 uint8_t u8Flags;
2785 /** Maximum number of physical mapped IDs */
2786 uint16_t u16MaxNumPhysicalMappedIDs;
2787 } fields;
2788 } u;
2789} MptConfigurationPageSASIOUnit2, *PMptConfigurationPageSASIOUnit2;
2790AssertCompileSize(MptConfigurationPageSASIOUnit2, 20);
2791
2792#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_MAP_TBL_FULL RT_BIT(0)
2793#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_MAP_DISABLED RT_BIT(1)
2794#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_ENC_DEV_UNMAPPED RT_BIT(2)
2795#define LSILOGICSCSI_SASIOUNIT2_STATUS_PERSISTENT_DEV_LIMIT_EXCEEDED RT_BIT(3)
2796
2797#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_MAP_DISABLE RT_BIT(0)
2798#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_SET(x) ((x & 0x7) << 1)
2799#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_GET(x) ((x >> 1) & 0x7)
2800#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_NO 0x0
2801#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_DIRECT_ATTACHED 0x1
2802#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_ENC 0x2
2803#define LSILOGICSCSI_SASIOUNIT2_FLAGS_PERSISTENT_PHYS_MAP_MODE_HOST 0x7
2804#define LSILOGICSCSI_SASIOUNIT2_FLAGS_RESERVE_TARGET_ID_ZERO RT_BIT(4)
2805#define LSILOGICSCSI_SASIOUNIT2_FLAGS_START_SLOT_NUMBER_ONE RT_BIT(5)
2806
2807/**
2808 * SAS I/O unit page 3 - Read/Write
2809 */
2810typedef struct MptConfigurationPageSASIOUnit3
2811{
2812 /** Union. */
2813 union
2814 {
2815 /** Byte view - variable. */
2816 uint8_t abPageData[1];
2817 /** Field view. */
2818 struct
2819 {
2820 /** The omnipresent header. */
2821 MptExtendedConfigurationPageHeader ExtHeader;
2822 /** Reserved */
2823 uint32_t u32Reserved;
2824 uint32_t u32MaxInvalidDwordCount;
2825 uint32_t u32InvalidDwordCountTime;
2826 uint32_t u32MaxRunningDisparityErrorCount;
2827 uint32_t u32RunningDisparityErrorTime;
2828 uint32_t u32MaxLossDwordSynchCount;
2829 uint32_t u32LossDwordSynchCountTime;
2830 uint32_t u32MaxPhysResetProblemCount;
2831 uint32_t u32PhyResetProblemTime;
2832 } fields;
2833 } u;
2834} MptConfigurationPageSASIOUnit3, *PMptConfigurationPageSASIOUnit3;
2835AssertCompileSize(MptConfigurationPageSASIOUnit3, 44);
2836
2837/**
2838 * SAS PHY page 0 - Readonly
2839 */
2840#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
2841typedef struct MptConfigurationPageSASPHY0
2842{
2843 /** Union. */
2844 union
2845 {
2846 /** Byte view - variable. */
2847 uint8_t abPageData[1];
2848 /** Field view. */
2849 struct
2850 {
2851 /** The omnipresent header. */
2852 MptExtendedConfigurationPageHeader ExtHeader;
2853 /** Owner dev handle. */
2854 uint16_t u16OwnerDevHandle;
2855 /** Reserved */
2856 uint16_t u16Reserved0;
2857 /** SAS address */
2858 SASADDRESS SASAddress;
2859 /** Attached device handle */
2860 uint16_t u16AttachedDevHandle;
2861 /** Attached phy identifier */
2862 uint8_t u8AttachedPhyIdentifier;
2863 /** Reserved */
2864 uint8_t u8Reserved1;
2865 /** Attached device information */
2866 uint32_t u32AttachedDeviceInfo;
2867 /** Programmed link rate */
2868 uint8_t u8ProgrammedLinkRate;
2869 /** Hardware link rate */
2870 uint8_t u8HwLinkRate;
2871 /** Change count */
2872 uint8_t u8ChangeCount;
2873 /** Flags */
2874 uint8_t u8Flags;
2875 /** Phy information */
2876 uint32_t u32PhyInfo;
2877 } fields;
2878 } u;
2879} MptConfigurationPageSASPHY0, *PMptConfigurationPageSASPHY0;
2880#pragma pack()
2881AssertCompileSize(MptConfigurationPageSASPHY0, 36);
2882
2883#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_SET(x) ((x) & 0x3)
2884#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_GET(x) ((x) & 0x3)
2885#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_NO 0x0
2886#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_END 0x1
2887#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_EDGE_EXPANDER 0x2
2888#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_TYPE_FANOUT_EXPANDER 0x3
2889#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SMP_INITIATOR RT_BIT(4)
2890#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_STP_INITIATOR RT_BIT(5)
2891#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SSP_INITIATOR RT_BIT(6)
2892#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SMP_TARGET RT_BIT(8)
2893#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_STP_TARGET RT_BIT(9)
2894#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SSP_TARGET RT_BIT(10)
2895#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_DIRECT_ATTACHED RT_BIT(11)
2896#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_LSI RT_BIT(12)
2897#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_ATAPI RT_BIT(13)
2898#define LSILOGICSCSI_SASPHY0_DEV_INFO_DEVICE_SEP RT_BIT(14)
2899
2900/**
2901 * SAS PHY page 1 - Readonly
2902 */
2903typedef struct MptConfigurationPageSASPHY1
2904{
2905 /** Union. */
2906 union
2907 {
2908 /** Byte view - variable. */
2909 uint8_t abPageData[1];
2910 /** Field view. */
2911 struct
2912 {
2913 /** The omnipresent header. */
2914 MptExtendedConfigurationPageHeader ExtHeader;
2915 /** Reserved */
2916 uint32_t u32Reserved0;
2917 uint32_t u32InvalidDwordCound;
2918 uint32_t u32RunningDisparityErrorCount;
2919 uint32_t u32LossDwordSynchCount;
2920 uint32_t u32PhyResetProblemCount;
2921 } fields;
2922 } u;
2923} MptConfigurationPageSASPHY1, *PMptConfigurationPageSASPHY1;
2924AssertCompileSize(MptConfigurationPageSASPHY1, 28);
2925
2926/**
2927 * SAS Device page 0 - Readonly
2928 */
2929#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
2930typedef struct MptConfigurationPageSASDevice0
2931{
2932 /** Union. */
2933 union
2934 {
2935 /** Byte view - variable. */
2936 uint8_t abPageData[1];
2937 /** Field view. */
2938 struct
2939 {
2940 /** The omnipresent header. */
2941 MptExtendedConfigurationPageHeader ExtHeader;
2942 /** Slot number */
2943 uint16_t u16Slot;
2944 /** Enclosure handle. */
2945 uint16_t u16EnclosureHandle;
2946 /** SAS address */
2947 SASADDRESS SASAddress;
2948 /** Parent device handle */
2949 uint16_t u16ParentDevHandle;
2950 /** Phy number */
2951 uint8_t u8PhyNum;
2952 /** Access status */
2953 uint8_t u8AccessStatus;
2954 /** Device handle */
2955 uint16_t u16DevHandle;
2956 /** Target ID */
2957 uint8_t u8TargetID;
2958 /** Bus */
2959 uint8_t u8Bus;
2960 /** Device info */
2961 uint32_t u32DeviceInfo;
2962 /** Flags */
2963 uint16_t u16Flags;
2964 /** Physical port */
2965 uint8_t u8PhysicalPort;
2966 /** Reserved */
2967 uint8_t u8Reserved0;
2968 } fields;
2969 } u;
2970} MptConfigurationPageSASDevice0, *PMptConfigurationPageSASDevice0;
2971#pragma pack()
2972AssertCompileSize(MptConfigurationPageSASDevice0, 36);
2973
2974#define LSILOGICSCSI_SASDEVICE0_STATUS_NO_ERRORS (0x00)
2975
2976#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_SET(x) ((x) & 0x3)
2977#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_GET(x) ((x) & 0x3)
2978#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_NO 0x0
2979#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_END 0x1
2980#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_EDGE_EXPANDER 0x2
2981#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_TYPE_FANOUT_EXPANDER 0x3
2982#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SMP_INITIATOR RT_BIT(4)
2983#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_STP_INITIATOR RT_BIT(5)
2984#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SSP_INITIATOR RT_BIT(6)
2985#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SMP_TARGET RT_BIT(8)
2986#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_STP_TARGET RT_BIT(9)
2987#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SSP_TARGET RT_BIT(10)
2988#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_DIRECT_ATTACHED RT_BIT(11)
2989#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_LSI RT_BIT(12)
2990#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_ATAPI RT_BIT(13)
2991#define LSILOGICSCSI_SASDEVICE0_DEV_INFO_DEVICE_SEP RT_BIT(14)
2992
2993#define LSILOGICSCSI_SASDEVICE0_FLAGS_DEVICE_PRESENT (RT_BIT(0))
2994#define LSILOGICSCSI_SASDEVICE0_FLAGS_DEVICE_MAPPED_TO_BUS_AND_TARGET_ID (RT_BIT(1))
2995#define LSILOGICSCSI_SASDEVICE0_FLAGS_DEVICE_MAPPING_PERSISTENT (RT_BIT(2))
2996
2997/**
2998 * SAS Device page 1 - Readonly
2999 */
3000#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
3001typedef struct MptConfigurationPageSASDevice1
3002{
3003 /** Union. */
3004 union
3005 {
3006 /** Byte view - variable. */
3007 uint8_t abPageData[1];
3008 /** Field view. */
3009 struct
3010 {
3011 /** The omnipresent header. */
3012 MptExtendedConfigurationPageHeader ExtHeader;
3013 /** Reserved */
3014 uint32_t u32Reserved0;
3015 /** SAS address */
3016 SASADDRESS SASAddress;
3017 /** Reserved */
3018 uint32_t u32Reserved;
3019 /** Device handle */
3020 uint16_t u16DevHandle;
3021 /** Target ID */
3022 uint8_t u8TargetID;
3023 /** Bus */
3024 uint8_t u8Bus;
3025 /** Initial REgister device FIS */
3026 uint32_t au32InitialRegDeviceFIS[5];
3027 } fields;
3028 } u;
3029} MptConfigurationPageSASDevice1, *PMptConfigurationPageSASDevice1;
3030#pragma pack()
3031AssertCompileSize(MptConfigurationPageSASDevice1, 48);
3032
3033/**
3034 * SAS Device page 2 - Read/Write persistent
3035 */
3036#pragma pack(1) /* Because of a uint64_t inside SASAddress, the struct size would be 24 without packing. */
3037typedef struct MptConfigurationPageSASDevice2
3038{
3039 /** Union. */
3040 union
3041 {
3042 /** Byte view - variable. */
3043 uint8_t abPageData[1];
3044 /** Field view. */
3045 struct
3046 {
3047 /** The omnipresent header. */
3048 MptExtendedConfigurationPageHeader ExtHeader;
3049 /** Physical identifier */
3050 SASADDRESS SASAddress;
3051 /** Enclosure mapping */
3052 uint32_t u32EnclosureMapping;
3053 } fields;
3054 } u;
3055} MptConfigurationPageSASDevice2, *PMptConfigurationPageSASDevice2;
3056#pragma pack()
3057AssertCompileSize(MptConfigurationPageSASDevice2, 20);
3058
3059/**
3060 * A device entitiy containing all pages.
3061 */
3062typedef struct MptSASDevice
3063{
3064 /** Pointer to the next device if any. */
3065 struct MptSASDevice *pNext;
3066 /** Pointer to the previous device if any. */
3067 struct MptSASDevice *pPrev;
3068
3069 MptConfigurationPageSASDevice0 SASDevicePage0;
3070 MptConfigurationPageSASDevice1 SASDevicePage1;
3071 MptConfigurationPageSASDevice2 SASDevicePage2;
3072} MptSASDevice, *PMptSASDevice;
3073
3074/**
3075 * SAS Expander page 0 - Readonly
3076 */
3077#pragma pack(1) /* SASAddress starts at offset 12, which isn't typically natural for uint64_t (inside it). */
3078typedef struct MptConfigurationPageSASExpander0
3079{
3080 /** Union. */
3081 union
3082 {
3083 /** Byte view - variable. */
3084 uint8_t abPageData[1];
3085 /** Field view. */
3086 struct
3087 {
3088 /** The omnipresent header. */
3089 MptExtendedConfigurationPageHeader ExtHeader;
3090 /** Physical port */
3091 uint8_t u8PhysicalPort;
3092 /** Reserved */
3093 uint8_t u8Reserved0;
3094 /** Enclosure handle */
3095 uint16_t u16EnclosureHandle;
3096 /** SAS address */
3097 SASADDRESS SASAddress;
3098 /** Discovery status */
3099 uint32_t u32DiscoveryStatus;
3100 /** Device handle. */
3101 uint16_t u16DevHandle;
3102 /** Parent device handle */
3103 uint16_t u16ParentDevHandle;
3104 /** Expander change count */
3105 uint16_t u16ExpanderChangeCount;
3106 /** Expander route indexes */
3107 uint16_t u16ExpanderRouteIndexes;
3108 /** Number of PHys in this expander */
3109 uint8_t u8NumPhys;
3110 /** SAS level */
3111 uint8_t u8SASLevel;
3112 /** Flags */
3113 uint8_t u8Flags;
3114 /** Reserved */
3115 uint8_t u8Reserved1;
3116 } fields;
3117 } u;
3118} MptConfigurationPageSASExpander0, *PMptConfigurationPageSASExpander0;
3119#pragma pack()
3120AssertCompileSize(MptConfigurationPageSASExpander0, 36);
3121
3122/**
3123 * SAS Expander page 1 - Readonly
3124 */
3125typedef struct MptConfigurationPageSASExpander1
3126{
3127 /** Union. */
3128 union
3129 {
3130 /** Byte view - variable. */
3131 uint8_t abPageData[1];
3132 /** Field view. */
3133 struct
3134 {
3135 /** The omnipresent header. */
3136 MptExtendedConfigurationPageHeader ExtHeader;
3137 /** Physical port */
3138 uint8_t u8PhysicalPort;
3139 /** Reserved */
3140 uint8_t u8Reserved0[3];
3141 /** Number of PHYs */
3142 uint8_t u8NumPhys;
3143 /** Number of the Phy the information in this page is for. */
3144 uint8_t u8Phy;
3145 /** Number of routing table entries */
3146 uint16_t u16NumTableEntriesProgrammed;
3147 /** Programmed link rate */
3148 uint8_t u8ProgrammedLinkRate;
3149 /** Hardware link rate */
3150 uint8_t u8HwLinkRate;
3151 /** Attached device handle */
3152 uint16_t u16AttachedDevHandle;
3153 /** Phy information */
3154 uint32_t u32PhyInfo;
3155 /** Attached device information */
3156 uint32_t u32AttachedDeviceInfo;
3157 /** Owner device handle. */
3158 uint16_t u16OwnerDevHandle;
3159 /** Change count */
3160 uint8_t u8ChangeCount;
3161 /** Negotiated link rate */
3162 uint8_t u8NegotiatedLinkRate;
3163 /** Phy identifier */
3164 uint8_t u8PhyIdentifier;
3165 /** Attached phy identifier */
3166 uint8_t u8AttachedPhyIdentifier;
3167 /** Reserved */
3168 uint8_t u8Reserved1;
3169 /** Discovery information */
3170 uint8_t u8DiscoveryInfo;
3171 /** Reserved */
3172 uint32_t u32Reserved;
3173 } fields;
3174 } u;
3175} MptConfigurationPageSASExpander1, *PMptConfigurationPageSASExpander1;
3176AssertCompileSize(MptConfigurationPageSASExpander1, 40);
3177
3178/**
3179 * Structure of all supported pages for the SCSI SPI controller.
3180 * Used to load the device state from older versions.
3181 */
3182typedef struct MptConfigurationPagesSupported_SSM_V2
3183{
3184 MptConfigurationPageManufacturing0 ManufacturingPage0;
3185 MptConfigurationPageManufacturing1 ManufacturingPage1;
3186 MptConfigurationPageManufacturing2 ManufacturingPage2;
3187 MptConfigurationPageManufacturing3 ManufacturingPage3;
3188 MptConfigurationPageManufacturing4 ManufacturingPage4;
3189 MptConfigurationPageIOUnit0 IOUnitPage0;
3190 MptConfigurationPageIOUnit1 IOUnitPage1;
3191 MptConfigurationPageIOUnit2 IOUnitPage2;
3192 MptConfigurationPageIOUnit3 IOUnitPage3;
3193 MptConfigurationPageIOC0 IOCPage0;
3194 MptConfigurationPageIOC1 IOCPage1;
3195 MptConfigurationPageIOC2 IOCPage2;
3196 MptConfigurationPageIOC3 IOCPage3;
3197 MptConfigurationPageIOC4 IOCPage4;
3198 MptConfigurationPageIOC6 IOCPage6;
3199 struct
3200 {
3201 MptConfigurationPageSCSISPIPort0 SCSISPIPortPage0;
3202 MptConfigurationPageSCSISPIPort1 SCSISPIPortPage1;
3203 MptConfigurationPageSCSISPIPort2 SCSISPIPortPage2;
3204 } aPortPages[1]; /* Currently only one port supported. */
3205 struct
3206 {
3207 struct
3208 {
3209 MptConfigurationPageSCSISPIDevice0 SCSISPIDevicePage0;
3210 MptConfigurationPageSCSISPIDevice1 SCSISPIDevicePage1;
3211 MptConfigurationPageSCSISPIDevice2 SCSISPIDevicePage2;
3212 MptConfigurationPageSCSISPIDevice3 SCSISPIDevicePage3;
3213 } aDevicePages[LSILOGICSCSI_PCI_SPI_DEVICES_MAX];
3214 } aBuses[1]; /* Only one bus at the moment. */
3215} MptConfigurationPagesSupported_SSM_V2, *PMptConfigurationPagesSupported_SSM_V2;
3216
3217typedef struct MptConfigurationPagesSpi
3218{
3219 struct
3220 {
3221 MptConfigurationPageSCSISPIPort0 SCSISPIPortPage0;
3222 MptConfigurationPageSCSISPIPort1 SCSISPIPortPage1;
3223 MptConfigurationPageSCSISPIPort2 SCSISPIPortPage2;
3224 } aPortPages[1]; /* Currently only one port supported. */
3225 struct
3226 {
3227 struct
3228 {
3229 MptConfigurationPageSCSISPIDevice0 SCSISPIDevicePage0;
3230 MptConfigurationPageSCSISPIDevice1 SCSISPIDevicePage1;
3231 MptConfigurationPageSCSISPIDevice2 SCSISPIDevicePage2;
3232 MptConfigurationPageSCSISPIDevice3 SCSISPIDevicePage3;
3233 } aDevicePages[LSILOGICSCSI_PCI_SPI_DEVICES_MAX];
3234 } aBuses[1]; /* Only one bus at the moment. */
3235} MptConfigurationPagesSpi, *PMptConfigurationPagesSpi;
3236
3237typedef struct MptPHY
3238{
3239 MptConfigurationPageSASPHY0 SASPHYPage0;
3240 MptConfigurationPageSASPHY1 SASPHYPage1;
3241} MptPHY, *PMptPHY;
3242
3243typedef struct MptConfigurationPagesSas
3244{
3245 /** Pointer to the manufacturing page 7 */
3246 PMptConfigurationPageManufacturing7 pManufacturingPage7;
3247 /** Size of the manufacturing page 7 */
3248 uint32_t cbManufacturingPage7;
3249 /** Size of the I/O unit page 0 */
3250 uint32_t cbSASIOUnitPage0;
3251 /** Pointer to the I/O unit page 0 */
3252 PMptConfigurationPageSASIOUnit0 pSASIOUnitPage0;
3253 /** Pointer to the I/O unit page 1 */
3254 PMptConfigurationPageSASIOUnit1 pSASIOUnitPage1;
3255 /** Size of the I/O unit page 1 */
3256 uint32_t cbSASIOUnitPage1;
3257 /** I/O unit page 2 */
3258 MptConfigurationPageSASIOUnit2 SASIOUnitPage2;
3259 /** I/O unit page 3 */
3260 MptConfigurationPageSASIOUnit3 SASIOUnitPage3;
3261
3262 /** Number of PHYs in the array. */
3263 uint32_t cPHYs;
3264 /** Pointer to an array of per PHYS pages. */
3265 R3PTRTYPE(PMptPHY) paPHYs;
3266
3267 /** Number of devices detected. */
3268 uint32_t cDevices;
3269 uint32_t u32Padding;
3270 /** Pointer to the first SAS device. */
3271 R3PTRTYPE(PMptSASDevice) pSASDeviceHead;
3272 /** Pointer to the last SAS device. */
3273 R3PTRTYPE(PMptSASDevice) pSASDeviceTail;
3274} MptConfigurationPagesSas, *PMptConfigurationPagesSas;
3275AssertCompile(RTASSERT_OFFSET_OF(MptConfigurationPagesSas,cbSASIOUnitPage0) + 4 == RTASSERT_OFFSET_OF(MptConfigurationPagesSas, pSASIOUnitPage0));
3276AssertCompile(RTASSERT_OFFSET_OF(MptConfigurationPagesSas,cPHYs) + 4 == RTASSERT_OFFSET_OF(MptConfigurationPagesSas, paPHYs));
3277AssertCompile(RTASSERT_OFFSET_OF(MptConfigurationPagesSas,cDevices) + 8 == RTASSERT_OFFSET_OF(MptConfigurationPagesSas, pSASDeviceHead));
3278
3279
3280/**
3281 * Structure of all supported pages for both controllers.
3282 */
3283typedef struct MptConfigurationPagesSupported
3284{
3285 MptConfigurationPageManufacturing0 ManufacturingPage0;
3286 MptConfigurationPageManufacturing1 ManufacturingPage1;
3287 MptConfigurationPageManufacturing2 ManufacturingPage2;
3288 MptConfigurationPageManufacturing3 ManufacturingPage3;
3289 MptConfigurationPageManufacturing4 ManufacturingPage4;
3290 MptConfigurationPageManufacturing5 ManufacturingPage5;
3291 MptConfigurationPageManufacturing6 ManufacturingPage6;
3292 MptConfigurationPageManufacturing8 ManufacturingPage8;
3293 MptConfigurationPageManufacturing9 ManufacturingPage9;
3294 MptConfigurationPageManufacturing10 ManufacturingPage10;
3295 MptConfigurationPageIOUnit0 IOUnitPage0;
3296 MptConfigurationPageIOUnit1 IOUnitPage1;
3297 MptConfigurationPageIOUnit2 IOUnitPage2;
3298 MptConfigurationPageIOUnit3 IOUnitPage3;
3299 MptConfigurationPageIOUnit4 IOUnitPage4;
3300 MptConfigurationPageIOC0 IOCPage0;
3301 MptConfigurationPageIOC1 IOCPage1;
3302 MptConfigurationPageIOC2 IOCPage2;
3303 MptConfigurationPageIOC3 IOCPage3;
3304 MptConfigurationPageIOC4 IOCPage4;
3305 MptConfigurationPageIOC6 IOCPage6;
3306 /* BIOS page 0 is not described */
3307 MptConfigurationPageBIOS1 BIOSPage1;
3308 MptConfigurationPageBIOS2 BIOSPage2;
3309 /* BIOS page 3 is not described */
3310 MptConfigurationPageBIOS4 BIOSPage4;
3311
3312 /** Controller dependent data. */
3313 union
3314 {
3315 MptConfigurationPagesSpi SpiPages;
3316 MptConfigurationPagesSas SasPages;
3317 } u;
3318} MptConfigurationPagesSupported, *PMptConfigurationPagesSupported;
3319
3320/**
3321 * Initializes a page header.
3322 */
3323#define MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags) \
3324 (pg)->u.fields.Header.u8PageType = (flags); \
3325 (pg)->u.fields.Header.u8PageNumber = (nr); \
3326 (pg)->u.fields.Header.u8PageLength = sizeof(type) / 4
3327
3328#define MPT_CONFIG_PAGE_HEADER_INIT_MANUFACTURING(pg, type, nr, flags) \
3329 RT_ZERO(*pg); \
3330 MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_MANUFACTURING)
3331
3332#define MPT_CONFIG_PAGE_HEADER_INIT_IO_UNIT(pg, type, nr, flags) \
3333 RT_ZERO(*pg); \
3334 MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_IO_UNIT)
3335
3336#define MPT_CONFIG_PAGE_HEADER_INIT_IOC(pg, type, nr, flags) \
3337 RT_ZERO(*pg); \
3338 MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_IOC)
3339
3340#define MPT_CONFIG_PAGE_HEADER_INIT_BIOS(pg, type, nr, flags) \
3341 RT_ZERO(*pg); \
3342 MPT_CONFIG_PAGE_HEADER_INIT(pg, type, nr, flags | MPT_CONFIGURATION_PAGE_TYPE_BIOS)
3343
3344/**
3345 * Initializes a extended page header.
3346 */
3347#define MPT_CONFIG_EXTENDED_PAGE_HEADER_INIT(pg, cb, nr, flags, exttype) \
3348 RT_BZERO(pg, cb); \
3349 (pg)->u.fields.ExtHeader.u8PageType = (flags) | MPT_CONFIGURATION_PAGE_TYPE_EXTENDED; \
3350 (pg)->u.fields.ExtHeader.u8PageNumber = (nr); \
3351 (pg)->u.fields.ExtHeader.u8ExtPageType = (exttype); \
3352 (pg)->u.fields.ExtHeader.u16ExtPageLength = (cb) / 4
3353
3354/**
3355 * Possible SG element types.
3356 */
3357enum MPTSGENTRYTYPE
3358{
3359 MPTSGENTRYTYPE_TRANSACTION_CONTEXT = 0x00,
3360 MPTSGENTRYTYPE_SIMPLE = 0x01,
3361 MPTSGENTRYTYPE_CHAIN = 0x03
3362};
3363
3364/**
3365 * Register interface.
3366 */
3367
3368/**
3369 * Defined states that the SCSI controller can have.
3370 */
3371typedef enum LSILOGICSTATE
3372{
3373 /** Reset state. */
3374 LSILOGICSTATE_RESET = 0x00,
3375 /** Ready state. */
3376 LSILOGICSTATE_READY = 0x01,
3377 /** Operational state. */
3378 LSILOGICSTATE_OPERATIONAL = 0x02,
3379 /** Fault state. */
3380 LSILOGICSTATE_FAULT = 0x04,
3381 /** 32bit size hack */
3382 LSILOGICSTATE_32BIT_HACK = 0x7fffffff
3383} LSILOGICSTATE;
3384
3385/**
3386 * Which entity needs to initialize the controller
3387 * to get into the operational state.
3388 */
3389typedef enum LSILOGICWHOINIT
3390{
3391 /** Not initialized. */
3392 LSILOGICWHOINIT_NOT_INITIALIZED = 0x00,
3393 /** System BIOS. */
3394 LSILOGICWHOINIT_SYSTEM_BIOS = 0x01,
3395 /** ROM Bios. */
3396 LSILOGICWHOINIT_ROM_BIOS = 0x02,
3397 /** PCI Peer. */
3398 LSILOGICWHOINIT_PCI_PEER = 0x03,
3399 /** Host driver. */
3400 LSILOGICWHOINIT_HOST_DRIVER = 0x04,
3401 /** Manufacturing. */
3402 LSILOGICWHOINIT_MANUFACTURING = 0x05,
3403 /** 32bit size hack. */
3404 LSILOGICWHOINIT_32BIT_HACK = 0x7fffffff
3405} LSILOGICWHOINIT;
3406
3407
3408/**
3409 * Doorbell state.
3410 */
3411typedef enum LSILOGICDOORBELLSTATE
3412{
3413 /** Invalid value. */
3414 LSILOGICDOORBELLSTATE_INVALID = 0,
3415 /** Doorbell not in use. */
3416 LSILOGICDOORBELLSTATE_NOT_IN_USE,
3417 /** Reply frame removal, transfer number of entries, low 16bits. */
3418 LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW,
3419 /** Reply frame removal, transfer number of entries, high 16bits. */
3420 LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH,
3421 /** Reply frame removal, remove next free frame, low part. */
3422 LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW,
3423 /** Reply frame removal, remove next free frame, high part. */
3424 LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH,
3425 /** Function handshake. */
3426 LSILOGICDOORBELLSTATE_FN_HANDSHAKE,
3427 /** 32bit hack. */
3428 LSILOGICDOORBELLSTATE_32BIT_HACK = 0x7fffffff
3429} LSILOGICDOORBELLSTATE;
3430/** Pointer to a doorbell state. */
3431typedef LSILOGICDOORBELLSTATE *PLSILOGICDOORBELLSTATE;
3432
3433
3434/**
3435 * IOC status codes.
3436 */
3437#define LSILOGIC_IOCSTATUS_SUCCESS 0x0000
3438#define LSILOGIC_IOCSTATUS_INVALID_FUNCTION 0x0001
3439#define LSILOGIC_IOCSTATUS_BUSY 0x0002
3440#define LSILOGIC_IOCSTATUS_INVALID_SGL 0x0003
3441#define LSILOGIC_IOCSTATUS_INTERNAL_ERROR 0x0004
3442#define LSILOGIC_IOCSTATUS_RESERVED 0x0005
3443#define LSILOGIC_IOCSTATUS_INSUFFICIENT_RESOURCES 0x0006
3444#define LSILOGIC_IOCSTATUS_INVALID_FIELD 0x0007
3445#define LSILOGIC_IOCSTATUS_INVALID_STATE 0x0008
3446#define LSILOGIC_IOCSTATUS_OP_STATE_NOT_SUPPOTED 0x0009
3447
3448/**
3449 * Size of the I/O and MMIO space.
3450 */
3451#define LSILOGIC_PCI_SPACE_IO_SIZE 256
3452#define LSILOGIC_PCI_SPACE_MEM_SIZE 128 * _1K
3453
3454/**
3455 * Doorbell register - Used to get the status of the controller and
3456 * initialise it.
3457 */
3458#define LSILOGIC_REG_DOORBELL 0x00
3459# define LSILOGIC_REG_DOORBELL_SET_STATE(enmState) (((enmState) & 0x0f) << 28)
3460# define LSILOGIC_REG_DOORBELL_SET_USED(enmDoorbell) (((enmDoorbell != LSILOGICDOORBELLSTATE_NOT_IN_USE) ? 1 : 0) << 27)
3461# define LSILOGIC_REG_DOORBELL_SET_WHOINIT(enmWhoInit) (((enmWhoInit) & 0x07) << 24)
3462# define LSILOGIC_REG_DOORBELL_SET_FAULT_CODE(u16Code) (u16Code)
3463# define LSILOGIC_REG_DOORBELL_GET_FUNCTION(x) (((x) & 0xff000000) >> 24)
3464# define LSILOGIC_REG_DOORBELL_GET_SIZE(x) (((x) & 0x00ff0000) >> 16)
3465
3466/**
3467 * Functions which can be passed through the system doorbell.
3468 */
3469#define LSILOGIC_DOORBELL_FUNCTION_IOC_MSG_UNIT_RESET 0x40
3470#define LSILOGIC_DOORBELL_FUNCTION_IO_UNIT_RESET 0x41
3471#define LSILOGIC_DOORBELL_FUNCTION_HANDSHAKE 0x42
3472#define LSILOGIC_DOORBELL_FUNCTION_REPLY_FRAME_REMOVAL 0x43
3473
3474/**
3475 * Write sequence register for the diagnostic register.
3476 */
3477#define LSILOGIC_REG_WRITE_SEQUENCE 0x04
3478
3479/**
3480 * Diagnostic register - used to reset the controller.
3481 */
3482#define LSILOGIC_REG_HOST_DIAGNOSTIC 0x08
3483# define LSILOGIC_REG_HOST_DIAGNOSTIC_DIAG_MEM_ENABLE (RT_BIT(0))
3484# define LSILOGIC_REG_HOST_DIAGNOSTIC_DISABLE_ARM (RT_BIT(1))
3485# define LSILOGIC_REG_HOST_DIAGNOSTIC_RESET_ADAPTER (RT_BIT(2))
3486# define LSILOGIC_REG_HOST_DIAGNOSTIC_DIAG_RW_ENABLE (RT_BIT(4))
3487# define LSILOGIC_REG_HOST_DIAGNOSTIC_RESET_HISTORY (RT_BIT(5))
3488# define LSILOGIC_REG_HOST_DIAGNOSTIC_FLASH_BAD_SIG (RT_BIT(6))
3489# define LSILOGIC_REG_HOST_DIAGNOSTIC_DRWE (RT_BIT(7))
3490# define LSILOGIC_REG_HOST_DIAGNOSTIC_PREVENT_IOC_BOOT (RT_BIT(9))
3491# define LSILOGIC_REG_HOST_DIAGNOSTIC_CLEAR_FLASH_BAD_SIG (RT_BIT(10))
3492
3493#define LSILOGIC_REG_TEST_BASE_ADDRESS 0x0c
3494#define LSILOGIC_REG_DIAG_RW_DATA 0x10
3495#define LSILOGIC_REG_DIAG_RW_ADDRESS 0x14
3496
3497/**
3498 * Interrupt status register.
3499 */
3500#define LSILOGIC_REG_HOST_INTR_STATUS 0x30
3501# define LSILOGIC_REG_HOST_INTR_STATUS_W_MASK (RT_BIT(3))
3502# define LSILOGIC_REG_HOST_INTR_STATUS_DOORBELL_STS (RT_BIT(31))
3503# define LSILOGIC_REG_HOST_INTR_STATUS_REPLY_INTR (RT_BIT(3))
3504# define LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL (RT_BIT(0))
3505
3506/**
3507 * Interrupt mask register.
3508 */
3509#define LSILOGIC_REG_HOST_INTR_MASK 0x34
3510# define LSILOGIC_REG_HOST_INTR_MASK_W_MASK (RT_BIT(0) | RT_BIT(3) | RT_BIT(8) | RT_BIT(9))
3511# define LSILOGIC_REG_HOST_INTR_MASK_IRQ_ROUTING (RT_BIT(8) | RT_BIT(9))
3512# define LSILOGIC_REG_HOST_INTR_MASK_DOORBELL RT_BIT(0)
3513# define LSILOGIC_REG_HOST_INTR_MASK_REPLY RT_BIT(3)
3514
3515/**
3516 * Queue registers.
3517 */
3518#define LSILOGIC_REG_REQUEST_QUEUE 0x40
3519#define LSILOGIC_REG_REPLY_QUEUE 0x44
3520
3521#endif /* !VBOX_INCLUDED_SRC_Storage_DevLsiLogicSCSI_h */
Note: See TracBrowser for help on using the repository browser.

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