Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

3178 Support for LSI 2208 chipset in mr_sas

Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Richard Lowe <richlowe@richlowe.net>
  • Loading branch information...
commit 2ffc8bca2d4d633ffdea78ed925cd1ca63584844 1 parent 01f55e4
Dan McDonald authored richlowe committed
View
5 usr/src/pkg/manifests/driver-storage-mr_sas.mf
@@ -21,6 +21,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -43,9 +44,13 @@ dir path=usr/share/man/man7d
$(sparc_ONLY)driver name=mr_sas class=scsi-self-identifying \
alias=pci1000,78 \
alias=pci1000,79 \
+ alias=pciex1000,5b \
+ alias=pciex1000,5d \
alias=pciex1000,78 \
alias=pciex1000,79
$(i386_ONLY)driver name=mr_sas class=scsi-self-identifying \
+ alias=pciex1000,5b \
+ alias=pciex1000,5d \
alias=pciex1000,78 \
alias=pciex1000,79
file path=kernel/drv/$(ARCH64)/mr_sas group=sys
View
2  usr/src/uts/common/Makefile.files
@@ -1995,7 +1995,7 @@ MEGA_SAS_OBJS = megaraid_sas.o
#
# MR_SAS module
#
-MR_SAS_OBJS = mr_sas.o
+MR_SAS_OBJS = ld_pd_map.o mr_sas.o mr_sas_tbolt.o mr_sas_list.o
#
# ISCSI_INITIATOR module
View
561 usr/src/uts/common/io/mr_sas/fusion.h
@@ -0,0 +1,561 @@
+/*
+ * fusion.h
+ *
+ * Solaris MegaRAID device driver for SAS2.0 controllers
+ * Copyright (c) 2008-2012, LSI Logic Corporation.
+ * All rights reserved.
+ *
+ * Version:
+ * Author:
+ * Swaminathan K S
+ * Arun Chandrashekhar
+ * Manju R
+ * Rasheed
+ * Shakeel Bukhari
+ */
+
+
+#ifndef _FUSION_H_
+#define _FUSION_H_
+
+#define U64 uint64_t
+#define U32 uint32_t
+#define U16 uint16_t
+#define U8 uint8_t
+#define S8 char
+#define S16 short
+#define S32 int
+
+/* MPI2 defines */
+#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x6C)
+#define MPI2_FUNCTION_IOC_INIT (0x02) /* IOC Init */
+#define MPI2_WHOINIT_HOST_DRIVER (0x04)
+#define MPI2_VERSION_MAJOR (0x02)
+#define MPI2_VERSION_MINOR (0x00)
+#define MPI2_VERSION_MAJOR_MASK (0xFF00)
+#define MPI2_VERSION_MAJOR_SHIFT (8)
+#define MPI2_VERSION_MINOR_MASK (0x00FF)
+#define MPI2_VERSION_MINOR_SHIFT (0)
+#define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \
+ MPI2_VERSION_MINOR)
+#define MPI2_HEADER_VERSION_UNIT (0x10)
+#define MPI2_HEADER_VERSION_DEV (0x00)
+#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
+#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
+#define MPI2_HEADER_VERSION_DEV_MASK (0x00FF)
+#define MPI2_HEADER_VERSION_DEV_SHIFT (0)
+#define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT \
+ << 8) | \
+ MPI2_HEADER_VERSION_DEV)
+#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03)
+#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG (0x8000)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG (0x0400)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP (0x0003)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100)
+#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004)
+#define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) /* SCSI IO */
+#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06)
+#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00)
+#define MPI2_SGE_FLAGS_64_BIT_ADDRESSING (0x02)
+#define MPI2_SCSIIO_CONTROL_WRITE (0x01000000)
+#define MPI2_SCSIIO_CONTROL_READ (0x02000000)
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x0E)
+#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F)
+#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00)
+#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F)
+#define MPI2_WRSEQ_FLUSH_KEY_VALUE (0x0)
+#define MPI2_WRITE_SEQUENCE_OFFSET (0x00000004)
+#define MPI2_WRSEQ_1ST_KEY_VALUE (0xF)
+#define MPI2_WRSEQ_2ND_KEY_VALUE (0x4)
+#define MPI2_WRSEQ_3RD_KEY_VALUE (0xB)
+#define MPI2_WRSEQ_4TH_KEY_VALUE (0x2)
+#define MPI2_WRSEQ_5TH_KEY_VALUE (0x7)
+#define MPI2_WRSEQ_6TH_KEY_VALUE (0xD)
+
+/* Invader defines */
+#define MPI2_TYPE_CUDA 0x2
+#define MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH 0x4000
+#define MR_RL_FLAGS_GRANT_DESTINATION_CPU0 0x00
+#define MR_RL_FLAGS_GRANT_DESTINATION_CPU1 0x10
+#define MR_RL_FLAGS_GRANT_DESTINATION_CUDA 0x80
+#define MR_RL_FLAGS_SEQ_NUM_ENABLE 0x8
+#define MPI2_NSEG_FLAGS_SHIFT 4
+
+
+#define MR_PD_INVALID 0xFFFF
+#define MAX_SPAN_DEPTH 8
+#define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH)
+#define MAX_ROW_SIZE 32
+#define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
+#define MAX_LOGICAL_DRIVES 64
+#define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES)
+#define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES)
+#define MAX_ARRAYS 128
+#define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS)
+#define MAX_PHYSICAL_DEVICES 256
+#define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
+
+/* get the mapping information of LD */
+#define MR_DCMD_LD_MAP_GET_INFO 0x0300e101
+
+#ifndef MPI2_POINTER
+#define MPI2_POINTER *
+#endif
+
+#pragma pack(1)
+
+typedef struct _MPI25_IEEE_SGE_CHAIN64
+{
+ U64 Address;
+ U32 Length;
+ U16 Reserved1;
+ U8 NextChainOffset;
+ U8 Flags;
+} MPI25_IEEE_SGE_CHAIN64, MPI2_POINTER PTR_MPI25_IEEE_SGE_CHAIN64,
+ Mpi25IeeeSgeChain64_t, MPI2_POINTER pMpi25IeeeSgeChain64_t;
+
+typedef struct _MPI2_SGE_SIMPLE_UNION
+{
+ U32 FlagsLength;
+ union
+ {
+ U32 Address32;
+ U64 Address64;
+ } u1;
+} MPI2_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_SGE_SIMPLE_UNION,
+ Mpi2SGESimpleUnion_t, MPI2_POINTER pMpi2SGESimpleUnion_t;
+
+typedef struct
+{
+ U8 CDB[20]; /* 0x00 */
+ U32 PrimaryReferenceTag; /* 0x14 */
+ U16 PrimaryApplicationTag; /* 0x18 */
+ U16 PrimaryApplicationTagMask; /* 0x1A */
+ U32 TransferLength; /* 0x1C */
+} MPI2_SCSI_IO_CDB_EEDP32, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_EEDP32,
+ Mpi2ScsiIoCdbEedp32_t, MPI2_POINTER pMpi2ScsiIoCdbEedp32_t;
+
+typedef struct _MPI2_SGE_CHAIN_UNION
+{
+ U16 Length;
+ U8 NextChainOffset;
+ U8 Flags;
+ union
+ {
+ U32 Address32;
+ U64 Address64;
+ } u1;
+} MPI2_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_SGE_CHAIN_UNION,
+ Mpi2SGEChainUnion_t, MPI2_POINTER pMpi2SGEChainUnion_t;
+
+typedef struct _MPI2_IEEE_SGE_SIMPLE32
+{
+ U32 Address;
+ U32 FlagsLength;
+} MPI2_IEEE_SGE_SIMPLE32, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE32,
+ Mpi2IeeeSgeSimple32_t, MPI2_POINTER pMpi2IeeeSgeSimple32_t;
+
+typedef struct _MPI2_IEEE_SGE_SIMPLE64
+{
+ U64 Address;
+ U32 Length;
+ U16 Reserved1;
+ U8 Reserved2;
+ U8 Flags;
+} MPI2_IEEE_SGE_SIMPLE64, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE64,
+ Mpi2IeeeSgeSimple64_t, MPI2_POINTER pMpi2IeeeSgeSimple64_t;
+
+typedef union _MPI2_IEEE_SGE_SIMPLE_UNION
+{
+ MPI2_IEEE_SGE_SIMPLE32 Simple32;
+ MPI2_IEEE_SGE_SIMPLE64 Simple64;
+} MPI2_IEEE_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE_UNION,
+ Mpi2IeeeSgeSimpleUnion_t, MPI2_POINTER pMpi2IeeeSgeSimpleUnion_t;
+
+typedef MPI2_IEEE_SGE_SIMPLE32 MPI2_IEEE_SGE_CHAIN32;
+typedef MPI2_IEEE_SGE_SIMPLE64 MPI2_IEEE_SGE_CHAIN64;
+
+typedef union _MPI2_IEEE_SGE_CHAIN_UNION
+{
+ MPI2_IEEE_SGE_CHAIN32 Chain32;
+ MPI2_IEEE_SGE_CHAIN64 Chain64;
+} MPI2_IEEE_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_CHAIN_UNION,
+ Mpi2IeeeSgeChainUnion_t, MPI2_POINTER pMpi2IeeeSgeChainUnion_t;
+
+typedef union _MPI2_SGE_IO_UNION
+{
+ MPI2_SGE_SIMPLE_UNION MpiSimple;
+ MPI2_SGE_CHAIN_UNION MpiChain;
+ MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple;
+ MPI2_IEEE_SGE_CHAIN_UNION IeeeChain;
+} MPI2_SGE_IO_UNION, MPI2_POINTER PTR_MPI2_SGE_IO_UNION,
+ Mpi2SGEIOUnion_t, MPI2_POINTER pMpi2SGEIOUnion_t;
+
+typedef union
+{
+ U8 CDB32[32];
+ MPI2_SCSI_IO_CDB_EEDP32 EEDP32;
+ MPI2_SGE_SIMPLE_UNION SGE;
+} MPI2_SCSI_IO_CDB_UNION, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_UNION,
+ Mpi2ScsiIoCdb_t, MPI2_POINTER pMpi2ScsiIoCdb_t;
+
+/* Default Request Descriptor */
+typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
+{
+ U8 RequestFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U16 LMID; /* 0x04 */
+ U16 DescriptorTypeDependent; /* 0x06 */
+} MPI2_DEFAULT_REQUEST_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_DEFAULT_REQUEST_DESCRIPTOR,
+ Mpi2DefaultRequestDescriptor_t,
+ MPI2_POINTER pMpi2DefaultRequestDescriptor_t;
+
+/* High Priority Request Descriptor */
+typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR
+{
+ U8 RequestFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U16 LMID; /* 0x04 */
+ U16 Reserved1; /* 0x06 */
+} MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR,
+ Mpi2HighPriorityRequestDescriptor_t,
+ MPI2_POINTER pMpi2HighPriorityRequestDescriptor_t;
+
+/* SCSI IO Request Descriptor */
+typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+{
+ U8 RequestFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U16 LMID; /* 0x04 */
+ U16 DevHandle; /* 0x06 */
+} MPI2_SCSI_IO_REQUEST_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST_DESCRIPTOR,
+ Mpi2SCSIIORequestDescriptor_t,
+ MPI2_POINTER pMpi2SCSIIORequestDescriptor_t;
+
+/* SCSI Target Request Descriptor */
+typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR
+{
+ U8 RequestFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U16 LMID; /* 0x04 */
+ U16 IoIndex; /* 0x06 */
+} MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR,
+ Mpi2SCSITargetRequestDescriptor_t,
+ MPI2_POINTER pMpi2SCSITargetRequestDescriptor_t;
+
+/* RAID Accelerator Request Descriptor */
+typedef struct _MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR
+{
+ U8 RequestFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U16 LMID; /* 0x04 */
+ U16 Reserved; /* 0x06 */
+} MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR,
+ Mpi2RAIDAcceleratorRequestDescriptor_t,
+ MPI2_POINTER pMpi2RAIDAcceleratorRequestDescriptor_t;
+
+/* Default Reply Descriptor */
+typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR
+{
+ U8 ReplyFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 DescriptorTypeDependent1; /* 0x02 */
+ U32 DescriptorTypeDependent2; /* 0x04 */
+} MPI2_DEFAULT_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR,
+ Mpi2DefaultReplyDescriptor_t, MPI2_POINTER pMpi2DefaultReplyDescriptor_t;
+
+/* Address Reply Descriptor */
+typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR
+{
+ U8 ReplyFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U32 ReplyFrameAddress; /* 0x04 */
+} MPI2_ADDRESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR,
+ Mpi2AddressReplyDescriptor_t, MPI2_POINTER pMpi2AddressReplyDescriptor_t;
+
+/* SCSI IO Success Reply Descriptor */
+typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
+{
+ U8 ReplyFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U16 TaskTag; /* 0x04 */
+ U16 Reserved1; /* 0x06 */
+} MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
+ Mpi2SCSIIOSuccessReplyDescriptor_t,
+ MPI2_POINTER pMpi2SCSIIOSuccessReplyDescriptor_t;
+
+/* TargetAssist Success Reply Descriptor */
+typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR
+{
+ U8 ReplyFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U8 SequenceNumber; /* 0x04 */
+ U8 Reserved1; /* 0x05 */
+ U16 IoIndex; /* 0x06 */
+} MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR,
+ Mpi2TargetAssistSuccessReplyDescriptor_t,
+ MPI2_POINTER pMpi2TargetAssistSuccessReplyDescriptor_t;
+
+/* Target Command Buffer Reply Descriptor */
+typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR
+{
+ U8 ReplyFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U8 VP_ID; /* 0x02 */
+ U8 Flags; /* 0x03 */
+ U16 InitiatorDevHandle; /* 0x04 */
+ U16 IoIndex; /* 0x06 */
+} MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR,
+ Mpi2TargetCommandBufferReplyDescriptor_t,
+ MPI2_POINTER pMpi2TargetCommandBufferReplyDescriptor_t;
+
+/* RAID Accelerator Success Reply Descriptor */
+typedef struct _MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
+{
+ U8 ReplyFlags; /* 0x00 */
+ U8 MSIxIndex; /* 0x01 */
+ U16 SMID; /* 0x02 */
+ U32 Reserved; /* 0x04 */
+} MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR,
+ MPI2_POINTER PTR_MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR,
+ Mpi2RAIDAcceleratorSuccessReplyDescriptor_t,
+ MPI2_POINTER pMpi2RAIDAcceleratorSuccessReplyDescriptor_t;
+
+/* union of Reply Descriptors */
+typedef union _MPI2_REPLY_DESCRIPTORS_UNION
+{
+ MPI2_DEFAULT_REPLY_DESCRIPTOR Default;
+ MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply;
+ MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess;
+ MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess;
+ MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
+ MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess;
+ U64 Words;
+} MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION,
+ Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t;
+
+/* IOCInit Request message */
+typedef struct _MPI2_IOC_INIT_REQUEST
+{
+ U8 WhoInit; /* 0x00 */
+ U8 Reserved1; /* 0x01 */
+ U8 ChainOffset; /* 0x02 */
+ U8 Function; /* 0x03 */
+ U16 Reserved2; /* 0x04 */
+ U8 Reserved3; /* 0x06 */
+ U8 MsgFlags; /* 0x07 */
+ U8 VP_ID; /* 0x08 */
+ U8 VF_ID; /* 0x09 */
+ U16 Reserved4; /* 0x0A */
+ U16 MsgVersion; /* 0x0C */
+ U16 HeaderVersion; /* 0x0E */
+ U32 Reserved5; /* 0x10 */
+ U16 Reserved6; /* 0x14 */
+ U8 Reserved7; /* 0x16 */
+ U8 HostMSIxVectors; /* 0x17 */
+ U16 Reserved8; /* 0x18 */
+ U16 SystemRequestFrameSize; /* 0x1A */
+ U16 ReplyDescriptorPostQueueDepth; /* 0x1C */
+ U16 ReplyFreeQueueDepth; /* 0x1E */
+ U32 SenseBufferAddressHigh; /* 0x20 */
+ U32 SystemReplyAddressHigh; /* 0x24 */
+ U64 SystemRequestFrameBaseAddress; /* 0x28 */
+ U64 ReplyDescriptorPostQueueAddress; /* 0x30 */
+ U64 ReplyFreeQueueAddress; /* 0x38 */
+ U64 TimeStamp; /* 0x40 */
+} MPI2_IOC_INIT_REQUEST, MPI2_POINTER PTR_MPI2_IOC_INIT_REQUEST,
+ Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2IOCInitRequest_t;
+
+
+typedef struct _MR_DEV_HANDLE_INFO {
+
+ /* Send bitmap of LDs that are idle with respect to FP */
+ U16 curDevHdl;
+
+ /* bitmap of valid device handles. */
+ U8 validHandles;
+ U8 reserved;
+ /* 0x04 dev handles for all the paths. */
+ U16 devHandle[2];
+} MR_DEV_HANDLE_INFO; /* 0x08, Total Size */
+
+typedef struct _MR_ARRAY_INFO {
+ U16 pd[MAX_RAIDMAP_ROW_SIZE];
+} MR_ARRAY_INFO; /* 0x40, Total Size */
+
+typedef struct _MR_QUAD_ELEMENT {
+ U64 logStart; /* 0x00 */
+ U64 logEnd; /* 0x08 */
+ U64 offsetInSpan; /* 0x10 */
+ U32 diff; /* 0x18 */
+ U32 reserved1; /* 0x1C */
+} MR_QUAD_ELEMENT; /* 0x20, Total size */
+
+typedef struct _MR_SPAN_INFO {
+ U32 noElements; /* 0x00 */
+ U32 reserved1; /* 0x04 */
+ MR_QUAD_ELEMENT quads[MAX_RAIDMAP_SPAN_DEPTH]; /* 0x08 */
+} MR_SPAN_INFO; /* 0x108, Total size */
+
+typedef struct _MR_LD_SPAN_ { /* SPAN structure */
+ /* 0x00, starting block number in array */
+ U64 startBlk;
+
+ /* 0x08, number of blocks */
+ U64 numBlks;
+
+ /* 0x10, array reference */
+ U16 arrayRef;
+
+ U8 reserved[6]; /* 0x12 */
+} MR_LD_SPAN; /* 0x18, Total Size */
+
+typedef struct _MR_SPAN_BLOCK_INFO {
+ /* number of rows/span */
+ U64 num_rows;
+
+ MR_LD_SPAN span; /* 0x08 */
+ MR_SPAN_INFO block_span_info; /* 0x20 */
+} MR_SPAN_BLOCK_INFO; /* 0x128, Total Size */
+
+typedef struct _MR_LD_RAID {
+ struct {
+ U32 fpCapable :1;
+ U32 reserved5 :3;
+ U32 ldPiMode :4;
+ U32 pdPiMode :4;
+
+ /* FDE or controller encryption (MR_LD_ENCRYPTION_TYPE) */
+ U32 encryptionType :8;
+
+ U32 fpWriteCapable :1;
+ U32 fpReadCapable :1;
+ U32 fpWriteAcrossStripe:1;
+ U32 fpReadAcrossStripe:1;
+ U32 reserved4 :8;
+ } capability; /* 0x00 */
+ U32 reserved6;
+ U64 size; /* 0x08, LD size in blocks */
+ U8 spanDepth; /* 0x10, Total Number of Spans */
+ U8 level; /* 0x11, RAID level */
+ /* 0x12, shift-count to get stripe size (0=512, 1=1K, 7=64K, etc.) */
+ U8 stripeShift;
+ U8 rowSize; /* 0x13, number of disks in a row */
+ /* 0x14, number of data disks in a row */
+ U8 rowDataSize;
+ U8 writeMode; /* 0x15, WRITE_THROUGH or WRITE_BACK */
+
+ /* 0x16, To differentiate between RAID1 and RAID1E */
+ U8 PRL;
+
+ U8 SRL; /* 0x17 */
+ U16 targetId; /* 0x18, ld Target Id. */
+
+ /* 0x1a, state of ld, state corresponds to MR_LD_STATE */
+ U8 ldState;
+
+ /* 0x1b, Pre calculate region type requests based on MFC etc.. */
+ U8 regTypeReqOnWrite;
+
+ U8 modFactor; /* 0x1c, same as rowSize */
+ /*
+ * 0x1d, region lock type used for read, valid only if
+ * regTypeOnReadIsValid=1
+ */
+ U8 regTypeReqOnRead;
+ U16 seqNum; /* 0x1e, LD sequence number */
+
+ struct {
+ /* This LD requires sync command before completing */
+ U32 ldSyncRequired:1;
+ U32 reserved:31;
+ } flags; /* 0x20 */
+
+ U8 reserved3[0x5C]; /* 0x24 */
+} MR_LD_RAID; /* 0x80, Total Size */
+
+typedef struct _MR_LD_SPAN_MAP {
+ MR_LD_RAID ldRaid; /* 0x00 */
+
+ /* 0x80, needed for GET_ARM() - R0/1/5 only. */
+ U8 dataArmMap[MAX_RAIDMAP_ROW_SIZE];
+
+ MR_SPAN_BLOCK_INFO spanBlock[MAX_RAIDMAP_SPAN_DEPTH]; /* 0xA0 */
+} MR_LD_SPAN_MAP; /* 0x9E0 */
+
+typedef struct _MR_FW_RAID_MAP {
+ /* total size of this structure, including this field */
+ U32 totalSize;
+ union {
+ /* Simple method of version checking variables */
+ struct {
+ U32 maxLd;
+ U32 maxSpanDepth;
+ U32 maxRowSize;
+ U32 maxPdCount;
+ U32 maxArrays;
+ } validationInfo;
+ U32 version[5];
+ U32 reserved1[5];
+ } u1;
+
+ U32 ldCount; /* count of lds */
+ U32 Reserved1;
+
+ /*
+ * 0x20 This doesn't correspond to
+ * FW Ld Tgt Id to LD, but will purge. For example: if tgt Id is 4
+ * and FW LD is 2, and there is only one LD, FW will populate the
+ * array like this. [0xFF, 0xFF, 0xFF, 0xFF, 0x0.....]. This is to
+ * help reduce the entire structure size if there are few LDs or
+ * driver is looking info for 1 LD only.
+ */
+ U8 ldTgtIdToLd[MAX_RAIDMAP_LOGICAL_DRIVES+ \
+ MAX_RAIDMAP_VIEWS]; /* 0x20 */
+ /* timeout value used by driver in FP IOs */
+ U8 fpPdIoTimeoutSec;
+ U8 reserved2[7];
+ MR_ARRAY_INFO arMapInfo[MAX_RAIDMAP_ARRAYS]; /* 0x00a8 */
+ MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
+
+ /* 0x28a8-[0 -MAX_RAIDMAP_LOGICAL_DRIVES+MAX_RAIDMAP_VIEWS+1]; */
+ MR_LD_SPAN_MAP ldSpanMap[1];
+}MR_FW_RAID_MAP; /* 0x3288, Total Size */
+
+typedef struct _LD_TARGET_SYNC {
+ U8 ldTargetId;
+ U8 reserved;
+ U16 seqNum;
+} LD_TARGET_SYNC;
+
+#pragma pack()
+
+struct IO_REQUEST_INFO {
+ U64 ldStartBlock;
+ U32 numBlocks;
+ U16 ldTgtId;
+ U8 isRead;
+ U16 devHandle;
+ U64 pdBlock;
+ U8 fpOkForIo;
+ U8 ldPI;
+};
+
+#endif /* _FUSION_H_ */
View
539 usr/src/uts/common/io/mr_sas/ld_pd_map.c
@@ -0,0 +1,539 @@
+/*
+ * **********************************************************************
+ *
+ * ld_pd_map.c
+ *
+ * Solaris MegaRAID device driver for SAS2.0 controllers
+ * Copyright (c) 2008-2012, LSI Logic Corporation.
+ * All rights reserved.
+ *
+ * Version:
+ * Author:
+ * Swaminathan K S
+ * Arun Chandrashekhar
+ * Manju R
+ * Rasheed
+ * Shakeel Bukhari
+ *
+ *
+ * This module contains functions for device drivers
+ * to get pd-ld mapping information.
+ *
+ * **********************************************************************
+ */
+
+#include <sys/scsi/scsi.h>
+#include "mr_sas.h"
+#include "ld_pd_map.h"
+
+/*
+ * This function will check if FAST IO is possible on this logical drive
+ * by checking the EVENT information available in the driver
+ */
+#define MR_LD_STATE_OPTIMAL 3
+#define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
+
+static void mr_update_load_balance_params(MR_FW_RAID_MAP_ALL *,
+ PLD_LOAD_BALANCE_INFO);
+
+#define FALSE 0
+#define TRUE 1
+
+typedef U64 REGION_KEY;
+typedef U32 REGION_LEN;
+extern int debug_level_g;
+
+
+MR_LD_RAID
+*MR_LdRaidGet(U32 ld, MR_FW_RAID_MAP_ALL *map)
+{
+ return (&map->raidMap.ldSpanMap[ld].ldRaid);
+}
+
+U16
+MR_GetLDTgtId(U32 ld, MR_FW_RAID_MAP_ALL *map)
+{
+ return (map->raidMap.ldSpanMap[ld].ldRaid.targetId);
+}
+
+
+static MR_SPAN_BLOCK_INFO *
+MR_LdSpanInfoGet(U32 ld, MR_FW_RAID_MAP_ALL *map)
+{
+ return (&map->raidMap.ldSpanMap[ld].spanBlock[0]);
+}
+
+static U8
+MR_LdDataArmGet(U32 ld, U32 armIdx, MR_FW_RAID_MAP_ALL *map)
+{
+ return (map->raidMap.ldSpanMap[ld].dataArmMap[armIdx]);
+}
+
+static U16
+MR_ArPdGet(U32 ar, U32 arm, MR_FW_RAID_MAP_ALL *map)
+{
+ return (map->raidMap.arMapInfo[ar].pd[arm]);
+}
+
+static U16
+MR_LdSpanArrayGet(U32 ld, U32 span, MR_FW_RAID_MAP_ALL *map)
+{
+ return (map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef);
+}
+
+static U16
+MR_PdDevHandleGet(U32 pd, MR_FW_RAID_MAP_ALL *map)
+{
+ return (map->raidMap.devHndlInfo[pd].curDevHdl);
+}
+
+U16
+MR_TargetIdToLdGet(U32 ldTgtId, MR_FW_RAID_MAP_ALL *map)
+{
+ return (map->raidMap.ldTgtIdToLd[ldTgtId]);
+}
+
+U16
+MR_CheckDIF(U32 ldTgtId, MR_FW_RAID_MAP_ALL *map)
+{
+ MR_LD_RAID *raid;
+ U32 ld;
+
+ ld = MR_TargetIdToLdGet(ldTgtId, map);
+
+ if (ld >= MAX_LOGICAL_DRIVES) {
+ return (FALSE);
+ }
+
+ raid = MR_LdRaidGet(ld, map);
+
+ return (raid->capability.ldPiMode == 0x8);
+}
+
+static MR_LD_SPAN *
+MR_LdSpanPtrGet(U32 ld, U32 span, MR_FW_RAID_MAP_ALL *map)
+{
+ return (&map->raidMap.ldSpanMap[ld].spanBlock[span].span);
+}
+
+/*
+ * This function will validate Map info data provided by FW
+ */
+U8
+MR_ValidateMapInfo(MR_FW_RAID_MAP_ALL *map, PLD_LOAD_BALANCE_INFO lbInfo)
+{
+ MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap;
+ U32 fwsize = sizeof (MR_FW_RAID_MAP) - sizeof (MR_LD_SPAN_MAP) +
+ (sizeof (MR_LD_SPAN_MAP) * pFwRaidMap->ldCount);
+
+ if (pFwRaidMap->totalSize != fwsize) {
+
+ con_log(CL_ANN1, (CE_NOTE,
+ "map info structure size 0x%x is "
+ "not matching with ld count\n", fwsize));
+ /* sizeof (foo) returns size_t, which is *LONG*. */
+ con_log(CL_ANN1, (CE_NOTE, "span map 0x%x total size 0x%x\n",\
+ (int)sizeof (MR_LD_SPAN_MAP), pFwRaidMap->totalSize));
+
+ return (0);
+ }
+
+ mr_update_load_balance_params(map, lbInfo);
+
+ return (1);
+}
+
+U32
+MR_GetSpanBlock(U32 ld, U64 row, U64 *span_blk, MR_FW_RAID_MAP_ALL *map,
+ int *div_error)
+{
+ MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map);
+ MR_QUAD_ELEMENT *qe;
+ MR_LD_RAID *raid = MR_LdRaidGet(ld, map);
+ U32 span, j;
+
+ for (span = 0; span < raid->spanDepth; span++, pSpanBlock++) {
+ for (j = 0; j < pSpanBlock->block_span_info.noElements; j++) {
+ qe = &pSpanBlock->block_span_info.quads[j];
+ if (qe->diff == 0) {
+ *div_error = 1;
+ return (span);
+ }
+ if (qe->logStart <= row && row <= qe->logEnd &&
+ (((row - qe->logStart) % qe->diff)) == 0) {
+ if (span_blk != NULL) {
+ U64 blk;
+ blk = ((row - qe->logStart) /
+ (qe->diff));
+
+ blk = (blk + qe->offsetInSpan) <<
+ raid->stripeShift;
+ *span_blk = blk;
+ }
+ return (span);
+ }
+ }
+ }
+ return (span);
+}
+
+
+/*
+ * *************************************************************
+ *
+ * This routine calculates the arm, span and block for
+ * the specified stripe and reference in stripe.
+ *
+ * Inputs :
+ *
+ * ld - Logical drive number
+ * stripRow - Stripe number
+ * stripRef - Reference in stripe
+ *
+ * Outputs :
+ *
+ * span - Span number
+ * block - Absolute Block number in the physical disk
+ */
+U8
+MR_GetPhyParams(struct mrsas_instance *instance, U32 ld, U64 stripRow,
+ U16 stripRef, U64 *pdBlock, U16 *pDevHandle,
+ MPI2_SCSI_IO_VENDOR_UNIQUE *pRAID_Context, MR_FW_RAID_MAP_ALL *map)
+{
+ MR_LD_RAID *raid = MR_LdRaidGet(ld, map);
+ U32 pd, arRef;
+ U8 physArm, span;
+ U64 row;
+ int error_code = 0;
+ U8 retval = TRUE;
+ U32 rowMod;
+ U32 armQ;
+ U32 arm;
+
+ ASSERT(raid->rowDataSize != 0);
+
+ row = (stripRow / raid->rowDataSize);
+
+ if (raid->level == 6) {
+ U32 logArm = (stripRow % (raid->rowDataSize));
+
+ if (raid->rowSize == 0) {
+ return (FALSE);
+ }
+ rowMod = (row % (raid->rowSize));
+ armQ = raid->rowSize-1-rowMod;
+ arm = armQ + 1 + logArm;
+ if (arm >= raid->rowSize)
+ arm -= raid->rowSize;
+ physArm = (U8)arm;
+ } else {
+ if (raid->modFactor == 0)
+ return (FALSE);
+ physArm = MR_LdDataArmGet(ld,
+ (stripRow % (raid->modFactor)), map);
+ }
+ if (raid->spanDepth == 1) {
+ span = 0;
+ *pdBlock = row << raid->stripeShift;
+ } else
+ span = (U8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code);
+
+ if (error_code == 1)
+ return (FALSE);
+
+ /* Get the array on which this span is present. */
+ arRef = MR_LdSpanArrayGet(ld, span, map);
+ /* Get the Pd. */
+ pd = MR_ArPdGet(arRef, physArm, map);
+ /* Get dev handle from Pd. */
+ if (pd != MR_PD_INVALID) {
+ *pDevHandle = MR_PdDevHandleGet(pd, map);
+ } else {
+ *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
+ if ((raid->level >= 5) &&
+ ((instance->device_id != PCI_DEVICE_ID_LSI_INVADER) ||
+ (instance->device_id == PCI_DEVICE_ID_LSI_INVADER &&
+ raid->regTypeReqOnRead != REGION_TYPE_UNUSED))) {
+ pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
+ } else if (raid->level == 1) {
+ /* Get Alternate Pd. */
+ pd = MR_ArPdGet(arRef, physArm + 1, map);
+ /* Get dev handle from Pd. */
+ if (pd != MR_PD_INVALID)
+ *pDevHandle = MR_PdDevHandleGet(pd, map);
+ }
+ }
+
+ *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
+
+ pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
+ physArm;
+
+ return (retval);
+}
+
+
+
+/*
+ * ***********************************************************************
+ *
+ * MR_BuildRaidContext function
+ *
+ * This function will initiate command processing. The start/end row and strip
+ * information is calculated then the lock is acquired.
+ * This function will return 0 if region lock
+ * was acquired OR return num strips ???
+ */
+
+U8
+MR_BuildRaidContext(struct mrsas_instance *instance,
+ struct IO_REQUEST_INFO *io_info, MPI2_SCSI_IO_VENDOR_UNIQUE *pRAID_Context,
+ MR_FW_RAID_MAP_ALL *map)
+{
+ MR_LD_RAID *raid;
+ U32 ld, stripSize, stripe_mask;
+ U64 endLba, endStrip, endRow;
+ U64 start_row, start_strip;
+ REGION_KEY regStart;
+ REGION_LEN regSize;
+ U8 num_strips, numRows;
+ U16 ref_in_start_stripe;
+ U16 ref_in_end_stripe;
+
+ U64 ldStartBlock;
+ U32 numBlocks, ldTgtId;
+ U8 isRead;
+ U8 retval = 0;
+
+ ldStartBlock = io_info->ldStartBlock;
+ numBlocks = io_info->numBlocks;
+ ldTgtId = io_info->ldTgtId;
+ isRead = io_info->isRead;
+
+ if (map == NULL) {
+ io_info->fpOkForIo = FALSE;
+ return (FALSE);
+ }
+
+ ld = MR_TargetIdToLdGet(ldTgtId, map);
+
+ if (ld >= MAX_LOGICAL_DRIVES) {
+ io_info->fpOkForIo = FALSE;
+ return (FALSE);
+ }
+
+ raid = MR_LdRaidGet(ld, map);
+
+ stripSize = 1 << raid->stripeShift;
+ stripe_mask = stripSize-1;
+ /*
+ * calculate starting row and stripe, and number of strips and rows
+ */
+ start_strip = ldStartBlock >> raid->stripeShift;
+ ref_in_start_stripe = (U16)(ldStartBlock & stripe_mask);
+ endLba = ldStartBlock + numBlocks - 1;
+ ref_in_end_stripe = (U16)(endLba & stripe_mask);
+ endStrip = endLba >> raid->stripeShift;
+ num_strips = (U8)(endStrip - start_strip + 1);
+ /* Check to make sure is not dividing by zero */
+ if (raid->rowDataSize == 0)
+ return (FALSE);
+ start_row = (start_strip / raid->rowDataSize);
+ endRow = (endStrip / raid->rowDataSize);
+ /* get the row count */
+ numRows = (U8)(endRow - start_row + 1);
+
+ /*
+ * calculate region info.
+ */
+ regStart = start_row << raid->stripeShift;
+ regSize = stripSize;
+
+ /* Check if we can send this I/O via FastPath */
+ if (raid->capability.fpCapable) {
+ if (isRead) {
+ io_info->fpOkForIo = (raid->capability.fpReadCapable &&
+ ((num_strips == 1) ||
+ raid->capability.fpReadAcrossStripe));
+ } else {
+ io_info->fpOkForIo =
+ (raid->capability.fpWriteCapable &&
+ ((num_strips == 1) ||
+ raid->capability.fpWriteAcrossStripe));
+ }
+ } else
+ io_info->fpOkForIo = FALSE;
+
+
+ /*
+ * Check for DIF support
+ */
+ if (!raid->capability.ldPiMode) {
+ io_info->ldPI = FALSE;
+ } else {
+ io_info->ldPI = TRUE;
+ }
+
+ if (numRows == 1) {
+ if (num_strips == 1) {
+ regStart += ref_in_start_stripe;
+ regSize = numBlocks;
+ }
+ } else {
+ if (start_strip == (start_row + 1) * raid->rowDataSize - 1) {
+ regStart += ref_in_start_stripe;
+ regSize = stripSize - ref_in_start_stripe;
+ }
+
+ if (numRows > 2) {
+ regSize += (numRows - 2) << raid->stripeShift;
+ }
+
+ if (endStrip == endRow * raid->rowDataSize) {
+ regSize += ref_in_end_stripe + 1;
+ } else {
+ regSize += stripSize;
+ }
+ }
+
+ pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec;
+
+ if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {
+ pRAID_Context->regLockFlags = (isRead) ?
+ raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
+ } else {
+ pRAID_Context->regLockFlags = (isRead) ?
+ REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite;
+ }
+
+ pRAID_Context->ldTargetId = raid->targetId;
+ pRAID_Context->regLockRowLBA = regStart;
+ pRAID_Context->regLockLength = regSize;
+ pRAID_Context->configSeqNum = raid->seqNum;
+
+ /*
+ * Get Phy Params only if FP capable,
+ * or else leave it to MR firmware to do the calculation.
+ */
+ if (io_info->fpOkForIo) {
+ /* if fast path possible then get the physical parameters */
+ retval = MR_GetPhyParams(instance, ld, start_strip,
+ ref_in_start_stripe, &io_info->pdBlock,
+ &io_info->devHandle, pRAID_Context, map);
+
+ /* If IO on an invalid Pd, then FP is not possible. */
+ if (io_info->devHandle == MR_PD_INVALID)
+ io_info->fpOkForIo = FALSE;
+
+ return (retval);
+
+ } else if (isRead) {
+ uint_t stripIdx;
+
+ for (stripIdx = 0; stripIdx < num_strips; stripIdx++) {
+ if (!MR_GetPhyParams(instance, ld,
+ start_strip + stripIdx, ref_in_start_stripe,
+ &io_info->pdBlock, &io_info->devHandle,
+ pRAID_Context, map)) {
+ return (TRUE);
+ }
+ }
+ }
+ return (TRUE);
+}
+
+
+void
+mr_update_load_balance_params(MR_FW_RAID_MAP_ALL *map,
+ PLD_LOAD_BALANCE_INFO lbInfo)
+{
+ int ldCount;
+ U16 ld;
+ MR_LD_RAID *raid;
+
+ for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
+ ld = MR_TargetIdToLdGet(ldCount, map);
+
+ if (ld >= MAX_LOGICAL_DRIVES) {
+ con_log(CL_ANN1,
+ (CE_NOTE, "mrsas: ld=%d Invalid ld \n", ld));
+ continue;
+ }
+
+ raid = MR_LdRaidGet(ld, map);
+
+ /* Two drive Optimal RAID 1 */
+ if ((raid->level == 1) && (raid->rowSize == 2) &&
+ (raid->spanDepth == 1) &&
+ raid->ldState == MR_LD_STATE_OPTIMAL) {
+ U32 pd, arRef;
+
+ lbInfo[ldCount].loadBalanceFlag = 1;
+
+ /* Get the array on which this span is present. */
+ arRef = MR_LdSpanArrayGet(ld, 0, map);
+
+ pd = MR_ArPdGet(arRef, 0, map); /* Get the Pd. */
+ /* Get dev handle from Pd. */
+ lbInfo[ldCount].raid1DevHandle[0] =
+ MR_PdDevHandleGet(pd, map);
+
+ pd = MR_ArPdGet(arRef, 1, map); /* Get the Pd. */
+ /* Get dev handle from Pd. */
+ lbInfo[ldCount].raid1DevHandle[1] =
+ MR_PdDevHandleGet(pd, map);
+ con_log(CL_ANN1, (CE_NOTE,
+ "mrsas: ld=%d load balancing enabled \n", ldCount));
+ } else {
+ lbInfo[ldCount].loadBalanceFlag = 0;
+ }
+ }
+}
+
+
+U8
+megasas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, U8 arm, U64 block,
+ U32 count)
+{
+ U16 pend0, pend1;
+ U64 diff0, diff1;
+ U8 bestArm;
+
+ /* get the pending cmds for the data and mirror arms */
+ pend0 = lbInfo->scsi_pending_cmds[0];
+ pend1 = lbInfo->scsi_pending_cmds[1];
+
+ /* Determine the disk whose head is nearer to the req. block */
+ diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]);
+ diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]);
+ bestArm = (diff0 <= diff1 ? 0 : 1);
+
+ if ((bestArm == arm && pend0 > pend1 + 16) ||
+ (bestArm != arm && pend1 > pend0 + 16)) {
+ bestArm ^= 1;
+ }
+
+ /* Update the last accessed block on the correct pd */
+ lbInfo->last_accessed_block[bestArm] = block + count - 1;
+ return (bestArm);
+}
+
+U16
+get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
+ struct IO_REQUEST_INFO *io_info)
+{
+ U8 arm, old_arm;
+ U16 devHandle;
+
+ old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1;
+
+ /* get best new arm */
+ arm = megasas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock,
+ io_info->numBlocks);
+
+ devHandle = lbInfo->raid1DevHandle[arm];
+
+ lbInfo->scsi_pending_cmds[arm]++;
+
+ return (devHandle);
+}
View
249 usr/src/uts/common/io/mr_sas/ld_pd_map.h
@@ -0,0 +1,249 @@
+/*
+ * ld_pd_map.h
+ *
+ * Solaris MegaRAID device driver for SAS2.0 controllers
+ * Copyright (c) 2008-2012, LSI Logic Corporation.
+ * All rights reserved.
+ *
+ * Version:
+ * Author:
+ * Swaminathan K S
+ * Arun Chandrashekhar
+ * Manju R
+ * Rasheed
+ * Shakeel Bukhari
+ */
+
+#ifndef _LD_PD_MAP
+#define _LD_PD_MAP
+#include <sys/scsi/scsi.h>
+#include "fusion.h"
+
+struct mrsas_instance; /* This will be defined in mr_sas.h */
+
+/* raid->write_mode; raid->read_ahead; dcmd->state */
+/* Write through */
+#define WRITE_THROUGH 0
+/* Delayed Write */
+#define WRITE_BACK 1
+
+/* SCSI CDB definitions */
+#define READ_6 0x08
+#define READ_16 0x88
+#define READ_10 0x28
+#define READ_12 0xA8
+#define WRITE_16 0x8A
+#define WRITE_10 0x2A
+
+/* maximum disks per array */
+#define MAX_ROW_SIZE 32
+/* maximum spans per logical drive */
+#define MAX_SPAN_DEPTH 8
+#define MEGASAS_LOAD_BALANCE_FLAG 0x1
+#define MR_DEFAULT_IO_TIMEOUT 20
+
+
+union desc_value {
+ U64 word;
+ struct {
+ U32 low;
+ U32 high;
+ } u1;
+};
+
+typedef struct _LD_LOAD_BALANCE_INFO
+{
+ U8 loadBalanceFlag;
+ U8 reserved1;
+ U16 raid1DevHandle[2];
+ U16 scsi_pending_cmds[2];
+ U64 last_accessed_block[2];
+} LD_LOAD_BALANCE_INFO, *PLD_LOAD_BALANCE_INFO;
+
+#pragma pack(1)
+typedef struct _MR_FW_RAID_MAP_ALL {
+ MR_FW_RAID_MAP raidMap;
+ MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1];
+} MR_FW_RAID_MAP_ALL;
+
+/*
+ * Raid Context structure which describes MegaRAID specific IO Parameters
+ * This resides at offset 0x60 where the SGL normally starts in MPT IO Frames
+ */
+typedef struct _MPI2_SCSI_IO_VENDOR_UNIQUE {
+ U8 nsegType; /* 0x00 nseg[7:4], Type[3:0] */
+ U8 resvd0; /* 0x01 */
+ U16 timeoutValue; /* 0x02 -0x03 */
+ U8 regLockFlags; /* 0x04 */
+ U8 reservedForHw1; /* 0x05 */
+ U16 ldTargetId; /* 0x06 - 0x07 */
+ U64 regLockRowLBA; /* 0x08 - 0x0F */
+ U32 regLockLength; /* 0x10 - 0x13 */
+ U16 nextLMId; /* 0x14 - 0x15 */
+ U8 extStatus; /* 0x16 */
+ U8 status; /* 0x17 status */
+ U8 RAIDFlags; /* 0x18 resvd[7:6], ioSubType[5:4], */
+ /* resvd[3:1], preferredCpu[0] */
+ U8 numSGE; /* 0x19 numSge; not including chain entries */
+ U16 configSeqNum; /* 0x1A -0x1B */
+ U8 spanArm; /* 0x1C span[7:5], arm[4:0] */
+ U8 resvd2[3]; /* 0x1D-0x1f */
+} MPI2_SCSI_IO_VENDOR_UNIQUE, MPI25_SCSI_IO_VENDOR_UNIQUE;
+
+#define RAID_CTX_SPANARM_ARM_SHIFT (0)
+#define RAID_CTX_SPANARM_ARM_MASK (0x1f)
+
+#define RAID_CTX_SPANARM_SPAN_SHIFT (5)
+#define RAID_CTX_SPANARM_SPAN_MASK (0xE0)
+
+
+/*
+ * RAID SCSI IO Request Message
+ * Total SGE count will be one less
+ * than _MPI2_SCSI_IO_REQUEST
+ */
+typedef struct _MPI2_RAID_SCSI_IO_REQUEST
+{
+ uint16_t DevHandle; /* 0x00 */
+ uint8_t ChainOffset; /* 0x02 */
+ uint8_t Function; /* 0x03 */
+ uint16_t Reserved1; /* 0x04 */
+ uint8_t Reserved2; /* 0x06 */
+ uint8_t MsgFlags; /* 0x07 */
+ uint8_t VP_ID; /* 0x08 */
+ uint8_t VF_ID; /* 0x09 */
+ uint16_t Reserved3; /* 0x0A */
+ uint32_t SenseBufferLowAddress; /* 0x0C */
+ uint16_t SGLFlags; /* 0x10 */
+ uint8_t SenseBufferLength; /* 0x12 */
+ uint8_t Reserved4; /* 0x13 */
+ uint8_t SGLOffset0; /* 0x14 */
+ uint8_t SGLOffset1; /* 0x15 */
+ uint8_t SGLOffset2; /* 0x16 */
+ uint8_t SGLOffset3; /* 0x17 */
+ uint32_t SkipCount; /* 0x18 */
+ uint32_t DataLength; /* 0x1C */
+ uint32_t BidirectionalDataLength; /* 0x20 */
+ uint16_t IoFlags; /* 0x24 */
+ uint16_t EEDPFlags; /* 0x26 */
+ uint32_t EEDPBlockSize; /* 0x28 */
+ uint32_t SecondaryReferenceTag; /* 0x2C */
+ uint16_t SecondaryApplicationTag; /* 0x30 */
+ uint16_t ApplicationTagTranslationMask; /* 0x32 */
+ uint8_t LUN[8]; /* 0x34 */
+ uint32_t Control; /* 0x3C */
+ Mpi2ScsiIoCdb_t CDB; /* 0x40 */
+ MPI2_SCSI_IO_VENDOR_UNIQUE RaidContext; /* 0x60 */
+ Mpi2SGEIOUnion_t SGL; /* 0x80 */
+} MPI2_RAID_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_RAID_SCSI_IO_REQUEST,
+Mpi2RaidSCSIIORequest_t, MPI2_POINTER pMpi2RaidSCSIIORequest_t;
+
+/*
+ * define region lock types
+ */
+typedef enum _REGION_TYPE {
+ REGION_TYPE_UNUSED = 0, /* lock is currently not active */
+ REGION_TYPE_SHARED_READ = 1, /* shared lock (for reads) */
+ REGION_TYPE_SHARED_WRITE = 2,
+ REGION_TYPE_EXCLUSIVE = 3 /* exclusive lock (for writes) */
+} REGION_TYPE;
+
+
+#define DM_PATH_MAXPATH 2
+#define DM_PATH_FIRSTPATH 0
+#define DM_PATH_SECONDPATH 1
+
+/* declare valid Region locking values */
+typedef enum _REGION_LOCK {
+ REGION_LOCK_BYPASS = 0,
+ /* for RAID 6 single-drive failure */
+ REGION_LOCK_UNCOND_SHARED_READ = 1,
+ REGION_LOCK_UNCOND_SHARED_WRITE = 2,
+ REGION_LOCK_UNCOND_SHARED_OTHER = 3,
+ REGION_LOCK_UNCOND_SHARED_EXCLUSIVE = 0xFF
+} REGION_LOCK;
+
+
+struct mrsas_init_frame2 {
+ uint8_t cmd; /* 00h */
+ uint8_t reserved_0; /* 01h */
+ uint8_t cmd_status; /* 02h */
+
+ uint8_t reserved_1; /* 03h */
+ uint32_t reserved_2; /* 04h */
+
+ uint32_t context; /* 08h */
+ uint32_t pad_0; /* 0Ch */
+
+ uint16_t flags; /* 10h */
+ uint16_t reserved_3; /* 12h */
+ uint32_t data_xfer_len; /* 14h */
+
+ uint32_t queue_info_new_phys_addr_lo; /* 18h */
+ uint32_t queue_info_new_phys_addr_hi; /* 1Ch */
+ uint32_t queue_info_old_phys_addr_lo; /* 20h */
+ uint32_t queue_info_old_phys_addr_hi; /* 24h */
+ uint64_t driverversion; /* 28h */
+ uint32_t reserved_4[4]; /* 30h */
+};
+
+
+/*
+ * Request descriptor types
+ */
+#define MPI2_REQ_DESCRIPT_FLAGS_LD_IO 0x7
+#define MPI2_REQ_DESCRIPT_FLAGS_MFA 0x1
+#define MPI2_REQ_DESCRIPT_FLAGS_NO_LOCK 0x2
+
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 1
+
+
+/*
+ * MPT RAID MFA IO Descriptor.
+ */
+typedef struct _MR_RAID_MFA_IO_DESCRIPTOR {
+ uint32_t RequestFlags : 8;
+ uint32_t MessageAddress1 : 24; /* bits 31:8 */
+ uint32_t MessageAddress2; /* bits 61:32 */
+} MR_RAID_MFA_IO_REQUEST_DESCRIPTOR,
+*PMR_RAID_MFA_IO_REQUEST_DESCRIPTOR;
+
+/* union of Request Descriptors */
+typedef union _MRSAS_REQUEST_DESCRIPTOR_UNION
+{
+ MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
+ MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority;
+ MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO;
+ MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
+ MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
+ MR_RAID_MFA_IO_REQUEST_DESCRIPTOR MFAIo;
+ U64 Words;
+} MRSAS_REQUEST_DESCRIPTOR_UNION;
+
+#pragma pack()
+
+enum {
+ MRSAS_SCSI_VARIABLE_LENGTH_CMD = 0x7F,
+ MRSAS_SCSI_SERVICE_ACTION_READ32 = 0x9,
+ MRSAS_SCSI_SERVICE_ACTION_WRITE32 = 0xB,
+ MRSAS_SCSI_ADDL_CDB_LEN = 0x18,
+ MRSAS_RD_WR_PROTECT = 0x20,
+ MRSAS_EEDPBLOCKSIZE = 512
+};
+
+
+#define IEEE_SGE_FLAGS_ADDR_MASK (0x03)
+#define IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00)
+#define IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01)
+#define IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02)
+#define IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03)
+#define IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80)
+#define IEEE_SGE_FLAGS_END_OF_LIST (0x40)
+
+
+U8 MR_ValidateMapInfo(MR_FW_RAID_MAP_ALL *map, PLD_LOAD_BALANCE_INFO lbInfo);
+U16 MR_CheckDIF(U32, MR_FW_RAID_MAP_ALL *);
+U8 MR_BuildRaidContext(struct mrsas_instance *, struct IO_REQUEST_INFO *,
+ MPI2_SCSI_IO_VENDOR_UNIQUE *, MR_FW_RAID_MAP_ALL *);
+
+#endif /* _LD_PD_MAP */
View
3,448 usr/src/uts/common/io/mr_sas/mr_sas.c
2,410 additions, 1,038 deletions not shown
View
12 usr/src/uts/common/io/mr_sas/mr_sas.conf
@@ -1,13 +1,15 @@
#
-# Copyright (c) 2008-2009, LSI Logic Corporation.
+# Copyright (c) 2008-2012, LSI Logic Corporation.
# All rights reserved.
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
#
# mr_sas.conf for sol 10 (and later) for all supported architectures
#
-# global definitions
+
+# MSI specific flag. Default is "yes".
+# mrsas-enable-msi="yes";
+
+# Fast-Path specific flag. Default is "yes".
+# mrsas-enable-fp="yes";
View
944 usr/src/uts/common/io/mr_sas/mr_sas.h
@@ -2,9 +2,17 @@
* mr_sas.h: header for mr_sas
*
* Solaris MegaRAID driver for SAS2.0 controllers
- * Copyright (c) 2008-2009, LSI Logic Corporation.
+ * Copyright (c) 2008-2012, LSI Logic Corporation.
* All rights reserved.
*
+ * Version:
+ * Author:
+ * Swaminathan K S
+ * Arun Chandrashekhar
+ * Manju R
+ * Rasheed
+ * Shakeel Bukhari
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
@@ -36,6 +44,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
+
#ifndef _MR_SAS_H_
#define _MR_SAS_H_
@@ -45,12 +54,13 @@ extern "C" {
#include <sys/scsi/scsi.h>
#include "mr_sas_list.h"
+#include "ld_pd_map.h"
/*
* MegaRAID SAS2.0 Driver meta data
*/
-#define MRSAS_VERSION "LSIv2.7"
-#define MRSAS_RELDATE "Apr 21, 2010"
+#define MRSAS_VERSION "6.503.00.00ILLUMOS"
+#define MRSAS_RELDATE "July 30, 2012"
#define MRSAS_TRUE 1
#define MRSAS_FALSE 0
@@ -58,16 +68,30 @@ extern "C" {
#define ADAPTER_RESET_NOT_REQUIRED 0
#define ADAPTER_RESET_REQUIRED 1
+#define PDSUPPORT 1
+
/*
* MegaRAID SAS2.0 device id conversion definitions.
*/
#define INST2LSIRDCTL(x) ((x) << INST_MINOR_SHIFT)
+#define MRSAS_GET_BOUNDARY_ALIGNED_LEN(len, new_len, boundary_len) { \
+ int rem; \
+ rem = (len / boundary_len); \
+ if ((rem * boundary_len) != len) { \
+ new_len = len + ((rem + 1) * boundary_len - len); \
+ } else { \
+ new_len = len; \
+ } \
+}
+
/*
* MegaRAID SAS2.0 supported controllers
*/
#define PCI_DEVICE_ID_LSI_2108VDE 0x0078
#define PCI_DEVICE_ID_LSI_2108V 0x0079
+#define PCI_DEVICE_ID_LSI_TBOLT 0x005b
+#define PCI_DEVICE_ID_LSI_INVADER 0x005d
/*
* Register Index for 2108 Controllers.
@@ -75,6 +99,7 @@ extern "C" {
#define REGISTER_SET_IO_2108 (2)
#define MRSAS_MAX_SGE_CNT 0x50
+#define MRSAS_APP_RESERVED_CMDS 32
#define MRSAS_IOCTL_DRIVER 0x12341234
#define MRSAS_IOCTL_FIRMWARE 0x12345678
@@ -82,13 +107,50 @@ extern "C" {
#define MRSAS_1_SECOND 1000000
+#ifdef PDSUPPORT
+
+#define UNCONFIGURED_GOOD 0x0
+#define PD_SYSTEM 0x40
+#define MR_EVT_PD_STATE_CHANGE 0x0072
+#define MR_EVT_PD_REMOVED_EXT 0x00f8
+#define MR_EVT_PD_INSERTED_EXT 0x00f7
+#define MR_DCMD_PD_GET_INFO 0x02020000
+#define MRSAS_TBOLT_PD_LUN 1
+#define MRSAS_TBOLT_PD_TGT_MAX 255
+#define MRSAS_TBOLT_GET_PD_MAX(s) ((s)->mr_tbolt_pd_max)
+
+#endif
+
+/* Raid Context Flags */
+#define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT 0x4
+#define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_MASK 0x30
+typedef enum MR_RAID_FLAGS_IO_SUB_TYPE {
+ MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0,
+ MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1
+} MR_RAID_FLAGS_IO_SUB_TYPE;
+
/* Dynamic Enumeration Flags */
-#define MRSAS_PD_LUN 1
#define MRSAS_LD_LUN 0
-#define MRSAS_PD_TGT_MAX 255
-#define MRSAS_GET_PD_MAX(s) ((s)->mr_pd_max)
#define WWN_STRLEN 17
-#define APP_RESERVE_CMDS 32
+#define LD_SYNC_BIT 1
+#define LD_SYNC_SHIFT 14
+/* ThunderBolt (TB) specific */
+#define MRSAS_THUNDERBOLT_MSG_SIZE 256
+#define MRSAS_THUNDERBOLT_MAX_COMMANDS 1024
+#define MRSAS_THUNDERBOLT_MAX_REPLY_COUNT 1024
+#define MRSAS_THUNDERBOLT_REPLY_SIZE 8
+#define MRSAS_THUNDERBOLT_MAX_CHAIN_COUNT 1
+
+#define MPI2_FUNCTION_PASSTHRU_IO_REQUEST 0xF0
+#define MPI2_FUNCTION_LD_IO_REQUEST 0xF1
+
+#define MR_EVT_LD_FAST_PATH_IO_STATUS_CHANGED (0xFFFF)
+
+#define MR_INTERNAL_MFI_FRAMES_SMID 1
+#define MR_CTRL_EVENT_WAIT_SMID 2
+#define MR_INTERNAL_DRIVER_RESET_SMID 3
+
+
/*
* =====================================
* MegaRAID SAS2.0 MFI firmware definitions
@@ -103,19 +165,18 @@ extern "C" {
/*
* FW posts its state in upper 4 bits of outbound_msg_0 register
*/
-#define MFI_STATE_SHIFT 28
-#define MFI_STATE_MASK ((uint32_t)0xF<<MFI_STATE_SHIFT)
-#define MFI_STATE_UNDEFINED ((uint32_t)0x0<<MFI_STATE_SHIFT)
-#define MFI_STATE_BB_INIT ((uint32_t)0x1<<MFI_STATE_SHIFT)
-#define MFI_STATE_FW_INIT ((uint32_t)0x4<<MFI_STATE_SHIFT)
-#define MFI_STATE_WAIT_HANDSHAKE ((uint32_t)0x6<<MFI_STATE_SHIFT)
-#define MFI_STATE_FW_INIT_2 ((uint32_t)0x7<<MFI_STATE_SHIFT)
-#define MFI_STATE_DEVICE_SCAN ((uint32_t)0x8<<MFI_STATE_SHIFT)
-#define MFI_STATE_BOOT_MESSAGE_PENDING ((uint32_t)0x9<<MFI_STATE_SHIFT)
-#define MFI_STATE_FLUSH_CACHE ((uint32_t)0xA<<MFI_STATE_SHIFT)
-#define MFI_STATE_READY ((uint32_t)0xB<<MFI_STATE_SHIFT)
-#define MFI_STATE_OPERATIONAL ((uint32_t)0xC<<MFI_STATE_SHIFT)
-#define MFI_STATE_FAULT ((uint32_t)0xF<<MFI_STATE_SHIFT)
+#define MFI_STATE_MASK 0xF0000000
+#define MFI_STATE_UNDEFINED 0x00000000
+#define MFI_STATE_BB_INIT 0x10000000
+#define MFI_STATE_FW_INIT 0x40000000
+#define MFI_STATE_WAIT_HANDSHAKE 0x60000000
+#define MFI_STATE_FW_INIT_2 0x70000000
+#define MFI_STATE_DEVICE_SCAN 0x80000000
+#define MFI_STATE_BOOT_MESSAGE_PENDING 0x90000000
+#define MFI_STATE_FLUSH_CACHE 0xA0000000
+#define MFI_STATE_READY 0xB0000000
+#define MFI_STATE_OPERATIONAL 0xC0000000
+#define MFI_STATE_FAULT 0xF0000000
#define MRMFI_FRAME_SIZE 64
@@ -148,7 +209,7 @@ extern "C" {
#define MFI_FRAME_DIR_WRITE 0x0008
#define MFI_FRAME_DIR_READ 0x0010
#define MFI_FRAME_DIR_BOTH 0x0018
-#define MFI_FRAME_IEEE 0x0020
+#define MFI_FRAME_IEEE 0x0020
/*
* Definition for cmd_status
@@ -182,12 +243,12 @@ extern "C" {
#define MR_DCMD_CTRL_EVENT_GET 0x01040300
#define MR_DCMD_CTRL_EVENT_WAIT 0x01040500
#define MR_DCMD_LD_GET_PROPERTIES 0x03030000
-#define MR_DCMD_PD_GET_INFO 0x02020000
/*
* Solaris Specific MAX values
*/
#define MAX_SGL 24
+
/*
* MFI command completion codes
*/
@@ -244,7 +305,6 @@ enum MFI_STAT {
MFI_STAT_TIME_NOT_SET = 0x31,
MFI_STAT_WRONG_STATE = 0x32,
MFI_STAT_LD_OFFLINE = 0x33,
- /* UNUSED: 0x34 to 0xfe */
MFI_STAT_INVALID_STATUS = 0xFF
};
@@ -270,11 +330,34 @@ enum MR_EVT_LOCALE {
MR_EVT_LOCALE_ALL = 0xffff
};
+enum MR_EVT_ARGS {
+ MR_EVT_ARGS_NONE,
+ MR_EVT_ARGS_CDB_SENSE,
+ MR_EVT_ARGS_LD,
+ MR_EVT_ARGS_LD_COUNT,
+ MR_EVT_ARGS_LD_LBA,
+ MR_EVT_ARGS_LD_OWNER,
+ MR_EVT_ARGS_LD_LBA_PD_LBA,
+ MR_EVT_ARGS_LD_PROG,
+ MR_EVT_ARGS_LD_STATE,
+ MR_EVT_ARGS_LD_STRIP,
+ MR_EVT_ARGS_PD,
+ MR_EVT_ARGS_PD_ERR,
+ MR_EVT_ARGS_PD_LBA,
+ MR_EVT_ARGS_PD_LBA_LD,
+ MR_EVT_ARGS_PD_PROG,
+ MR_EVT_ARGS_PD_STATE,
+ MR_EVT_ARGS_PCI,
+ MR_EVT_ARGS_RATE,
+ MR_EVT_ARGS_STR,
+ MR_EVT_ARGS_TIME,
+ MR_EVT_ARGS_ECC
+};
+
#define MR_EVT_CFG_CLEARED 0x0004
#define MR_EVT_LD_CREATED 0x008a
#define MR_EVT_LD_DELETED 0x008b
-#define MR_EVT_PD_REMOVED_EXT 0x00f8
-#define MR_EVT_PD_INSERTED_EXT 0x00f7
+#define MR_EVT_CFG_FP_CHANGE 0x017B
enum LD_STATE {
LD_OFFLINE = 0,
@@ -302,6 +385,7 @@ enum MRSAS_EVT {
* @param dma_handle : dma handle
* @param dma_cookie : scatter-gather list
* @param dma_attr : dma attributes for this buffer
+ *
* Our DMA object. The caller must initialize the size and dma attributes
* (dma_attr) fields before allocating the resources.
*/
@@ -321,23 +405,26 @@ struct mrsas_eventinfo {
int tgt;
int lun;
int event;
+ uint64_t wwn;
};
struct mrsas_ld {
dev_info_t *dip;
uint8_t lun_type;
- uint8_t reserved[3];
+ uint8_t flag;
+ uint8_t reserved[2];
};
-struct mrsas_pd {
+
+#ifdef PDSUPPORT
+struct mrsas_tbolt_pd {
dev_info_t *dip;
uint8_t lun_type;
uint8_t dev_id;
- uint8_t flags;
+ uint8_t flag;
uint8_t reserved;
};
-
-struct mrsas_pd_info {
+struct mrsas_tbolt_pd_info {
uint16_t deviceId;
uint16_t seqNum;
uint8_t inquiryData[96];
@@ -363,6 +450,7 @@ struct mrsas_pd_info {
uint8_t reserved2[16];
} pathInfo;
};
+#endif
typedef struct mrsas_instance {
uint32_t *producer;
@@ -372,6 +460,12 @@ typedef struct mrsas_instance {
dma_obj_t mfi_internal_dma_obj;
uint16_t adapterresetinprogress;
uint16_t deadadapter;
+ /* ThunderBolt (TB) specific */
+ dma_obj_t mpi2_frame_pool_dma_obj;
+ dma_obj_t request_desc_dma_obj;
+ dma_obj_t reply_desc_dma_obj;
+ dma_obj_t ld_map_obj[2];
+
uint8_t init_id;
uint8_t flag_ieee;
uint8_t disable_online_ctrl_reset;
@@ -382,11 +476,17 @@ typedef struct mrsas_instance {
uint32_t max_sectors_per_req;
struct mrsas_cmd **cmd_list;
+
mlist_t cmd_pool_list;
kmutex_t cmd_pool_mtx;
+ kmutex_t sync_map_mtx;
mlist_t app_cmd_pool_list;
kmutex_t app_cmd_pool_mtx;
+ mlist_t cmd_app_pool_list;
+ kmutex_t cmd_app_pool_mtx;
+
+
mlist_t cmd_pend_list;
kmutex_t cmd_pend_mtx;
@@ -407,6 +507,9 @@ typedef struct mrsas_instance {
kcondvar_t abort_cmd_cv;
kmutex_t abort_cmd_mtx;
+ kmutex_t reg_write_mtx;
+ kmutex_t chip_mtx;
+
dev_info_t *dip;
ddi_acc_handle_t pci_handle;
@@ -420,6 +523,7 @@ typedef struct mrsas_instance {
ddi_iblock_cookie_t soft_iblock_cookie;
ddi_softintr_t soft_intr_id;
uint8_t softint_running;
+ uint8_t tbolt_softint_running;
kmutex_t completed_pool_mtx;
mlist_t completed_pool_list;
@@ -436,23 +540,99 @@ typedef struct mrsas_instance {
char iocnode[16];
int fm_capabilities;
+ /*
+ * Driver resources unroll flags. The flag is set for resources that
+ * are needed to be free'd at detach() time.
+ */
+ struct _unroll {
+ uint8_t softs; /* The software state was allocated. */
+ uint8_t regs; /* Controller registers mapped. */
+ uint8_t intr; /* Interrupt handler added. */
+ uint8_t reqs; /* Request structs allocated. */
+ uint8_t mutexs; /* Mutex's allocated. */
+ uint8_t taskq; /* Task q's created. */
+ uint8_t tran; /* Tran struct allocated */
+ uint8_t tranSetup; /* Tran attached to the ddi. */
+ uint8_t devctl; /* Device nodes for cfgadm created. */
+ uint8_t scsictl; /* Device nodes for cfgadm created. */
+ uint8_t ioctl; /* Device nodes for ioctl's created. */
+ uint8_t timer; /* Timer started. */
+ uint8_t aenPend; /* AEN cmd pending f/w. */
+ uint8_t mapUpdate_pend; /* LD MAP update cmd pending f/w. */
+ uint8_t soft_isr; /* Soft interrupt handler allocated. */
+ uint8_t ldlist_buff; /* Logical disk list allocated. */
+ uint8_t pdlist_buff; /* Physical disk list allocated. */
+ uint8_t syncCmd; /* Sync map command allocated. */
+ uint8_t verBuff; /* 2108 MFI buffer allocated. */
+ uint8_t alloc_space_mfi; /* Allocated space for 2108 MFI. */
+ uint8_t alloc_space_mpi2; /* Allocated space for 2208 MPI2. */
+ } unroll;
+
+
+ /* function template pointer */
+ struct mrsas_function_template *func_ptr;
+
- struct mrsas_func_ptr *func_ptr;
/* MSI interrupts specific */
- ddi_intr_handle_t *intr_htable;
+ ddi_intr_handle_t *intr_htable; /* Interrupt handle array */
+ size_t intr_htable_size; /* Int. handle array size */
int intr_type;
int intr_cnt;
- size_t intr_size;
uint_t intr_pri;
int intr_cap;
ddi_taskq_t *taskq;
struct mrsas_ld *mr_ld_list;
+ kmutex_t config_dev_mtx;
+ /* ThunderBolt (TB) specific */
+ ddi_softintr_t tbolt_soft_intr_id;
+
+#ifdef PDSUPPORT
+ uint32_t mr_tbolt_pd_max;
+ struct mrsas_tbolt_pd *mr_tbolt_pd_list;
+#endif
+
+ uint8_t fast_path_io;
+
+ uint16_t tbolt;
+ uint16_t reply_read_index;
+ uint16_t reply_size; /* Single Reply struct size */
+ uint16_t raid_io_msg_size; /* Single message size */
+ uint32_t io_request_frames_phy;
+ uint8_t *io_request_frames;
+ /* Virtual address of request desc frame pool */
+ MRSAS_REQUEST_DESCRIPTOR_UNION *request_message_pool;
+ /* Physical address of request desc frame pool */
+ uint32_t request_message_pool_phy;
+ /* Virtual address of reply Frame */
+ MPI2_REPLY_DESCRIPTORS_UNION *reply_frame_pool;
+ /* Physical address of reply Frame */
+ uint32_t reply_frame_pool_phy;
+ uint8_t *reply_pool_limit; /* Last reply frame address */
+ /* Physical address of Last reply frame */
+ uint32_t reply_pool_limit_phy;
+ uint32_t reply_q_depth; /* Reply Queue Depth */
+ uint8_t max_sge_in_main_msg;
+ uint8_t max_sge_in_chain;
+ uint8_t chain_offset_io_req;
+ uint8_t chain_offset_mpt_msg;
+ MR_FW_RAID_MAP_ALL *ld_map[2];
+ uint32_t ld_map_phy[2];
+ uint32_t size_map_info;
+ uint64_t map_id;
+ LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES];
+ struct mrsas_cmd *map_update_cmd;
+ uint32_t SyncRequired;
kmutex_t ocr_flags_mtx;
+ dma_obj_t drv_ver_dma_obj;
} mrsas_t;
-struct mrsas_func_ptr {
- int (*read_fw_status_reg)(struct mrsas_instance *);
+
+/*
+ * Function templates for various controller specific functions
+ */
+struct mrsas_function_template {
+ uint32_t (*read_fw_status_reg)(struct mrsas_instance *);
void (*issue_cmd)(struct mrsas_cmd *, struct mrsas_instance *);
int (*issue_cmd_in_sync_mode)(struct mrsas_instance *,
struct mrsas_cmd *);
@@ -461,6 +641,8 @@ struct mrsas_func_ptr {
void (*enable_intr)(struct mrsas_instance *);
void (*disable_intr)(struct mrsas_instance *);
int (*intr_ack)(struct mrsas_instance *);
+ int (*init_adapter)(struct mrsas_instance *);
+/* int (*reset_adapter)(struct mrsas_instance *); */
};
/*
@@ -480,13 +662,11 @@ struct mrsas_func_ptr {
* console messages debug levels
*/
#define CL_NONE 0 /* No debug information */
-#define CL_TEST_OCR 1
-#define CL_ANN 2 /* print unconditionally, announcements */
-#define CL_ANN1 3 /* No o/p */
-#define CL_DLEVEL1 4 /* debug level 1, informative */
-#define CL_DLEVEL2 5 /* debug level 2, verbose */
-#define CL_DLEVEL3 6 /* debug level 3, very verbose */
-
+#define CL_ANN 1 /* print unconditionally, announcements */
+#define CL_ANN1 2 /* No-op */
+#define CL_DLEVEL1 3 /* debug level 1, informative */
+#define CL_DLEVEL2 4 /* debug level 2, verbose */
+#define CL_DLEVEL3 5 /* debug level 3, very verbose */
#ifdef __SUNPRO_C
#define __func__ ""
@@ -547,9 +727,9 @@ struct mrsas_func_ptr {
#define HIGH_LEVEL_INTR 1
#define NORMAL_LEVEL_INTR 0
+#define IO_TIMEOUT_VAL 0
#define IO_RETRY_COUNT 3
#define MAX_FW_RESET_COUNT 3
-
/*
* scsa_cmd - Per-command mr private data
* @param cmd_dmahandle : dma handle
@@ -598,13 +778,20 @@ struct scsa_cmd {
struct mrsas_cmd {
+ /*
+ * ThunderBolt(TB) We would be needing to have a placeholder
+ * for RAID_MSG_IO_REQUEST inside this structure. We are
+ * supposed to embed the mr_frame inside the RAID_MSG and post
+ * it down to the firmware.
+ */
union mrsas_frame *frame;
uint32_t frame_phys_addr;
uint8_t *sense;
+ uint8_t *sense1;
uint32_t sense_phys_addr;
+ uint32_t sense_phys_addr1;
dma_obj_t frame_dma_obj;
uint8_t frame_dma_obj_status;
-
uint32_t index;
uint8_t sync_cmd;
uint8_t cmd_status;
@@ -613,8 +800,16 @@ struct mrsas_cmd {
uint32_t frame_count;
struct scsa_cmd *cmd;
struct scsi_pkt *pkt;
+ Mpi2RaidSCSIIORequest_t *scsi_io_request;
+ Mpi2SGEIOUnion_t *sgl;
+ uint32_t sgl_phys_addr;
+ uint32_t scsi_io_request_phys_addr;
+ MRSAS_REQUEST_DESCRIPTOR_UNION *request_desc;
+ uint16_t SMID;
uint16_t retry_count_for_ocr;
uint16_t drv_pkt_time;
+ uint16_t load_balance_flag;
+
};
#define MAX_MGMT_ADAPTERS 1024
@@ -637,8 +832,8 @@ struct mrsas_mgmt_info {
int max_index;
};
-#pragma pack(1)
+#pragma pack(1)
/*
* SAS controller properties
*/
@@ -662,6 +857,7 @@ struct mrsas_ctrl_prop {
uint8_t cluster_enable;
uint8_t coercion_mode;
uint8_t alarm_enable;
+
uint8_t reserved_1[13];
uint32_t on_off_properties;
uint8_t reserved_4[28];
@@ -867,12 +1063,15 @@ struct mrsas_ctrl_info {
#define MRSAS_IOCTL_CMD 0
+#define MRDRV_TGT_VALID 1
+
/*
* FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
* SGLs based on the size of dma_addr_t
*/
#define IS_DMA64 (sizeof (dma_addr_t) == 8)
+#define RESERVED0_REGISTER 0x00 /* XScale */
#define IB_MSG_0_OFF 0x10 /* XScale */
#define OB_MSG_0_OFF 0x18 /* XScale */
#define IB_DOORBELL_OFF 0x20 /* XScale & ROC */
@@ -883,13 +1082,18 @@ struct mrsas_ctrl_info {
#define OB_SCRATCH_PAD_0_OFF 0xB0 /* ROC */
#define OB_INTR_MASK 0xFFFFFFFF
#define OB_DOORBELL_CLEAR_MASK 0xFFFFFFFF
-#define WRITE_SEQ_OFF 0x000000FC
-#define HOST_DIAG_OFF 0x000000F8
-#define DIAG_RESET_ADAPTER 0x00000004
-#define DIAG_WRITE_ENABLE 0x00000080
-/*
- * All MFI register set macros accept mrsas_register_set*
- */
+#define SYSTOIOP_INTERRUPT_MASK 0x80000000
+#define OB_SCRATCH_PAD_2_OFF 0xB4
+#define WRITE_TBOLT_SEQ_OFF 0x00000004
+#define DIAG_TBOLT_RESET_ADAPTER 0x00000004
+#define HOST_TBOLT_DIAG_OFF 0x00000008
+#define RESET_TBOLT_STATUS_OFF 0x000003C3
+#define WRITE_SEQ_OFF 0x000000FC
+#define HOST_DIAG_OFF 0x000000F8
+#define DIAG_RESET_ADAPTER 0x00000004
+#define DIAG_WRITE_ENABLE 0x00000080
+#define SYSTOIOP_INTERRUPT_MASK 0x80000000
+
#define WR_IB_WRITE_SEQ(v, instance) ddi_put32((instance)->regmap_handle, \
(uint32_t *)((uintptr_t)(instance)->regmap + WRITE_SEQ_OFF), (v))
@@ -899,6 +1103,13 @@ struct mrsas_ctrl_info {
#define WR_IB_DRWE(v, instance) ddi_put32((instance)->regmap_handle, \
(uint32_t *)((uintptr_t)(instance)->regmap + HOST_DIAG_OFF), (v))
+#define IB_LOW_QPORT 0xC0
+#define IB_HIGH_QPORT 0xC4
+#define OB_DOORBELL_REGISTER 0x9C /* 1078 implementation */
+
+/*
+ * All MFI register set macros accept mrsas_register_set*
+ */
#define WR_IB_MSG_0(v, instance) ddi_put32((instance)->regmap_handle, \
(uint32_t *)((uintptr_t)(instance)->regmap + IB_MSG_0_OFF), (v))
@@ -933,6 +1144,56 @@ struct mrsas_ctrl_info {
#define RD_OB_SCRATCH_PAD_0(instance) ddi_get32((instance)->regmap_handle, \
(uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_0_OFF))
+/* Thunderbolt specific registers */
+#define RD_OB_SCRATCH_PAD_2(instance) ddi_get32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_2_OFF))
+
+#define WR_TBOLT_IB_WRITE_SEQ(v, instance) \
+ ddi_put32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + WRITE_TBOLT_SEQ_OFF), (v))
+
+#define RD_TBOLT_HOST_DIAG(instance) ddi_get32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + HOST_TBOLT_DIAG_OFF))
+
+#define WR_TBOLT_HOST_DIAG(v, instance) ddi_put32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + HOST_TBOLT_DIAG_OFF), (v))
+
+#define RD_TBOLT_RESET_STAT(instance) ddi_get32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + RESET_TBOLT_STATUS_OFF))
+
+
+#define WR_MPI2_REPLY_POST_INDEX(v, instance)\
+ ddi_put32((instance)->regmap_handle,\
+ (uint32_t *)\
+ ((uintptr_t)(instance)->regmap + MPI2_REPLY_POST_HOST_INDEX_OFFSET),\
+ (v))
+
+
+#define RD_MPI2_REPLY_POST_INDEX(instance)\
+ ddi_get32((instance)->regmap_handle,\
+ (uint32_t *)\
+ ((uintptr_t)(instance)->regmap + MPI2_REPLY_POST_HOST_INDEX_OFFSET))
+
+#define WR_IB_LOW_QPORT(v, instance) ddi_put32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + IB_LOW_QPORT), (v))
+
+#define WR_IB_HIGH_QPORT(v, instance) ddi_put32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + IB_HIGH_QPORT), (v))
+
+#define WR_OB_DOORBELL_REGISTER_CLEAR(v, instance)\
+ ddi_put32((instance)->regmap_handle,\
+ (uint32_t *)((uintptr_t)(instance)->regmap + OB_DOORBELL_REGISTER), \
+ (v))
+
+#define WR_RESERVED0_REGISTER(v, instance) ddi_put32((instance)->regmap_handle,\
+ (uint32_t *)((uintptr_t)(instance)->regmap + RESERVED0_REGISTER), \
+ (v))
+
+#define RD_RESERVED0_REGISTER(instance) ddi_get32((instance)->regmap_handle, \
+ (uint32_t *)((uintptr_t)(instance)->regmap + RESERVED0_REGISTER))
+
+
+
/*
* When FW is in MFI_STATE_READY or MFI_STATE_OPERATIONAL, the state data
* of Outbound Msg Reg 0 indicates max concurrent cmds supported, max SGEs
@@ -948,6 +1209,9 @@ struct mrsas_ctrl_info {
#define MFI_REPLY_2108_MESSAGE_INTR 0x00000001
#define MFI_REPLY_2108_MESSAGE_INTR_MASK 0x00000005
+/* Fusion interrupt mask */
+#define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000008)
+
#define MFI_POLL_TIMEOUT_SECS 60
#define MFI_ENABLE_INTR(instance) ddi_put32((instance)->regmap_handle, \
@@ -973,45 +1237,45 @@ struct mrsas_ctrl_info {
* on_off_property of mrsas_ctrl_prop
* bit0-9, 11-31 are reserved
*/
-#define DISABLE_OCR_PROP_FLAG 0x00000400 /* bit 10 */
+#define DISABLE_OCR_PROP_FLAG 0x00000400 /* bit 10 */
struct mrsas_register_set {
- uint32_t reserved_0[4];
+ uint32_t reserved_0[4]; /* 0000h */
- uint32_t inbound_msg_0;
- uint32_t inbound_msg_1;
- uint32_t outbound_msg_0;
- uint32_t outbound_msg_1;
+ uint32_t inbound_msg_0; /* 0010h */
+ uint32_t inbound_msg_1; /* 0014h */
+ uint32_t outbound_msg_0; /* 0018h */
+ uint32_t outbound_msg_1; /* 001Ch */
- uint32_t inbound_doorbell;
- uint32_t inbound_intr_status;
- uint32_t inbound_intr_mask;
+ uint32_t inbound_doorbell; /* 0020h */
+ uint32_t inbound_intr_status; /* 0024h */
+ uint32_t inbound_intr_mask; /* 0028h */
- uint32_t outbound_doorbell;
- uint32_t outbound_intr_status;
- uint32_t outbound_intr_mask;
+ uint32_t outbound_doorbell; /* 002Ch */
+ uint32_t outbound_intr_status; /* 0030h */
+ uint32_t outbound_intr_mask; /* 0034h */
- uint32_t reserved_1[2];
+ uint32_t reserved_1[2]; /* 0038h */
- uint32_t inbound_queue_port;
- uint32_t outbound_queue_port;
+ uint32_t inbound_queue_port; /* 0040h */
+ uint32_t outbound_queue_port; /* 0044h */
- uint32_t reserved_2[22];
+ uint32_t reserved_2[22]; /* 0048h */
- uint32_t outbound_doorbell_clear;
+ uint32_t outbound_doorbell_clear; /* 00A0h */
- uint32_t reserved_3[3];
+ uint32_t reserved_3[3]; /* 00A4h */
- uint32_t outbound_scratch_pad;
+ uint32_t outbound_scratch_pad; /* 00B0h */
- uint32_t reserved_4[3];
+ uint32_t reserved_4[3]; /* 00B4h */
- uint32_t inbound_low_queue_port;
+ uint32_t inbound_low_queue_port; /* 00C0h */
- uint32_t inbound_high_queue_port;
+ uint32_t inbound_high_queue_port; /* 00C4h */
- uint32_t reserved_5;
- uint32_t index_registers[820];
+ uint32_t reserved_5; /* 00C8h */
+ uint32_t index_registers[820]; /* 00CCh */
};
struct mrsas_sge32 {
@@ -1037,24 +1301,24 @@ union mrsas_sgl {
};
struct mrsas_header {
- uint8_t cmd;
- uint8_t sense_len;
- uint8_t cmd_status;
- uint8_t scsi_status;
-
- uint8_t target_id;
- uint8_t lun;
- uint8_t cdb_len;
- uint8_t sge_count;
-
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
-
- uint16_t flags;
- uint16_t timeout;
- uint32_t data_xferlen;
+ uint8_t cmd; /* 00h */
+ uint8_t sense_len; /* 01h */
+ uint8_t cmd_status; /* 02h */
+ uint8_t scsi_status; /* 03h */
+
+ uint8_t target_id; /* 04h */
+ uint8_t lun; /* 05h */
+ uint8_t cdb_len; /* 06h */
+ uint8_t sge_count; /* 07h */
+
+ uint32_t context; /* 08h */
+ uint8_t req_id; /* 0Ch */
+ uint8_t msgvector; /* 0Dh */
+ uint16_t pad_0; /* 0Eh */
+
+ uint16_t flags; /* 10h */
+ uint16_t timeout; /* 12h */
+ uint32_t data_xferlen; /* 14h */
};
union mrsas_sgl_frame {
@@ -1063,198 +1327,199 @@ union mrsas_sgl_frame {
};
struct mrsas_init_frame {
- uint8_t cmd;
- uint8_t reserved_0;
- uint8_t cmd_status;
-
- uint8_t reserved_1;
- uint32_t reserved_2;
-
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
-
- uint16_t flags;
- uint16_t reserved_3;
- uint32_t data_xfer_len;
-
- uint32_t queue_info_new_phys_addr_lo;
- uint32_t queue_info_new_phys_addr_hi;
- uint32_t queue_info_old_phys_addr_lo;
- uint32_t queue_info_old_phys_addr_hi;
-
- uint32_t reserved_4[6];
+ uint8_t cmd; /* 00h */
+ uint8_t reserved_0; /* 01h */
+ uint8_t cmd_status; /* 02h */
+
+ uint8_t reserved_1; /* 03h */
+ uint32_t reserved_2; /* 04h */
+
+ uint32_t context; /* 08h */
+ uint8_t req_id; /* 0Ch */
+ uint8_t msgvector; /* 0Dh */
+ uint16_t pad_0; /* 0Eh */
+
+ uint16_t flags; /* 10h */
+ uint16_t reserved_3; /* 12h */
+ uint32_t data_xfer_len; /* 14h */
+
+ uint32_t queue_info_new_phys_addr_lo; /* 18h */
+ uint32_t queue_info_new_phys_addr_hi; /* 1Ch */
+ uint32_t queue_info_old_phys_addr_lo; /* 20h */
+ uint32_t queue_info_old_phys_addr_hi; /* 24h */
+ uint64_t driverversion; /* 28h */
+ uint32_t reserved_4[4]; /* 30h */
};
struct mrsas_init_queue_info {
- uint32_t init_flags;
- uint32_t reply_queue_entries;
-
- uint32_t reply_queue_start_phys_addr_lo;
- uint32_t reply_queue_start_phys_addr_hi;
- uint32_t producer_index_phys_addr_lo;
- uint32_t producer_index_phys_addr_hi;
- uint32_t consumer_index_phys_addr_lo;
- uint32_t consumer_index_phys_addr_hi;
+ uint32_t init_flags; /* 00h */
+ uint32_t reply_queue_entries; /* 04h */
+
+ uint32_t reply_queue_start_phys_addr_lo; /* 08h */
+ uint32_t reply_queue_start_phys_addr_hi; /* 0Ch */
+ uint32_t producer_index_phys_addr_lo; /* 10h */
+ uint32_t producer_index_phys_addr_hi; /* 14h */
+ uint32_t consumer_index_phys_addr_lo; /* 18h */
+ uint32_t consumer_index_phys_addr_hi; /* 1Ch */
};
struct mrsas_io_frame {
- uint8_t cmd;
- uint8_t sense_len;
- uint8_t cmd_status;
- uint8_t scsi_status;
+ uint8_t cmd; /* 00h */
+ uint8_t sense_len; /* 01h */
+ uint8_t cmd_status; /* 02h */
+ uint8_t scsi_status; /* 03h */
- uint8_t target_id;
- uint8_t access_byte;
- uint8_t reserved_0;
- uint8_t sge_count;
+ uint8_t target_id; /* 04h */
+ uint8_t access_byte; /* 05h */
+ uint8_t reserved_0; /* 06h */
+ uint8_t sge_count; /* 07h */
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
+ uint32_t context; /* 08h */
+ uint8_t req_id; /* 0Ch */
+ uint8_t msgvector; /* 0Dh */
+ uint16_t pad_0; /* 0Eh */
- uint16_t flags;
- uint16_t timeout;
- uint32_t lba_count;
+ uint16_t flags; /* 10h */
+ uint16_t timeout; /* 12h */
+ uint32_t lba_count; /* 14h */
- uint32_t sense_buf_phys_addr_lo;
- uint32_t sense_buf_phys_addr_hi;
+ uint32_t sense_buf_phys_addr_lo; /* 18h */
+ uint32_t sense_buf_phys_addr_hi; /* 1Ch */
- uint32_t start_lba_lo;
- uint32_t start_lba_hi;
+ uint32_t start_lba_lo; /* 20h */
+ uint32_t start_lba_hi; /* 24h */
- union mrsas_sgl sgl;
+ union mrsas_sgl sgl; /* 28h */
};
struct mrsas_pthru_frame {
- uint8_t cmd;
- uint8_t sense_len;
- uint8_t cmd_status;
- uint8_t scsi_status;
-
- uint8_t target_id;
- uint8_t lun;
- uint8_t cdb_len;
- uint8_t sge_count;
-
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
-
- uint16_t flags;
- uint16_t timeout;
- uint32_t data_xfer_len;
-
- uint32_t sense_buf_phys_addr_lo;
- uint32_t sense_buf_phys_addr_hi;
-
- uint8_t cdb[16];
- union mrsas_sgl sgl;
+ uint8_t cmd; /* 00h */
+ uint8_t sense_len; /* 01h */
+ uint8_t cmd_status; /* 02h */
+ uint8_t scsi_status; /* 03h */
+
+ uint8_t target_id; /* 04h */
+ uint8_t lun; /* 05h */
+ uint8_t cdb_len; /* 06h */
+ uint8_t sge_count; /* 07h */
+
+ uint32_t context; /* 08h */
+ uint8_t req_id; /* 0Ch */
+ uint8_t msgvector; /* 0Dh */
+ uint16_t pad_0; /* 0Eh */
+
+ uint16_t flags; /* 10h */
+ uint16_t timeout; /* 12h */
+ uint32_t data_xfer_len; /* 14h */
+
+ uint32_t sense_buf_phys_addr_lo; /* 18h */
+ uint32_t sense_buf_phys_addr_hi; /* 1Ch */
+
+ uint8_t cdb[16]; /* 20h */
+ union mrsas_sgl sgl; /* 30h */
};
struct mrsas_dcmd_frame {
- uint8_t cmd;
- uint8_t reserved_0;
- uint8_t cmd_status;
- uint8_t reserved_1[4];
- uint8_t sge_count;
+ uint8_t cmd; /* 00h */
+ uint8_t reserved_0; /* 01h */
+ uint8_t cmd_status; /* 02h */
+ uint8_t reserved_1[4]; /* 03h */
+ uint8_t sge_count; /* 07h */
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
+ uint32_t context; /* 08h */
+ uint8_t req_id; /* 0Ch */
+ uint8_t msgvector; /* 0Dh */
+ uint16_t pad_0; /* 0Eh */
- uint16_t flags;
- uint16_t timeout;
+ uint16_t flags; /* 10h */
+ uint16_t timeout; /* 12h */
- uint32_t data_xfer_len;
- uint32_t opcode;
+ uint32_t data_xfer_len; /* 14h */
+ uint32_t opcode; /* 18h */
- union {
+ /* uint8_t mbox[DCMD_MBOX_SZ]; */ /* 1Ch */
+ union { /* 1Ch */
uint8_t b[DCMD_MBOX_SZ];
uint16_t s[6];
uint32_t w[3];
} mbox;
- union mrsas_sgl sgl;
+ union mrsas_sgl sgl; /* 28h */
};
struct mrsas_abort_frame {
- uint8_t cmd;
- uint8_t reserved_0;
- uint8_t cmd_status;
+ uint8_t cmd; /* 00h */
+ uint8_t reserved_0; /* 01h */
+ uint8_t cmd_status; /* 02h */
- uint8_t reserved_1;
- uint32_t reserved_2;
+ uint8_t reserved_1; /* 03h */
+ uint32_t reserved_2; /* 04h */
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
+ uint32_t context; /* 08h */
+ uint8_t req_id; /* 0Ch */
+ uint8_t msgvector; /* 0Dh */
+ uint16_t pad_0; /* 0Eh */
- uint16_t flags;
- uint16_t reserved_3;
- uint32_t reserved_4;
+ uint16_t flags; /* 10h */
+ uint16_t reserved_3; /* 12h */
+ uint32_t reserved_4; /* 14h */
- uint32_t abort_context;
- uint32_t pad_1;
+ uint32_t abort_context; /* 18h */
+ uint32_t pad_1; /* 1Ch */
- uint32_t abort_mfi_phys_addr_lo;
- uint32_t abort_mfi_phys_addr_hi;
+ uint32_t abort_mfi_phys_addr_lo; /* 20h */
+ uint32_t abort_mfi_phys_addr_hi; /* 24h */
- uint32_t reserved_5[6];
+ uint32_t reserved_5[6]; /* 28h */
};
struct mrsas_smp_frame {
- uint8_t cmd;
- uint8_t reserved_1;
- uint8_t cmd_status;
- uint8_t connection_status;
+ uint8_t cmd; /* 00h */
+ uint8_t reserved_1; /* 01h */
+ uint8_t cmd_status; /* 02h */
+ uint8_t connection_status; /* 03h */
- uint8_t reserved_2[3];
- uint8_t sge_count;
+ uint8_t reserved_2[3]; /* 04h */
+ uint8_t sge_count; /* 07h */
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
+ uint32_t context; /* 08h */
+ uint8_t req_id; /* 0Ch */
+ uint8_t msgvector; /* 0Dh */
+ uint16_t pad_0; /* 0Eh */
- uint16_t flags;
- uint16_t timeout;
+ uint16_t flags; /* 10h */
+ uint16_t timeout; /* 12h */
- uint32_t data_xfer_len;
+ uint32_t data_xfer_len; /* 14h */
- uint64_t sas_addr;
+ uint64_t sas_addr; /* 20h */
- union mrsas_sgl sgl[2];
+ union mrsas_sgl sgl[2]; /* 28h */
};
struct mrsas_stp_frame {
- uint8_t cmd;
- uint8_t reserved_1;
- uint8_t cmd_status;
- uint8_t connection_status;
+ uint8_t cmd; /* 00h */
+ uint8_t reserved_1; /* 01h */
+ uint8_t cmd_status; /* 02h */
+ uint8_t connection_status; /* 03h */
- uint8_t target_id;
- uint8_t reserved_2[2];
- uint8_t sge_count;
+ uint8_t target_id; /* 04h */
+ uint8_t reserved_2[2]; /* 04h */
+ uint8_t sge_count; /* 07h */
- uint32_t context;
- uint8_t req_id;
- uint8_t msgvector;
- uint16_t pad_0;
+ uint32_t cont